OSDN Git Service

2007-03-04 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / tr1 / type_traits
1 // TR1 type_traits -*- C++ -*-
2
3 // Copyright (C) 2004, 2005, 2006 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 tr1/type_traits
31  *  This is a TR1 C++ Library header. 
32  */
33
34 #ifndef _TR1_TYPE_TRAITS
35 #define _TR1_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 _GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_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   template<typename _Tp, _Tp __v>
102     const _Tp integral_constant<_Tp, __v>::value;
103
104   /// @brief  primary type categories [4.5.1].
105   template<typename>
106     struct is_void
107     : public false_type { };
108   _DEFINE_SPEC(0, is_void, void, true)
109
110   template<typename>
111     struct is_integral
112     : public false_type { };
113   _DEFINE_SPEC(0, is_integral, bool, true)
114   _DEFINE_SPEC(0, is_integral, char, true)
115   _DEFINE_SPEC(0, is_integral, signed char, true)
116   _DEFINE_SPEC(0, is_integral, unsigned char, true)
117 #ifdef _GLIBCXX_USE_WCHAR_T
118   _DEFINE_SPEC(0, is_integral, wchar_t, true)
119 #endif
120   _DEFINE_SPEC(0, is_integral, short, true)
121   _DEFINE_SPEC(0, is_integral, unsigned short, true)
122   _DEFINE_SPEC(0, is_integral, int, true)
123   _DEFINE_SPEC(0, is_integral, unsigned int, true)
124   _DEFINE_SPEC(0, is_integral, long, true)
125   _DEFINE_SPEC(0, is_integral, unsigned long, true)
126   _DEFINE_SPEC(0, is_integral, long long, true)
127   _DEFINE_SPEC(0, is_integral, unsigned long long, true)
128
129   template<typename>
130     struct is_floating_point
131     : public false_type { };
132   _DEFINE_SPEC(0, is_floating_point, float, true)
133   _DEFINE_SPEC(0, is_floating_point, double, true)
134   _DEFINE_SPEC(0, is_floating_point, long double, true)
135
136   template<typename>
137     struct is_array
138     : public false_type { };
139
140   template<typename _Tp, std::size_t _Size>
141     struct is_array<_Tp[_Size]>
142     : public true_type { };
143
144   template<typename _Tp>
145     struct is_array<_Tp[]>
146     : public true_type { };
147
148   template<typename>
149     struct is_pointer
150     : public false_type { };
151   _DEFINE_SPEC(1, is_pointer, _Tp*, true)
152  
153   template<typename>
154     struct is_reference
155     : public false_type { };
156
157   template<typename _Tp>
158     struct is_reference<_Tp&>
159     : public true_type { };
160
161   template<typename>
162     struct is_member_object_pointer
163     : public false_type { };
164   _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*,
165                !is_function<_Tp>::value)
166
167   template<typename>
168     struct is_member_function_pointer
169     : public false_type { };
170   _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
171                is_function<_Tp>::value)
172
173   template<typename _Tp>
174     struct is_enum
175     : public integral_constant<bool, !(is_fundamental<_Tp>::value
176                                        || is_array<_Tp>::value
177                                        || is_pointer<_Tp>::value
178                                        || is_reference<_Tp>::value
179                                        || is_member_pointer<_Tp>::value
180                                        || is_function<_Tp>::value
181                                        || __is_union_or_class<_Tp>::value)>
182     { };
183
184   template<typename>
185     struct is_union { };
186
187   template<typename>
188     struct is_class { };
189
190   template<typename _Tp>
191     struct is_function
192     : public integral_constant<bool, !(__in_array<_Tp>::__value
193                                        || __is_union_or_class<_Tp>::value
194                                        || is_reference<_Tp>::value
195                                        || is_void<_Tp>::value)>
196     { };
197
198   /// @brief  composite type traits [4.5.2].
199   template<typename _Tp>
200     struct is_arithmetic
201     : public integral_constant<bool, (is_integral<_Tp>::value
202                                       || is_floating_point<_Tp>::value)>
203     { };
204
205   template<typename _Tp>
206     struct is_fundamental
207     : public integral_constant<bool, (is_arithmetic<_Tp>::value
208                                       || is_void<_Tp>::value)>
209     { };
210
211   template<typename _Tp>
212     struct is_object
213     : public integral_constant<bool, !(is_function<_Tp>::value
214                                        || is_reference<_Tp>::value
215                                        || is_void<_Tp>::value)>
216     { };
217
218   template<typename _Tp>
219     struct is_scalar
220     : public integral_constant<bool, (is_arithmetic<_Tp>::value
221                                       || is_enum<_Tp>::value
222                                       || is_pointer<_Tp>::value
223                                       || is_member_pointer<_Tp>::value)>
224     { };
225
226   template<typename _Tp>
227     struct is_compound
228     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
229
230   template<typename _Tp>
231     struct is_member_pointer
232     : public integral_constant<bool,
233                                (is_member_object_pointer<_Tp>::value
234                                 || is_member_function_pointer<_Tp>::value)>
235     { };
236
237   template<typename _Tp>
238     struct __is_union_or_class_helper
239     : public __sfinae_types
240     {
241     private:
242       template<typename _Up>
243         static __one __test(int _Up::*);
244       template<typename>
245         static __two __test(...);
246     
247     public:
248       static const bool __value = sizeof(__test<_Tp>(0)) == 1;
249     };
250
251   // Extension.
252   template<typename _Tp>
253     struct __is_union_or_class
254     : public integral_constant<bool, __is_union_or_class_helper<_Tp>::__value>
255     { };
256   
257   /// @brief  type properties [4.5.3].
258   template<typename>
259     struct is_const
260     : public false_type { };
261
262   template<typename _Tp>
263     struct is_const<_Tp const>
264     : public true_type { };
265   
266   template<typename>
267     struct is_volatile
268     : public false_type { };
269
270   template<typename _Tp>
271     struct is_volatile<_Tp volatile>
272     : public true_type { };
273
274   template<typename _Tp>
275     struct is_pod
276     : public integral_constant<bool, (is_void<_Tp>::value
277                                       || is_scalar<typename
278                                       remove_all_extents<_Tp>::type>::value)>
279     { };
280
281   // NB: Without compiler support we cannot tell union from class types,
282   // and is_empty and is_polymorphic don't work at all with the former. 
283   template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
284     struct __is_empty_helper
285     { 
286     private:
287       template<typename>
288         struct __first { };
289       template<typename _Up>
290         struct __second
291         : public _Up { };
292            
293     public:
294       static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
295     };
296
297   template<typename _Tp>
298     struct __is_empty_helper<_Tp, true>
299     { static const bool __value = false; };
300
301   template<typename _Tp>
302     struct is_empty
303     : public integral_constant<bool, __is_empty_helper<_Tp>::__value>
304     { };
305
306   template<typename _Tp, bool = !__is_union_or_class<_Tp>::value>
307     struct __is_polymorphic_helper
308     { 
309     private:
310       template<typename _Up>
311         struct __first
312         : public _Up { };
313       template<typename _Up>
314         struct __second
315         : public _Up
316         { 
317           virtual void __dummy();
318           virtual ~__second() throw();
319         };
320
321     public:
322       static const bool __value = sizeof(__first<_Tp>) == sizeof(__second<_Tp>);
323     };
324
325   template<typename _Tp>
326     struct __is_polymorphic_helper<_Tp, true>
327     { static const bool __value = false; };
328
329   template<typename _Tp>
330     struct is_polymorphic
331     : public integral_constant<bool, __is_polymorphic_helper<_Tp>::__value>
332     { };
333
334   // Exploit the resolution DR core/337.
335   template<typename _Tp>
336     struct is_abstract
337     : public integral_constant<bool, (!__in_array<_Tp>::__value
338                                       && __is_union_or_class<_Tp>::value)> { };
339
340   template<typename _Tp>
341     struct has_trivial_constructor
342     : public integral_constant<bool, is_pod<_Tp>::value> { };
343
344   template<typename _Tp>
345     struct has_trivial_copy
346     : public integral_constant<bool, is_pod<_Tp>::value> { };
347
348   template<typename _Tp>
349     struct has_trivial_assign
350     : public integral_constant<bool, is_pod<_Tp>::value> { };
351
352   template<typename _Tp>
353     struct has_trivial_destructor
354     : public integral_constant<bool, is_pod<_Tp>::value> { };
355
356   template<typename _Tp>
357     struct has_nothrow_constructor
358     : public integral_constant<bool, is_pod<_Tp>::value> { };
359
360   template<typename _Tp>
361     struct has_nothrow_copy
362     : public integral_constant<bool, is_pod<_Tp>::value> { };
363
364   template<typename _Tp>
365     struct has_nothrow_assign
366     : public integral_constant<bool, is_pod<_Tp>::value> { };
367
368   template<typename>
369     struct has_virtual_destructor
370     : public false_type { };
371
372   template<typename>
373     struct is_signed
374     : public false_type { };
375   _DEFINE_SPEC(0, is_signed, signed char, true)
376   _DEFINE_SPEC(0, is_signed, short, true)
377   _DEFINE_SPEC(0, is_signed, int, true)
378   _DEFINE_SPEC(0, is_signed, long, true)
379   _DEFINE_SPEC(0, is_signed, long long, true)
380
381   template<typename>
382     struct is_unsigned
383     : public false_type { };
384   _DEFINE_SPEC(0, is_unsigned, unsigned char, true)
385   _DEFINE_SPEC(0, is_unsigned, unsigned short, true)
386   _DEFINE_SPEC(0, is_unsigned, unsigned int, true)
387   _DEFINE_SPEC(0, is_unsigned, unsigned long, true)
388   _DEFINE_SPEC(0, is_unsigned, unsigned long long, true)
389
390   template<typename _Tp>
391     struct alignment_of
392     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
393   
394   template<typename>
395     struct rank
396     : public integral_constant<std::size_t, 0> { };
397    
398   template<typename _Tp, std::size_t _Size>
399     struct rank<_Tp[_Size]>
400     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
401
402   template<typename _Tp>
403     struct rank<_Tp[]>
404     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
405    
406   template<typename, unsigned>
407     struct extent
408     : public integral_constant<std::size_t, 0> { };
409   
410   template<typename _Tp, unsigned _Uint, std::size_t _Size>
411     struct extent<_Tp[_Size], _Uint>
412     : public integral_constant<std::size_t,
413                                _Uint == 0 ? _Size : extent<_Tp,
414                                                            _Uint - 1>::value>
415     { };
416
417   template<typename _Tp, unsigned _Uint>
418     struct extent<_Tp[], _Uint>
419     : public integral_constant<std::size_t,
420                                _Uint == 0 ? 0 : extent<_Tp,
421                                                        _Uint - 1>::value>
422     { };
423   
424   /// @brief  relationships between types [4.6].
425   template<typename, typename>
426     struct is_same
427     : public false_type { };
428
429   template<typename _Tp>
430     struct is_same<_Tp, _Tp>
431     : public true_type { };
432
433   // See Daveed Vandevoorde explanation in http://tinyurl.com/502f.
434   // Also see Rani Sharoni in http://tinyurl.com/6jvyq.
435   template<typename _Base, typename _Derived,
436            bool = (!__is_union_or_class<_Base>::value
437                    || !__is_union_or_class<_Derived>::value
438                    || is_same<_Base, _Derived>::value)>
439     struct __is_base_of_helper
440     : public __sfinae_types
441     {
442     private:
443       typedef typename remove_cv<_Base>::type     _NoCv_Base;      
444       typedef typename remove_cv<_Derived>::type  _NoCv_Derived;
445       
446       template<typename _Up>
447         static __one __test(_NoCv_Derived&, _Up);
448       static __two __test(_NoCv_Base&, int);
449    
450       struct _Conv
451       {
452         operator _NoCv_Derived&();
453         operator _NoCv_Base&() const;
454       };
455    
456     public:
457       static const bool __value = sizeof(__test(_Conv(), 0)) == 1;
458     };
459
460   template<typename _Base, typename _Derived>
461     struct __is_base_of_helper<_Base, _Derived, true>
462     { static const bool __value = is_same<_Base, _Derived>::value; };
463
464   template<typename _Base, typename _Derived>
465     struct is_base_of
466     : public integral_constant<bool,
467                                __is_base_of_helper<_Base, _Derived>::__value>
468     { };
469
470   template<typename _From, typename _To>
471     struct __is_convertible_simple
472     : public __sfinae_types
473     {
474     private:
475       static __one __test(_To);
476       static __two __test(...);
477       static _From __makeFrom();
478     
479     public:
480       static const bool __value = sizeof(__test(__makeFrom())) == 1;
481     };
482
483   template<typename _Tp>
484     struct __is_int_or_cref
485     {
486       typedef typename remove_reference<_Tp>::type __rr_Tp;
487       static const bool __value = (is_integral<_Tp>::value
488                                    || (is_integral<__rr_Tp>::value
489                                        && is_const<__rr_Tp>::value
490                                        && !is_volatile<__rr_Tp>::value));
491     };
492
493   template<typename _From, typename _To,
494            bool = (is_void<_From>::value || is_void<_To>::value
495                    || is_function<_To>::value || is_array<_To>::value
496                    // This special case is here only to avoid warnings.            
497                    || (is_floating_point<typename
498                        remove_reference<_From>::type>::value
499                        && __is_int_or_cref<_To>::__value))>
500     struct __is_convertible_helper
501     {
502       // "An imaginary lvalue of type From...".
503       static const bool __value = (__is_convertible_simple<typename
504                                    add_reference<_From>::type, _To>::__value);
505     };
506
507   template<typename _From, typename _To>
508     struct __is_convertible_helper<_From, _To, true>
509     { static const bool __value = (is_void<_To>::value
510                                    || (__is_int_or_cref<_To>::__value
511                                        && !is_void<_From>::value)); };
512
513   template<typename _From, typename _To>
514     struct is_convertible
515     : public integral_constant<bool,
516                                __is_convertible_helper<_From, _To>::__value>
517     { };
518
519   /// @brief  const-volatile modifications [4.7.1].
520   template<typename _Tp>
521     struct remove_const
522     { typedef _Tp     type; };
523
524   template<typename _Tp>
525     struct remove_const<_Tp const>
526     { typedef _Tp     type; };
527   
528   template<typename _Tp>
529     struct remove_volatile
530     { typedef _Tp     type; };
531
532   template<typename _Tp>
533     struct remove_volatile<_Tp volatile>
534     { typedef _Tp     type; };
535   
536   template<typename _Tp>
537     struct remove_cv
538     {
539       typedef typename
540       remove_const<typename remove_volatile<_Tp>::type>::type     type;
541     };
542   
543   template<typename _Tp>
544     struct add_const
545     { typedef _Tp const     type; };
546    
547   template<typename _Tp>
548     struct add_volatile
549     { typedef _Tp volatile     type; };
550   
551   template<typename _Tp>
552     struct add_cv
553     {
554       typedef typename
555       add_const<typename add_volatile<_Tp>::type>::type     type;
556     };
557
558   /// @brief  reference modifications [4.7.2].
559   template<typename _Tp>
560     struct remove_reference
561     { typedef _Tp     type; };
562
563   template<typename _Tp>
564     struct remove_reference<_Tp&>
565     { typedef _Tp     type; };
566
567   // NB: Careful with reference to void.
568   template<typename _Tp, bool = (is_void<_Tp>::value
569                                  || is_reference<_Tp>::value)>
570     struct __add_reference_helper
571     { typedef _Tp&    type; };
572
573   template<typename _Tp>
574     struct __add_reference_helper<_Tp, true>
575     { typedef _Tp     type; };
576
577   template<typename _Tp>
578     struct add_reference
579     : public __add_reference_helper<_Tp>
580     { };
581
582   /// @brief  array modifications [4.7.3].
583   template<typename _Tp>
584     struct remove_extent
585     { typedef _Tp     type; };
586
587   template<typename _Tp, std::size_t _Size>
588     struct remove_extent<_Tp[_Size]>
589     { typedef _Tp     type; };
590
591   template<typename _Tp>
592     struct remove_extent<_Tp[]>
593     { typedef _Tp     type; };
594
595   template<typename _Tp>
596     struct remove_all_extents
597     { typedef _Tp     type; };
598
599   template<typename _Tp, std::size_t _Size>
600     struct remove_all_extents<_Tp[_Size]>
601     { typedef typename remove_all_extents<_Tp>::type     type; };
602
603   template<typename _Tp>
604     struct remove_all_extents<_Tp[]>
605     { typedef typename remove_all_extents<_Tp>::type     type; };
606
607   /// @brief  pointer modifications [4.7.4].
608 #undef _DEFINE_SPEC_BODY
609 #define _DEFINE_SPEC_BODY(_Value)      \
610     { typedef _Tp     type; };
611
612   template<typename _Tp>
613     struct remove_pointer
614     { typedef _Tp     type; };
615   _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
616   
617   template<typename _Tp>
618     struct add_pointer
619     { typedef typename remove_reference<_Tp>::type*     type; };
620
621   /// @brief  other transformations [4.8].
622   
623   // Due to c++/19163 and c++/17743, for the time being we cannot use
624   // the correct, neat implementation :-(
625   // 
626   // template<std::size_t _Len, std::size_t _Align>
627   //   struct aligned_storage
628   //   { typedef char type[_Len] __attribute__((__aligned__(_Align))); }
629   //
630   // Temporary workaround, useful for Align up to 32:
631   template<std::size_t, std::size_t>
632     struct aligned_storage { };
633
634   template<std::size_t _Len>
635     struct aligned_storage<_Len, 1>
636     {
637       union type
638       {
639         unsigned char __data[_Len];
640         char __align __attribute__((__aligned__(1)));
641       };
642     };
643
644   template<std::size_t _Len>
645     struct aligned_storage<_Len, 2>
646     {
647       union type
648       {
649         unsigned char __data[_Len];
650         char __align __attribute__((__aligned__(2)));
651       };
652     };
653
654   template<std::size_t _Len>
655     struct aligned_storage<_Len, 4>
656     {
657       union type
658       {
659         unsigned char __data[_Len];
660         char __align __attribute__((__aligned__(4)));
661       };
662     };
663
664   template<std::size_t _Len>
665     struct aligned_storage<_Len, 8>
666     {
667       union type
668       {
669         unsigned char __data[_Len];
670         char __align __attribute__((__aligned__(8)));
671       };
672     };
673
674   template<std::size_t _Len>
675     struct aligned_storage<_Len, 16>
676     {
677       union type
678       {
679         unsigned char __data[_Len];
680         char __align __attribute__((__aligned__(16)));
681       };
682     };
683   
684   template<std::size_t _Len>
685     struct aligned_storage<_Len, 32>
686     {
687       union type
688       {
689         unsigned char __data[_Len];
690         char __align __attribute__((__aligned__(32)));
691       };
692     };
693
694 #undef _DEFINE_SPEC_0_HELPER
695 #undef _DEFINE_SPEC_1_HELPER
696 #undef _DEFINE_SPEC_2_HELPER
697 #undef _DEFINE_SPEC
698 #undef _DEFINE_SPEC_BODY
699
700 _GLIBCXX_END_NAMESPACE
701 }
702
703 #endif