1 // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
2 // Hinnant & John Maddock 2000. Permission to copy, use, modify,
3 // sell and distribute this software is granted provided this
4 // copyright notice appears in all copies. This software is provided
5 // "as is" without express or implied warranty, and with no claim as
6 // to its suitability for any purpose.
8 // See http://www.boost.org for most recent version including documentation.
10 // defines traits classes for cv-qualified types:
11 // is_const, is_volatile, remove_const, remove_volatile, remove_cv.
15 // Fixed is_const/is_volatile so that they work with reference types
17 #ifndef BOOST_CV_TYPE_TRAITS_HPP
18 #define BOOST_CV_TYPE_TRAITS_HPP
20 #ifndef BOOST_ICE_TYPE_TRAITS_HPP
21 #include <boost/type_traits/ice.hpp>
23 #ifndef BOOST_FWD_TYPE_TRAITS_HPP
24 #include <boost/type_traits/fwd.hpp>
26 #ifndef BOOST_TT_REFERENCE_TRAITS_HPP
27 # include <boost/type_traits/reference_traits.hpp>
29 #ifndef BOOST_TT_ARRAY_TRAITS_HPP
30 # include <boost/type_traits/array_traits.hpp>
32 #ifndef BOOST_TT_UTILITY_HPP
33 # include <boost/type_traits/utility.hpp>
38 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
41 // implementation helper:
44 struct cv_traits_imp{};
47 struct cv_traits_imp<T*>
49 BOOST_STATIC_CONSTANT(bool, is_const = false);
50 BOOST_STATIC_CONSTANT(bool, is_volatile = false);
51 typedef T unqualified_type;
55 struct cv_traits_imp<const T*>
57 BOOST_STATIC_CONSTANT(bool, is_const = true);
58 BOOST_STATIC_CONSTANT(bool, is_volatile = false);
59 typedef T unqualified_type;
63 struct cv_traits_imp<volatile T*>
65 BOOST_STATIC_CONSTANT(bool, is_const = false);
66 BOOST_STATIC_CONSTANT(bool, is_volatile = true);
67 typedef T unqualified_type;
71 struct cv_traits_imp<const volatile T*>
73 BOOST_STATIC_CONSTANT(bool, is_const = true);
74 BOOST_STATIC_CONSTANT(bool, is_volatile = true);
75 typedef T unqualified_type;
78 template <class T, bool is_vol>
79 struct remove_const_helper
84 struct remove_const_helper<T, true>
86 typedef volatile T type;
89 template <class T, bool is_vol>
90 struct remove_volatile_helper
95 struct remove_volatile_helper<T, true>
100 } // namespace detail
102 // * convert a type T to a non-volatile type - remove_volatile<T>
103 template <typename T>
104 struct remove_volatile
106 typedef typename detail::cv_traits_imp<T*>::unqualified_type uq_type;
107 typedef typename detail::remove_volatile_helper<uq_type, ::boost::is_const<T>::value>::type type;
109 template <typename T> struct remove_volatile<T&>{ typedef T& type; };
110 template <typename T, std::size_t N> struct remove_volatile<volatile T[N]>{ typedef T type[N]; };
111 template <typename T, std::size_t N> struct remove_volatile<const volatile T[N]>{ typedef const T type[N]; };
113 // * convert a type T to non-const type - remove_const<T>
114 template <typename T>
117 typedef typename detail::cv_traits_imp<T*>::unqualified_type uq_type;
118 typedef typename detail::remove_const_helper<uq_type, ::boost::is_volatile<T>::value>::type type;
120 template <typename T> struct remove_const<T&>{ typedef T& type; };
121 template <typename T, std::size_t N> struct remove_const<const T[N]>{ typedef T type[N]; };
122 template <typename T, std::size_t N> struct remove_const<const volatile T[N]>{ typedef volatile T type[N]; };
124 // convert a type T to a non-cv-qualified type - remove_cv<T>
125 template <typename T>
128 typedef typename detail::cv_traits_imp<T*>::unqualified_type type;
130 template <typename T> struct remove_cv<T&>{ typedef T& type; };
131 template <typename T, std::size_t N> struct remove_cv<const T[N]>{ typedef T type[N]; };
132 template <typename T, std::size_t N> struct remove_cv<volatile T[N]>{ typedef T type[N]; };
133 template <typename T, std::size_t N> struct remove_cv<const volatile T[N]>{ typedef T type[N]; };
135 //* is a type T declared const - is_const<T>
136 template <typename T>
139 BOOST_STATIC_CONSTANT(bool, value = detail::cv_traits_imp<T*>::is_const);
141 template <typename T> struct is_const<T&>
142 { BOOST_STATIC_CONSTANT(bool, value = false); };
143 #if defined(__BORLANDC__)
144 // these are illegal specialisations; cv-qualifies applied to
145 // references have no effect according to [8.3.2p1],
146 // C++ Builder requires them though as it treats cv-qualified
147 // references as distinct types...
148 template <typename T> struct is_const<T&const>
149 { BOOST_STATIC_CONSTANT(bool, value = false); };
150 template <typename T> struct is_const<T&volatile>
151 { BOOST_STATIC_CONSTANT(bool, value = false); };
152 template <typename T> struct is_const<T&const volatile>
153 { BOOST_STATIC_CONSTANT(bool, value = false); };
156 //* is a type T declared volatile - is_volatile<T>
157 template <typename T>
160 BOOST_STATIC_CONSTANT(bool, value = detail::cv_traits_imp<T*>::is_volatile);
162 template <typename T> struct is_volatile<T&>
163 { BOOST_STATIC_CONSTANT(bool, value = false); };
164 #if defined(__BORLANDC__)
165 // these are illegal specialisations; cv-qualifies applied to
166 // references have no effect according to [8.3.2p1],
167 // C++ Builder requires them though as it treats cv-qualified
168 // references as distinct types...
169 template <typename T> struct is_volatile<T&const>
170 { BOOST_STATIC_CONSTANT(bool, value = false); };
171 template <typename T> struct is_volatile<T&volatile>
172 { BOOST_STATIC_CONSTANT(bool, value = false); };
173 template <typename T> struct is_volatile<T&const volatile>
174 { BOOST_STATIC_CONSTANT(bool, value = false); };
177 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
178 // The following three don't work:
179 template <typename T> struct remove_volatile{ typedef T type; };
180 template <typename T> struct remove_const{ typedef T type; };
181 template <typename T> struct remove_cv{ typedef T type; };
184 using ::boost::type_traits::yes_type;
185 using ::boost::type_traits::no_type;
186 yes_type is_const_helper(const volatile void*);
187 no_type is_const_helper(volatile void *);
188 yes_type is_volatile_helper(const volatile void*);
189 no_type is_volatile_helper(const void *);
194 template <bool is_ref, bool array>
196 : ::boost::type_traits::false_unary_metafunction
200 struct is_const_impl<false,false>
208 BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_const_helper(t))));
213 struct is_const_impl<false,true>
221 BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_const_helper(&t))));
226 template <typename T>
228 : ::boost::detail::is_const_impl<
229 is_reference<T>::value
236 struct is_const<void>
238 BOOST_STATIC_CONSTANT(bool, value = false);
240 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
242 struct is_const<const void>
244 BOOST_STATIC_CONSTANT(bool, value = true);
247 struct is_const<volatile void>
249 BOOST_STATIC_CONSTANT(bool, value = false);
252 struct is_const<const volatile void>
254 BOOST_STATIC_CONSTANT(bool, value = true);
260 template <bool is_ref, bool array>
261 struct is_volatile_impl
262 : ::boost::type_traits::false_unary_metafunction
266 struct is_volatile_impl<false,false>
274 BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_volatile_helper(t))));
279 struct is_volatile_impl<false,true>
287 BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_volatile_helper(&t))));
292 template <typename T>
294 : ::boost::detail::is_volatile_impl<
295 is_reference<T>::value
303 struct is_volatile<void>
305 BOOST_STATIC_CONSTANT(bool, value = false);
307 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
309 struct is_volatile<const void>
311 BOOST_STATIC_CONSTANT(bool, value = false);
314 struct is_volatile<volatile void>
316 BOOST_STATIC_CONSTANT(bool, value = true);
319 struct is_volatile<const volatile void>
321 BOOST_STATIC_CONSTANT(bool, value = true);
325 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
327 // * convert a type T to const type - add_const<T>
328 // this is not required since the result is always
329 // the same as "T const", but it does suppress warnings
330 // from some compilers:
331 template <typename T>
334 #if defined(BOOST_MSVC)
335 // This bogus warning will appear when add_const is applied to a
336 // const volatile reference because we can't detect const volatile
337 // references with MSVC6.
338 # pragma warning(push)
339 # pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored
341 typedef T const type;
342 #if defined(BOOST_MSVC)
343 # pragma warning(pop)
346 // * convert a type T to volatile type - add_volatile<T>
347 // this is not required since the result is always
348 // the same as "T volatile", but it does suppress warnings
349 // from some compilers:
350 template <typename T>
353 #if defined(BOOST_MSVC)
354 // This bogus warning will appear when add_volatile is applied to a
355 // const volatile reference because we can't detect const volatile
356 // references with MSVC6.
357 # pragma warning(push)
358 # pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored
360 typedef T volatile type;
361 #if defined(BOOST_MSVC)
362 # pragma warning(pop)
365 // * convert a type T to a const volatile type - add_cv<T>
366 // this is not required since the result is always
367 // the same as "T const volatile", but it does suppress warnings
368 // from some compilers:
369 template <typename T>
372 #if defined(BOOST_MSVC)
373 // This bogus warning will appear when add_volatile is applied to a
374 // const volatile reference because we can't detect const volatile
375 // references with MSVC6.
376 # pragma warning(push)
377 # pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored
379 typedef T const volatile type;
380 #if defined(BOOST_MSVC)
381 # pragma warning(pop)
384 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
386 struct add_const<T&>{ typedef T& type; };
388 struct add_volatile<T&>{ typedef T& type; };
390 struct add_cv<T&>{ typedef T& type; };
396 #endif // BOOST_CV_TYPE_TRAITS_HPP