]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libstdc++-v3/contrib/libstdc++-v3-4.1.0/include/tr1/type_traits
Inital import
[l4.git] / l4 / pkg / libstdc++-v3 / contrib / libstdc++-v3-4.1.0 / include / tr1 / type_traits
1 // TR1 type_traits -*- C++ -*-
2
3 // Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 /** @file 
31  *  This is a TR1 C++ Library header. 
32  */
33
34 #ifndef _TYPE_TRAITS
35 #define _TYPE_TRAITS 1
36
37 #include <bits/c++config.h>
38 #include <tr1/type_traits_fwd.h>
39
40 // namespace std::tr1
41 namespace std
42 {
43 namespace tr1
44 {
45   // For use in __in_array and elsewhere.
46   struct __sfinae_types
47   {
48     typedef char __one;
49     typedef struct { char __arr[2]; } __two;
50   };
51
52   template<typename _Tp>
53     struct __in_array
54     : public __sfinae_types
55     {
56     private:
57       template<typename _Up>
58         static __one __test(_Up(*)[1]);
59       template<typename>
60         static __two __test(...);
61     
62     public:
63       static const bool __value = sizeof(__test<_Tp>(0)) == 1;
64     };
65
66 #define _DEFINE_SPEC_BODY(_Value)                                    \
67     : public integral_constant<bool, _Value> { };
68
69 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value)                         \
70   template<>                                                         \
71     struct _Spec                                                     \
72     _DEFINE_SPEC_BODY(_Value)
73
74 #define _DEFINE_SPEC_1_HELPER(_Spec, _Value)                         \
75   template<typename _Tp>                                             \
76     struct _Spec                                                     \
77     _DEFINE_SPEC_BODY(_Value)
78       
79 #define _DEFINE_SPEC_2_HELPER(_Spec, _Value)                         \
80   template<typename _Tp, typename _Cp>                               \
81     struct _Spec                                                     \
82     _DEFINE_SPEC_BODY(_Value)
83
84 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)                  \
85   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value)              \
86   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value)        \
87   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value)     \
88   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value)
89
90   /// @brief  helper classes [4.3].
91   template<typename _Tp, _Tp __v>
92     struct integral_constant
93     {
94       static const _Tp                      value = __v;
95       typedef _Tp                           value_type;
96       typedef integral_constant<_Tp, __v>   type;
97     };
98   typedef integral_constant<bool, true>     true_type;
99   typedef integral_constant<bool, false>    false_type;
100
101   /// @brief  primary type categories [4.5.1].
102   template<typename>
103     struct is_void
104     : public false_type { };
105   _DEFINE_SPEC(0, is_void, void, true)
106
107   template<typename>
108     struct is_integral
109     : public false_type { };
110   _DEFINE_SPEC(0, is_integral, bool, true)
111   _DEFINE_SPEC(0, is_integral, char, true)
112   _DEFINE_SPEC(0, is_integral, signed char, true)
113   _DEFINE_SPEC(0, is_integral, unsigned char, true)
114 #ifdef _GLIBCXX_USE_WCHAR_T
115   _DEFINE_SPEC(0, is_integral, wchar_t, true)
116 #endif
117   _DEFINE_SPEC(0, is_integral, short, true)
118   _DEFINE_SPEC(0, is_integral, unsigned short, true)
119   _DEFINE_SPEC(0, is_integral, int, true)
120   _DEFINE_SPEC(0, is_integral, unsigned int, true)
121   _DEFINE_SPEC(0, is_integral, long, true)
122   _DEFINE_SPEC(0, is_integral, unsigned long, true)
123   _DEFINE_SPEC(0, is_integral, long long, true)
124   _DEFINE_SPEC(0, is_integral, unsigned long long, true)
125
126   template<typename>
127     struct is_floating_point
128     : public false_type { };
129   _DEFINE_SPEC(0, is_floating_point, float, true)
130   _DEFINE_SPEC(0, is_floating_point, double, true)
131   _DEFINE_SPEC(0, is_floating_point, long double, true)
132
133   template<typename>
134     struct is_array
135     : public false_type { };
136
137   template<typename _Tp, std::size_t _Size>
138     struct is_array<_Tp[_Size]>
139     : public true_type { };
140
141   template<typename _Tp>
142     struct is_array<_Tp[]>
143     : public true_type { };
144
145   template<typename>
146     struct is_pointer
147     : public false_type { };
148   _DEFINE_SPEC(1, is_pointer, _Tp*, true)
149  
150   template<typename>
151     struct is_reference
152     : public false_type { };
153
154   template<typename _Tp>
155     struct is_reference<_Tp&>
156     : public true_type { };
157
158   template<typename>
159     struct is_member_object_pointer
160     : public false_type { };
161   _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*,
162                !is_function<_Tp>::value)
163
164   template<typename>
165     struct is_member_function_pointer
166     : public false_type { };
167   _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
168                is_function<_Tp>::value)
169
170   template<typename _Tp>
171     struct is_enum
172     : public integral_constant<bool, !(is_fundamental<_Tp>::value
173                                        || is_array<_Tp>::value
174                                        || is_pointer<_Tp>::value
175                                        || is_reference<_Tp>::value
176                                        || is_member_pointer<_Tp>::value
177                                        || is_function<_Tp>::value
178                                        || __is_union_or_class<_Tp>::value)>
179     { };
180
181   template<typename>
182     struct is_union { };
183
184   template<typename>
185     struct is_class { };
186
187   template<typename _Tp>
188     struct is_function
189     : public integral_constant<bool, !(__in_array<_Tp>::__value
190                                        || __is_union_or_class<_Tp>::value
191                                        || is_reference<_Tp>::value
192                                        || is_void<_Tp>::value)>
193     { };
194
195   /// @brief  composite type traits [4.5.2].
196   template<typename _Tp>
197     struct is_arithmetic
198     : public integral_constant<bool, (is_integral<_Tp>::value
199                                       || is_floating_point<_Tp>::value)>
200     { };
201
202   template<typename _Tp>
203     struct is_fundamental
204     : public integral_constant<bool, (is_arithmetic<_Tp>::value
205                                       || is_void<_Tp>::value)>
206     { };
207
208   template<typename _Tp>
209     struct is_object
210     : public integral_constant<bool, !(is_function<_Tp>::value
211                                        || is_reference<_Tp>::value
212                                        || is_void<_Tp>::value)>
213     { };
214
215   template<typename _Tp>
216     struct is_scalar
217     : public integral_constant<bool, (is_arithmetic<_Tp>::value
218                                       || is_enum<_Tp>::value
219                                       || is_pointer<_Tp>::value
220                                       || is_member_pointer<_Tp>::value)>
221     { };
222
223   template<typename _Tp>
224     struct is_compound
225     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
226
227   template<typename _Tp>
228     struct is_member_pointer
229     : public integral_constant<bool,
230                                (is_member_object_pointer<_Tp>::value
231                                 || is_member_function_pointer<_Tp>::value)>
232     { };
233
234   template<typename _Tp>
235     struct __is_union_or_class_helper
236     : public __sfinae_types
237     {
238     private:
239       template<typename _Up>
240         static __one __test(int _Up::*);
241       template<typename>
242         static __two __test(...);
243     
244     public:
245       static const bool __value = sizeof(__test<_Tp>(0)) == 1;
246     };
247
248   // Extension.
249   template<typename _Tp>
250     struct __is_union_or_class
251     : public integral_constant<bool, __is_union_or_class_helper<_Tp>::__value>
252     { };
253   
254   /// @brief  type properties [4.5.3].
255   template<typename>
256     struct is_const
257     : public false_type { };
258
259   template<typename _Tp>
260     struct is_const<_Tp const>
261     : public true_type { };
262   
263   template<typename>
264     struct is_volatile
265     : public false_type { };
266
267   template<typename _Tp>
268     struct is_volatile<_Tp volatile>
269     : public true_type { };
270
271   template<typename _Tp>
272     struct is_pod
273     : public integral_constant<bool, (is_void<_Tp>::value
274                                       || is_scalar<typename
275                                       remove_all_extents<_Tp>::type>::value)>
276     { };
277
278   // N.B. Without compiler support we cannot tell union from class types,
279   // and is_empty and is_polymorphic don't work at all with the former. 
280   template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
281     struct __is_empty_helper
282     { 
283     private:
284       template<typename>
285         struct __first { };
286       template<typename _Up>
287         struct __second
288         : public _Up { };
289            
290     public:
291       static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
292     };
293
294   template<typename _Tp>
295     struct __is_empty_helper<_Tp, true>
296     { static const bool __value = false; };
297
298   template<typename _Tp>
299     struct is_empty
300     : public integral_constant<bool, __is_empty_helper<_Tp>::__value>
301     { };
302
303   template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
304     struct __is_polymorphic_helper
305     { 
306     private:
307       template<typename _Up>
308         struct __first
309         : public _Up { };
310       template<typename _Up>
311         struct __second
312         : public _Up
313         { 
314           virtual void __dummy();
315           virtual ~__second() throw();
316         };
317
318     public:
319       static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
320     };
321
322   template<typename _Tp>
323     struct __is_polymorphic_helper<_Tp, true>
324     { static const bool __value = false; };
325
326   template<typename _Tp>
327     struct is_polymorphic
328     : public integral_constant<bool, __is_polymorphic_helper<_Tp>::__value>
329     { };
330
331   // Exploit the resolution DR core/337.
332   template<typename _Tp>
333     struct is_abstract
334     : public integral_constant<bool, (!__in_array<_Tp>::__value
335                                       && __is_union_or_class<_Tp>::value)> { };
336
337   template<typename _Tp>
338     struct has_trivial_constructor
339     : public integral_constant<bool, is_pod<_Tp>::value> { };
340
341   template<typename _Tp>
342     struct has_trivial_copy
343     : public integral_constant<bool, is_pod<_Tp>::value> { };
344
345   template<typename _Tp>
346     struct has_trivial_assign
347     : public integral_constant<bool, is_pod<_Tp>::value> { };
348
349   template<typename _Tp>
350     struct has_trivial_destructor
351     : public integral_constant<bool, is_pod<_Tp>::value> { };
352
353   template<typename _Tp>
354     struct has_nothrow_constructor
355     : public integral_constant<bool, is_pod<_Tp>::value> { };
356
357   template<typename _Tp>
358     struct has_nothrow_copy
359     : public integral_constant<bool, is_pod<_Tp>::value> { };
360
361   template<typename _Tp>
362     struct has_nothrow_assign
363     : public integral_constant<bool, is_pod<_Tp>::value> { };
364
365   template<typename>
366     struct has_virtual_destructor
367     : public false_type { };
368
369   template<typename>
370     struct is_signed
371     : public false_type { };
372   _DEFINE_SPEC(0, is_signed, signed char, true)
373   _DEFINE_SPEC(0, is_signed, short, true)
374   _DEFINE_SPEC(0, is_signed, int, true)
375   _DEFINE_SPEC(0, is_signed, long, true)
376   _DEFINE_SPEC(0, is_signed, long long, true)
377
378   template<typename>
379     struct is_unsigned
380     : public false_type { };
381   _DEFINE_SPEC(0, is_unsigned, unsigned char, true)
382   _DEFINE_SPEC(0, is_unsigned, unsigned short, true)
383   _DEFINE_SPEC(0, is_unsigned, unsigned int, true)
384   _DEFINE_SPEC(0, is_unsigned, unsigned long, true)
385   _DEFINE_SPEC(0, is_unsigned, unsigned long long, true)
386
387   template<typename _Tp>
388     struct alignment_of
389     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
390   
391   template<typename>
392     struct rank
393     : public integral_constant<std::size_t, 0> { };
394    
395   template<typename _Tp, std::size_t _Size>
396     struct rank<_Tp[_Size]>
397     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
398
399   template<typename _Tp>
400     struct rank<_Tp[]>
401     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
402    
403   template<typename, unsigned>
404     struct extent
405     : public integral_constant<std::size_t, 0> { };
406   
407   template<typename _Tp, unsigned _Uint, std::size_t _Size>
408     struct extent<_Tp[_Size], _Uint>
409     : public integral_constant<std::size_t,
410                                _Uint == 0 ? _Size : extent<_Tp,
411                                                            _Uint - 1>::value>
412     { };
413
414   template<typename _Tp, unsigned _Uint>
415     struct extent<_Tp[], _Uint>
416     : public integral_constant<std::size_t,
417                                _Uint == 0 ? 0 : extent<_Tp,
418                                                        _Uint - 1>::value>
419     { };
420   
421   /// @brief  relationships between types [4.6].
422   template<typename, typename>
423     struct is_same
424     : public false_type { };
425
426   template<typename _Tp>
427     struct is_same<_Tp, _Tp>
428     : public true_type { };
429
430   // See Daveed Vandevoorde explanation in http://tinyurl.com/502f.
431   // Also see Rani Sharoni in http://tinyurl.com/6jvyq.
432   template<typename _Base, typename _Derived,
433            bool = (!__is_union_or_class<_Base>::value
434                    || !__is_union_or_class<_Derived>::value
435                    || is_same<_Base, _Derived>::value)>
436     struct __is_base_of_helper
437     : public __sfinae_types
438     {
439     private:
440       typedef typename remove_cv<_Base>::type     _NoCv_Base;      
441       typedef typename remove_cv<_Derived>::type  _NoCv_Derived;
442       
443       template<typename _Up>
444         static __one __test(_NoCv_Derived&, _Up);
445       static __two __test(_NoCv_Base&, int);
446    
447       struct _Conv
448       {
449         operator _NoCv_Derived&();
450         operator _NoCv_Base&() const;
451       };
452    
453     public:
454       static const bool __value = sizeof(__test(_Conv(), 0)) == 1;
455     };
456
457   template<typename _Base, typename _Derived>
458     struct __is_base_of_helper<_Base, _Derived, true>
459     { static const bool __value = is_same<_Base, _Derived>::value; };
460
461   template<typename _Base, typename _Derived>
462     struct is_base_of
463     : public integral_constant<bool,
464                                __is_base_of_helper<_Base, _Derived>::__value>
465     { };
466
467   template<typename _From, typename _To>
468     struct __is_convertible_simple
469     : public __sfinae_types
470     {
471     private:
472       static __one __test(_To);
473       static __two __test(...);
474       static _From __makeFrom();
475     
476     public:
477       static const bool __value = sizeof(__test(__makeFrom())) == 1;
478     };
479
480   template<typename _Tp>
481     struct __is_int_or_cref
482     {
483       typedef typename remove_reference<_Tp>::type __rr_Tp;
484       static const bool __value = (is_integral<_Tp>::value
485                                    || (is_integral<__rr_Tp>::value
486                                        && is_const<__rr_Tp>::value
487                                        && !is_volatile<__rr_Tp>::value));
488     };
489
490   template<typename _From, typename _To,
491            bool = (is_void<_From>::value || is_void<_To>::value
492                    || is_function<_To>::value || is_array<_To>::value
493                    // This special case is here only to avoid warnings.            
494                    || (is_floating_point<typename
495                        remove_reference<_From>::type>::value
496                        && __is_int_or_cref<_To>::__value))>
497     struct __is_convertible_helper
498     {
499       // "An imaginary lvalue of type From...".
500       static const bool __value = (__is_convertible_simple<typename
501                                    add_reference<_From>::type, _To>::__value);
502     };
503
504   template<typename _From, typename _To>
505     struct __is_convertible_helper<_From, _To, true>
506     { static const bool __value = (is_void<_To>::value
507                                    || (__is_int_or_cref<_To>::__value
508                                        && !is_void<_From>::value)); };
509
510   template<typename _From, typename _To>
511     struct is_convertible
512     : public integral_constant<bool,
513                                __is_convertible_helper<_From, _To>::__value>
514     { };
515
516   /// @brief  const-volatile modifications [4.7.1].
517   template<typename _Tp>
518     struct remove_const
519     { typedef _Tp     type; };
520
521   template<typename _Tp>
522     struct remove_const<_Tp const>
523     { typedef _Tp     type; };
524   
525   template<typename _Tp>
526     struct remove_volatile
527     { typedef _Tp     type; };
528
529   template<typename _Tp>
530     struct remove_volatile<_Tp volatile>
531     { typedef _Tp     type; };
532   
533   template<typename _Tp>
534     struct remove_cv
535     {
536       typedef typename
537       remove_const<typename remove_volatile<_Tp>::type>::type     type;
538     };
539   
540   template<typename _Tp>
541     struct add_const
542     { typedef _Tp const     type; };
543    
544   template<typename _Tp>
545     struct add_volatile
546     { typedef _Tp volatile     type; };
547   
548   template<typename _Tp>
549     struct add_cv
550     {
551       typedef typename
552       add_const<typename add_volatile<_Tp>::type>::type     type;
553     };
554
555   /// @brief  reference modifications [4.7.2].
556   template<typename _Tp>
557     struct remove_reference
558     { typedef _Tp     type; };
559
560   template<typename _Tp>
561     struct remove_reference<_Tp&>
562     { typedef _Tp     type; };
563   
564   template<typename _Tp>
565     struct add_reference
566     { typedef _Tp&    type; };
567
568   template<typename _Tp>
569     struct add_reference<_Tp&>
570     { typedef _Tp&    type; };
571
572   /// @brief  array modififications [4.7.3].
573   template<typename _Tp>
574     struct remove_extent
575     { typedef _Tp     type; };
576
577   template<typename _Tp, std::size_t _Size>
578     struct remove_extent<_Tp[_Size]>
579     { typedef _Tp     type; };
580
581   template<typename _Tp>
582     struct remove_extent<_Tp[]>
583     { typedef _Tp     type; };
584
585   template<typename _Tp>
586     struct remove_all_extents
587     { typedef _Tp     type; };
588
589   template<typename _Tp, std::size_t _Size>
590     struct remove_all_extents<_Tp[_Size]>
591     { typedef typename remove_all_extents<_Tp>::type     type; };
592
593   template<typename _Tp>
594     struct remove_all_extents<_Tp[]>
595     { typedef typename remove_all_extents<_Tp>::type     type; };
596
597   /// @brief  pointer modifications [4.7.4].
598 #undef _DEFINE_SPEC_BODY
599 #define _DEFINE_SPEC_BODY(_Value)      \
600     { typedef _Tp     type; };
601
602   template<typename _Tp>
603     struct remove_pointer
604     { typedef _Tp     type; };
605   _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
606   
607   template<typename _Tp>
608     struct add_pointer
609     { typedef typename remove_reference<_Tp>::type*     type; };
610
611   /// @brief  other transformations [4.8].
612   
613   // Due to c++/19163 and c++/17743, for the time being we cannot use
614   // the correct, neat implementation :-(
615   // 
616   // template<std::size_t _Len, std::size_t _Align>
617   //   struct aligned_storage
618   //   { typedef char type[_Len] __attribute__((__aligned__(_Align))); }
619   //
620   // Temporary workaround, useful for Align up to 32:
621   template<std::size_t, std::size_t>
622     struct aligned_storage { };
623
624   template<std::size_t _Len>
625     struct aligned_storage<_Len, 1>
626     {
627       union type
628       {
629         unsigned char __data[_Len];
630         char __align __attribute__((__aligned__(1)));
631       };
632     };
633
634   template<std::size_t _Len>
635     struct aligned_storage<_Len, 2>
636     {
637       union type
638       {
639         unsigned char __data[_Len];
640         char __align __attribute__((__aligned__(2)));
641       };
642     };
643
644   template<std::size_t _Len>
645     struct aligned_storage<_Len, 4>
646     {
647       union type
648       {
649         unsigned char __data[_Len];
650         char __align __attribute__((__aligned__(4)));
651       };
652     };
653
654   template<std::size_t _Len>
655     struct aligned_storage<_Len, 8>
656     {
657       union type
658       {
659         unsigned char __data[_Len];
660         char __align __attribute__((__aligned__(8)));
661       };
662     };
663
664   template<std::size_t _Len>
665     struct aligned_storage<_Len, 16>
666     {
667       union type
668       {
669         unsigned char __data[_Len];
670         char __align __attribute__((__aligned__(16)));
671       };
672     };
673   
674   template<std::size_t _Len>
675     struct aligned_storage<_Len, 32>
676     {
677       union type
678       {
679         unsigned char __data[_Len];
680         char __align __attribute__((__aligned__(32)));
681       };
682     };
683
684 #undef _DEFINE_SPEC_0_HELPER
685 #undef _DEFINE_SPEC_1_HELPER
686 #undef _DEFINE_SPEC_2_HELPER
687 #undef _DEFINE_SPEC
688 #undef _DEFINE_SPEC_BODY
689
690 }
691 }
692
693 #endif