1 // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
2 // Permission to copy, use, modify, sell and
3 // distribute this software is granted provided this copyright notice appears
4 // in all copies. This software is provided "as is" without express or implied
5 // warranty, and with no claim as to its suitability for any purpose.
7 // See http://www.boost.org for most recent version including documentation.
9 // defines traits classes for cv-qualified types:
10 // is_const, is_volatile, remove_const, remove_volatile, remove_cv.
14 // Fixed is_const/is_volatile so that they work with reference types
16 #ifndef BOOST_CV_TYPE_TRAITS_HPP
17 #define BOOST_CV_TYPE_TRAITS_HPP
19 #ifndef BOOST_ICE_TYPE_TRAITS_HPP
20 #include <boost/type_traits/ice.hpp>
22 #ifndef BOOST_FWD_TYPE_TRAITS_HPP
23 #include <boost/type_traits/fwd.hpp>
28 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
31 // implementation helper:
34 struct cv_traits_imp{};
37 struct cv_traits_imp<T*>
39 BOOST_STATIC_CONSTANT(bool, is_const = false);
40 BOOST_STATIC_CONSTANT(bool, is_volatile = false);
41 typedef T unqualified_type;
45 struct cv_traits_imp<const T*>
47 BOOST_STATIC_CONSTANT(bool, is_const = true);
48 BOOST_STATIC_CONSTANT(bool, is_volatile = false);
49 typedef T unqualified_type;
53 struct cv_traits_imp<volatile T*>
55 BOOST_STATIC_CONSTANT(bool, is_const = false);
56 BOOST_STATIC_CONSTANT(bool, is_volatile = true);
57 typedef T unqualified_type;
61 struct cv_traits_imp<const volatile T*>
63 BOOST_STATIC_CONSTANT(bool, is_const = true);
64 BOOST_STATIC_CONSTANT(bool, is_volatile = true);
65 typedef T unqualified_type;
68 template <class T, bool is_vol>
69 struct remove_const_helper
74 struct remove_const_helper<T, true>
76 typedef volatile T type;
79 template <class T, bool is_vol>
80 struct remove_volatile_helper
85 struct remove_volatile_helper<T, true>
92 // * convert a type T to a non-volatile type - remove_volatile<T>
94 struct remove_volatile
96 typedef typename detail::cv_traits_imp<T*>::unqualified_type uq_type;
97 typedef typename detail::remove_volatile_helper<uq_type, ::boost::is_const<T>::value>::type type;
99 template <typename T> struct remove_volatile<T&>{ typedef T& type; };
100 template <typename T, std::size_t N> struct remove_volatile<volatile T[N]>{ typedef T type[N]; };
101 template <typename T, std::size_t N> struct remove_volatile<const volatile T[N]>{ typedef const T type[N]; };
103 // * convert a type T to non-const type - remove_const<T>
104 template <typename T>
107 typedef typename detail::cv_traits_imp<T*>::unqualified_type uq_type;
108 typedef typename detail::remove_const_helper<uq_type, ::boost::is_volatile<T>::value>::type type;
110 template <typename T> struct remove_const<T&>{ typedef T& type; };
111 template <typename T, std::size_t N> struct remove_const<const T[N]>{ typedef T type[N]; };
112 template <typename T, std::size_t N> struct remove_const<const volatile T[N]>{ typedef volatile T type[N]; };
114 // convert a type T to a non-cv-qualified type - remove_cv<T>
115 template <typename T>
118 typedef typename detail::cv_traits_imp<T*>::unqualified_type type;
120 template <typename T> struct remove_cv<T&>{ typedef T& type; };
121 template <typename T, std::size_t N> struct remove_cv<const T[N]>{ typedef T type[N]; };
122 template <typename T, std::size_t N> struct remove_cv<volatile T[N]>{ typedef T type[N]; };
123 template <typename T, std::size_t N> struct remove_cv<const volatile T[N]>{ typedef T type[N]; };
125 //* is a type T declared const - is_const<T>
126 template <typename T>
129 BOOST_STATIC_CONSTANT(bool, value = detail::cv_traits_imp<T*>::is_const);
131 template <typename T> struct is_const<T&>
132 { BOOST_STATIC_CONSTANT(bool, value = false); };
133 #if defined(__BORLANDC__)
134 // these are illegal specialisations; cv-qualifies applied to
135 // references have no effect according to [8.3.2p1],
136 // C++ Builder requires them though as it treats cv-qualified
137 // references as distinct types...
138 template <typename T> struct is_const<T&const>
139 { BOOST_STATIC_CONSTANT(bool, value = false); };
140 template <typename T> struct is_const<T&volatile>
141 { BOOST_STATIC_CONSTANT(bool, value = false); };
142 template <typename T> struct is_const<T&const volatile>
143 { BOOST_STATIC_CONSTANT(bool, value = false); };
146 //* is a type T declared volatile - is_volatile<T>
147 template <typename T>
150 BOOST_STATIC_CONSTANT(bool, value = detail::cv_traits_imp<T*>::is_volatile);
152 template <typename T> struct is_volatile<T&>
153 { BOOST_STATIC_CONSTANT(bool, value = false); };
154 #if defined(__BORLANDC__)
155 // these are illegal specialisations; cv-qualifies applied to
156 // references have no effect according to [8.3.2p1],
157 // C++ Builder requires them though as it treats cv-qualified
158 // references as distinct types...
159 template <typename T> struct is_volatile<T&const>
160 { BOOST_STATIC_CONSTANT(bool, value = false); };
161 template <typename T> struct is_volatile<T&volatile>
162 { BOOST_STATIC_CONSTANT(bool, value = false); };
163 template <typename T> struct is_volatile<T&const volatile>
164 { BOOST_STATIC_CONSTANT(bool, value = false); };
167 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
168 // The following three don't work:
169 template <typename T> struct remove_volatile{ typedef T type; };
170 template <typename T> struct remove_const{ typedef T type; };
171 template <typename T> struct remove_cv{ typedef T type; };
174 using ::boost::type_traits::yes_type;
175 using ::boost::type_traits::no_type;
176 yes_type is_const_helper(const volatile void*);
177 no_type is_const_helper(volatile void *);
178 yes_type is_volatile_helper(const volatile void*);
179 no_type is_volatile_helper(const void *);
182 template <typename T>
188 BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_const_helper(&t))));
192 struct is_const<void>
194 BOOST_STATIC_CONSTANT(bool, value = false);
196 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
198 struct is_const<const void>
200 BOOST_STATIC_CONSTANT(bool, value = true);
203 struct is_const<volatile void>
205 BOOST_STATIC_CONSTANT(bool, value = false);
208 struct is_const<const volatile void>
210 BOOST_STATIC_CONSTANT(bool, value = true);
214 template <typename T>
220 BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_volatile_helper(&t))));
224 struct is_volatile<void>
226 BOOST_STATIC_CONSTANT(bool, value = false);
228 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
230 struct is_volatile<const void>
232 BOOST_STATIC_CONSTANT(bool, value = false);
235 struct is_volatile<volatile void>
237 BOOST_STATIC_CONSTANT(bool, value = true);
240 struct is_volatile<const volatile void>
242 BOOST_STATIC_CONSTANT(bool, value = true);
246 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
248 // * convert a type T to const type - add_const<T>
249 // this is not required since the result is always
250 // the same as "T const", but it does suppress warnings
251 // from some compilers:
252 template <typename T>
255 typedef T const type;
257 // * convert a type T to volatile type - add_volatile<T>
258 // this is not required since the result is always
259 // the same as "T volatile", but it does suppress warnings
260 // from some compilers:
261 template <typename T>
264 typedef T volatile type;
266 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
268 struct add_const<T&>{ typedef T& type; };
270 struct add_volatile<T&>{ typedef T& type; };
276 #endif // BOOST_CV_TYPE_TRAITS_HPP