]> git.lyx.org Git - lyx.git/blob - boost/boost/type_traits/object_traits.hpp
major boost update
[lyx.git] / boost / boost / type_traits / object_traits.hpp
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.
6 //
7 //  See http://www.boost.org for most recent version including documentation.
8 //
9 //  defines object traits classes:
10 //  is_object, is_scalar, is_class, is_compound, is_POD, 
11 //  has_trivial_constructor, has_trivial_copy, has_trivial_assign, 
12 //  has_trivial_destructor, is_empty.
13 //
14
15 #ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
16 #define BOOST_OBJECT_TYPE_TRAITS_HPP
17
18 #ifndef BOOST_ICE_TYPE_TRAITS_HPP
19 #include <boost/type_traits/ice.hpp>
20 #endif
21 #ifndef BOOST_FWD_TYPE_TRAITS_HPP
22 #include <boost/type_traits/fwd.hpp>
23 #endif
24 #ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
25 #include <boost/type_traits/composite_traits.hpp>
26 #endif
27 #ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
28 #include <boost/type_traits/arithmetic_traits.hpp>
29 #endif
30 #ifndef BOOST_FUNCTION_TYPE_TRAITS_HPP
31 #include <boost/type_traits/function_traits.hpp>
32 #endif
33 #ifndef BOOST_TYPE_TRAITS_IS_CLASS_HPP
34 # include <boost/type_traits/is_class.hpp>
35 #endif 
36
37 #ifdef BOOST_HAS_SGI_TYPE_TRAITS
38 #  include <type_traits.h>
39 #  include <boost/type_traits/same_traits.hpp>
40 #endif
41
42 namespace boost{
43
44 /**********************************************
45  *
46  * is_object
47  *
48  **********************************************/
49 template <typename T>
50 struct is_object
51 {
52 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
53    BOOST_STATIC_CONSTANT(bool, value =
54       (::boost::type_traits::ice_and<
55          ::boost::type_traits::ice_not< ::boost::is_reference<T>::value>::value,
56          ::boost::type_traits::ice_not< ::boost::is_void<T>::value>::value,
57          ::boost::type_traits::ice_not< ::boost::is_function<T>::value>::value
58       >::value));
59 #else
60    BOOST_STATIC_CONSTANT(bool, value =
61       (::boost::type_traits::ice_and<
62          ::boost::type_traits::ice_not< ::boost::is_reference<T>::value>::value,
63          ::boost::type_traits::ice_not< ::boost::is_void<T>::value>::value
64       >::value));
65 #endif
66 };
67
68 /**********************************************
69  *
70  * is_scalar
71  *
72  **********************************************/
73 template <typename T>
74 struct is_scalar
75
76    BOOST_STATIC_CONSTANT(bool, value =
77       (::boost::type_traits::ice_or<
78          ::boost::is_arithmetic<T>::value,
79          ::boost::is_enum<T>::value,
80          ::boost::is_pointer<T>::value,
81          ::boost::is_member_pointer<T>::value
82       >::value));
83 };
84
85 # ifndef BOOST_TYPE_TRAITS_IS_CLASS_DEFINED
86 // conforming compilers use the implementation in <boost/type_traits/is_class.hpp>
87 /**********************************************
88  *
89  * is_class
90  *
91  **********************************************/
92 template <typename T>
93 struct is_class
94 {
95 #  ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
96
97    BOOST_STATIC_CONSTANT(bool, value =
98       (::boost::type_traits::ice_and<
99          ::boost::type_traits::ice_not< ::boost::is_union<T>::value >::value,
100          ::boost::type_traits::ice_not< ::boost::is_scalar<T>::value >::value,
101          ::boost::type_traits::ice_not< ::boost::is_array<T>::value >::value,
102          ::boost::type_traits::ice_not< ::boost::is_reference<T>::value>::value,
103          ::boost::type_traits::ice_not< ::boost::is_void<T>::value >::value,
104          ::boost::type_traits::ice_not< ::boost::is_function<T>::value >::value
105       >::value));
106 #  else
107    BOOST_STATIC_CONSTANT(bool, value =
108       (::boost::type_traits::ice_and<
109          ::boost::type_traits::ice_not< ::boost::is_union<T>::value >::value,
110          ::boost::type_traits::ice_not< ::boost::is_scalar<T>::value >::value,
111          ::boost::type_traits::ice_not< ::boost::is_array<T>::value >::value,
112          ::boost::type_traits::ice_not< ::boost::is_reference<T>::value>::value,
113          ::boost::type_traits::ice_not< ::boost::is_void<T>::value >::value
114       >::value));
115 #  endif
116 };
117 # endif // nonconforming implementations
118 /**********************************************
119  *
120  * is_compound
121  *
122  **********************************************/
123 template <typename T> struct is_compound
124 {
125    BOOST_STATIC_CONSTANT(bool, value =
126       (::boost::type_traits::ice_or<
127          ::boost::is_array<T>::value,
128          ::boost::is_pointer<T>::value,
129          ::boost::is_reference<T>::value,
130          ::boost::is_class<T>::value,
131          ::boost::is_union<T>::value,
132          ::boost::is_enum<T>::value,
133          ::boost::is_member_pointer<T>::value
134       >::value));
135 };
136
137 /**********************************************
138  *
139  * is_POD
140  *
141  **********************************************/
142
143 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
144 template <typename T> struct is_POD
145
146     BOOST_STATIC_CONSTANT(
147         bool, value =
148         (::boost::type_traits::ice_or<
149          ::boost::is_scalar<T>::value,
150          ::boost::is_void<T>::value,
151          BOOST_IS_POD(T)
152          >::value));
153 };
154
155 template <typename T, std::size_t sz>
156 struct is_POD<T[sz]>
157 {
158    BOOST_STATIC_CONSTANT(bool, value = ::boost::is_POD<T>::value);
159 };
160 #else
161 namespace detail
162 {
163   template <bool is_array = false> struct is_POD_helper;
164 }
165
166 template <typename T> struct is_POD
167
168    BOOST_STATIC_CONSTANT(
169        bool, value = (
170            ::boost::detail::is_POD_helper<
171               ::boost::is_array<T>::value
172            >::template apply<T>::value
173            )
174        );
175 };
176
177 namespace detail
178 {
179   template <bool is_array>
180   struct is_POD_helper
181   {
182       template <typename T> struct apply
183       {
184           BOOST_STATIC_CONSTANT(
185               bool, value =
186               (::boost::type_traits::ice_or<
187                ::boost::is_scalar<T>::value,
188                ::boost::is_void<T>::value,
189                BOOST_IS_POD(T)
190                >::value));
191       };
192   };
193
194   template <bool b>
195   struct bool_to_type
196   {
197       typedef ::boost::type_traits::no_type type;
198   };
199
200   template <>
201   struct bool_to_type<true>
202   {
203       typedef ::boost::type_traits::yes_type type;
204   };
205   
206   template <class ArrayType>
207   struct is_POD_array_helper
208   {
209       typedef
210 #if !defined(__BORLANDC__) || __BORLANDC__ > 0x551
211       typename
212 #endif 
213       ::boost::detail::bool_to_type<(::boost::is_POD<ArrayType>::value)>::type type;
214       
215       type instance() const;
216   };
217   
218   template <class T>
219   is_POD_array_helper<T> is_POD_array(T*);
220
221   template <>
222   struct is_POD_helper<true>
223   {
224       template <typename T> struct apply
225       {
226           static T& help();
227
228           BOOST_STATIC_CONSTANT(
229               bool, value =
230               sizeof(is_POD_array(help()).instance()) == sizeof(::boost::type_traits::yes_type));
231       };
232   };
233 }
234 #endif
235
236 /**********************************************
237  *
238  * has_trivial_constructor
239  *
240  **********************************************/
241 template <typename T>
242 struct has_trivial_constructor
243 {
244    BOOST_STATIC_CONSTANT(bool, value =
245       (::boost::type_traits::ice_or<
246          ::boost::is_POD<T>::value,
247          BOOST_HAS_TRIVIAL_CONSTRUCTOR(T)
248       >::value));
249 };
250
251 /**********************************************
252  *
253  * has_trivial_copy
254  *
255  **********************************************/
256 template <typename T>
257 struct has_trivial_copy
258 {
259    BOOST_STATIC_CONSTANT(bool, value =
260       (::boost::type_traits::ice_and<
261          ::boost::type_traits::ice_or<
262             ::boost::is_POD<T>::value,
263             BOOST_HAS_TRIVIAL_COPY(T)
264          >::value,
265       ::boost::type_traits::ice_not< ::boost::is_volatile<T>::value >::value
266       >::value));
267 };
268
269 /**********************************************
270  *
271  * has_trivial_assign
272  *
273  **********************************************/
274 template <typename T>
275 struct has_trivial_assign
276 {
277    BOOST_STATIC_CONSTANT(bool, value =
278       (::boost::type_traits::ice_and<
279          ::boost::type_traits::ice_or<
280             ::boost::is_POD<T>::value,
281             BOOST_HAS_TRIVIAL_ASSIGN(T)
282          >::value,
283       ::boost::type_traits::ice_not< ::boost::is_const<T>::value >::value,
284       ::boost::type_traits::ice_not< ::boost::is_volatile<T>::value >::value
285       >::value));
286 };
287
288 /**********************************************
289  *
290  * has_trivial_destructor
291  *
292  **********************************************/
293 template <typename T>
294 struct has_trivial_destructor
295 {
296    BOOST_STATIC_CONSTANT(bool, value =
297       (::boost::type_traits::ice_or<
298          ::boost::is_POD<T>::value,
299          BOOST_HAS_TRIVIAL_DESTRUCTOR(T)
300       >::value));
301 };
302
303 /**********************************************
304  *
305  * has_nothrow_constructor
306  *
307  **********************************************/
308 template <typename T>
309 struct has_nothrow_constructor
310 {
311    BOOST_STATIC_CONSTANT(bool, value =
312       (::boost::has_trivial_constructor<T>::value));
313 };
314
315 /**********************************************
316  *
317  * has_nothrow_copy
318  *
319  **********************************************/
320 template <typename T>
321 struct has_nothrow_copy
322 {
323    BOOST_STATIC_CONSTANT(bool, value =
324       (::boost::has_trivial_copy<T>::value));
325 };
326
327 /**********************************************
328  *
329  * has_nothrow_assign
330  *
331  **********************************************/
332 template <typename T>
333 struct has_nothrow_assign
334 {
335    BOOST_STATIC_CONSTANT(bool, value =
336       (::boost::has_trivial_assign<T>::value));
337 };
338
339 /**********************************************
340  *
341  * is_empty
342  *
343  **********************************************/
344 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
345 namespace detail
346 {
347   template <typename T>
348   struct empty_helper_t1 : public T
349   {
350 //#ifdef __MWERKS__
351       empty_helper_t1();  // hh compiler bug workaround
352 //#endif
353       int i[256];
354   };
355   struct empty_helper_t2 { int i[256]; };
356 }
357
358 # ifndef __BORLANDC__
359 namespace detail
360 {
361   template <typename T, bool is_a_class = false>
362   struct empty_helper{ BOOST_STATIC_CONSTANT(bool, value = false); };
363
364   template <typename T>
365   struct empty_helper<T, true>
366   {
367       BOOST_STATIC_CONSTANT(
368           bool, value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)));
369   };
370 }
371
372 template <typename T>
373 struct is_empty
374 {
375  private:
376     typedef typename remove_cv<T>::type cvt;
377     
378  public:
379     BOOST_STATIC_CONSTANT(
380         bool, value = (
381             ::boost::type_traits::ice_or<
382               ::boost::detail::empty_helper<T,::boost::is_class<T>::value>::value
383               , BOOST_IS_EMPTY(cvt)
384             >::value
385             ));
386 };
387
388 # else // __BORLANDC__
389
390 namespace detail
391 {
392   template <typename T, bool is_a_class, bool convertible_to_int>
393   struct empty_helper{ BOOST_STATIC_CONSTANT(bool, value = false); };
394
395   template <typename T>
396   struct empty_helper<T, true, false>
397   {
398       BOOST_STATIC_CONSTANT(bool, value =
399                             (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)));
400   };
401 }
402
403 template <typename T>
404 struct is_empty
405 {
406 private:
407    typedef typename remove_cv<T>::type cvt;
408    typedef typename add_reference<T>::type r_type;
409 public:
410    BOOST_STATIC_CONSTANT(
411        bool, value = (
412            ::boost::type_traits::ice_or<
413               ::boost::detail::empty_helper<
414                   T
415                 , ::boost::is_class<T>::value
416                 , ::boost::is_convertible< r_type,int>::value
417               >::value
418               , BOOST_IS_EMPTY(cvt)
419            >::value));
420 };
421 # endif // __BORLANDC__
422
423 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
424 #ifdef BOOST_MSVC6_MEMBER_TEMPLATES
425
426 namespace detail{
427
428 template <typename T>
429 struct empty_helper_t1 : public T
430 {
431    empty_helper_t1();
432    int i[256];
433 };
434 struct empty_helper_t2 { int i[256]; };
435
436 template <typename T>
437 struct empty_helper_base
438 {
439    enum{ value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)) };
440 };
441
442 template <typename T>
443 struct empty_helper_nonbase
444 {
445    enum{ value = false };
446 };
447
448 template <bool base>
449 struct empty_helper_chooser
450 {
451    template <class T>
452    struct rebind
453    {
454       typedef empty_helper_nonbase<T> type;
455    };
456 };
457
458 template <>
459 struct empty_helper_chooser<true>
460 {
461    template <class T>
462    struct rebind
463    {
464       typedef empty_helper_base<T> type;
465    };
466 };
467
468 } // namespace detail
469
470 template <typename T> 
471 struct is_empty
472
473 private:
474    typedef ::boost::detail::empty_helper_chooser<
475       ::boost::type_traits::ice_and<
476          ::boost::type_traits::ice_not< 
477             ::boost::is_reference<T>::value>::value,
478          ::boost::type_traits::ice_not< 
479             ::boost::is_convertible<T,double>::value>::value,
480          ::boost::type_traits::ice_not< 
481             ::boost::is_pointer<T>::value>::value,
482          ::boost::type_traits::ice_not< 
483             ::boost::is_member_pointer<T>::value>::value,
484          ::boost::type_traits::ice_not< 
485             ::boost::is_array<T>::value>::value,
486          ::boost::type_traits::ice_not< 
487             ::boost::is_void<T>::value>::value,
488          ::boost::type_traits::ice_not< 
489             ::boost::is_convertible<T, const volatile void*>::value>::value
490       >::value> chooser;
491    typedef typename chooser::template rebind<T> bound_type;
492    typedef typename bound_type::type eh_type;
493 public:
494    BOOST_STATIC_CONSTANT(bool, value =
495       (::boost::type_traits::ice_or<eh_type::value, BOOST_IS_EMPTY(T)>::value)); 
496 };
497
498 #else
499 template <typename T> struct is_empty
500 { enum{ value = BOOST_IS_EMPTY(T) }; };
501 #endif  // BOOST_MSVC6_MEMBER_TEMPLATES
502
503 #endif  // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
504
505 /**********************************************
506  *
507  * is_stateless
508  *
509  **********************************************/
510 template <typename T>
511 struct is_stateless
512 {
513   BOOST_STATIC_CONSTANT(bool, value = 
514     (::boost::type_traits::ice_and<
515        ::boost::has_trivial_constructor<T>::value,
516        ::boost::has_trivial_copy<T>::value,
517        ::boost::has_trivial_destructor<T>::value,
518        ::boost::is_class<T>::value,
519        ::boost::is_empty<T>::value
520      >::value));
521 };
522
523 template <class Base, class Derived>
524 struct is_base_and_derived
525 {
526    BOOST_STATIC_CONSTANT(bool, value =
527       (::boost::type_traits::ice_and<
528          ::boost::is_convertible<Derived*,Base*>::value,
529          ::boost::is_class<Derived>::value,
530          ::boost::is_class<Base>::value
531       >::value)
532    );
533 };
534
535 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
536 template <class Base, class Derived>
537 struct is_base_and_derived<Base&, Derived>
538 {
539    BOOST_STATIC_CONSTANT(bool, value = false);
540 };
541 template <class Base, class Derived>
542 struct is_base_and_derived<Base, Derived&>
543 {
544    BOOST_STATIC_CONSTANT(bool, value = false);
545 };
546 template <class Base, class Derived>
547 struct is_base_and_derived<Base&, Derived&>
548 {
549    BOOST_STATIC_CONSTANT(bool, value = false);
550 };
551 #endif
552
553 } // namespace boost
554
555 #endif // BOOST_OBJECT_TYPE_TRAITS_HPP
556
557
558
559
560
561
562