2#include "gaia/config/config.h"
11 struct is_reference_wrapper: std::false_type {};
13 struct is_reference_wrapper<std::reference_wrapper<U>>: std::true_type {};
15 template <
class C,
class Pointed,
class Object,
class... Args>
16 constexpr decltype(
auto) invoke_memptr(Pointed C::* member, Object&& object, Args&&... args) {
17 using object_t = std::decay_t<Object>;
18 constexpr bool is_member_function = std::is_function_v<Pointed>;
19 constexpr bool is_wrapped = is_reference_wrapper<object_t>::value;
20 constexpr bool is_derived_object = std::is_same_v<C, object_t> || std::is_base_of_v<C, object_t>;
22 if constexpr (is_member_function) {
23 if constexpr (is_derived_object)
24 return (GAIA_FWD(
object).*member)(GAIA_FWD(args)...);
25 else if constexpr (is_wrapped)
26 return (
object.get().*member)(GAIA_FWD(args)...);
28 return ((*GAIA_FWD(
object)).*member)(GAIA_FWD(args)...);
30 static_assert(std::is_object_v<Pointed> &&
sizeof...(args) == 0);
31 if constexpr (is_derived_object)
32 return GAIA_FWD(
object).*member;
33 else if constexpr (is_wrapped)
34 return object.get().*member;
36 return (*GAIA_FWD(
object)).*member;
48 template <
class F,
class... Args>
49 constexpr decltype(
auto) invoke(F&& f, Args&&... args)
noexcept(std::is_nothrow_invocable_v<F, Args...>) {
50 if constexpr (std::is_member_pointer_v<std::decay_t<F>>)
51 return detail::invoke_memptr(f, GAIA_FWD(args)...);
53 return GAIA_FWD(f)(GAIA_FWD(args)...);