]> git.lyx.org Git - lyx.git/blob - boost/boost/type_traits/cv_traits.hpp
update boost
[lyx.git] / boost / boost / type_traits / cv_traits.hpp
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.
7 //
8 //  See http://www.boost.org for most recent version including documentation.
9 //
10 //  defines traits classes for cv-qualified types:
11 //  is_const, is_volatile, remove_const, remove_volatile, remove_cv.
12 //
13 //  Revision History:
14 //  24th March 2001:
15 //    Fixed is_const/is_volatile so that they work with reference types
16
17 #ifndef BOOST_CV_TYPE_TRAITS_HPP
18 #define BOOST_CV_TYPE_TRAITS_HPP
19
20 #ifndef BOOST_ICE_TYPE_TRAITS_HPP
21 #include <boost/type_traits/ice.hpp>
22 #endif
23 #ifndef BOOST_FWD_TYPE_TRAITS_HPP
24 #include <boost/type_traits/fwd.hpp>
25 #endif
26 #ifndef BOOST_TT_REFERENCE_TRAITS_HPP
27 # include <boost/type_traits/reference_traits.hpp>
28 #endif
29 #ifndef BOOST_TT_ARRAY_TRAITS_HPP
30 # include <boost/type_traits/array_traits.hpp>
31 #endif
32 #ifndef BOOST_TT_UTILITY_HPP
33 # include <boost/type_traits/utility.hpp>
34 #endif 
35
36 namespace boost{
37
38 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
39 namespace detail{
40 //
41 // implementation helper:
42 //
43 template <class T>
44 struct cv_traits_imp{};
45
46 template <class T>
47 struct cv_traits_imp<T*>
48 {
49    BOOST_STATIC_CONSTANT(bool, is_const = false);
50    BOOST_STATIC_CONSTANT(bool, is_volatile = false);
51    typedef T unqualified_type;
52 };
53
54 template <class T>
55 struct cv_traits_imp<const T*>
56 {
57    BOOST_STATIC_CONSTANT(bool, is_const = true);
58    BOOST_STATIC_CONSTANT(bool, is_volatile = false);
59    typedef T unqualified_type;
60 };
61
62 template <class T>
63 struct cv_traits_imp<volatile T*>
64 {
65    BOOST_STATIC_CONSTANT(bool, is_const = false);
66    BOOST_STATIC_CONSTANT(bool, is_volatile = true);
67    typedef T unqualified_type;
68 };
69
70 template <class T>
71 struct cv_traits_imp<const volatile T*>
72 {
73    BOOST_STATIC_CONSTANT(bool, is_const = true);
74    BOOST_STATIC_CONSTANT(bool, is_volatile = true);
75    typedef T unqualified_type;
76 };
77
78 template <class T, bool is_vol>
79 struct remove_const_helper
80 {
81    typedef T type;
82 };
83 template <class T>
84 struct remove_const_helper<T, true>
85 {
86    typedef volatile T type;
87 };
88
89 template <class T, bool is_vol>
90 struct remove_volatile_helper
91 {
92    typedef T type;
93 };
94 template <class T>
95 struct remove_volatile_helper<T, true>
96 {
97    typedef const T type;
98 };
99
100 } // namespace detail
101
102 // * convert a type T to a non-volatile type - remove_volatile<T>
103 template <typename T>
104 struct remove_volatile
105 {
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;
108 };
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]; };
112
113 // * convert a type T to non-const type - remove_const<T>
114 template <typename T>
115 struct remove_const
116 {
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;
119 };
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]; };
123
124 //  convert a type T to a non-cv-qualified type - remove_cv<T>
125 template <typename T>
126 struct remove_cv
127 {
128    typedef typename detail::cv_traits_imp<T*>::unqualified_type type;
129 };
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]; };
134
135 //* is a type T  declared const - is_const<T>
136 template <typename T>
137 struct is_const
138 {
139    BOOST_STATIC_CONSTANT(bool, value = detail::cv_traits_imp<T*>::is_const);
140 };
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); };
154 #endif
155
156 //* is a type T declared volatile - is_volatile<T>
157 template <typename T>
158 struct is_volatile
159 {
160    BOOST_STATIC_CONSTANT(bool, value = detail::cv_traits_imp<T*>::is_volatile);
161 };
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); };
175 #endif
176
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; };
182
183 namespace detail{
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 *);
190 }
191
192 namespace detail
193 {
194   template <bool is_ref, bool array>
195   struct is_const_impl
196       : ::boost::type_traits::false_unary_metafunction
197   {};
198
199   template <>
200   struct is_const_impl<false,false>
201   {
202       template <class T>
203       struct apply
204       {
205        private:
206           static T* t;
207        public:
208           BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_const_helper(t))));
209       };      
210   };
211
212   template <>
213   struct is_const_impl<false,true>
214   {
215       template <class T>
216       struct apply
217       {
218        private:
219           static T t;
220        public:
221           BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_const_helper(&t))));
222       };      
223   };
224 }
225
226 template <typename T>
227 struct is_const
228     : ::boost::detail::is_const_impl<
229           is_reference<T>::value
230         , is_array<T>::value
231      >::template apply<T>
232
233 };
234
235 template <>
236 struct is_const<void>
237 {
238    BOOST_STATIC_CONSTANT(bool, value = false);
239 };
240 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
241 template <>
242 struct is_const<const void>
243 {
244    BOOST_STATIC_CONSTANT(bool, value = true);
245 };
246 template <>
247 struct is_const<volatile void>
248 {
249    BOOST_STATIC_CONSTANT(bool, value = false);
250 };
251 template <>
252 struct is_const<const volatile void>
253 {
254    BOOST_STATIC_CONSTANT(bool, value = true);
255 };
256 #endif
257
258 namespace detail
259 {
260   template <bool is_ref, bool array>
261   struct is_volatile_impl
262       : ::boost::type_traits::false_unary_metafunction
263   {};
264
265   template <>
266   struct is_volatile_impl<false,false>
267   {
268       template <class T>
269       struct apply
270       {
271        private:
272           static T* t;
273        public:
274           BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_volatile_helper(t))));
275       };      
276   };
277
278   template <>
279   struct is_volatile_impl<false,true>
280   {
281       template <class T>
282       struct apply
283       {
284        private:
285           static T t;
286        public:
287           BOOST_STATIC_CONSTANT(bool, value = (sizeof(detail::yes_type) == sizeof(detail::is_volatile_helper(&t))));
288       };      
289   };
290 }
291
292 template <typename T>
293 struct is_volatile
294     : ::boost::detail::is_volatile_impl<
295           is_reference<T>::value
296         , is_array<T>::value
297      >::template apply<T>
298
299 };
300
301
302 template <>
303 struct is_volatile<void>
304 {
305    BOOST_STATIC_CONSTANT(bool, value = false);
306 };
307 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
308 template <>
309 struct is_volatile<const void>
310 {
311    BOOST_STATIC_CONSTANT(bool, value = false);
312 };
313 template <>
314 struct is_volatile<volatile void>
315 {
316    BOOST_STATIC_CONSTANT(bool, value = true);
317 };
318 template <>
319 struct is_volatile<const volatile void>
320 {
321    BOOST_STATIC_CONSTANT(bool, value = true);
322 };
323 #endif
324
325 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
326
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>
332 struct add_const
333 {
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
340 #endif 
341    typedef T const type;
342 #if defined(BOOST_MSVC)
343 # pragma warning(pop)
344 #endif 
345 };
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>
351 struct add_volatile
352 {
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
359 #endif 
360    typedef T volatile type;
361 #if defined(BOOST_MSVC)
362 # pragma warning(pop)
363 #endif 
364 };
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>
370 struct add_cv
371 {
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
378 #endif 
379    typedef T const volatile type;
380 #if defined(BOOST_MSVC)
381 # pragma warning(pop)
382 #endif 
383 };
384 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
385 template <class T>
386 struct add_const<T&>{ typedef T& type; };
387 template <class T>
388 struct add_volatile<T&>{ typedef T& type; };
389 template <class T>
390 struct add_cv<T&>{ typedef T& type; };
391 #endif
392
393 } // namespace boost
394
395
396 #endif // BOOST_CV_TYPE_TRAITS_HPP
397
398
399
400