Skip to content
Flecs v4.1
function_traits.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/utils/function_traits.hpp
3 * @brief Compile-time utilities to inspect properties of functions.
4 *
5 * Code from: https://stackoverflow.com/questions/27024238/c-template-mechanism-to-get-the-number-of-function-arguments-which-would-work
6 */
7
8#pragma once
9
10namespace flecs {
11namespace _ {
12
13/** @private Argument list type holder. */
14template <typename ... Args>
15struct arg_list { };
16
17/** @private Base type that contains the function traits definitions. */
18template <typename ReturnType, typename... Args>
19struct function_traits_defs
20{
21 static constexpr bool is_callable = true;
22 static constexpr size_t arity = sizeof...(Args);
23 using return_type = ReturnType;
24 using args = arg_list<Args ...>;
25};
26
27/** @private Primary template for function_traits_impl. */
28template <typename T>
29struct function_traits_impl {
30 static constexpr bool is_callable = false;
31};
32
33/** @private Specialization for free functions. */
34template <typename ReturnType, typename... Args>
35struct function_traits_impl<ReturnType(Args...)>
36 : function_traits_defs<ReturnType, Args...> {};
37
38/** @private Specialization for function pointers. */
39template <typename ReturnType, typename... Args>
40struct function_traits_impl<ReturnType(*)(Args...)>
41 : function_traits_defs<ReturnType, Args...> {};
42
43/** @private Specialization for member function pointers. */
44template <typename ClassType, typename ReturnType, typename... Args>
45struct function_traits_impl<ReturnType(ClassType::*)(Args...)>
46 : function_traits_defs<ReturnType, Args...> {};
47
48/** @private Specialization for const member function pointers. */
49template <typename ClassType, typename ReturnType, typename... Args>
50struct function_traits_impl<ReturnType(ClassType::*)(Args...) const>
51 : function_traits_defs<ReturnType, Args...> {};
52
53/** @private Specialization for const& member function pointers. */
54template <typename ClassType, typename ReturnType, typename... Args>
55struct function_traits_impl<ReturnType(ClassType::*)(Args...) const&>
56 : function_traits_defs<ReturnType, Args...> {};
57
58/** @private Specialization for const&& member function pointers. */
59template <typename ClassType, typename ReturnType, typename... Args>
60struct function_traits_impl<ReturnType(ClassType::*)(Args...) const&&>
61 : function_traits_defs<ReturnType, Args...> {};
62
63/** @private Specialization for volatile member function pointers. */
64template <typename ClassType, typename ReturnType, typename... Args>
65struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile>
66 : function_traits_defs<ReturnType, Args...> {};
67
68/** @private Specialization for volatile& member function pointers. */
69template <typename ClassType, typename ReturnType, typename... Args>
70struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile&>
71 : function_traits_defs<ReturnType, Args...> {};
72
73/** @private Specialization for volatile&& member function pointers. */
74template <typename ClassType, typename ReturnType, typename... Args>
75struct function_traits_impl<ReturnType(ClassType::*)(Args...) volatile&&>
76 : function_traits_defs<ReturnType, Args...> {};
77
78/** @private Specialization for const volatile member function pointers. */
79template <typename ClassType, typename ReturnType, typename... Args>
80struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile>
81 : function_traits_defs<ReturnType, Args...> {};
82
83/** @private Specialization for const volatile& member function pointers. */
84template <typename ClassType, typename ReturnType, typename... Args>
85struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile&>
86 : function_traits_defs<ReturnType, Args...> {};
87
88/** @private Specialization for const volatile&& member function pointers. */
89template <typename ClassType, typename ReturnType, typename... Args>
90struct function_traits_impl<ReturnType(ClassType::*)(Args...) const volatile&&>
91 : function_traits_defs<ReturnType, Args...> {};
92
93/** @private Primary template for function_traits_no_cv. */
94template <typename T, typename V = void>
95struct function_traits_no_cv
96 : function_traits_impl<T> {};
97
98/** @private Specialization for callable objects with operator(). */
99template <typename T>
100struct function_traits_no_cv<T, decltype((void)&T::operator())>
101 : function_traits_impl<decltype(&T::operator())> {};
102
103/** @private Front-facing template that decays T before extracting traits. */
104template <typename T>
105struct function_traits
106 : function_traits_no_cv< decay_t<T> > {};
107
108} // namespace _
109
110
111/** Trait to check if a type is callable. */
112template <typename T>
114 static constexpr bool value = _::function_traits<T>::is_callable;
115};
116
117/** Trait to get the number of arguments of a callable. */
118template <typename T>
119struct arity {
120 static constexpr int value = _::function_traits<T>::arity;
121};
122
123/** Get the return type of a callable. */
124template <typename T>
125using return_type_t = typename _::function_traits<T>::return_type;
126
127/** Get the argument list type of a callable. */
128template <typename T>
129using arg_list_t = typename _::function_traits<T>::args;
130
131/** Extract the first argument type from a callable (implementation). */
132template<typename Func, typename ... Args>
134
135/** Extract the first argument type from an arg_list. */
136template<typename Func, typename T, typename ... Args>
137struct first_arg_impl<Func, _::arg_list<T, Args ...> > {
138 using type = T;
139};
140
141/** Get the first argument type of a callable. */
142template<typename Func>
143struct first_arg {
144 using type = typename first_arg_impl<Func, arg_list_t<Func>>::type;
145};
146
147/** Convenience alias for the first argument type of a callable. */
148template <typename Func>
149using first_arg_t = typename first_arg<Func>::type;
150
151/** Extract the second argument type from a callable (implementation). */
152template<typename Func, typename ... Args>
154
155/** Extract the second argument type from an arg_list. */
156template<typename Func, typename First, typename T, typename ... Args>
157struct second_arg_impl<Func, _::arg_list<First, T, Args ...> > {
158 using type = T;
159};
160
161/** Get the second argument type of a callable. */
162template<typename Func>
164 using type = typename second_arg_impl<Func, arg_list_t<Func>>::type;
165};
166
167/** Convenience alias for the second argument type of a callable. */
168template <typename Func>
169using second_arg_t = typename second_arg<Func>::type;
170
171} // namespace flecs
typename _::function_traits< T >::args arg_list_t
Get the argument list type of a callable.
typename _::function_traits< T >::return_type return_type_t
Get the return type of a callable.
typename first_arg< Func >::type first_arg_t
Convenience alias for the first argument type of a callable.
typename second_arg< Func >::type second_arg_t
Convenience alias for the second argument type of a callable.
Int to enum.
Definition component.hpp:18
Trait to get the number of arguments of a callable.
Extract the first argument type from a callable (implementation).
Get the first argument type of a callable.
Trait to check if a type is callable.
Extract the second argument type from a callable (implementation).
Get the second argument type of a callable.