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
#include <type_traits> | |
#include <tuple> | |
#include <functional> | |
template <typename FType> | |
struct function_traits; | |
template <typename RType, typename... ArgTypes> | |
struct function_traits<RType(ArgTypes...)> { | |
using arity = std::integral_constant<size_t, sizeof...(ArgTypes)>; | |
using result_type = RType; | |
using arg_tuple = std::tuple<ArgTypes...>; | |
template <size_t Index> | |
using arg_type = typename std::tuple_element<Index, arg_tuple>::type; | |
}; | |
namespace details { | |
template <typename T> | |
struct function_type_impl | |
: function_type_impl<decltype(&T::operator())> | |
{ }; | |
template <typename RType, typename... ArgTypes> | |
struct function_type_impl<RType(ArgTypes...)> { | |
using type = RType(ArgTypes...); | |
}; | |
template <typename RType, typename... ArgTypes> | |
struct function_type_impl<RType(*)(ArgTypes...)> { | |
using type = RType(ArgTypes...); | |
}; | |
template <typename RType, typename... ArgTypes> | |
struct function_type_impl<std::function<RType(ArgTypes...)>> { | |
using type = RType(ArgTypes...); | |
}; | |
template <typename T, typename RType, typename... ArgTypes> | |
struct function_type_impl<RType(T::*)(ArgTypes...)> { | |
using type = RType(ArgTypes...); | |
}; | |
template <typename T, typename RType, typename... ArgTypes> | |
struct function_type_impl<RType(T::*)(ArgTypes...) const> { | |
using type = RType(ArgTypes...); | |
}; | |
} | |
template <typename T> | |
struct function_type | |
: details::function_type_impl<typename std::remove_cv<typename std::remove_reference<T>::type>::type> | |
{ }; | |
// --- shortcuts --- | |
template <typename FType> | |
using function_type_traits_t = function_traits<typename function_type<FType>::type>; | |
template <typename FType> | |
constexpr auto function_arity_val = function_type_traits_t<FType>::arity::value; | |
template <typename FType> | |
using function_arg_tuple_t = typename function_type_traits_t<FType>::arg_tuple; |
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
struct meow { | |
void f(int, char, float) { } | |
}; | |
template <typename FType> | |
void test() { | |
using FTypeTraits = function_traits<FType>; | |
static_assert(typename FTypeTraits::arity() == 3, "fail"); | |
static_assert(std::is_same<typename FTypeTraits::result_type, void>(), "fail"); | |
static_assert(std::is_same<typename FTypeTraits::template arg_type<0>, int>(), "fail"); | |
static_assert(std::is_same<typename FTypeTraits::template arg_type<1>, char>(), "fail"); | |
static_assert(std::is_same<typename FTypeTraits::template arg_type<2>, float>(), "fail"); | |
} | |
void test1() { | |
using FType = void(int, char, float); | |
test<FType>(); | |
} | |
void test2() { | |
using FType = function_type<decltype(&meow::f)>::type; | |
test<FType>(); | |
} | |
void test3() { | |
using FType = function_type<void(* const volatile &)(int, char, float)>::type; | |
test<FType>(); | |
} | |
void test4() { | |
using FType = function_type<std::function<void(int, char, float)>>::type; | |
test<FType>(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment