20#include <initializer_list>
28# define NOEXCEPT_SPECIFIER
29# define NOEXCEPT_SPECIALIZATION
31# define NOEXCEPT_SPECIFIER noexcept(IsNoExcept)
32# define NOEXCEPT_SPECIALIZATION , bool IsNoExcept
42 static constexpr bool isNoExcept =
false;
44 static constexpr bool isNoExcept = IsNoExcept;
47 template <
typename CallableType>
49 using is_callable = std::conditional_t<isNoExcept,
50 std::is_nothrow_invocable_r<ResultType, CallableType, ArgTypes...>,
51 std::is_invocable_r<ResultType, CallableType, ArgTypes...>>;
53 template <
typename UnqualifiedCallableType>
55 using is_qualified_callable =
56 std::conjunction<is_callable<UnqualifiedCallableType GENERATE_WITH_CV GENERATE_WITH_REF>,
57 is_callable<UnqualifiedCallableType GENERATE_WITH_SELF_QUALIFIERS>>;
69 , activeDispatcherFunction_(std::exchange(other.activeDispatcherFunction_,
nullptr))
73 template <
typename CallableType,
74 typename DecayedCallableType = std::decay_t<CallableType>,
75 std::enable_if_t<std::conjunction_v<std::negation<std::is_same<DecayedCallableType, MoveOnlyFunctionImpl>>,
76 std::negation<IsInPlaceType<DecayedCallableType>>,
77 is_qualified_callable<DecayedCallableType>>,
82 if constexpr (std::is_function_v<std::remove_pointer_t<DecayedCallableType>> ||
86 if constexpr (!std::is_reference_v<CallableType>)
88 if (callable ==
nullptr)
95 activeDispatcherFunction_ = &dispatcherFunction<DecayedCallableType>;
98 template <
typename CallableType,
99 typename... FunctionArgTypes,
100 std::enable_if_t<std::conjunction_v<std::is_constructible<CallableType, FunctionArgTypes...>,
101 is_qualified_callable<CallableType>>,
104 FunctionArgTypes&&... args)
noexcept(
isNothrowInit<CallableType, FunctionArgTypes...>())
105 : activeDispatcherFunction_(&dispatcherFunction<CallableType>)
107 static_assert(std::is_same_v<std::decay_t<CallableType>, CallableType>);
112 typename CallableType,
114 typename... FunctionArgTypes,
116 std::conjunction_v<std::is_constructible<CallableType, std::initializer_list<ILArgTypes>&, FunctionArgTypes...>,
117 is_qualified_callable<CallableType>>,
120 std::initializer_list<ILArgTypes> initializeList,
121 FunctionArgTypes&&... args)
noexcept(
isNothrowInit<CallableType,
122 std::initializer_list<ILArgTypes>&,
123 FunctionArgTypes...>())
124 : activeDispatcherFunction_(&dispatcherFunction<CallableType>)
126 static_assert(std::is_same_v<std::decay_t<CallableType>, CallableType>);
133 activeDispatcherFunction_ = std::exchange(other.activeDispatcherFunction_,
nullptr);
141 activeDispatcherFunction_ =
nullptr;
150 assert(*
this !=
nullptr &&
"Trying to execute empty callable object.");
151 return activeDispatcherFunction_(
this, std::forward<ArgTypes>(args)...);
155 explicit operator bool() const noexcept {
return activeDispatcherFunction_ !=
nullptr; }
160 return lhs.activeDispatcherFunction_ ==
nullptr;
166 return lhs.activeDispatcherFunction_ !=
nullptr;
176 std::swap(activeDispatcherFunction_, other.activeDispatcherFunction_);
180 template <
typename ParameterType>
181 using SanitizedParameterType = std::conditional_t<std::is_scalar_v<ParameterType>, ParameterType, ParameterType&&>;
183 template <
typename Tp>
185 SanitizedParameterType<ArgTypes>... args)
noexcept(isNoExcept)
188 std::forward<Tp GENERATE_WITH_SELF_QUALIFIERS>(*getCallableAs<Tp GENERATE_WITH_CV>(self)),
189 std::forward<SanitizedParameterType<ArgTypes>>(args)...);
192 using DispatcherFunctionType = ResultType (*)(MoveOnlyFunctionBase
GENERATE_WITH_CV*,
193 SanitizedParameterType<ArgTypes>...)
noexcept(isNoExcept);
194 DispatcherFunctionType activeDispatcherFunction_ =
nullptr;
199#undef GENERATE_WITH_CV
200#undef GENERATE_WITH_REF
201#undef GENERATE_WITH_SELF_QUALIFIERS
202#undef NOEXCEPT_SPECIFIER
203#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:173
friend bool operator==(const MoveOnlyFunctionImpl &lhs, std::nullptr_t) noexcept
Compares a std::move_only_function with nullptr.
Definition move_only_function_impl.h:158
MoveOnlyFunctionImpl(CallableType &&callable) noexcept(isNothrowInit< DecayedCallableType, CallableType >())
Definition move_only_function_impl.h:80
MoveOnlyFunctionImpl & operator=(std::nullptr_t) noexcept
Replaces or destroys the target.
Definition move_only_function_impl.h:138
ResultType operator()(ArgTypes... args) GENERATE_WITH_CV GENERATE_WITH_REF noexcept(isNoExcept)
Invokes the target.
Definition move_only_function_impl.h:148
MoveOnlyFunctionImpl(MoveOnlyFunctionImpl &&other) noexcept
Definition move_only_function_impl.h:67
~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:164
ResultType result_type
Definition move_only_function_impl.h:60
MoveOnlyFunctionImpl & operator=(MoveOnlyFunctionImpl &&other) noexcept
Definition move_only_function_impl.h:130
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:119
MoveOnlyFunctionImpl(std::in_place_type_t< CallableType >, FunctionArgTypes &&... args) noexcept(isNothrowInit< CallableType, FunctionArgTypes... >())
Definition move_only_function_impl.h:103
friend void swap(MoveOnlyFunctionImpl &lhs, MoveOnlyFunctionImpl &rhs) noexcept
Specializes the std::swap algorithm.
Definition move_only_function_impl.h:170
#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:32
#define NOEXCEPT_SPECIFIER
Definition move_only_function_impl.h:31
Definition move_only_function_impl.h:25
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