[CMAKE]
[reactos.git] / lib / 3rdparty / stlport / stlport / type_traits
1 // -*- C++ -*- Time-stamp: <08/07/20 19:10:15 ptr>
2
3 /*
4 * Copyright (c) 2007, 2008
5 * Petr Ovtchenkov
6 *
7 * Licensed under the Academic Free License version 3.0
8 *
9 * Derived from original <misc/type_traits.h> of 'complement' project
10 * [http://complement.sourceforge.net]
11 * to make it close to JTC1/SC22/WG21 C++ 0x working draft
12 * [http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2008/n2521.pdf]
13 */
14
15 #ifndef __STLP_TYPE_TRAITS
16 #define __STLP_TYPE_TRAITS
17
18 #ifndef _STLP_OUTERMOST_HEADER_ID
19 # define _STLP_OUTERMOST_HEADER_ID 0x3
20 # include <stl/_prolog.h>
21 #endif
22
23 // libstdc++ v3, timestamp 20050519 (3.4.4) has __type_traits,
24 // libstdc++ v3, timestamp 20060306 (3.4.6) has __type_traits,
25 // while libstdc++ v3, 20050921 (4.0.2) not; use libstdc++ instead
26 // # if defined(STLPORT) || (defined(__GNUC__) && (__GNUC__ < 4)) /* !defined(__GLIBCXX__) || (defined(__GNUC__) && (__GNUC__ < 4)) */
27
28 _STLP_BEGIN_NAMESPACE
29
30 _STLP_BEGIN_TR1_NAMESPACE
31
32 namespace detail {
33
34 struct __select_types
35 {
36 typedef char __t1;
37 struct __t2
38 {
39 char __two[2];
40 };
41 };
42
43 template <class _Tp>
44 struct __instance :
45 public __select_types
46 {
47 private:
48 template <class _Up>
49 static __t1 __test(_Up(*)[1]);
50
51 template <class>
52 static __t2 __test(...);
53
54 public:
55 #ifdef _STLP_STATIC_CONST_INIT_BUG
56 static const bool __value;
57 #else
58 static const bool __value = sizeof(__test<_Tp>(0)) == sizeof(__select_types::__t1);
59 #endif
60
61 };
62
63 #ifdef _STLP_STATIC_CONST_INIT_BUG
64 template <class _Tp>
65 const bool __instance<_Tp>::__value = sizeof(__instance<_Tp>::__test<_Tp>(0)) == sizeof(__select_types::__t1);
66 #endif
67
68 template <class T>
69 struct __uoc_aux : // union or class
70 public __select_types
71 {
72 private:
73 template <class _Up>
74 static __t1 __test( int _Up::* );
75
76 template <class>
77 static __t2 __test(...);
78
79 public:
80 #ifdef __FIT_NO_INLINE_TEMPLATE_STATIC_INITIALISATION
81 static const bool __value;
82 #else
83 static const bool __value = sizeof(__test<T>(0)) == sizeof(__select_types::__t1);
84 #endif
85 };
86
87 #ifdef __FIT_NO_INLINE_TEMPLATE_STATIC_INITIALISATION
88 template <class T>
89 const bool __uoc_aux<T>::__value = sizeof(__uoc_aux<T>::__test<T>(0)) == sizeof(__select_types::__t1);
90 #endif
91
92 template <class T>
93 class __empty
94 { };
95
96 template <class T, bool B>
97 class __inheritance_aux
98 {};
99
100 template <class T>
101 class __inheritance_aux<T,true> :
102 public T
103 {
104 public:
105 virtual ~__inheritance_aux()
106 { }
107 };
108
109 #if 0
110 template <class T, bool B>
111 struct __virtual_aux
112 {
113 public:
114 #ifdef _STLP_STATIC_CONST_INIT_BUG
115 static const bool __value;
116 #else
117 static const bool __value = B ? (sizeof(__inheritance_aux<T,B>) == sizeof(T)) : false;
118 #endif
119 };
120
121 #ifdef _STLP_STATIC_CONST_INIT_BUG
122 template <class T, bool B>
123 const bool __virtual_aux<T,B>::__value = B ? (sizeof(__inheritance_aux<T,B>) == sizeof(T)) : false;
124 #endif
125 #endif
126
127 } // namespace detail
128
129 template <class _Tp, _Tp __v>
130 struct integral_constant
131 {
132 static const _Tp value = __v;
133 // enum { value = __v }; ?
134
135 typedef _Tp value_type;
136 typedef integral_constant<_Tp, __v> type;
137 };
138
139 typedef integral_constant<bool, true> true_type;
140 typedef integral_constant<bool, false> false_type;
141
142 namespace detail {
143
144 template <typename _Tp>
145 struct __is_union_or_class :
146 public integral_constant<bool, __uoc_aux<_Tp>::__value>
147 { };
148
149 #if 0
150 template<typename _Tp>
151 struct __is_vtbl : // has virtual table?
152 public integral_constant<bool, __virtual_aux<_Tp,__is_union_or_class<_Tp>::value >::__value>
153 { };
154 #endif
155
156 template <typename _Tp>
157 struct __is_vtbl : // has virtual table?
158 public integral_constant<bool, __is_union_or_class<_Tp>::value ? (sizeof(__inheritance_aux<_Tp,__is_union_or_class<_Tp>::value>) == sizeof(_Tp)) : false >
159 { };
160
161 } // namespace detail
162
163 #define __SPEC_(C,T,B) \
164 template <> \
165 struct C<T> : \
166 public integral_constant<bool, B> \
167 { }
168
169 #define __CV_SPEC(C,T,B) \
170 __SPEC_(C,T,B); \
171 __SPEC_(C,const T,B); \
172 __SPEC_(C,volatile T,B); \
173 __SPEC_(C,const volatile T,B)
174
175 #define __SPEC_1(C,T,B) \
176 template <class _Tp> \
177 struct C<T> : \
178 public integral_constant<bool, B> \
179 { }
180
181 #define __CV_SPEC_1(C,T,B) \
182 __SPEC_1(C,T,B); \
183 __SPEC_1(C,T const,B); \
184 __SPEC_1(C,T volatile,B); \
185 __SPEC_1(C,T const volatile,B)
186
187 #define __SPEC_2(C,T,B) \
188 template <class _Tp1, class _Tp2> \
189 struct C<T> : \
190 public integral_constant<bool, B> \
191 { }
192
193 #define __CV_SPEC_2(C,T,B) \
194 __SPEC_2(C,T,B); \
195 __SPEC_2(C,T const,B); \
196 __SPEC_2(C,T volatile,B); \
197 __SPEC_2(C,T const volatile,B)
198
199 // [4.5.1] primary type categories:
200
201 template <class _Tp>
202 struct is_void :
203 public false_type
204 { };
205
206 template <>
207 struct is_void<void> :
208 public true_type
209 { };
210
211 template <class _Tp>
212 struct is_integral :
213 public false_type
214 { };
215
216 __CV_SPEC(is_integral,bool,true);
217 __CV_SPEC(is_integral,char,true);
218 __CV_SPEC(is_integral,signed char,true);
219 __CV_SPEC(is_integral,unsigned char,true);
220 __CV_SPEC(is_integral,wchar_t,true);
221 __CV_SPEC(is_integral,short,true);
222 __CV_SPEC(is_integral,unsigned short,true);
223 __CV_SPEC(is_integral,int,true);
224 __CV_SPEC(is_integral,unsigned int,true);
225 __CV_SPEC(is_integral,long,true);
226 __CV_SPEC(is_integral,unsigned long,true);
227 __CV_SPEC(is_integral,long long,true);
228 __CV_SPEC(is_integral,unsigned long long,true);
229
230 template <class _Tp>
231 struct is_floating_point :
232 public false_type
233 { };
234
235 __CV_SPEC(is_floating_point,float,true);
236 __CV_SPEC(is_floating_point,double,true);
237 __CV_SPEC(is_floating_point,long double,true);
238
239 template <class _Tp>
240 struct is_array :
241 public false_type
242 { };
243
244 template <class _Tp, std::size_t _Sz>
245 struct is_array<_Tp[_Sz]> :
246 public true_type
247 { };
248
249 template <class _Tp>
250 struct is_array<_Tp[]> :
251 public true_type
252 { };
253
254 template <class _Tp>
255 struct is_pointer :
256 public false_type
257 { };
258
259 __CV_SPEC_1(is_pointer,_Tp *,true);
260
261 template <class _Tp>
262 struct is_lvalue_reference :
263 public false_type
264 { };
265
266 template <class _Tp>
267 struct is_lvalue_reference<_Tp&> :
268 public true_type
269 { };
270
271 template <class _Tp>
272 struct is_rvalue_reference :
273 public false_type
274 { };
275
276 // template <class _Tp>
277 // struct is_rvalue_reference<_Tp&&> :
278 // public true_type
279 // { };
280
281 template <class _Tp>
282 struct is_reference :
283 public false_type
284 { };
285
286 template <class _Tp>
287 struct is_reference<_Tp&> :
288 public true_type
289 { };
290
291 template <class _Tp>
292 struct is_function :
293 public integral_constant<bool, !(detail::__instance<_Tp>::__value
294 || detail::__is_union_or_class<_Tp>::value
295 || is_reference<_Tp>::value
296 || is_void<_Tp>::value)>
297 { };
298
299 template <class _Tp>
300 struct is_member_object_pointer :
301 public false_type
302 { };
303
304 // _SPEC_FULL2(is_member_object_pointer, _Tp1 _Tp2::*,!is_function<_Tp1>::value);
305
306 template <class _Tp1, class _Tp2>
307 struct is_member_object_pointer<_Tp1 _Tp2::*> :
308 public integral_constant<bool, !is_function<_Tp1>::value>
309 { };
310
311 template <class _Tp1, class _Tp2>
312 struct is_member_object_pointer<_Tp1 _Tp2::* const> :
313 public integral_constant<bool, !is_function<_Tp1>::value>
314 { };
315
316 template <class _Tp1, class _Tp2>
317 struct is_member_object_pointer<_Tp1 _Tp2::* volatile> :
318 public integral_constant<bool, !is_function<_Tp1>::value>
319 { };
320
321 template <class _Tp1, class _Tp2>
322 struct is_member_object_pointer<_Tp1 _Tp2::* const volatile> :
323 public integral_constant<bool, !is_function<_Tp1>::value>
324 { };
325
326 template <class _Tp>
327 struct is_member_function_pointer :
328 public false_type
329 { };
330
331 // _SPEC_FULL2(is_member_function_pointer,_Tp1 _Tp2::*,is_function<_Tp1>::value);
332
333 template <class _Tp1, class _Tp2>
334 struct is_member_function_pointer<_Tp1 _Tp2::*> :
335 public integral_constant<bool, is_function<_Tp1>::value>
336 { };
337
338 template <class _Tp1, class _Tp2>
339 struct is_member_function_pointer<_Tp1 _Tp2::* const> :
340 public integral_constant<bool, is_function<_Tp1>::value>
341 { };
342
343 template <class _Tp1, class _Tp2>
344 struct is_member_function_pointer<_Tp1 _Tp2::* volatile> :
345 public integral_constant<bool, is_function<_Tp1>::value>
346 { };
347
348 template <class _Tp1, class _Tp2>
349 struct is_member_function_pointer<_Tp1 _Tp2::* const volatile> :
350 public integral_constant<bool, is_function<_Tp1>::value>
351 { };
352
353 template <class _Tp>
354 struct is_member_pointer :
355 public integral_constant<bool, (is_member_object_pointer<_Tp>::value || is_member_function_pointer<_Tp>::value)>
356 { };
357
358 // 4.5.2 composite type categories
359
360 template <class _Tp>
361 struct is_arithmetic :
362 public integral_constant<bool, (is_integral<_Tp>::value || is_floating_point<_Tp>::value)>
363 { };
364
365 template <class _Tp>
366 struct is_fundamental :
367 public integral_constant<bool, (is_arithmetic<_Tp>::value || is_void<_Tp>::value)>
368 { };
369
370 // [4.5.1] primary type categories (continued):
371
372 template <class _Tp>
373 struct is_enum :
374 public integral_constant<bool, !(is_fundamental<_Tp>::value
375 || is_array<_Tp>::value
376 || is_pointer<_Tp>::value
377 || is_reference<_Tp>::value
378 || is_member_pointer<_Tp>::value
379 || is_function<_Tp>::value
380 || detail::__is_union_or_class<_Tp>::value) >
381 { };
382
383 template <class T>
384 struct is_union
385 { };
386
387 template <class T>
388 struct is_class
389 { };
390
391 // is_function (above)
392
393 // 4.5.2 composite type categories (continued)
394
395 // is_arithmetic (above)
396 // is_fundamental (above)
397
398 template <class _Tp>
399 struct is_object :
400 public integral_constant<bool, (is_arithmetic<_Tp>::value ||
401 is_array<_Tp>::value ||
402 is_pointer<_Tp>::value ||
403 is_member_pointer<_Tp>::value ||
404 detail::__is_union_or_class<_Tp>::value)>
405 { };
406
407 template <class _Tp>
408 struct is_scalar :
409 public integral_constant<bool, (is_arithmetic<_Tp>::value
410 || is_enum<_Tp>::value
411 || is_pointer<_Tp>::value
412 || is_member_pointer<_Tp>::value)>
413 { };
414
415 template <class _Tp>
416 struct is_compound :
417 public integral_constant<bool, !is_fundamental<_Tp>::value>
418 { };
419
420 // is_member_pointer
421
422 // 4.5.3 type properties:
423
424 template <class _Tp>
425 struct is_const :
426 public false_type
427 { };
428
429 template <class _Tp>
430 struct is_const<_Tp const> :
431 public true_type
432 { };
433
434 template <class _Tp>
435 struct is_volatile :
436 public false_type
437 { };
438
439 template <class _Tp>
440 struct is_volatile<_Tp volatile> :
441 public true_type
442 { };
443
444
445 // 4.7.3 array modifications:
446
447 template <class _Tp>
448 struct remove_extent
449 {
450 typedef _Tp type;
451 };
452
453 template <class _Tp, std::size_t _Sz>
454 struct remove_extent<_Tp[_Sz]>
455 {
456 typedef _Tp type;
457 };
458
459 template <class _Tp>
460 struct remove_extent<_Tp[]>
461 {
462 typedef _Tp type;
463 };
464
465 template <class _Tp>
466 struct remove_all_extents
467 {
468 typedef _Tp type;
469 };
470
471 template <class _Tp, std::size_t _Size>
472 struct remove_all_extents<_Tp[_Size]>
473 {
474 typedef typename remove_all_extents<_Tp>::type type;
475 };
476
477 template<typename _Tp>
478 struct remove_all_extents<_Tp[]>
479 {
480 typedef typename remove_all_extents<_Tp>::type type;
481 };
482
483 // 4.5.3 type properties (continued):
484
485 template <class _Tp>
486 struct is_trivial :
487 public integral_constant<bool, (is_void<_Tp>::value
488 || is_scalar<typename remove_all_extents<_Tp>::type>::value)>
489 { };
490
491 template <class _Tp>
492 struct is_standard_layout :
493 public integral_constant<bool, (is_void<_Tp>::value
494 || is_scalar<typename remove_all_extents<_Tp>::type>::value)>
495 { };
496
497 template <class _Tp>
498 struct is_pod :
499 public integral_constant<bool, (is_void<_Tp>::value
500 || is_scalar<typename remove_all_extents<_Tp>::type>::value)>
501 { };
502
503 template<typename _Tp>
504 struct is_empty
505 : public integral_constant<bool, (detail::__is_union_or_class<_Tp>::value
506 && (sizeof(detail::__empty<_Tp>) == sizeof(_Tp)))>
507 { };
508
509 // is_polimorphic
510 // is_abstract
511
512 template <class _Tp>
513 struct has_trivial_constructor :
514 public integral_constant<bool, is_pod<_Tp>::value>
515 { };
516
517 template <class _Tp>
518 struct has_trivial_copy :
519 public integral_constant<bool, is_pod<_Tp>::value>
520 { };
521
522 template <class _Tp>
523 struct has_trivial_assign :
524 public integral_constant<bool, is_pod<_Tp>::value>
525 { };
526
527 template <class _Tp>
528 struct has_trivial_destructor :
529 public integral_constant<bool, is_pod<_Tp>::value>
530 { };
531
532 template <class _Tp>
533 struct has_nothrow_constructor :
534 public integral_constant<bool, is_pod<_Tp>::value>
535 { };
536
537 template <class _Tp>
538 struct has_nothrow_copy :
539 public integral_constant<bool, is_pod<_Tp>::value>
540 { };
541
542 template <class _Tp>
543 struct has_nothrow_assign :
544 public integral_constant<bool, is_pod<_Tp>::value>
545 { };
546
547 template <class _Tp>
548 struct has_virtual_destructor :
549 public false_type
550 { };
551
552 template <class _Tp>
553 struct is_signed :
554 public false_type
555 { };
556
557 __CV_SPEC(is_signed,signed char,true);
558 __CV_SPEC(is_signed,short,true);
559 __CV_SPEC(is_signed,int,true);
560 __CV_SPEC(is_signed,long,true);
561 __CV_SPEC(is_signed,long long,true);
562
563 template <class _Tp>
564 struct is_unsigned :
565 public false_type
566 { };
567
568 __CV_SPEC(is_unsigned,unsigned char,true);
569 __CV_SPEC(is_unsigned,unsigned short,true);
570 __CV_SPEC(is_unsigned,unsigned int,true);
571 __CV_SPEC(is_unsigned,unsigned long,true);
572 __CV_SPEC(is_unsigned,unsigned long long,true);
573
574 // alignment_of
575 // rank
576 // extent
577
578 // 4.6 type relations:
579
580 template <class _Tp1, class _Tp2>
581 struct is_same :
582 public false_type
583 { };
584
585 template <class _Tp>
586 struct is_same<_Tp, _Tp> :
587 public true_type
588 { };
589
590 // is_base_of
591 // is_convertible
592
593 // 4.7.1 const-volatile modifications
594
595 template <class _Tp>
596 struct remove_const
597 {
598 typedef _Tp type;
599 };
600
601 template <class _Tp>
602 struct remove_const<_Tp const>
603 {
604 typedef _Tp type;
605 };
606
607 template <class _Tp>
608 struct remove_volatile
609 {
610 typedef _Tp type;
611 };
612
613 template <class _Tp>
614 struct remove_volatile<_Tp volatile>
615 {
616 typedef _Tp type;
617 };
618
619 template <class _Tp>
620 struct remove_cv
621 {
622 typedef typename remove_const<typename remove_volatile<_Tp>::type>::type type;
623 };
624
625 template <class _Tp>
626 struct add_const
627 {
628 typedef _Tp const type;
629 };
630
631 template <class _Tp>
632 struct add_volatile
633 {
634 typedef _Tp volatile type;
635 };
636
637 template <class _Tp>
638 struct add_cv
639 {
640 typedef typename add_const<typename add_volatile<_Tp>::type>::type type;
641 };
642
643 // 4.7.2 reference modifications:
644
645 template <class _Tp>
646 struct remove_reference
647 {
648 typedef _Tp type;
649 };
650
651 template <class _Tp>
652 struct remove_reference<_Tp&>
653 {
654 typedef _Tp type;
655 };
656
657 template <class _Tp>
658 struct add_reference
659 {
660 typedef _Tp& type;
661 };
662
663 template <class _Tp>
664 struct add_reference<_Tp&>
665 {
666 typedef _Tp& type;
667 };
668
669 // 4.7.3 array modifications (see above)
670
671 // 4.7.4 pointer modifications:
672
673 template <class _Tp>
674 struct remove_pointer
675 {
676 typedef _Tp type;
677 };
678
679 template <class _Tp>
680 struct remove_pointer<_Tp *>
681 {
682 typedef _Tp type;
683 };
684
685 template <class _Tp>
686 struct remove_pointer<_Tp * const>
687 {
688 typedef _Tp type;
689 };
690
691 template <class _Tp>
692 struct remove_pointer<_Tp * volatile>
693 {
694 typedef _Tp type;
695 };
696
697 template <class _Tp>
698 struct remove_pointer<_Tp * const volatile>
699 {
700 typedef _Tp type;
701 };
702
703 template <class _Tp>
704 struct add_pointer
705 {
706 typedef typename remove_reference<_Tp>::type * type;
707 };
708
709 // 20.5.7 other transformations:
710
711 // template <std::size_t Len, std::size_t Align> struct aligned_storage;
712 // template <std::size_t Len, class... Types> struct aligned_union;
713
714 namespace detail {
715
716 template <bool,class _U>
717 struct _decay_aux2
718 {
719 typedef typename remove_cv<_U>::type type;
720 };
721
722 template <class _U>
723 struct _decay_aux2<true,_U>
724 {
725 typedef typename add_pointer<_U>::type type;
726 };
727
728 template <bool, class _U>
729 struct _decay_aux1
730 {
731 typedef typename _decay_aux2<is_function<_U>::value,_U>::type type;
732 };
733
734 template <class _U>
735 struct _decay_aux1<true,_U>
736 {
737 typedef typename remove_extent<_U>::type* type;
738 };
739
740 } // namespace detail
741
742 template <class _Tp>
743 class decay
744 {
745 private:
746 typedef typename remove_reference<_Tp>::type _U;
747
748 public:
749 typedef typename detail::_decay_aux1<is_array<_U>::value,_U>::type type;
750 };
751
752 template <bool, class _Tp = void>
753 struct enable_if
754 {
755 };
756
757 template <class _Tp>
758 struct enable_if<true,_Tp>
759 {
760 typedef _Tp type;
761 };
762
763 template <bool, class _Tp1, class _Tp2>
764 struct conditional
765 {
766 typedef _Tp2 type;
767 };
768
769 template <class _Tp1, class _Tp2>
770 struct conditional<true,_Tp1,_Tp2>
771 {
772 typedef _Tp1 type;
773 };
774
775 // template <class... _Tp> struct common_type;
776
777 #undef __CV_SPEC
778 #undef __SPEC_
779 #undef __CV_SPEC_1
780 #undef __SPEC_1
781 #undef __CV_SPEC_2
782 #undef __SPEC_2
783
784 _STLP_END_NAMESPACE // tr1
785
786 _STLP_END_NAMESPACE
787
788 // # else // __GLIBCXX__ && (__GNUC__ >= 4) && !STLPORT
789 // # include <tr1/type_traits>
790 // # endif
791
792 #if (_STLP_OUTERMOST_HEADER_ID == 0x3)
793 # include <stl/_epilog.h>
794 # undef _STLP_OUTERMOST_HEADER_ID
795 #endif
796
797 #endif // __STLP_TYPE_TRAITS
798