Skip to content

Commit 7942fe7

Browse files
committed
refactor: enhance function_traits specialization for noexcept and member function pointers
1 parent ef28125 commit 7942fe7

File tree

1 file changed

+82
-49
lines changed

1 file changed

+82
-49
lines changed

src/details.h

Lines changed: 82 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -51,132 +51,165 @@ struct function_traits;
5151
* @brief Specialization for function pointers.
5252
*
5353
* @tparam R The return type of the function.
54+
* @tparam NX Whether the function is noexcept.
5455
* @tparam Args The argument types of the function.
5556
*/
56-
template<typename R, typename... Args>
57-
struct function_traits<R (*)(Args...)> {
57+
template<typename R, bool NX, typename... Args>
58+
struct function_traits<R (*)(Args...) noexcept(NX)> {
5859
using return_type = R; ///< The return type of the function.
5960
using args_tuple = std::tuple<Args...>; ///< A tuple of the argument types.
6061
};
6162

62-
/**
63-
* @brief Specialization for noexcept function pointers.
64-
*
65-
* @tparam R The return type of the function.
66-
* @tparam Args The argument types of the function.
67-
*/
68-
template<typename R, typename... Args>
69-
struct function_traits<R (*)(Args...) noexcept> : function_traits<R (*)(Args...)> {};
70-
7163
/**
7264
* @brief Specialization for member function pointers.
7365
*
7466
* @tparam R The return type of the member function.
7567
* @tparam C The class type.
68+
* @tparam NX Whether the member function is noexcept.
7669
* @tparam Args The argument types of the member function.
7770
*/
78-
template<typename R, typename C, typename... Args>
79-
struct function_traits<R (C::*)(Args...)> {
80-
using return_type = R; ///< The return type of the member function.
81-
using args_tuple = std::tuple<Args...>; ///< A tuple of the argument types.
82-
};
71+
template<typename R, typename C, bool NX, typename... Args>
72+
struct function_traits<R (C::*)(Args...) noexcept(NX)> : function_traits<R (*)(Args...) noexcept(NX)> {};
8373

8474
/**
8575
* @brief Specialization for const member function pointers.
8676
*
8777
* @tparam R The return type of the member function.
8878
* @tparam C The class type.
79+
* @tparam NX Whether the member function is noexcept.
8980
* @tparam Args The argument types of the member function.
9081
*/
91-
template<typename R, typename C, typename... Args>
92-
struct function_traits<R (C::*)(Args...) const> : function_traits<R (C::*)(Args...)> {};
82+
template<typename R, typename C, bool NX, typename... Args>
83+
struct function_traits<R (C::*)(Args...) const noexcept(NX)> : function_traits<R (C::*)(Args...) noexcept(NX)> {};
9384

9485
/**
9586
* @brief Specialization for volatile member function pointers.
9687
*
9788
* @tparam R The return type of the member function.
9889
* @tparam C The class type.
90+
* @tparam NX Whether the member function is noexcept.
9991
* @tparam Args The argument types of the member function.
10092
*/
101-
template<typename R, typename C, typename... Args>
102-
struct function_traits<R (C::*)(Args...) volatile> : function_traits<R (C::*)(Args...)> {};
93+
template<typename R, typename C, bool NX, typename... Args>
94+
struct function_traits<R (C::*)(Args...) volatile noexcept(NX)> : function_traits<R (C::*)(Args...) noexcept(NX)> {};
10395

10496
/**
10597
* @brief Specialization for const volatile member function pointers.
10698
*
10799
* @tparam R The return type of the member function.
108100
* @tparam C The class type.
101+
* @tparam NX Whether the member function is noexcept.
102+
* @tparam Args The argument types of the member function.
103+
*/
104+
template<typename R, typename C, bool NX, typename... Args>
105+
struct function_traits<R (C::*)(Args...) const volatile noexcept(NX)>
106+
: function_traits<R (C::*)(Args...) noexcept(NX)> {};
107+
108+
/**
109+
* @brief Specialization for lvalue reference member function pointers.
110+
*
111+
* @tparam R The return type of the member function.
112+
* @tparam C The class type.
113+
* @tparam NX Whether the member function is noexcept.
114+
* @tparam Args The argument types of the member function.
115+
*/
116+
template<typename R, typename C, bool NX, typename... Args>
117+
struct function_traits<R (C::*)(Args...) & noexcept(NX)> : function_traits<R (C::*)(Args...) noexcept(NX)> {};
118+
119+
/**
120+
* @brief Specialization for const lvalue reference member function pointers.
121+
*
122+
* @tparam R The return type of the member function.
123+
* @tparam C The class type.
124+
* @tparam NX Whether the member function is noexcept.
109125
* @tparam Args The argument types of the member function.
110126
*/
111-
template<typename R, typename C, typename... Args>
112-
struct function_traits<R (C::*)(Args...) const volatile> : function_traits<R (C::*)(Args...)> {};
127+
template<typename R, typename C, bool NX, typename... Args>
128+
struct function_traits<R (C::*)(Args...) const & noexcept(NX)> : function_traits<R (C::*)(Args...) noexcept(NX)> {};
113129

114130
/**
115-
* @brief Specialization for noexcept member function pointers.
131+
* @brief Specialization for volatile lvalue reference member function pointers.
116132
*
117133
* @tparam R The return type of the member function.
118134
* @tparam C The class type.
135+
* @tparam NX Whether the member function is noexcept.
119136
* @tparam Args The argument types of the member function.
120137
*/
121-
template<typename R, typename C, typename... Args>
122-
struct function_traits<R (C::*)(Args...) noexcept> : function_traits<R (C::*)(Args...)> {};
138+
template<typename R, typename C, bool NX, typename... Args>
139+
struct function_traits<R (C::*)(Args...) volatile & noexcept(NX)> : function_traits<R (C::*)(Args...) noexcept(NX)> {};
123140

124141
/**
125-
* @brief Specialization for const noexcept member function pointers.
142+
* @brief Specialization for const volatile lvalue reference member function pointers.
126143
*
127144
* @tparam R The return type of the member function.
128145
* @tparam C The class type.
146+
* @tparam NX Whether the member function is noexcept.
129147
* @tparam Args The argument types of the member function.
130148
*/
131-
template<typename R, typename C, typename... Args>
132-
struct function_traits<R (C::*)(Args...) const noexcept> : function_traits<R (C::*)(Args...)> {};
149+
template<typename R, typename C, bool NX, typename... Args>
150+
struct function_traits<R (C::*)(Args...) const volatile & noexcept(NX)>
151+
: function_traits<R (C::*)(Args...) noexcept(NX)> {};
133152

134153
/**
135-
* @brief Specialization for volatile noexcept member function pointers.
154+
* @brief Specialization for rvalue reference member function pointers.
136155
*
137156
* @tparam R The return type of the member function.
138157
* @tparam C The class type.
158+
* @tparam NX Whether the member function is noexcept.
139159
* @tparam Args The argument types of the member function.
140160
*/
141-
template<typename R, typename C, typename... Args>
142-
struct function_traits<R (C::*)(Args...) volatile noexcept> : function_traits<R (C::*)(Args...)> {};
161+
template<typename R, typename C, bool NX, typename... Args>
162+
struct function_traits<R (C::*)(Args...) && noexcept(NX)> : function_traits<R (C::*)(Args...) noexcept(NX)> {};
143163

144164
/**
145-
* @brief Specialization for const volatile noexcept member function pointers.
165+
* @brief Specialization for const rvalue reference member function pointers.
146166
*
147167
* @tparam R The return type of the member function.
148168
* @tparam C The class type.
169+
* @tparam NX Whether the member function is noexcept.
149170
* @tparam Args The argument types of the member function.
150171
*/
151-
template<typename R, typename C, typename... Args>
152-
struct function_traits<R (C::*)(Args...) const volatile noexcept> : function_traits<R (C::*)(Args...)> {};
172+
template<typename R, typename C, bool NX, typename... Args>
173+
struct function_traits<R (C::*)(Args...) const && noexcept(NX)> : function_traits<R (C::*)(Args...) noexcept(NX)> {};
174+
175+
/**
176+
* @brief Specialization for volatile rvalue reference member function pointers.
177+
*
178+
* @tparam R The return type of the member function.
179+
* @tparam C The class type.
180+
* @tparam NX Whether the member function is noexcept.
181+
* @tparam Args The argument types of the member function.
182+
*/
183+
template<typename R, typename C, bool NX, typename... Args>
184+
struct function_traits<R (C::*)(Args...) volatile && noexcept(NX)> : function_traits<R (C::*)(Args...) noexcept(NX)> {};
185+
186+
/**
187+
* @brief Specialization for const volatile rvalue reference member function pointers.
188+
*
189+
* @tparam R The return type of the member function.
190+
* @tparam C The class type.
191+
* @tparam NX Whether the member function is noexcept.
192+
* @tparam Args The argument types of the member function.
193+
*/
194+
template<typename R, typename C, bool NX, typename... Args>
195+
struct function_traits<R (C::*)(Args...) const volatile && noexcept(NX)>
196+
: function_traits<R (C::*)(Args...) noexcept(NX)> {};
153197

154198
/**
155199
* @brief Specialization for `std::function`.
156200
*
157-
* @tparam R The return type of the function.
158-
* @tparam Args The argument types of the function.
201+
* @tparam S The type of the function, which includes the return type and argument types.
159202
*/
160-
template<typename R, typename... Args>
161-
struct function_traits<std::function<R(Args...)>> {
162-
using return_type = R; ///< The return type of the function.
163-
using args_tuple = std::tuple<Args...>; ///< A tuple of the argument types.
164-
};
203+
template<typename S>
204+
struct function_traits<std::function<S>> : function_traits<std::decay_t<S>> {};
165205

166206
/**
167207
* @brief Specialization for functors (objects with `operator()`).
168208
*
169209
* @tparam T The functor type.
170210
*/
171211
template<typename T>
172-
struct function_traits {
173-
private:
174-
using call_type = function_traits<decltype(&T::operator())>; ///< Type traits for the call operator.
175-
176-
public:
177-
using return_type = typename call_type::return_type; ///< The return type of the functor.
178-
using args_tuple = typename call_type::args_tuple; ///< A tuple of the argument types.
179-
};
212+
struct function_traits : function_traits<decltype(&T::operator())> {};
180213
/** @} */
181214

182215
/**

0 commit comments

Comments
 (0)