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 defined(_MSC_VER) && _MSC_VER < 1932
84 if constexpr (!std::is_reference_v<CallableType>)
87 if (callable ==
nullptr)
91#if defined(_MSC_VER) && _MSC_VER < 1932
96 activeDispatcherFunction_ = &dispatcherFunction<DecayedCallableType>;
99 template <
typename CallableType,
100 typename... FunctionArgTypes,
101 std::enable_if_t<std::conjunction_v<std::is_constructible<CallableType, FunctionArgTypes...>,
102 is_qualified_callable<CallableType>>,
105 FunctionArgTypes&&... args)
noexcept(
isNothrowInit<CallableType, FunctionArgTypes...>())
106 : activeDispatcherFunction_(&dispatcherFunction<CallableType>)
108 static_assert(std::is_same_v<std::decay_t<CallableType>, CallableType>);
113 typename CallableType,
115 typename... FunctionArgTypes,
117 std::conjunction_v<std::is_constructible<CallableType, std::initializer_list<ILArgTypes>&, FunctionArgTypes...>,
118 is_qualified_callable<CallableType>>,
121 std::initializer_list<ILArgTypes> initializeList,
122 FunctionArgTypes&&... args)
noexcept(
isNothrowInit<CallableType,
123 std::initializer_list<ILArgTypes>&,
124 FunctionArgTypes...>())
125 : activeDispatcherFunction_(&dispatcherFunction<CallableType>)
127 static_assert(std::is_same_v<std::decay_t<CallableType>, CallableType>);
134 activeDispatcherFunction_ = std::exchange(other.activeDispatcherFunction_,
nullptr);
142 activeDispatcherFunction_ =
nullptr;
151 assert(*
this !=
nullptr &&
"Trying to execute empty callable object.");
152 return activeDispatcherFunction_(
this, std::forward<ArgTypes>(args)...);
156 explicit operator bool() const noexcept {
return activeDispatcherFunction_ !=
nullptr; }
161 return lhs.activeDispatcherFunction_ ==
nullptr;
167 return lhs.activeDispatcherFunction_ !=
nullptr;
177 std::swap(activeDispatcherFunction_, other.activeDispatcherFunction_);
181 template <
typename ParameterType>
182 using SanitizedParameterType = std::conditional_t<std::is_scalar_v<ParameterType>, ParameterType, ParameterType&&>;
184 template <
typename Tp>
186 SanitizedParameterType<ArgTypes>... args)
noexcept(isNoExcept)
189 std::forward<Tp GENERATE_WITH_SELF_QUALIFIERS>(*getCallableAs<Tp GENERATE_WITH_CV>(self)),
190 std::forward<SanitizedParameterType<ArgTypes>>(args)...);
193 using DispatcherFunctionType = ResultType (*)(MoveOnlyFunctionBase
GENERATE_WITH_CV*,
194 SanitizedParameterType<ArgTypes>...)
noexcept(isNoExcept);
195 DispatcherFunctionType activeDispatcherFunction_ =
nullptr;
200#undef GENERATE_WITH_CV
201#undef GENERATE_WITH_REF
202#undef GENERATE_WITH_SELF_QUALIFIERS
203#undef NOEXCEPT_SPECIFIER
204#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:174
friend bool operator==(const MoveOnlyFunctionImpl &lhs, std::nullptr_t) noexcept
Compares a std::move_only_function with nullptr.
Definition move_only_function_impl.h:159
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:139
ResultType operator()(ArgTypes... args) GENERATE_WITH_CV GENERATE_WITH_REF noexcept(isNoExcept)
Invokes the target.
Definition move_only_function_impl.h:149
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:165
ResultType result_type
Definition move_only_function_impl.h:56
MoveOnlyFunctionImpl & operator=(MoveOnlyFunctionImpl &&other) noexcept
Definition move_only_function_impl.h:131
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:120
MoveOnlyFunctionImpl(std::in_place_type_t< CallableType >, FunctionArgTypes &&... args) noexcept(isNothrowInit< CallableType, FunctionArgTypes... >())
Definition move_only_function_impl.h:104
friend void swap(MoveOnlyFunctionImpl &lhs, MoveOnlyFunctionImpl &rhs) noexcept
Specializes the std::swap algorithm.
Definition move_only_function_impl.h:171
#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