20#include "pw_preprocessor/compiler.h"
42template <
typename Signature>
46inline constexpr bool is_function_ref_v =
false;
48template <
typename Sig>
49inline constexpr bool is_function_ref_v<FunctionRef<Sig>> =
true;
51namespace function::internal {
53template <
bool kIsConst,
bool IsNoExcept,
typename R,
typename... Args>
58 alignas(
void*)
char buffer[
sizeof(
void*)];
62template <
bool kIsConst,
typename R,
typename... Args>
67 std::enable_if_t<std::is_function_v<F> &&
68 std::is_invocable_r_v<R, F*, Args...>,
71 : invoker_([](
void* obj_ptr, Args... args) -> R {
72 Storage* s = static_cast<Storage*>(obj_ptr);
73 return (*reinterpret_cast<F*>(s->ptr))(std::forward<Args>(args)...);
75 obj_.ptr =
reinterpret_cast<void*
>(f);
81 !is_function_ref_v<std::decay_t<F>> &&
82 !std::is_member_pointer_v<std::remove_reference_t<F>> &&
83 std::is_invocable_r_v<
85 std::conditional_t<kIsConst,
86 const std::remove_reference_t<F>&,
87 std::remove_reference_t<F>&>,
91 : invoker_([](
void* obj_ptr, Args... args) -> R {
92 Storage* s = static_cast<Storage*>(obj_ptr);
93 using FPtr = std::conditional_t<kIsConst,
94 const std::remove_reference_t<F>*,
95 std::remove_reference_t<F>*>;
96 return (*static_cast<FPtr>(s->ptr))(std::forward<Args>(args)...);
98 obj_.ptr =
const_cast<void*
>(
static_cast<const void*
>(&f));
102 template <
bool kOtherConst,
104 std::enable_if_t<(!kOtherConst || kIsConst),
int> = 0>
108 : obj_(other.obj_), invoker_(other.invoker_) {}
113 R operator()(Args... args)
const {
114 return invoker_(
const_cast<Storage*
>(&obj_), std::forward<Args>(args)...);
118 template <bool, bool,
typename,
typename...>
121 using Invoker = R (*)(
void*, Args...);
128template <
bool kIsConst,
typename R,
typename... Args>
132 template <
typename F,
133 std::enable_if_t<std::is_function_v<F> &&
134 std::is_invocable_r_v<R, F*, Args...> &&
135 std::is_nothrow_invocable_v<F*, Args...>,
138 : invoker_([](
void* obj_ptr, Args... args) noexcept -> R {
139 Storage* s = static_cast<Storage*>(obj_ptr);
140 return (*reinterpret_cast<F*>(s->ptr))(std::forward<Args>(args)...);
142 obj_.ptr =
reinterpret_cast<void*
>(f);
146 template <
typename F,
148 !is_function_ref_v<std::decay_t<F>> &&
149 !std::is_member_pointer_v<std::remove_reference_t<F>> &&
150 std::is_invocable_r_v<
152 std::conditional_t<kIsConst,
153 const std::remove_reference_t<F>&,
154 std::remove_reference_t<F>&>,
156 std::is_nothrow_invocable_v<
157 std::conditional_t<kIsConst,
158 const std::remove_reference_t<F>&,
159 std::remove_reference_t<F>&>,
163 : invoker_([](
void* obj_ptr, Args... args) noexcept -> R {
164 Storage* s = static_cast<Storage*>(obj_ptr);
165 using FPtr = std::conditional_t<kIsConst,
166 const std::remove_reference_t<F>*,
167 std::remove_reference_t<F>*>;
168 return (*static_cast<FPtr>(s->ptr))(std::forward<Args>(args)...);
170 obj_.ptr =
const_cast<void*
>(
static_cast<const void*
>(&f));
177 std::enable_if_t<kOtherNoExcept && (!kOtherConst || kIsConst),
int> = 0>
181 : obj_(other.obj_), invoker_(other.invoker_) {}
186 R operator()(Args... args)
const noexcept {
187 return invoker_(
const_cast<Storage*
>(&obj_), std::forward<Args>(args)...);
191 template <bool, bool,
typename,
typename...>
194 using Invoker = R (*)(
void*, Args...)
noexcept;
203template <
typename R,
typename... Args>
215template <
typename R,
typename... Args>
227template <
typename R,
typename... Args>
239template <
typename R,
typename... Args>
Definition: function_ref.h:43
Definition: function_ref.h:54
#define PW_ATTRIBUTE_LIFETIME_BOUND
Definition: compiler.h:267
The Pigweed namespace.
Definition: alignment.h:27
Definition: function_ref.h:56