2 // (C) Copyright Tobias Schwinger
4 // Use modification and distribution are subject to the boost Software License,
5 // Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
7 //------------------------------------------------------------------------------
9 #ifndef BOOST_FT_DETAIL_CV_TRAITS_HPP_INCLUDED
10 #define BOOST_FT_DETAIL_CV_TRAITS_HPP_INCLUDED
13 #include <boost/detail/workaround.hpp>
15 #if BOOST_WORKAROUND(__BORLANDC__, <= 0x582)
16 # include <boost/type_traits/remove_cv.hpp>
17 # include <boost/type_traits/remove_pointer.hpp>
18 # include <boost/type_traits/remove_reference.hpp>
21 #include <boost/function_types/property_tags.hpp>
23 namespace boost { namespace function_types { namespace detail {
25 #if !BOOST_WORKAROUND(__BORLANDC__, <= 0x582)
27 template<typename T> struct cv_traits
28 { typedef non_cv tag; typedef T type; };
29 template<typename T> struct cv_traits<T &>
30 { typedef non_cv tag; typedef T type; };
31 template<typename T> struct cv_traits<T *>
32 { typedef non_cv tag; typedef T type; };
33 template<typename T> struct cv_traits<T * const>
34 { typedef non_cv tag; typedef T type; };
35 template<typename T> struct cv_traits<T * volatile>
36 { typedef non_cv tag; typedef T type; };
37 template<typename T> struct cv_traits<T * const volatile>
38 { typedef non_cv tag; typedef T type; };
40 template<typename T> struct cv_traits<T const>
41 { typedef const_non_volatile tag; typedef T type; };
42 template<typename T> struct cv_traits<T const &>
43 { typedef const_non_volatile tag; typedef T type; };
44 template<typename T> struct cv_traits<T const *>
45 { typedef const_non_volatile tag; typedef T type; };
46 template<typename T> struct cv_traits<T const * const>
47 { typedef const_non_volatile tag; typedef T type; };
48 template<typename T> struct cv_traits<T const * volatile>
49 { typedef const_non_volatile tag; typedef T type; };
50 template<typename T> struct cv_traits<T const * const volatile>
51 { typedef const_non_volatile tag; typedef T type; };
53 template<typename T> struct cv_traits<T volatile>
54 { typedef volatile_non_const tag; typedef T type; };
55 template<typename T> struct cv_traits<T volatile &>
56 { typedef volatile_non_const tag; typedef T type; };
57 template<typename T> struct cv_traits<T volatile *>
58 { typedef volatile_non_const tag; typedef T type; };
59 template<typename T> struct cv_traits<T volatile * const>
60 { typedef volatile_non_const tag; typedef T type; };
61 template<typename T> struct cv_traits<T volatile * volatile>
62 { typedef volatile_non_const tag; typedef T type; };
63 template<typename T> struct cv_traits<T volatile * const volatile>
64 { typedef volatile_non_const tag; typedef T type; };
66 template<typename T> struct cv_traits<T const volatile>
67 { typedef cv_qualified tag; typedef T type; };
68 template<typename T> struct cv_traits<T const volatile &>
69 { typedef cv_qualified tag; typedef T type; };
70 template<typename T> struct cv_traits<T const volatile *>
71 { typedef cv_qualified tag; typedef T type; };
72 template<typename T> struct cv_traits<T const volatile * const>
73 { typedef cv_qualified tag; typedef T type; };
74 template<typename T> struct cv_traits<T const volatile * volatile>
75 { typedef cv_qualified tag; typedef T type; };
76 template<typename T> struct cv_traits<T const volatile * const volatile>
77 { typedef cv_qualified tag; typedef T type; };
80 template<std::size_t> struct cv_tag_impl;
82 template<> struct cv_tag_impl<1> { typedef non_cv type;};
83 template<> struct cv_tag_impl<2> { typedef const_non_volatile type; };
84 template<> struct cv_tag_impl<3> { typedef volatile_non_const type; };
85 template<> struct cv_tag_impl<4> { typedef cv_qualified type; };
87 typedef char (& case_1)[1];
88 typedef char (& case_2)[2];
89 typedef char (& case_3)[3];
90 typedef char (& case_4)[4];
92 template<typename T> case_1 switch_cv(T *);
93 template<typename T> case_2 switch_cv(T const *);
94 template<typename T> case_3 switch_cv(T volatile *);
95 template<typename T> case_4 switch_cv(T const volatile *);
97 template<typename T> T * ref_to_ptr(T &);
98 template<typename T> T const * ref_to_ptr(T const &);
99 template<typename T> T volatile * ref_to_ptr(T volatile &);
100 template<typename T> T const volatile * ref_to_ptr(T const volatile &);
102 template<typename T> T * ref_to_ptr(T * const volatile &);
108 BOOST_STATIC_CONSTANT(std::size_t, value =
109 sizeof(::boost::function_types::detail::switch_cv(
110 ::boost::function_types::detail::ref_to_ptr(_t) ) ));
113 template<typename T> struct cv_traits
115 typedef typename boost::function_types::detail::cv_tag_impl<
116 ::boost::function_types::detail::cv_code<T>::value >::type
119 // may require Boost.TypeTraits broken compiler specializations
121 typedef typename boost::remove_cv<
122 typename boost::remove_pointer<
123 typename boost::remove_reference<T>::type
129 } } } // namespace boost::function_types::detail