40template <
typename Signature, std::size_t Capacity = 32,
41 std::size_t Alignment =
alignof(std::max_align_t)>
44template <
typename R,
typename... Args, std::size_t Capacity, std::size_t Alignment>
46 static_assert(Capacity >=
sizeof(
void*),
"Capacity must hold at least a pointer");
47 static_assert(Alignment > 0 && (Alignment & (Alignment - 1)) == 0,
48 "Alignment must be a power of two");
51 static constexpr std::size_t
capacity = Capacity;
56 static constexpr bool fits =
57 sizeof(std::decay_t<F>) <= Capacity &&
alignof(std::decay_t<F>) <= Alignment &&
58 std::is_nothrow_move_constructible_v<std::decay_t<F>>;
63 template <
typename F,
typename D = std::decay_t<F>,
64 typename = std::enable_if_t<!std::is_same_v<D, FixedFunction> &&
65 !std::is_same_v<D, std::
nullptr_t> &&
66 std::is_invocable_r_v<R, D&, Args...>>>
68 std::is_nothrow_constructible_v<D, F&&>) {
69 static_assert(
sizeof(D) <= Capacity,
70 "callable is too large for this FixedFunction: capture less (pointers or "
71 "indices instead of objects) or raise Capacity");
72 static_assert(
alignof(D) <= Alignment,
73 "callable needs stricter alignment than this FixedFunction provides");
74 static_assert(std::is_nothrow_move_constructible_v<D>,
75 "callable must be nothrow move constructible so moving a FixedFunction "
77 ::new (
static_cast<void*
>(storage_)) D(std::forward<F>(f));
78 vtable_ = &vtable_for<D>;
101 template <
typename F,
typename D = std::decay_t<F>,
102 typename = std::enable_if_t<!std::is_same_v<D, FixedFunction> &&
103 !std::is_same_v<D, std::
nullptr_t> &&
104 std::is_invocable_r_v<R, D&, Args...>>>
107 return *
this = std::move(replacement);
117 vtable_->destroy(storage_);
124 other = std::move(*
this);
125 *
this = std::move(tmp);
128 [[nodiscard]]
explicit operator bool() const noexcept {
129 return vtable_ !=
nullptr;
136 return static_cast<bool>(f);
141 return vtable_->invoke(storage_, std::forward<Args>(args)...);
146 R (*invoke)(
void* target, Args&&... args);
147 void (*relocate)(
void* dst,
void* src)
noexcept;
148 void (*destroy)(
void* target)
noexcept;
151 template <
typename D>
152 static constexpr VTable vtable_for = {
153 [](
void* target, Args&&... args) -> R {
154 D& callable = *
static_cast<D*
>(target);
155 if constexpr (std::is_void_v<R>) {
156 callable(std::forward<Args>(args)...);
158 return callable(std::forward<Args>(args)...);
161 [](
void* dst,
void* src)
noexcept {
162 ::new (dst) D(std::move(*
static_cast<D*
>(src)));
163 static_cast<D*
>(src)->~D();
165 [](
void* target)
noexcept {
static_cast<D*
>(target)->~D(); },
168 void take(FixedFunction&
other)
noexcept {
170 other.vtable_->relocate(storage_,
other.storage_);
171 vtable_ =
other.vtable_;
172 other.vtable_ =
nullptr;
176 alignas(Alignment)
unsigned char storage_[Capacity];
177 const VTable* vtable_ =
nullptr;
FixedFunction() noexcept=default
FixedFunction(FixedFunction &&other) noexcept
Definition fixed_function.hpp:84
FixedFunction(F &&f) noexcept(std::is_nothrow_constructible_v< D, F && >)
Definition fixed_function.hpp:67
FixedFunction & operator=(std::nullptr_t) noexcept
Definition fixed_function.hpp:96
FixedFunction & operator=(FixedFunction &&other) noexcept
Definition fixed_function.hpp:88
static constexpr std::size_t capacity
Definition fixed_function.hpp:51
FixedFunction & operator=(const FixedFunction &)=delete
R operator()(Args... args)
Call the target. Precondition: not empty (undefined behaviour otherwise).
Definition fixed_function.hpp:140
static constexpr bool fits
True if a callable of type F can be stored.
Definition fixed_function.hpp:56
~FixedFunction()
Definition fixed_function.hpp:110
friend bool operator!=(const FixedFunction &f, std::nullptr_t) noexcept
Definition fixed_function.hpp:135
friend bool operator==(const FixedFunction &f, std::nullptr_t) noexcept
Definition fixed_function.hpp:132
void reset() noexcept
Destroy the target and become empty.
Definition fixed_function.hpp:115
FixedFunction(const FixedFunction &)=delete
FixedFunction & operator=(F &&f) noexcept(std::is_nothrow_constructible_v< D, F && >)
Definition fixed_function.hpp:105
static constexpr std::size_t alignment
Definition fixed_function.hpp:52
void swap(FixedFunction &other) noexcept
Definition fixed_function.hpp:122
Definition fixed_function.hpp:42
Definition generated_event_source.hpp:33
@ other
Definition udev_monitor.hpp:26