-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathfunction_traits.hpp
58 lines (43 loc) · 1.98 KB
/
function_traits.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//----------------------------------------------------------------------------
// copyright 2014 Keean Schupke
// compile with -std=c++11
// function-traits.h
#ifndef FUNCTION_TRAITS_HPP
#define FUNCTION_TRAITS_HPP
#include <tuple>
using namespace std;
//----------------------------------------------------------------------------
// traits for functions, function objects and lambdas
template <typename F> struct function_traits;
template <typename return_type, typename... arg_types>
struct function_traits<return_type(*)(arg_types...)>
: public function_traits<return_type(arg_types...)> {};
template <typename R, typename... Args>
struct function_traits<R(Args...)> {
static constexpr size_t arity = sizeof...(Args);
using return_type = R;
template <size_t N> struct argument {
static_assert(N < arity, "error: invalid parameter index.");
using type = typename tuple_element<N, tuple<Args...>>::type;
};
};
template <typename class_type, typename return_type, typename... arg_types>
struct function_traits<return_type(class_type::*)(arg_types...)>
: public function_traits<return_type(class_type&, arg_types...)> {};
template <typename class_type, typename return_type, typename... arg_types>
struct function_traits<return_type(class_type::*)(arg_types...) const>
: public function_traits<return_type(class_type&, arg_types...)> {};
template <typename class_type, typename return_type>
struct function_traits<return_type(class_type::*)>
: public function_traits<return_type(class_type&)> {};
template <typename F> struct function_traits {
using call_type = function_traits<decltype(&F::operator())>;
using return_type = typename call_type::return_type;
static constexpr size_t arity = call_type::arity - 1;
template <size_t N>
struct argument {
static_assert(N < arity, "error: invalid parameter index.");
using type = typename call_type::template argument<N+1>::type;
};
};
#endif // FUNCTION_TRAITS_HPP