1 // Copyright David Abrahams 2002.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #ifndef INDIRECT_TRAITS_DWA2002131_HPP
6 # define INDIRECT_TRAITS_DWA2002131_HPP
7 # include <boost/type_traits/is_function.hpp>
8 # include <boost/type_traits/is_reference.hpp>
9 # include <boost/type_traits/is_pointer.hpp>
10 # include <boost/type_traits/is_class.hpp>
11 # include <boost/type_traits/is_const.hpp>
12 # include <boost/type_traits/is_volatile.hpp>
13 # include <boost/type_traits/is_member_function_pointer.hpp>
14 # include <boost/type_traits/remove_cv.hpp>
15 # include <boost/type_traits/remove_reference.hpp>
16 # include <boost/type_traits/remove_pointer.hpp>
18 # include <boost/type_traits/detail/ice_and.hpp>
19 # include <boost/detail/workaround.hpp>
21 # include <boost/mpl/if.hpp>
22 # include <boost/mpl/bool.hpp>
23 # include <boost/mpl/and.hpp>
24 # include <boost/mpl/not.hpp>
25 # include <boost/mpl/aux_/lambda_support.hpp>
27 # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
28 # include <boost/detail/is_function_ref_tester.hpp>
31 namespace boost { namespace detail {
33 namespace indirect_traits {
35 # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
37 struct is_reference_to_const : mpl::false_
42 struct is_reference_to_const<T const&> : mpl::true_
46 # if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround
48 struct is_reference_to_const<T const volatile&> : mpl::true_
54 struct is_reference_to_function : mpl::false_
59 struct is_reference_to_function<T&> : is_function<T>
64 struct is_pointer_to_function : mpl::false_
68 // There's no such thing as a pointer-to-cv-function, so we don't need
69 // specializations for those
71 struct is_pointer_to_function<T*> : is_function<T>
76 struct is_reference_to_member_function_pointer_impl : mpl::false_
81 struct is_reference_to_member_function_pointer_impl<T&>
82 : is_member_function_pointer<typename remove_cv<T>::type>
88 struct is_reference_to_member_function_pointer
89 : is_reference_to_member_function_pointer_impl<T>
91 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T))
95 struct is_reference_to_function_pointer_aux
98 , is_pointer_to_function<
100 typename remove_reference<T>::type
105 // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those
109 struct is_reference_to_function_pointer
111 is_reference_to_function<T>
113 , is_reference_to_function_pointer_aux<T>
119 struct is_reference_to_non_const
123 is_reference_to_const<T>
130 struct is_reference_to_volatile : mpl::false_
135 struct is_reference_to_volatile<T volatile&> : mpl::true_
139 # if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround
141 struct is_reference_to_volatile<T const volatile&> : mpl::true_
148 struct is_reference_to_pointer : mpl::false_
153 struct is_reference_to_pointer<T*&> : mpl::true_
158 struct is_reference_to_pointer<T* const&> : mpl::true_
163 struct is_reference_to_pointer<T* volatile&> : mpl::true_
168 struct is_reference_to_pointer<T* const volatile&> : mpl::true_
173 struct is_reference_to_class
178 typename remove_reference<T>::type
183 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T))
187 struct is_pointer_to_class
192 typename remove_pointer<T>::type
197 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T))
202 using namespace boost::detail::is_function_ref_tester_;
204 typedef char (&inner_yes_type)[3];
205 typedef char (&inner_no_type)[2];
206 typedef char (&outer_no_type)[1];
208 template <typename V>
211 typedef typename mpl::if_<
218 template <typename V>
219 struct is_volatile_help
221 typedef typename mpl::if_<
228 template <typename V>
229 struct is_pointer_help
231 typedef typename mpl::if_<
238 template <typename V>
241 typedef typename mpl::if_<
249 struct is_reference_to_function_aux
252 BOOST_STATIC_CONSTANT(
253 bool, value = sizeof(detail::is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type));
257 struct is_reference_to_function
258 : mpl::if_<is_reference<T>, is_reference_to_function_aux<T>, mpl::bool_<false> >::type
263 struct is_pointer_to_function_aux
266 BOOST_STATIC_CONSTANT(
268 = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type));
269 typedef mpl::bool_<value> type;
273 struct is_pointer_to_function
274 : mpl::if_<is_pointer<T>, is_pointer_to_function_aux<T>, mpl::bool_<false> >::type
276 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T))
282 struct apply : mpl::false_
287 template <typename V>
288 typename is_const_help<V>::type reference_to_const_helper(V&);
290 reference_to_const_helper(...);
298 BOOST_STATIC_CONSTANT(
300 = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type));
301 typedef mpl::bool_<value> type;
305 template <bool ref = true>
306 struct is_reference_to_const_helper1 : true_helper1
311 struct is_reference_to_const_helper1<false> : false_helper1
317 struct is_reference_to_const
318 : is_reference_to_const_helper1<is_reference<T>::value>::template apply<T>
323 template <bool ref = true>
324 struct is_reference_to_non_const_helper1
330 BOOST_STATIC_CONSTANT(
332 = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type));
337 struct is_reference_to_non_const_helper1<false> : false_helper1
343 struct is_reference_to_non_const
344 : is_reference_to_non_const_helper1<is_reference<T>::value>::template apply<T>
349 template <typename V>
350 typename is_volatile_help<V>::type reference_to_volatile_helper(V&);
352 reference_to_volatile_helper(...);
354 template <bool ref = true>
355 struct is_reference_to_volatile_helper1
361 BOOST_STATIC_CONSTANT(
363 = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type));
368 struct is_reference_to_volatile_helper1<false> : false_helper1
374 struct is_reference_to_volatile
375 : is_reference_to_volatile_helper1<is_reference<T>::value>::template apply<T>
379 template <typename V>
380 typename is_pointer_help<V>::type reference_to_pointer_helper(V&);
381 outer_no_type reference_to_pointer_helper(...);
384 struct is_reference_to_pointer
387 BOOST_STATIC_CONSTANT(
389 = (is_reference<T>::value
390 && sizeof((reference_to_pointer_helper)(t)) == sizeof(inner_yes_type))
395 struct is_reference_to_function_pointer
398 , is_pointer_to_function_aux<T>
402 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T))
407 struct is_member_function_pointer_help
408 : mpl::if_<is_member_function_pointer<T>, inner_yes_type, inner_no_type>
411 template <typename V>
412 typename is_member_function_pointer_help<V>::type member_function_pointer_helper(V&);
413 outer_no_type member_function_pointer_helper(...);
416 struct is_pointer_to_member_function_aux
419 BOOST_STATIC_CONSTANT(
421 = sizeof((member_function_pointer_helper)(t)) == sizeof(inner_yes_type));
422 typedef mpl::bool_<value> type;
426 struct is_reference_to_member_function_pointer
429 , is_pointer_to_member_function_aux<T>
433 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T))
436 template <typename V>
437 typename is_class_help<V>::type reference_to_class_helper(V const volatile&);
438 outer_no_type reference_to_class_helper(...);
441 struct is_reference_to_class
444 BOOST_STATIC_CONSTANT(
446 = (is_reference<T>::value
447 & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type)))
449 typedef mpl::bool_<value> type;
450 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T))
453 template <typename V>
454 typename is_class_help<V>::type pointer_to_class_helper(V const volatile*);
455 outer_no_type pointer_to_class_helper(...);
458 struct is_pointer_to_class
461 BOOST_STATIC_CONSTANT(
463 = (is_pointer<T>::value
464 && sizeof(pointer_to_class_helper(t)) == sizeof(inner_yes_type))
467 # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
471 using namespace indirect_traits;
473 }} // namespace boost::python::detail
475 #endif // INDIRECT_TRAITS_DWA2002131_HPP