22 #ifndef GEARS_CONCEPTS_FUNCTION_HPP
23 #define GEARS_CONCEPTS_FUNCTION_HPP
36 template<
typename... Args>
37 using Void_ =
typename void_type<Args...>::type;
42 template<
typename T,
typename... Args>
43 using FRet = decltype(std::declval<T>()(std::declval<Args>()...));
45 template<
typename T,
typename Signature,
typename =
void>
46 struct is_callable : std::false_type {
47 static_assert(std::is_function<Signature>(),
"Signature must be a function");
50 template<
typename T,
typename = concept_checker_t>
51 struct is_function_impl : std::is_function<T> {};
54 struct is_function_impl<T, TrueIf<std::is_class<Bare<T>>>> {
56 using no =
struct {
char s[2]; };
58 struct F {
void operator()(); };
59 struct Derived : T, F { };
60 template<
typename U, U>
struct Check;
63 static no test(Check<
void (F::*)(), &V::operator()>*);
68 static const bool value =
sizeof(test<Derived>(0)) ==
sizeof(yes);
71 template<
typename T,
typename R,
typename... Args>
72 struct is_callable<T, R(Args...), Void_<decltype(sink<R>(std::declval<T>()(std::declval<Args>()...)))>> : std::true_type {};
74 template<
typename T,
typename... Args>
75 struct is_callable<T, void(Args...), Void_<FRet<T, Args...>>> : std::is_void<FRet<T, Args...>> {};
79 static auto test(
int) -> decltype(std::declval<T&>()(), std::true_type{}) {}
81 static std::false_type test(...);
108 template<
typename T,
typename Signature>
109 struct Callable : detail::is_callable<T, Signature> {};
132 struct Function : std::integral_constant<bool, detail::is_function_impl<typename std::remove_pointer<T>::type>::value> {};
136 #endif // GEARS_CONCEPTS_FUNCTION_HPP