15 #ifndef MLPACK_CORE_SFINAE_UTILITY
16 #define MLPACK_CORE_SFINAE_UTILITY
18 #include <type_traits>
42 template<
typename Class,
43 template<
typename...>
class MethodForm,
44 size_t AdditionalArgsCount>
47 template<
typename Class,
template<
typename...>
class MethodForm>
50 void operator()(MethodForm<Class>);
53 template<
typename Class,
template<
typename...>
class MethodForm>
57 void operator()(MethodForm<Class, T1>);
60 template<
typename Class,
template<
typename...>
class MethodForm>
63 template<
class T1,
class T2>
64 void operator()(MethodForm<Class, T1, T2>);
67 template<
typename Class,
template<
typename...>
class MethodForm>
70 template<
class T1,
class T2,
class T3>
71 void operator()(MethodForm<Class, T1, T2, T3>);
74 template<
typename Class,
template<
typename...>
class MethodForm>
77 template<
class T1,
class T2,
class T3,
class T4>
78 void operator()(MethodForm<Class, T1, T2, T3, T4>);
81 template<
typename Class,
template<
typename...>
class MethodForm>
84 template<
class T1,
class T2,
class T3,
class T4,
class T5>
85 void operator()(MethodForm<Class, T1, T2, T3, T4, T5>);
88 template<
typename Class,
template<
typename...>
class MethodForm>
91 template<
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
92 void operator()(MethodForm<Class, T1, T2, T3, T4, T5, T6>);
95 template<
typename Class,
template<
typename...>
class MethodForm>
98 template<
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
99 void operator()(MethodForm<Class, T1, T2, T3, T4, T5, T6, T7>);
103 template<
typename U, U>
struct SigCheck : std::true_type {};
128 #define HAS_MEM_FUNC(FUNC, NAME) \
129 template<typename T, typename sig, typename = std::true_type> \
130 struct NAME : std::false_type {}; \
132 template<typename T, typename sig> \
137 std::integral_constant<bool, mlpack::sfinae::SigCheck<sig, &T::FUNC>::value> \
138 > : std::true_type {};
143 #define HAS_METHOD_FORM_BASE(METHOD, NAME, MAXN) \
144 template<typename Class, \
145 template<typename...> class MF , \
150 template<typename C, template<typename...> class MethodForm, int N> \
151 using MFD = mlpack::sfinae::MethodFormDetector<C, MethodForm, N>; \
154 struct WithNAdditionalArgs \
156 using yes = char[1]; \
157 using no = char[2]; \
159 template<typename T, typename ResultType> \
160 using EnableIfVoid = \
161 typename std::enable_if<std::is_void<T>::value, ResultType>::type; \
163 template<typename C> \
164 static EnableIfVoid<decltype(MFD<C, MF, N>()(&C::METHOD)), yes&> chk(int); \
166 static no& chk(...); \
168 static const bool value = sizeof(chk<Class>(0)) == sizeof(yes); \
172 struct WithGreaterOrEqualNumberOfAdditionalArgs \
174 using type = typename std::conditional< \
175 WithNAdditionalArgs<N>::value, \
177 typename std::conditional< \
179 WithGreaterOrEqualNumberOfAdditionalArgs<N + 1>, \
180 std::false_type>::type>::type; \
181 static const bool value = type::value; \
184 static const bool value = \
185 WithGreaterOrEqualNumberOfAdditionalArgs<MinN>::value; \
201 #define HAS_ANY_METHOD_FORM(FUNC, NAME) \
202 template <typename T> \
205 template <typename Q = T> \
207 std::enable_if<std::is_member_function_pointer<decltype(&Q::FUNC)>::value, \
209 f(int) { return 1;} \
211 template <typename Q = T> \
212 static char f(char) { return 0; } \
214 static const bool value = sizeof(f<T>(0)) != sizeof(char); \
220 #define SINGLE_ARG(...) __VA_ARGS__
252 #define HAS_METHOD_FORM(METHOD, NAME) \
253 HAS_METHOD_FORM_BASE(SINGLE_ARG(METHOD), SINGLE_ARG(NAME), 7)
285 #define HAS_EXACT_METHOD_FORM(METHOD, NAME) \
286 HAS_METHOD_FORM_BASE(SINGLE_ARG(METHOD), SINGLE_ARG(NAME), 0)
Utility struct for checking signatures.