50 class Function<Return (Args...), Capacity, Alignment>
77 moveFrom (std::move (other));
88 moveFrom (std::move (other));
113 template <
typename Func,
typename DecayedFunc = std::decay_t<Func>,
114 typename = std::enable_if_t<
115 !std::is_same<DecayedFunc, Function>::value &&
116 (std::is_
void<Return>::value ||
117 std::is_convertible<
typename std::result_of<DecayedFunc&(Args...)>::type, Return>::value)>>
120 static_assert (
sizeof (DecayedFunc) <= Capacity,
"Callable size exceeds Function capacity.");
121 static_assert (
alignof (DecayedFunc) <= Alignment,
"Callable alignment exceeds Function alignment.");
122 static_assert (std::is_nothrow_move_constructible<DecayedFunc>::value,
123 "Callable must be nothrow move constructible.");
125 new (&_storage) DecayedFunc (std::forward<Func> (callable));
127 _invoker = [] (
void* storage, Args&&... args) -> Return {
128 return static_cast<Return
> ((*
static_cast<DecayedFunc*
> (storage)) (std::forward<Args> (args)...));
132 _destructor =
nullptr;
134 if (!std::is_trivially_copyable<DecayedFunc>::value)
136 _manager = [] (
void* dst,
void* src)
noexcept {
137 DecayedFunc* source =
static_cast<DecayedFunc*
> (src);
138 new (dst) DecayedFunc (std::move (*source));
139 source->~DecayedFunc ();
143 if (!std::is_trivially_destructible<DecayedFunc>::value)
145 _destructor = [] (
void* storage)
noexcept {
146 static_cast<DecayedFunc*
> (storage)->~DecayedFunc ();
152 _size = std::is_empty<DecayedFunc>::value ? 0 :
sizeof (DecayedFunc);
169 Return operator() (Args... args)
const
173 throw std::bad_function_call ();
175 return _invoker (&_storage, std::forward<Args> (args)...);
182 explicit operator bool () const noexcept
184 return _invoker !=
nullptr;
201 other = std::move (*
this);
202 *
this = std::move (tmp);
207 using InvokerFunc = Return (*) (
void*, Args&&...);
210 using ManagerFunc = void (*) (
void*,
void*);
213 using DestructorFunc = void (*) (
void*);
218 void clear () noexcept
220 if (_invoker ==
nullptr)
227 _destructor (&_storage);
232 _destructor =
nullptr;
239 void moveFrom (Function&& other)
noexcept
241 _invoker = other._invoker;
242 _manager = other._manager;
243 _destructor = other._destructor;
246 if (_invoker ==
nullptr)
253 _manager (&_storage, &other._storage);
257 std::memcpy (&_storage, &other._storage, _size);
260 other._invoker =
nullptr;
261 other._manager =
nullptr;
262 other._destructor =
nullptr;
267 alignas (Alignment)
mutable unsigned char _storage[Capacity];
270 InvokerFunc _invoker =
nullptr;
273 ManagerFunc _manager =
nullptr;
276 DestructorFunc _destructor =
nullptr;
279 std::size_t _size = 0;