2 // Copyright (C) 2000 John Maddock (john_maddock@compuserve.com)
4 // Permission to copy and use this software is granted,
5 // provided this copyright notice appears in all copies.
6 // Permission to modify the code and to distribute modified code is granted,
7 // provided this copyright notice appears in all copies, and a notice
8 // that the code was modified is included with the copyright notice.
10 // This software is provided "as is" without express or implied warranty,
11 // and with no claim as to its suitability for any purpose.
13 #ifndef BOOST_FUNCTION_TYPE_TRAITS_HPP
14 #define BOOST_FUNCTION_TYPE_TRAITS_HPP
16 #ifndef BOOST_ICE_TYPE_TRAITS_HPP
17 #include <boost/type_traits/ice.hpp>
19 #ifndef BOOST_FWD_TYPE_TRAITS_HPP
20 #include <boost/type_traits/fwd.hpp>
22 #ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
23 #include <boost/type_traits/composite_traits.hpp>
26 // is a type a function?
27 // Please note that this implementation is unnecessarily complex:
28 // we could just use !is_convertible<T*, const volatile void*>::value,
29 // except that some compilers erroneously allow conversions from
30 // function pointers to void*.
35 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
38 struct is_function_helper_base{ BOOST_STATIC_CONSTANT(bool, value = false); };
40 struct is_function_helper_base<R (*)(void)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
41 template <class R, class A0>
42 struct is_function_helper_base<R (*)(A0)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
43 template <class R, class A0, class A1>
44 struct is_function_helper_base<R (*)(A0, A1)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
45 template <class R, class A0, class A1, class A2>
46 struct is_function_helper_base<R (*)(A0, A1, A2)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
47 template <class R, class A0, class A1, class A2, class A3>
48 struct is_function_helper_base<R (*)(A0, A1, A2, A3)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
49 template <class R, class A0, class A1, class A2, class A3, class A4>
50 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
51 template <class R, class A0, class A1, class A2, class A3, class A4, class A5>
52 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
53 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6>
54 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
55 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
56 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
57 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
58 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
59 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
60 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
61 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
62 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
63 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11>
64 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
65 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12>
66 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
67 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13>
68 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
69 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14>
70 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
71 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15>
72 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
73 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16>
74 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
75 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17>
76 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
77 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18>
78 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
79 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19>
80 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
81 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20>
82 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
83 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20, class A21>
84 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
85 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20, class A21, class A22>
86 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
87 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20, class A21, class A22, class A23>
88 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
89 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20, class A21, class A22, class A23, class A24>
90 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
91 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20, class A21, class A22, class A23, class A24, class A25>
92 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
93 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20, class A21, class A22, class A23, class A24, class A25, class A26>
94 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
95 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20, class A21, class A22, class A23, class A24, class A25, class A26, class A27>
96 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
97 template <class R, class A0, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11, class A12, class A13, class A14, class A15, class A16, class A17, class A18, class A19, class A20, class A21, class A22, class A23, class A24, class A25, class A26, class A27, class A28>
98 struct is_function_helper_base<R (*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28)>{ BOOST_STATIC_CONSTANT(bool, value = true); };
101 struct is_function_helper : is_function_helper_base<T*>{};
106 struct is_function_helper
109 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_function_tester(t)) == sizeof(::boost::type_traits::yes_type));
110 //BOOST_STATIC_CONSTANT(bool, value = (!::boost::is_convertible<T*, const volatile void*>::value));
116 struct is_function_ref_helper
118 BOOST_STATIC_CONSTANT(bool, value = false);
121 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
122 template <class T, bool is_ref>
123 struct is_function_chooser
125 typedef is_function_helper<T> type;
128 struct is_function_chooser<T, true>
130 typedef is_function_ref_helper<T> type;
133 } // namespace detail
139 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
140 typedef typename detail::is_function_chooser<T, ::boost::is_reference<T>::value>::type m_type;
142 // without partial specialistaion we can't use is_reference on
143 // function types, that leaves this template broken in the case that
145 typedef detail::is_function_helper<T> m_type;
148 BOOST_STATIC_CONSTANT(bool, value = m_type::value);
151 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
154 template<typename Function> struct function_traits_helper;
157 struct function_traits_helper<R (*)(void)>
159 BOOST_STATIC_CONSTANT(int, arity = 0);
160 typedef R result_type;
163 template<typename R, typename T1>
164 struct function_traits_helper<R (*)(T1)>
166 BOOST_STATIC_CONSTANT(int, arity = 1);
167 typedef R result_type;
168 typedef T1 arg1_type;
171 template<typename R, typename T1, typename T2>
172 struct function_traits_helper<R (*)(T1, T2)>
174 BOOST_STATIC_CONSTANT(int, arity = 2);
175 typedef R result_type;
176 typedef T1 arg1_type;
177 typedef T2 arg2_type;
180 template<typename R, typename T1, typename T2, typename T3>
181 struct function_traits_helper<R (*)(T1, T2, T3)>
183 BOOST_STATIC_CONSTANT(int, arity = 3);
184 typedef R result_type;
185 typedef T1 arg1_type;
186 typedef T2 arg2_type;
187 typedef T3 arg3_type;
190 template<typename R, typename T1, typename T2, typename T3, typename T4>
191 struct function_traits_helper<R (*)(T1, T2, T3, T4)>
193 BOOST_STATIC_CONSTANT(int, arity = 4);
194 typedef R result_type;
195 typedef T1 arg1_type;
196 typedef T2 arg2_type;
197 typedef T3 arg3_type;
198 typedef T4 arg4_type;
201 template<typename R, typename T1, typename T2, typename T3, typename T4,
203 struct function_traits_helper<R (*)(T1, T2, T3, T4, T5)>
205 BOOST_STATIC_CONSTANT(int, arity = 5);
206 typedef R result_type;
207 typedef T1 arg1_type;
208 typedef T2 arg2_type;
209 typedef T3 arg3_type;
210 typedef T4 arg4_type;
211 typedef T5 arg5_type;
214 template<typename R, typename T1, typename T2, typename T3, typename T4,
215 typename T5, typename T6>
216 struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6)>
218 BOOST_STATIC_CONSTANT(int, arity = 6);
219 typedef R result_type;
220 typedef T1 arg1_type;
221 typedef T2 arg2_type;
222 typedef T3 arg3_type;
223 typedef T4 arg4_type;
224 typedef T5 arg5_type;
225 typedef T6 arg6_type;
228 template<typename R, typename T1, typename T2, typename T3, typename T4,
229 typename T5, typename T6, typename T7>
230 struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6, T7)>
232 BOOST_STATIC_CONSTANT(int, arity = 7);
233 typedef R result_type;
234 typedef T1 arg1_type;
235 typedef T2 arg2_type;
236 typedef T3 arg3_type;
237 typedef T4 arg4_type;
238 typedef T5 arg5_type;
239 typedef T6 arg6_type;
240 typedef T7 arg7_type;
243 template<typename R, typename T1, typename T2, typename T3, typename T4,
244 typename T5, typename T6, typename T7, typename T8>
245 struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6, T7, T8)>
247 BOOST_STATIC_CONSTANT(int, arity = 8);
248 typedef R result_type;
249 typedef T1 arg1_type;
250 typedef T2 arg2_type;
251 typedef T3 arg3_type;
252 typedef T4 arg4_type;
253 typedef T5 arg5_type;
254 typedef T6 arg6_type;
255 typedef T7 arg7_type;
256 typedef T8 arg8_type;
259 template<typename R, typename T1, typename T2, typename T3, typename T4,
260 typename T5, typename T6, typename T7, typename T8, typename T9>
261 struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9)>
263 BOOST_STATIC_CONSTANT(int, arity = 9);
264 typedef R result_type;
265 typedef T1 arg1_type;
266 typedef T2 arg2_type;
267 typedef T3 arg3_type;
268 typedef T4 arg4_type;
269 typedef T5 arg5_type;
270 typedef T6 arg6_type;
271 typedef T7 arg7_type;
272 typedef T8 arg8_type;
273 typedef T9 arg9_type;
276 template<typename R, typename T1, typename T2, typename T3, typename T4,
277 typename T5, typename T6, typename T7, typename T8, typename T9,
279 struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>
281 BOOST_STATIC_CONSTANT(int, arity = 10);
282 typedef R result_type;
283 typedef T1 arg1_type;
284 typedef T2 arg2_type;
285 typedef T3 arg3_type;
286 typedef T4 arg4_type;
287 typedef T5 arg5_type;
288 typedef T6 arg6_type;
289 typedef T7 arg7_type;
290 typedef T8 arg8_type;
291 typedef T9 arg9_type;
292 typedef T10 arg10_type;
295 } // end namespace detail
297 template<typename Function>
298 struct function_traits :
299 public detail::function_traits_helper<typename add_pointer<Function>::type>
314 type_of_size<1> function_arity_helper(R (*f)());
316 template<typename R, typename T1>
317 type_of_size<2> function_arity_helper(R (*f)(T1));
319 template<typename R, typename T1, typename T2>
320 type_of_size<3> function_arity_helper(R (*f)(T1, T2));
322 template<typename R, typename T1, typename T2, typename T3>
323 type_of_size<4> function_arity_helper(R (*f)(T1, T2, T3));
325 template<typename R, typename T1, typename T2, typename T3, typename T4>
326 type_of_size<5> function_arity_helper(R (*f)(T1, T2, T3, T4));
328 template<typename R, typename T1, typename T2, typename T3, typename T4,
330 type_of_size<6> function_arity_helper(R (*f)(T1, T2, T3, T4, T5));
332 template<typename R, typename T1, typename T2, typename T3, typename T4,
333 typename T5, typename T6>
334 type_of_size<7> function_arity_helper(R (*f)(T1, T2, T3, T4, T5, T6));
336 template<typename R, typename T1, typename T2, typename T3, typename T4,
337 typename T5, typename T6, typename T7>
338 type_of_size<8> function_arity_helper(R (*f)(T1, T2, T3, T4, T5, T6, T7));
340 template<typename R, typename T1, typename T2, typename T3, typename T4,
341 typename T5, typename T6, typename T7, typename T8>
342 type_of_size<9> function_arity_helper(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8));
344 template<typename R, typename T1, typename T2, typename T3, typename T4,
345 typename T5, typename T6, typename T7, typename T8, typename T9>
346 type_of_size<10> function_arity_helper(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8,
349 template<typename R, typename T1, typename T2, typename T3, typename T4,
350 typename T5, typename T6, typename T7, typename T8, typename T9,
352 type_of_size<11> function_arity_helper(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8,
354 } // end namespace detail
356 // Won't work with references
357 template<typename Function>
358 struct function_traits
360 BOOST_STATIC_CONSTANT(int, arity = (sizeof(detail::function_arity_helper((Function*)0))-1));
363 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
366 #endif // BOOST_FUNCTION_TYPE_TRAITS_HPP