16 #ifndef OPENKALMAN_COMPATIBILITY_INVOKE_HPP 17 #define OPENKALMAN_COMPATIBILITY_INVOKE_HPP 21 #if __cplusplus >= 202002L 26 template<
typename>
static constexpr
bool is_reference_wrapper_v =
false;
27 template<
typename U>
static constexpr
bool is_reference_wrapper_v<std::reference_wrapper<U>> =
true;
28 template<
typename U>
static constexpr
bool is_reference_wrapper_v<stdex::reference_wrapper<U>> =
true;
30 template<
typename C,
typename Pointed,
typename Object,
typename...Args>
31 static constexpr decltype(
auto)
32 invoke_memptr(Pointed C::* member, Object&&
object, Args&&... args)
34 using object_t = remove_cvref_t<Object>;
35 constexpr
bool is_member_function = std::is_function_v<Pointed>;
36 constexpr
bool is_wrapped = is_reference_wrapper_v<object_t>;
37 constexpr
bool is_derived_object = std::is_same_v<C, object_t> or std::is_base_of_v<C, object_t>;
39 if constexpr (is_member_function)
41 if constexpr (is_derived_object)
42 return (std::forward<Object>(
object) .* member) (std::forward<Args>(args)...);
43 else if constexpr (is_wrapped)
44 return (
object.
get() .* member)(std::forward<Args>(args)...);
46 return ((*std::forward<Object>(
object)) .* member) (std::forward<Args>(args)...);
50 static_assert(std::is_object_v<Pointed> &&
sizeof...(args) == 0);
51 if constexpr (is_derived_object)
52 return std::forward<Object>(object) .* member;
53 else if constexpr (is_wrapped)
54 return object.get() .* member;
56 return (*std::forward<Object>(
object)) .* member;
66 template<
typename F,
typename...Args>
67 static constexpr std::invoke_result_t<F, Args...>
68 invoke(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_v<F, Args...>)
70 if constexpr (std::is_member_pointer_v<stdex::remove_cvref_t<F>>)
71 return detail::invoke_memptr(f,
std::forward<Args>(args)...);
73 return
std::forward<F>(f)(
std::forward<Args>(args)...);
78 #if __cplusplus >= 202302L 86 template<
typename R,
typename F,
typename...Args> requires std::is_invocable_r_v<R, F, Args...>
88 template<
typename R,
typename F,
typename...Args, std::enable_if_t<std::is_invocable_r_v<R, F, Args...>,
int> = 0>
90 constexpr R invoke_r(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_r_v<R, F, Args...>)
92 if constexpr (std::is_void_v<R>)
93 stdex::invoke(std::forward<F>(f), std::forward<Args>(args)...);
95 return stdex::invoke(std::forward<F>(f), std::forward<Args>(args)...);
Definition: basics.hpp:55