34namespace essence::detail {
35 template <
typename R,
typename T,
typename... Args>
37 using std_function_type = std::function<R(Args...)>;
39 template <auto Function, std::convertible_to<T> U>
40 requires std::is_member_function_pointer_v<
decltype(Function)>
41 && std::is_invocable_r_v<R,
decltype(std::mem_fn(Function)), U, Args...>
42 static std::function<R(Args...)> make(U&& obj) {
44 [&]<
typename... Unbound>(Unbound&&... args) {
return (obj.*Function)(std::forward<Unbound>(args)...); };
48 template <
typename Function>
51#define MAKE_MEMBER_FUNCTION_WRAPPER(...) \
52 template <typename R, typename T, typename... Args> \
53 struct member_function_wrapper<R (T::*)(Args...) __VA_ARGS__> : member_function_wrapper_base<R, T, Args...> {}
55 MAKE_MEMBER_FUNCTION_WRAPPER();
56 MAKE_MEMBER_FUNCTION_WRAPPER(
const);
57 MAKE_MEMBER_FUNCTION_WRAPPER(
volatile);
58 MAKE_MEMBER_FUNCTION_WRAPPER(
const volatile);
59 MAKE_MEMBER_FUNCTION_WRAPPER(&);
60 MAKE_MEMBER_FUNCTION_WRAPPER(
const&);
61 MAKE_MEMBER_FUNCTION_WRAPPER(
volatile&);
62 MAKE_MEMBER_FUNCTION_WRAPPER(
const volatile&);
63 MAKE_MEMBER_FUNCTION_WRAPPER(&&);
64 MAKE_MEMBER_FUNCTION_WRAPPER(
const&&);
65 MAKE_MEMBER_FUNCTION_WRAPPER(
volatile&&);
66 MAKE_MEMBER_FUNCTION_WRAPPER(
const volatile&&);
70 template <auto Function,
typename T>
71 requires std::is_member_function_pointer_v<
decltype(Function)>
72 auto make_member_function(T&& obj) {
76 template <
typename Function>
78 using type =
decltype(std::function{std::declval<Function>()});
81 template <
typename Function>
82 requires std::is_member_function_pointer_v<Function>
87 template <
typename Function>
88 using make_std_function_t =
typename make_std_function<Function>::type;
90 template <
typename StdFunction>
93 template <
typename R,
typename... Args>
95 using return_type = R;
97 template <std::
size_t I>
98 using arg_type = std::tuple_element_t<I, std::tuple<Args...>>;
100 static constexpr std::size_t arg_count =
sizeof...(Args);
103 template <
typename Function>
105 using std_func_type = make_std_function_t<Function>;
108 template <std::
size_t I>
114 template <
typename Function>
115 using function_return_type =
typename function_traits<Function>::return_type;
117 template <
typename Function, std::
size_t I = 0>
120 template <
typename Callable,
typename... Args>
123 template <
typename Callable,
typename R,
typename... Args>
124 concept invocable_r = std::is_invocable_r_v<R, Callable, Args...>;
126 template <
typename Callable,
typename R,
typename... Args>
129 template <
typename Callable,
typename... Args>
132 template <
typename Callable,
typename R,
typename... Args>
135 template <
typename Callable,
typename R,
typename... Args>
137 nothrow_invocable<Callable, Args...> && !std::same_as<std::invoke_result_t<Callable, Args...>, R>;
139 template <
typename Callable,
typename... Args>
142 template <
typename Callable,
typename R,
typename... Args>
144 std::is_null_pointer_v<std::decay_t<Callable>> ||
invocable_r<Callable, R, Args...>;
146 template <
typename Callable,
typename R,
typename... Args>
148 std::is_null_pointer_v<std::decay_t<Callable>> ||
invocable_not_r<Callable, R, Args...>;
150 template <
typename Callable,
typename... Args>
152 std::is_null_pointer_v<std::decay_t<Callable>> ||
nothrow_invocable<Callable, Args...>;
154 template <
typename Callable,
typename R,
typename... Args>
156 std::is_null_pointer_v<std::decay_t<Callable>> ||
nothrow_invocable_r<Callable, R, Args...>;
158 template <
typename Callable,
typename R,
typename... Args>
162 template <
typename Callable,
typename... Args>
164 constexpr auto invoke_optional(Callable&& callable, Args&&... args)
noexcept(
167 if constexpr (std::is_null_pointer_v<std::decay_t<Callable>>) {
170 using result_type = std::invoke_result_t<Callable, Args...>;
172 auto valid = convert_to_boolean(callable);
174 if constexpr (std::is_void_v<result_type>) {
176 std::invoke(std::forward<Callable>(callable), std::forward<Args>(args)...);
180 return std::optional{std::invoke(std::forward<Callable>(callable), std::forward<Args>(args)...)};
185 return std::optional<result_type>{};
190 template <
typename Callable,
typename R,
typename... Args>
192 constexpr auto invoke_optional_or(Callable&& callable, R&& default_value, Args&&... args)
noexcept(
195 auto result = invoke_optional(std::forward<Callable>(callable), std::forward<Args>(args)...);
197 if constexpr (std::is_null_pointer_v<
decltype(result)>) {
198 return std::forward<R>(default_value);
200 return std::move(result).value_or(std::forward<R>(default_value));
Definition functional.hpp:127
Definition functional.hpp:124
Definition functional.hpp:121
Definition functional.hpp:136
Definition functional.hpp:133
Definition functional.hpp:130
Definition functional.hpp:147
Definition functional.hpp:143
Definition functional.hpp:140
Definition functional.hpp:159
Definition functional.hpp:155
Definition functional.hpp:151
Definition functional.hpp:36
Definition functional.hpp:49
Definition functional.hpp:104
Definition functional.hpp:77
Definition functional.hpp:91