Import gcc-4.4.1
[dragonfly.git] / contrib / gcc-4.4 / libstdc++-v3 / include / std / type_traits
1 // C++0x type_traits -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /** @file include/type_traits
26  *  This is a Standard C++ Library header.
27  */
28
29 #ifndef _GLIBCXX_TYPE_TRAITS
30 #define _GLIBCXX_TYPE_TRAITS 1
31
32 #pragma GCC system_header
33
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <c++0x_warning.h>
36 #else
37
38 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
39 #  error C++0x header cannot be included from TR1 header
40 #endif
41
42 #include <cstddef>
43
44 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
45 #  include <tr1_impl/type_traits>
46 #else
47 #  define _GLIBCXX_INCLUDE_AS_CXX0X
48 #  define _GLIBCXX_BEGIN_NAMESPACE_TR1
49 #  define _GLIBCXX_END_NAMESPACE_TR1
50 #  define _GLIBCXX_TR1
51 #  include <tr1_impl/type_traits>
52 #  undef _GLIBCXX_TR1
53 #  undef _GLIBCXX_END_NAMESPACE_TR1
54 #  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
55 #  undef _GLIBCXX_INCLUDE_AS_CXX0X
56 #endif
57
58 namespace std
59 {
60   /** @addtogroup metaprogramming
61    * @{
62    */
63
64   // Primary classification traits.
65
66   /// is_lvalue_reference
67   template<typename>
68     struct is_lvalue_reference
69     : public false_type { };
70
71   template<typename _Tp>
72     struct is_lvalue_reference<_Tp&>
73     : public true_type { };
74
75   /// is_rvalue_reference
76   template<typename>
77     struct is_rvalue_reference
78     : public false_type { };
79
80   template<typename _Tp>
81     struct is_rvalue_reference<_Tp&&>
82     : public true_type { };
83
84   // Secondary classification traits.
85
86   /// is_reference
87   template<typename _Tp>
88     struct is_reference
89     : public integral_constant<bool, (is_lvalue_reference<_Tp>::value
90                                       || is_rvalue_reference<_Tp>::value)>
91     { };
92
93   // Reference transformations.
94
95   /// remove_reference
96   template<typename _Tp>
97     struct remove_reference
98     { typedef _Tp   type; };
99
100   template<typename _Tp>
101     struct remove_reference<_Tp&>
102     { typedef _Tp   type; };
103
104   template<typename _Tp>
105     struct remove_reference<_Tp&&>
106     { typedef _Tp   type; };
107
108   template<typename _Tp,
109            bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
110            bool = is_rvalue_reference<_Tp>::value>
111     struct __add_lvalue_reference_helper
112     { typedef _Tp   type; };
113
114   template<typename _Tp>
115     struct __add_lvalue_reference_helper<_Tp, true, false>
116     { typedef _Tp&   type; };
117
118   template<typename _Tp>
119     struct __add_lvalue_reference_helper<_Tp, false, true>
120     { typedef typename remove_reference<_Tp>::type&   type; };
121
122   /// add_lvalue_reference
123   template<typename _Tp>
124     struct add_lvalue_reference
125     : public __add_lvalue_reference_helper<_Tp>
126     { };
127
128   template<typename _Tp,
129            bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
130     struct __add_rvalue_reference_helper
131     { typedef _Tp   type; };
132
133   template<typename _Tp>
134     struct __add_rvalue_reference_helper<_Tp, true>
135     { typedef _Tp&&   type; };
136
137   /// add_rvalue_reference
138   template<typename _Tp>
139     struct add_rvalue_reference
140     : public __add_rvalue_reference_helper<_Tp>
141     { };
142
143   // Scalar properties and transformations.
144
145   template<typename _Tp,
146            bool = is_integral<_Tp>::value,
147            bool = is_floating_point<_Tp>::value>
148     struct __is_signed_helper
149     : public false_type { };
150
151   template<typename _Tp>
152     struct __is_signed_helper<_Tp, false, true>
153     : public true_type { };
154
155   template<typename _Tp>
156     struct __is_signed_helper<_Tp, true, false>
157     : public integral_constant<bool, _Tp(-1) < _Tp(0)>
158     { };
159
160   /// is_signed
161   template<typename _Tp>
162     struct is_signed
163     : public integral_constant<bool, __is_signed_helper<_Tp>::value>
164     { };
165
166   /// is_unsigned
167   template<typename _Tp>
168     struct is_unsigned
169     : public integral_constant<bool, (is_arithmetic<_Tp>::value
170                                       && !is_signed<_Tp>::value)>
171     { };
172
173   // Member introspection.
174
175   /// is_pod
176   template<typename _Tp>
177     struct is_pod
178     : public integral_constant<bool, __is_pod(_Tp)>
179     { };
180
181   /// has_trivial_default_constructor
182   template<typename _Tp>
183     struct has_trivial_default_constructor
184     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
185     { };
186
187   /// has_trivial_copy_constructor
188   template<typename _Tp>
189     struct has_trivial_copy_constructor
190     : public integral_constant<bool, __has_trivial_copy(_Tp)>
191     { };
192
193   /// has_trivial_assign
194   template<typename _Tp>
195     struct has_trivial_assign
196     : public integral_constant<bool, __has_trivial_assign(_Tp)>
197     { };
198
199   /// has_trivial_destructor
200   template<typename _Tp>
201     struct has_trivial_destructor
202     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
203     { };
204
205   /// has_nothrow_default_constructor
206   template<typename _Tp>
207     struct has_nothrow_default_constructor
208     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
209     { };
210
211   /// has_nothrow_copy_constructor
212   template<typename _Tp>
213     struct has_nothrow_copy_constructor
214     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
215     { };
216
217   /// has_nothrow_assign
218   template<typename _Tp>
219     struct has_nothrow_assign
220     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
221     { };
222
223   /// is_base_of
224   template<typename _Base, typename _Derived>
225     struct is_base_of
226     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
227     { };
228
229   // Relationships between types.
230   template<typename _From, typename _To>
231     struct __is_convertible_simple
232     : public __sfinae_types
233     {
234     private:
235       static __one __test(_To);
236       static __two __test(...);
237       static _From __makeFrom();
238     
239     public:
240       static const bool __value = sizeof(__test(__makeFrom())) == 1;
241     };
242
243   template<typename _Tp>
244     struct __is_int_or_cref
245     {
246       typedef typename remove_reference<_Tp>::type __rr_Tp;
247       static const bool __value = (is_integral<_Tp>::value
248                                    || (is_integral<__rr_Tp>::value
249                                        && is_const<__rr_Tp>::value
250                                        && !is_volatile<__rr_Tp>::value));
251     };
252
253   template<typename _From, typename _To,
254            bool = (is_void<_From>::value || is_void<_To>::value
255                    || is_function<_To>::value || is_array<_To>::value
256                    // This special case is here only to avoid warnings.
257                    || (is_floating_point<typename
258                        remove_reference<_From>::type>::value
259                        && __is_int_or_cref<_To>::__value))>
260     struct __is_convertible_helper
261     {
262       // "An imaginary lvalue of type From...".
263       static const bool __value = (__is_convertible_simple<typename
264                                    add_lvalue_reference<_From>::type,
265                                    _To>::__value);
266     };
267
268   template<typename _From, typename _To>
269     struct __is_convertible_helper<_From, _To, true>
270     { static const bool __value = (is_void<_To>::value
271                                    || (__is_int_or_cref<_To>::__value
272                                        && !is_void<_From>::value)); };
273
274   // XXX FIXME
275   // The C++0x specifications are different, see N2255.
276   /// is_convertible
277   template<typename _From, typename _To>
278     struct is_convertible
279     : public integral_constant<bool,
280                                __is_convertible_helper<_From, _To>::__value>
281     { };
282
283   template<std::size_t _Len>
284     struct __aligned_storage_msa
285     { 
286       union __type
287       {
288         unsigned char __data[_Len];
289         struct __attribute__((__aligned__)) { } __align; 
290       };
291     };
292
293   /**
294    *  @brief Alignment type.
295    *
296    *  The value of _Align is a default-alignment which shall be the
297    *  most stringent alignment requirement for any C++ object type
298    *  whose size is no greater than _Len (3.9). The member typedef
299    *  type shall be a POD type suitable for use as uninitialized
300    *  storage for any object whose size is at most _Len and whose
301    *  alignment is a divisor of _Align.
302   */
303   template<std::size_t _Len, std::size_t _Align =
304            __alignof__(typename __aligned_storage_msa<_Len>::__type)>
305     struct aligned_storage
306     { 
307       union type
308       {
309         unsigned char __data[_Len];
310         struct __attribute__((__aligned__((_Align)))) { } __align; 
311       };
312     };
313
314
315   // Define a nested type if some predicate holds.
316   // Primary template.
317   /// enable_if
318   template<bool, typename _Tp = void>
319     struct enable_if 
320     { };
321
322   // Partial specialization for true.
323   template<typename _Tp>
324     struct enable_if<true, _Tp>
325     { typedef _Tp type; };
326
327
328   // A conditional expression, but for types. If true, first, if false, second.
329   // Primary template.
330   /// conditional
331   template<bool _Cond, typename _Iftrue, typename _Iffalse>
332     struct conditional
333     { typedef _Iftrue type; };
334
335   // Partial specialization for false.
336   template<typename _Iftrue, typename _Iffalse>
337     struct conditional<false, _Iftrue, _Iffalse>
338     { typedef _Iffalse type; };
339
340
341   // Decay trait for arrays and functions, used for perfect forwarding
342   // in make_pair, make_tuple, etc.
343   template<typename _Up, 
344            bool _IsArray = is_array<_Up>::value,
345            bool _IsFunction = is_function<_Up>::value> 
346     struct __decay_selector;
347
348   // NB: DR 705.
349   template<typename _Up> 
350     struct __decay_selector<_Up, false, false>
351     { typedef typename remove_cv<_Up>::type __type; };
352
353   template<typename _Up> 
354     struct __decay_selector<_Up, true, false>
355     { typedef typename remove_extent<_Up>::type* __type; };
356
357   template<typename _Up> 
358     struct __decay_selector<_Up, false, true>
359     { typedef typename add_pointer<_Up>::type __type; };
360
361   /// decay
362   template<typename _Tp> 
363     struct decay 
364     { 
365     private:
366       typedef typename remove_reference<_Tp>::type __remove_type;
367
368     public:
369       typedef typename __decay_selector<__remove_type>::__type type;
370     };
371
372
373   // Utility for constructing identically cv-qualified types.
374   template<typename _Unqualified, bool _IsConst, bool _IsVol>
375     struct __cv_selector;
376
377   template<typename _Unqualified>
378     struct __cv_selector<_Unqualified, false, false>
379     { typedef _Unqualified __type; };
380
381   template<typename _Unqualified>
382     struct __cv_selector<_Unqualified, false, true>
383     { typedef volatile _Unqualified __type; };
384
385   template<typename _Unqualified>
386     struct __cv_selector<_Unqualified, true, false>
387     { typedef const _Unqualified __type; };
388
389   template<typename _Unqualified>
390     struct __cv_selector<_Unqualified, true, true>
391     { typedef const volatile _Unqualified __type; };
392
393   template<typename _Qualified, typename _Unqualified,
394            bool _IsConst = is_const<_Qualified>::value,
395            bool _IsVol = is_volatile<_Qualified>::value>
396     struct __match_cv_qualifiers
397     {
398     private:
399       typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
400
401     public:
402       typedef typename __match::__type __type; 
403     };
404
405
406   // Utility for finding the unsigned versions of signed integral types.
407   template<typename _Tp>
408     struct __make_unsigned
409     { typedef _Tp __type; };
410
411   template<>
412     struct __make_unsigned<char>
413     { typedef unsigned char __type; };
414
415   template<>
416     struct __make_unsigned<signed char>
417     { typedef unsigned char __type; };
418
419   template<>
420     struct __make_unsigned<short>
421     { typedef unsigned short __type; };
422
423   template<>
424     struct __make_unsigned<int>
425     { typedef unsigned int __type; };
426
427   template<>
428     struct __make_unsigned<long>
429     { typedef unsigned long __type; };
430
431   template<>
432     struct __make_unsigned<long long>
433     { typedef unsigned long long __type; };
434
435
436   // Select between integral and enum: not possible to be both.
437   template<typename _Tp, 
438            bool _IsInt = is_integral<_Tp>::value,
439            bool _IsEnum = is_enum<_Tp>::value>
440     struct __make_unsigned_selector;
441   
442   template<typename _Tp>
443     struct __make_unsigned_selector<_Tp, true, false>
444     {
445     private:
446       typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
447       typedef typename __unsignedt::__type __unsigned_type;
448       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
449
450     public:
451       typedef typename __cv_unsigned::__type __type;
452     };
453
454   template<typename _Tp>
455     struct __make_unsigned_selector<_Tp, false, true>
456     {
457     private:
458       // With -fshort-enums, an enum may be as small as a char.
459       typedef unsigned char __smallest;
460       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
461       static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
462       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
463       typedef conditional<__b2, unsigned int, unsigned long> __cond2;
464       typedef typename __cond2::type __cond2_type;
465       typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
466       typedef typename __cond1::type __cond1_type;
467
468     public:
469       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
470     };
471
472   // Given an integral/enum type, return the corresponding unsigned
473   // integer type.
474   // Primary template.
475   /// make_unsigned
476   template<typename _Tp>
477     struct make_unsigned 
478     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
479
480   // Integral, but don't define.
481   template<>
482     struct make_unsigned<bool>;
483
484
485   // Utility for finding the signed versions of unsigned integral types.
486   template<typename _Tp>
487     struct __make_signed
488     { typedef _Tp __type; };
489
490   template<>
491     struct __make_signed<char>
492     { typedef signed char __type; };
493
494   template<>
495     struct __make_signed<unsigned char>
496     { typedef signed char __type; };
497
498   template<>
499     struct __make_signed<unsigned short>
500     { typedef signed short __type; };
501
502   template<>
503     struct __make_signed<unsigned int>
504     { typedef signed int __type; };
505
506   template<>
507     struct __make_signed<unsigned long>
508     { typedef signed long __type; };
509
510   template<>
511     struct __make_signed<unsigned long long>
512     { typedef signed long long __type; };
513
514
515   // Select between integral and enum: not possible to be both.
516   template<typename _Tp, 
517            bool _IsInt = is_integral<_Tp>::value,
518            bool _IsEnum = is_enum<_Tp>::value>
519     struct __make_signed_selector;
520   
521   template<typename _Tp>
522     struct __make_signed_selector<_Tp, true, false>
523     {
524     private:
525       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
526       typedef typename __signedt::__type __signed_type;
527       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
528
529     public:
530       typedef typename __cv_signed::__type __type;
531     };
532
533   template<typename _Tp>
534     struct __make_signed_selector<_Tp, false, true>
535     {
536     private:
537       // With -fshort-enums, an enum may be as small as a char.
538       typedef signed char __smallest;
539       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
540       static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
541       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
542       typedef conditional<__b2, signed int, signed long> __cond2;
543       typedef typename __cond2::type __cond2_type;
544       typedef conditional<__b1, signed short, __cond2_type> __cond1;
545       typedef typename __cond1::type __cond1_type;
546
547     public:
548       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
549     };
550
551   // Given an integral/enum type, return the corresponding signed
552   // integer type.
553   // Primary template.
554   /// make_signed
555   template<typename _Tp>
556     struct make_signed 
557     { typedef typename __make_signed_selector<_Tp>::__type type; };
558
559   // Integral, but don't define.
560   template<>
561     struct make_signed<bool>;
562
563   /// common_type
564   template<typename... _Tp>
565     struct common_type;
566
567   template<typename _Tp>
568     struct common_type<_Tp>
569     {
570       static_assert(sizeof(_Tp) > 0, "must be complete type");
571       typedef _Tp type;
572     };
573
574   template<typename _Tp, typename _Up>
575     class common_type<_Tp, _Up>
576     {
577       static_assert(sizeof(_Tp) > 0, "must be complete type");
578       static_assert(sizeof(_Up) > 0, "must be complete type");
579
580       static _Tp&& __t();
581       static _Up&& __u();
582
583       // HACK: Prevents optimization of ?: in the decltype
584       // expression when the condition is the literal, "true".
585       // See, PR36628.
586       static bool __true_or_false();
587
588     public:
589       typedef decltype(__true_or_false() ? __t() : __u()) type;
590     };
591
592   template<typename _Tp, typename _Up, typename... _Vp>
593     struct common_type<_Tp, _Up, _Vp...>
594     {
595       typedef typename
596         common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
597     };
598
599   // @} group metaprogramming
600 }
601
602 #endif  // __GXX_EXPERIMENTAL_CXX0X__
603
604 #endif  // _GLIBCXX_TYPE_TRAITS 
605