25#ifndef JOIN_CORE_FUNCTION_HPP
26#define JOIN_CORE_FUNCTION_HPP
42 template <
typename Signature, std::
size_t Capacity = 32, std::
size_t Alignment = alignof (std::max_align_t)>
48 template <
typename Return,
typename... Args, std::size_t Capacity, std::size_t Alignment>
49 class Function<Return (Args...), Capacity, Alignment>
76 moveFrom (std::move (other));
87 moveFrom (std::move (other));
112 template <
typename Func,
typename DecayedFunc = std::decay_t<Func>,
113 typename = std::enable_if_t<
114 !std::is_same<DecayedFunc, Function>::value &&
115 (std::is_
void<Return>::value ||
116 std::is_convertible<
typename std::result_of<DecayedFunc&(Args...)>::type, Return>::value)>>
119 static_assert (
sizeof (DecayedFunc) <= Capacity,
"Callable size exceeds Function capacity.");
120 static_assert (
alignof (DecayedFunc) <= Alignment,
"Callable alignment exceeds Function alignment.");
121 static_assert (std::is_nothrow_move_constructible<DecayedFunc>::value,
122 "Callable must be nothrow move constructible.");
124 new (&_storage) DecayedFunc (std::forward<Func> (callable));
126 _invoker = [] (
void* storage, Args&&... args) -> Return {
127 return static_cast<Return
> ((*
static_cast<DecayedFunc*
> (storage)) (std::forward<Args> (args)...));
130 _manager = [] (
void* dst,
void* src)
noexcept {
131 DecayedFunc* source =
static_cast<DecayedFunc*
> (src);
132 new (dst) DecayedFunc (std::move (*source));
133 source->~DecayedFunc ();
136 _destructor = [] (
void* storage)
noexcept {
137 static_cast<DecayedFunc*
> (storage)->~DecayedFunc ();
155 Return operator() (Args&&... args)
159 throw std::bad_function_call ();
161 return _invoker (&_storage, std::forward<Args> (args)...);
168 explicit operator bool () const noexcept
170 return _invoker !=
nullptr;
187 other = std::move (*
this);
188 *
this = std::move (tmp);
193 using InvokerFunc = Return (*) (
void*, Args&&...);
196 using ManagerFunc = void (*) (
void*,
void*);
199 using DestructorFunc = void (*) (
void*);
204 void clear () noexcept
208 _destructor (&_storage);
211 _destructor =
nullptr;
218 void moveFrom (Function&& other)
noexcept
220 _invoker = other._invoker;
221 _manager = other._manager;
222 _destructor = other._destructor;
226 _manager (&_storage, &other._storage);
227 other._invoker =
nullptr;
228 other._manager =
nullptr;
229 other._destructor =
nullptr;
234 alignas (Alignment)
unsigned char _storage[Capacity];
237 InvokerFunc _invoker =
nullptr;
240 ManagerFunc _manager =
nullptr;
243 DestructorFunc _destructor =
nullptr;
Function(Func &&callable)
construct with a callable object.
Definition function.hpp:117
void reset() noexcept
clear the stored callable.
Definition function.hpp:176
Function(std::nullptr_t) noexcept
construct from nullptr.
Definition function.hpp:94
void swap(Function &other) noexcept
swap two Function instances.
Definition function.hpp:184
~Function()
destructor.
Definition function.hpp:144
Function() noexcept=default
default constructor.
fixed-capacity move-only allocation-free alternative to std::function.
Definition function.hpp:43
Definition acceptor.hpp:32