Last active
December 31, 2020 11:56
-
-
Save juxeii/dc2eb600c32a8461bc0a278687816189 to your computer and use it in GitHub Desktop.
Blog post for CallableTraits
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <typename T> | |
using AsFunction = decltype(std::function{std::declval<T>()}); | |
#if defined(__GNUC__) || defined(__GNUG__) | |
// CTAD bug in gcc, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98077 | |
#define AS_FUNCTION(T) decltype(std::function{std::declval<T>()}) | |
#else | |
#define AS_FUNCTION(T) AsFunction<T> | |
#endif | |
template <typename T, typename = void> | |
struct is_callable : std::false_type | |
{ | |
}; | |
template <typename T> | |
struct is_callable<T, std::void_t<AS_FUNCTION(T)>> : std::true_type | |
{ | |
}; | |
template <typename T> | |
inline constexpr auto is_callable_v = is_callable<T>::value; | |
static_assert(!is_callable_v<int>); | |
auto l = []{}; | |
static_assert(is_callable_v<decltype(l)>); | |
template <typename T> | |
struct function_components | |
{ | |
}; | |
template <typename R, typename... Args> | |
struct function_components<std::function<R(Args...)>> | |
{ | |
using type = std::tuple<R(Args...), R, std::tuple<std::decay_t<Args>...>>; | |
}; | |
template <typename T> | |
using function_components_t = typename function_components<T>::type; | |
template <typename T, auto I> | |
using get_function_component_t = std::tuple_element_t<I, function_components_t<T>>; | |
template <typename T> | |
using function_signature_t = get_function_component_t<T, 0>; | |
template <typename T> | |
using function_result_t = get_function_component_t<T, 1>; | |
template <typename T> | |
using function_arguments_t = get_function_component_t<T, 2>; | |
template <typename T> | |
struct callable_to_function | |
{ | |
static_assert(is_callable_v<T>); | |
using type = AS_FUNCTION(T); | |
}; | |
template <typename T> | |
using callable_to_function_t = typename callable_to_function<T>::type; | |
template <typename T> | |
struct callable_result | |
{ | |
using type = function_result_t<callable_to_function_t<T>>; | |
}; | |
template <typename T> | |
using callable_result_t = typename callable_result<T>::type; | |
template <typename T> | |
struct callable_arguments | |
{ | |
using type = function_arguments_t<callable_to_function_t<T>>; | |
}; | |
template <typename T> | |
using callable_arguments_t = typename callable_arguments<T>::type; | |
auto someFunc() | |
{ | |
return 42; | |
} | |
using R = callable_result_t<decltype(someFunc)>; | |
static_assert(std::is_same_v<R, int>); | |
template <typename T> | |
struct callable_arguments | |
{ | |
using type = function_arguments_t<callable_to_function_t<T>>; | |
}; | |
template <typename T> | |
using callable_arguments_t = typename callable_arguments<T>::type; | |
auto sum(int x, int y) | |
{ | |
return x+y; | |
} | |
using R = callable_arguments_t<decltype(sum)>; | |
static_assert(std::is_same_v<R, std::tuple<int, int>>); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment