30 template <
typename Ret,
typename... Args>
33 using Storage =
void*;
35 using Move = void (*) (Storage, Storage);
36 using Call = Ret (*) (Storage, Args...);
37 using Clear = void (*) (Storage);
39 constexpr Vtable (Move moveIn, Call callIn, Clear clearIn) noexcept
40 :
move (moveIn), call (callIn), clear (clearIn) {}
44 Clear clear =
nullptr;
47 template <
typename Fn>
50 new (
to)
Fn (std::move (*
reinterpret_cast<Fn*
> (
from)));
53 template <
typename Fn,
typename Ret,
typename... Args>
56 (*
reinterpret_cast<Fn*
> (s)) (std::forward<Args> (args)...);
59 template <
typename Fn,
typename Ret,
typename... Args>
62 return (*
reinterpret_cast<Fn*
> (s)) (std::forward<Args> (args)...);
65 template <
typename Fn>
73 template <
typename Fn,
typename Ret,
typename... Args>
80template <
size_t len,
typename T>
81class FixedSizeFunction;
95template <
size_t len,
typename Ret,
typename... Args>
96class FixedSizeFunction<len,
Ret (Args...)>
101 template <
typename Item>
104 template <
typename Item,
typename Fn = Decay<Item>>
106 &&
alignof (
Fn) <=
alignof (Storage)
107 && ! std::is_same_v<FixedSizeFunction, Fn>,
115 FixedSizeFunction (
std::nullptr_t) noexcept
116 : FixedSizeFunction() {}
118 FixedSizeFunction (
const FixedSizeFunction&) =
delete;
121 template <
typename Callable,
122 typename Fn = Decay<Callable>,
123 IntIfValidConversion<Callable> = 0>
126 static_assert (
sizeof (
Fn) <= len,
127 "The requested function cannot fit in this FixedSizeFunction");
128 static_assert (
alignof (
Fn) <=
alignof (Storage),
129 "FixedSizeFunction cannot accommodate the requested alignment requirements");
131 static constexpr auto vtableForCallable = detail::makeVtable<
Fn, Ret, Args...>();
132 vtable = &vtableForCallable;
134 [[maybe_unused]]
auto* ptr =
new (&storage)
Fn (std::forward<Callable> (callable));
135 jassert ((
void*) ptr == (
void*) &storage);
140 : vtable (other.vtable)
142 move (std::move (other));
146 template <
size_t otherLen, std::enable_if_t<(otherLen < len),
int> = 0>
147 FixedSizeFunction (FixedSizeFunction<otherLen, Ret (Args...)>&& other) noexcept
148 : vtable (other.vtable)
150 move (std::move (other));
154 FixedSizeFunction& operator= (std::
nullptr_t) noexcept
156 return *this = FixedSizeFunction();
159 FixedSizeFunction& operator= (const FixedSizeFunction&) = delete;
162 template <
typename Callable, IntIfVal
idConversion<Callable> = 0>
163 FixedSizeFunction& operator= (Callable&& callable)
165 return *
this = FixedSizeFunction (std::forward<Callable> (callable));
169 template <
size_t otherLen, std::enable_if_t<(otherLen < len),
int> = 0>
170 FixedSizeFunction& operator= (FixedSizeFunction<otherLen, Ret (Args...)>&& other) noexcept
172 return *this = FixedSizeFunction (std::move (other));
176 FixedSizeFunction& operator= (FixedSizeFunction&& other) noexcept
179 vtable = other.vtable;
180 move (std::move (other));
185 ~FixedSizeFunction() noexcept { clear(); }
190 Ret operator() (Args... args) const
192 if (vtable !=
nullptr)
193 return vtable->call (&storage, std::forward<Args> (args)...);
199 explicit operator bool()
const noexcept {
return vtable !=
nullptr; }
202 template <
size_t,
typename>
203 friend class FixedSizeFunction;
205 void clear() noexcept
207 if (vtable !=
nullptr)
208 vtable->clear (&storage);
211 template <
size_t otherLen,
typename T>
214 if (vtable !=
nullptr)
215 vtable->move (&
other.storage, &storage);
218 const detail::Vtable<
Ret, Args...>* vtable =
nullptr;
219 mutable Storage storage;
222template <
size_t len,
typename T>
223bool operator!= (
const FixedSizeFunction<len, T>& fn,
std::nullptr_t) {
return bool (fn); }
225template <
size_t len,
typename T>
226bool operator!= (
std::nullptr_t,
const FixedSizeFunction<len, T>& fn) {
return bool (fn); }
228template <
size_t len,
typename T>
229bool operator== (
const FixedSizeFunction<len, T>& fn,
std::nullptr_t) {
return ! (fn !=
nullptr); }
231template <
size_t len,
typename T>
232bool operator== (
std::nullptr_t,
const FixedSizeFunction<len, T>& fn) {
return ! (fn !=
nullptr); }
FixedSizeFunction() noexcept=default
Create an empty function.
FixedSizeFunction(FixedSizeFunction &&other) noexcept
Move constructor.
FixedSizeFunction(Callable &&callable)
Forwards the passed Callable into the internal storage buffer.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...