Flecs v4.0
A fast entity component system (ECS) for C & C++
Loading...
Searching...
No Matches
function_traits.hpp
Go to the documentation of this file.
1
8namespace flecs {
9namespace _ {
10
11template <typename ... Args>
12struct arg_list { };
13
14// Base type that contains the traits
15template <typename ReturnType, typename... Args>
17{
18 static constexpr bool is_callable = true;
19 static constexpr size_t arity = sizeof...(Args);
20 using return_type = ReturnType;
21 using args = arg_list<Args ...>;
22};
23
24// Primary template for function_traits_impl
25template <typename T>
27 static constexpr bool is_callable = false;
28};
29
30// Template specializations for the different kinds of function types (whew)
31template <typename ReturnType, typename... Args>
32struct function_traits_impl<ReturnType(Args...)>
33 : function_traits_defs<ReturnType, Args...> {};
34
35template <typename ReturnType, typename... Args>
36struct function_traits_impl<ReturnType(*)(Args...)>
37 : function_traits_defs<ReturnType, Args...> {};
38
39template <typename ClassType, typename ReturnType, typename... Args>
40struct function_traits_impl<ReturnType(ClassType::*)(Args...)>
41 : function_traits_defs<ReturnType, Args...> {};
42
43template <typename ClassType, typename ReturnType, typename... Args>
44struct function_traits_impl<ReturnType(ClassType::*)(Args...) const>
45 : function_traits_defs<ReturnType, Args...> {};
46
47template <typename ClassType, typename ReturnType, typename... Args>
48struct function_traits_impl<ReturnType(ClassType::*)(Args...) const&>
49 : function_traits_defs<ReturnType, Args...> {};
50
51template <typename ClassType, typename ReturnType, typename... Args>
52struct function_traits_impl<ReturnType(ClassType::*)(Args...) const&&>
53 : function_traits_defs<ReturnType, Args...> {};
54
55template <typename ClassType, typename ReturnType, typename... Args>
56struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile>
57 : function_traits_defs<ReturnType, Args...> {};
58
59template <typename ClassType, typename ReturnType, typename... Args>
60struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile&>
61 : function_traits_defs<ReturnType, Args...> {};
62
63template <typename ClassType, typename ReturnType, typename... Args>
64struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile&&>
65 : function_traits_defs<ReturnType, Args...> {};
66
67template <typename ClassType, typename ReturnType, typename... Args>
68struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile>
69 : function_traits_defs<ReturnType, Args...> {};
70
71template <typename ClassType, typename ReturnType, typename... Args>
72struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile&>
73 : function_traits_defs<ReturnType, Args...> {};
74
75template <typename ClassType, typename ReturnType, typename... Args>
76struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile&&>
77 : function_traits_defs<ReturnType, Args...> {};
78
79// Primary template for function_traits_no_cv. If T is not a function, the
80// compiler will attempt to instantiate this template and fail, because its base
81// is undefined.
82template <typename T, typename V = void>
85
86// Specialized template for function types
87template <typename T>
88struct function_traits_no_cv<T, decltype((void)&T::operator())>
89 : function_traits_impl<decltype(&T::operator())> {};
90
91// Front facing template that decays T before ripping it apart.
92template <typename T>
94 : function_traits_no_cv< decay_t<T> > {};
95
96} // _
97
98
99template <typename T>
101 static constexpr bool value = _::function_traits<T>::is_callable;
102};
103
104template <typename T>
105struct arity {
106 static constexpr int value = _::function_traits<T>::arity;
107};
108
109template <typename T>
110using return_type_t = typename _::function_traits<T>::return_type;
111
112template <typename T>
113using arg_list_t = typename _::function_traits<T>::args;
114
115// First arg
116template<typename Func, typename ... Args>
118
119template<typename Func, typename T, typename ... Args>
120struct first_arg_impl<Func, _::arg_list<T, Args ...> > {
121 using type = T;
122};
123
124template<typename Func>
125struct first_arg {
126 using type = typename first_arg_impl<Func, arg_list_t<Func>>::type;
127};
128
129template <typename Func>
130using first_arg_t = typename first_arg<Func>::type;
131
132// Last arg
133template<typename Func, typename ... Args>
135
136template<typename Func, typename First, typename T, typename ... Args>
137struct second_arg_impl<Func, _::arg_list<First, T, Args ...> > {
138 using type = T;
139};
140
141template<typename Func>
143 using type = typename second_arg_impl<Func, arg_list_t<Func>>::type;
144};
145
146template <typename Func>
147using second_arg_t = typename second_arg<Func>::type;
148
149} // flecs