75 : target_{.function =
reinterpret_cast<ErasedFunction
>(fp)},
76 invoke_(fp ? &invoke_function_pointer_<
decltype(fp)> :
nullptr) {}
82 std::enable_if_t<std::is_pointer_v<Fp> &&
83 std::is_function_v<std::remove_pointer_t<Fp>> &&
84 std::is_invocable_r_v<R, Fp, Args...>,
int> = 0>
86 : target_{.function =
reinterpret_cast<ErasedFunction
>(fp)},
87 invoke_(fp ? &invoke_function_pointer_<Fp> :
nullptr) {}
93 class = std::enable_if_t<
94 !std::is_same_v<std::remove_cvref_t<Fn>,
function_ref> &&
95 !std::is_pointer_v<std::remove_cvref_t<Fn>> &&
96 !std::is_function_v<std::remove_reference_t<Fn>> &&
97 !std::is_member_pointer_v<std::remove_cvref_t<Fn>> &&
98 std::is_invocable_r_v<R, Fn&, Args...>>>
100 : target_{.object =
static_cast<const void*
>(std::addressof(fn))},
101 invoke_(&invoke_callable_<std::remove_reference_t<Fn>>) {}
108 target_.object =
nullptr;
114 target_.function =
reinterpret_cast<ErasedFunction
>(fp);
115 invoke_ = fp ? &invoke_function_pointer_<
decltype(fp)> :
nullptr;
120 std::enable_if_t<std::is_pointer_v<Fp> &&
121 std::is_function_v<std::remove_pointer_t<Fp>> &&
122 std::is_invocable_r_v<R, Fp, Args...>,
int> = 0>
124 target_.function =
reinterpret_cast<ErasedFunction
>(fp);
125 invoke_ = fp ? &invoke_function_pointer_<Fp> :
nullptr;
130 class = std::enable_if_t<
131 !std::is_same_v<std::remove_cvref_t<Fn>,
function_ref> &&
132 !std::is_pointer_v<std::remove_cvref_t<Fn>> &&
133 !std::is_function_v<std::remove_reference_t<Fn>> &&
134 !std::is_member_pointer_v<std::remove_cvref_t<Fn>> &&
135 std::is_invocable_r_v<R, Fn&, Args...>>>
137 target_.object =
static_cast<const void*
>(std::addressof(fn));
138 invoke_ = &invoke_callable_<std::remove_reference_t<Fn>>;
143 explicit constexpr operator bool() const noexcept {
return invoke_ !=
nullptr; }
148 return invoke_(target_, std::forward<Args>(args)...);
152 return a.invoke_ ==
nullptr;
155 return a.invoke_ ==
nullptr;
158 return a.invoke_ !=
nullptr;
161 return a.invoke_ !=
nullptr;
165 using ErasedFunction = void (*)();
167 const void*
object =
nullptr;
168 ErasedFunction function;
170 using Invoker = R (*)(Target, Args...);
173 static R invoke_callable_(Target target, Args... args) {
175 auto* p =
const_cast<Fn*
>(
static_cast<const Fn*
>(target.object));
176 if constexpr (std::is_void_v<R>) {
177 std::invoke(*p, std::forward<Args>(args)...);
179 return std::invoke(*p, std::forward<Args>(args)...);
184 static R invoke_function_pointer_(Target target, Args... args) {
187 auto fp =
reinterpret_cast<Fp
>(target.function);
188 if constexpr (std::is_void_v<R>) {
189 std::invoke(fp, std::forward<Args>(args)...);
191 return std::invoke(fp, std::forward<Args>(args)...);
196 Invoker invoke_ =
nullptr;