24 #include "concepts.hpp"
26 #include <type_traits>
30 #ifdef __has_include // Check if __has_include is present
31 # if __has_include(<version>) // Check for version header
33 # if defined(__cpp_lib_is_invocable) && !defined(HIP_HAS_INVOCABLE)
34 # define HIP_HAS_INVOCABLE __cpp_lib_is_invocable
36 # if defined(__cpp_lib_result_of_sfinae) && !defined(HIP_HAS_RESULT_OF_SFINAE)
37 # define HIP_HAS_RESULT_OF_SFINAE __cpp_lib_result_of_sfinae
42 #ifndef HIP_HAS_INVOCABLE
43 #define HIP_HAS_INVOCABLE 0
46 #ifndef HIP_HAS_RESULT_OF_SFINAE
47 #define HIP_HAS_RESULT_OF_SFINAE 0
51 #if (__cplusplus < 201406L)
52 #if (__cplusplus < 201402L)
53 template <
bool cond,
typename T =
void>
54 using enable_if_t =
typename enable_if<cond, T>::type;
55 template <
bool cond,
typename T,
typename U>
56 using conditional_t =
typename conditional<cond, T, U>::type;
58 using decay_t =
typename decay<T>::type;
59 template <FunctionalProcedure F,
typename... Ts>
60 using result_of_t =
typename result_of<F(Ts...)>::type;
62 using remove_reference_t =
typename remove_reference<T>::type;
68 template <
typename...>
72 template <
typename,
typename =
void>
73 struct is_callable_impl;
75 template <FunctionalProcedure F,
typename... Ts>
76 struct is_callable_impl<F(Ts...)> : std::is_invocable<F, Ts...> {};
77 #elif HIP_HAS_RESULT_OF_SFINAE
78 template <
typename,
typename =
void>
79 struct is_callable_impl : std::false_type {};
81 template <FunctionalProcedure F,
typename... Ts>
82 struct is_callable_impl<F(Ts...), void_t_<typename std::result_of<F(Ts...)>::type > > : std::true_type {};
84 template <
class Base,
class T,
class Derived>
85 auto simple_invoke(T Base::*pmd, Derived&& ref)
86 -> decltype(
static_cast<Derived&&
>(ref).*pmd);
88 template <
class PMD,
class Po
inter>
89 auto simple_invoke(PMD&& pmd, Pointer&& ptr)
90 -> decltype((*
static_cast<Pointer&&
>(ptr)).*
static_cast<PMD&&
>(pmd));
92 template <
class Base,
class T,
class Derived>
93 auto simple_invoke(T Base::*pmd,
const std::reference_wrapper<Derived>& ref)
94 -> decltype(ref.get().*pmd);
96 template <
class Base,
class T,
class Derived,
class... Args>
97 auto simple_invoke(T Base::*pmf, Derived&& ref, Args&&... args)
98 -> decltype((
static_cast<Derived&&
>(ref).*pmf)(
static_cast<Args&&
>(args)...));
100 template <
class PMF,
class Pointer,
class... Args>
101 auto simple_invoke(PMF&& pmf, Pointer&& ptr, Args&&... args)
102 -> decltype(((*
static_cast<Pointer&&
>(ptr)).*
static_cast<PMF&&
>(pmf))(
static_cast<Args&&
>(args)...));
104 template <
class Base,
class T,
class Derived,
class... Args>
105 auto simple_invoke(T Base::*pmf,
const std::reference_wrapper<Derived>& ref, Args&&... args)
106 -> decltype((ref.get().*pmf)(
static_cast<Args&&
>(args)...));
108 template<
class F,
class... Ts>
109 auto simple_invoke(F&& f, Ts&&... xs)
110 -> decltype(f(
static_cast<Ts&&
>(xs)...));
112 template <
typename,
typename =
void>
115 template <FunctionalProcedure F,
typename... Ts>
116 struct is_callable_impl<F(Ts...), void_t_<decltype(simple_invoke(std::declval<F>(), std::declval<Ts>()...))> >
121 template <
typename Call>
124 #define count_macro_args_impl_hip_(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \
125 _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \
126 _26, _27, _28, _29, _30, _31, _n, ...) \
128 #define count_macro_args_hip_(...) \
129 count_macro_args_impl_hip_(, ##__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
130 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, \
133 #define overloaded_macro_expand_hip_(macro, arg_cnt) macro##arg_cnt
134 #define overload_macro_impl_hip_(macro, arg_cnt) overloaded_macro_expand_hip_(macro, arg_cnt)
135 #define overload_macro_hip_(macro, ...) \
136 overload_macro_impl_hip_(macro, count_macro_args_hip_(__VA_ARGS__))(__VA_ARGS__)