OSDN Git Service

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