16#include <initializer_list>
24# define NOEXCEPT_SPECIFIER
25# define NOEXCEPT_SPECIALIZATION
27# define NOEXCEPT_SPECIFIER noexcept(IsNoExcept)
28# define NOEXCEPT_SPECIALIZATION , bool IsNoExcept
38 static constexpr bool isNoExcept =
false;
40 static constexpr bool isNoExcept = IsNoExcept;
43 template <
typename CallableType>
45 using is_callable = std::conditional_t<isNoExcept,
46 std::is_nothrow_invocable_r<ResultType, CallableType, ArgTypes...>,
47 std::is_invocable_r<ResultType, CallableType, ArgTypes...>>;
49 template <
typename UnqualifiedCallableType>
51 using is_qualified_callable =
52 std::conjunction<is_callable<UnqualifiedCallableType GENERATE_WITH_CV GENERATE_WITH_REF>,
53 is_callable<UnqualifiedCallableType GENERATE_WITH_SELF_QUALIFIERS>>;
65 , activeDispatcherFunction_(std::exchange(other.activeDispatcherFunction_,
nullptr))
69 template <
typename CallableType,
70 typename DecayedCallableType = std::decay_t<CallableType>,
71 std::enable_if_t<std::conjunction_v<std::negation<std::is_same<DecayedCallableType, MoveOnlyFunctionImpl>>,
72 std::negation<IsInPlaceType<DecayedCallableType>>,
73 is_qualified_callable<DecayedCallableType>>,
78 if constexpr (std::is_function_v<std::remove_pointer_t<DecayedCallableType>> ||
82 if constexpr (!std::is_reference_v<CallableType>)
84 if (callable ==
nullptr)
91 activeDispatcherFunction_ = &dispatcherFunction<DecayedCallableType>;
94 template <
typename CallableType,
95 typename... FunctionArgTypes,
96 std::enable_if_t<std::conjunction_v<std::is_constructible<CallableType, FunctionArgTypes...>,
97 is_qualified_callable<CallableType>>,
100 FunctionArgTypes&&... args)
noexcept(
isNothrowInit<CallableType, FunctionArgTypes...>())
101 : activeDispatcherFunction_(&dispatcherFunction<CallableType>)
103 static_assert(std::is_same_v<std::decay_t<CallableType>, CallableType>);
108 typename CallableType,
110 typename... FunctionArgTypes,
112 std::conjunction_v<std::is_constructible<CallableType, std::initializer_list<ILArgTypes>&, FunctionArgTypes...>,
113 is_qualified_callable<CallableType>>,
116 std::initializer_list<ILArgTypes> initializeList,
117 FunctionArgTypes&&... args)
noexcept(
isNothrowInit<CallableType,
118 std::initializer_list<ILArgTypes>&,
119 FunctionArgTypes...>())
120 : activeDispatcherFunction_(&dispatcherFunction<CallableType>)
122 static_assert(std::is_same_v<std::decay_t<CallableType>, CallableType>);
129 activeDispatcherFunction_ = std::exchange(other.activeDispatcherFunction_,
nullptr);
137 activeDispatcherFunction_ =
nullptr;
146 assert(*
this !=
nullptr &&
"Trying to execute empty callable object.");
147 return activeDispatcherFunction_(
this, std::forward<ArgTypes>(args)...);
151 explicit operator bool() const noexcept {
return activeDispatcherFunction_ !=
nullptr; }
156 return lhs.activeDispatcherFunction_ ==
nullptr;
162 return lhs.activeDispatcherFunction_ !=
nullptr;
172 std::swap(activeDispatcherFunction_, other.activeDispatcherFunction_);
176 template <
typename ParameterType>
177 using SanitizedParameterType = std::conditional_t<std::is_scalar_v<ParameterType>, ParameterType, ParameterType&&>;
179 template <
typename Tp>
181 SanitizedParameterType<ArgTypes>... args)
noexcept(isNoExcept)
184 std::forward<Tp GENERATE_WITH_SELF_QUALIFIERS>(*getCallableAs<Tp GENERATE_WITH_CV>(self)),
185 std::forward<SanitizedParameterType<ArgTypes>>(args)...);
188 using DispatcherFunctionType = ResultType (*)(MoveOnlyFunctionBase
GENERATE_WITH_CV*,
189 SanitizedParameterType<ArgTypes>...)
noexcept(isNoExcept);
190 DispatcherFunctionType activeDispatcherFunction_ =
nullptr;
195#undef GENERATE_WITH_CV
196#undef GENERATE_WITH_REF
197#undef GENERATE_WITH_SELF_QUALIFIERS
198#undef NOEXCEPT_SPECIFIER
199#undef NOEXCEPT_SPECIALIZATION
Definition move_only_function.h:56
MoveOnlyFunctionBase() noexcept
Definition move_only_function.h:86
static constexpr bool isNothrowInit() noexcept
Returns true if the given CallableType can be initialized without throwing given the specified ArgTyp...
Definition move_only_function.h:60
void swap(MoveOnlyFunctionBase &other) noexcept
Definition move_only_function.h:128
void initializeCallable(ArgTypes &&... args) noexcept(isNothrowInit< CallableType, ArgTypes... >())
Definition move_only_function.h:94
MoveOnlyFunctionBase & operator=(MoveOnlyFunctionBase &&other) noexcept
Definition move_only_function.h:111
void swap(MoveOnlyFunctionImpl &other) noexcept
Swaps the target of the std::move_only_function objects.
Definition move_only_function_impl.h:169
friend bool operator==(const MoveOnlyFunctionImpl &lhs, std::nullptr_t) noexcept
Compares a std::move_only_function with nullptr.
Definition move_only_function_impl.h:154
MoveOnlyFunctionImpl(CallableType &&callable) noexcept(isNothrowInit< DecayedCallableType, CallableType >())
Definition move_only_function_impl.h:76
MoveOnlyFunctionImpl & operator=(std::nullptr_t) noexcept
Replaces or destroys the target.
Definition move_only_function_impl.h:134
ResultType operator()(ArgTypes... args) GENERATE_WITH_CV GENERATE_WITH_REF noexcept(isNoExcept)
Invokes the target.
Definition move_only_function_impl.h:144
MoveOnlyFunctionImpl(MoveOnlyFunctionImpl &&other) noexcept
Definition move_only_function_impl.h:63
~MoveOnlyFunctionImpl()=default
MoveOnlyFunctionImpl() noexcept=default
friend bool operator!=(const MoveOnlyFunctionImpl &lhs, std::nullptr_t) noexcept
Compares a std::move_only_function with nullptr.
Definition move_only_function_impl.h:160
ResultType result_type
Definition move_only_function_impl.h:56
MoveOnlyFunctionImpl & operator=(MoveOnlyFunctionImpl &&other) noexcept
Definition move_only_function_impl.h:126
MoveOnlyFunctionImpl(std::in_place_type_t< CallableType >, std::initializer_list< ILArgTypes > initializeList, FunctionArgTypes &&... args) noexcept(isNothrowInit< CallableType, std::initializer_list< ILArgTypes > &, FunctionArgTypes... >())
Definition move_only_function_impl.h:115
MoveOnlyFunctionImpl(std::in_place_type_t< CallableType >, FunctionArgTypes &&... args) noexcept(isNothrowInit< CallableType, FunctionArgTypes... >())
Definition move_only_function_impl.h:99
friend void swap(MoveOnlyFunctionImpl &lhs, MoveOnlyFunctionImpl &rhs) noexcept
Specializes the std::swap algorithm.
Definition move_only_function_impl.h:166
#define GENERATE_WITH_REF
Definition move_only_function.h:219
#define GENERATE_WITH_CV
Definition move_only_function.h:218
#define NOEXCEPT_SPECIALIZATION
Definition move_only_function_impl.h:28
#define NOEXCEPT_SPECIFIER
Definition move_only_function_impl.h:27
Definition move_only_function_impl.h:21
constexpr bool is_move_only_function_v
Definition move_only_function.h:210
constexpr R invoke_r(F &&f, Args &&... args) noexcept(std::is_nothrow_invocable_r_v< R, F, Args... >)
Definition move_only_function.h:29