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