OSDN Git Service

f4d0b267759c121734d06ba2ff03aa123294da7e
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / type_traits
1 // C++0x type_traits -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009, 2010 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 <bits/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 <bits/c++config.h>
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_trivial
177   template<typename _Tp>
178     struct is_trivial
179     : public integral_constant<bool, __is_trivial(_Tp)>
180     { };
181
182   /// is_standard_layout
183   template<typename _Tp>
184     struct is_standard_layout
185     : public integral_constant<bool, __is_standard_layout(_Tp)>
186     { };
187
188   /// is_pod
189   // Could use is_standard_layout && is_trivial instead of the builtin.
190   template<typename _Tp>
191     struct is_pod
192     : public integral_constant<bool, __is_pod(_Tp)>
193     { };
194
195   template<typename _Tp>
196     typename add_rvalue_reference<_Tp>::type declval() noexcept;
197
198   template<typename _Tp, typename... _Args>
199     class __is_constructible_helper
200     : public __sfinae_types
201     {
202       template<typename _Tp1, typename... _Args1>
203         static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int);
204
205       template<typename, typename...>
206         static __two __test(...);
207
208     public:
209       static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1;
210     };
211
212   template<typename _Tp, typename _Arg>
213     class __is_constructible_helper<_Tp, _Arg>
214     : public __sfinae_types
215     {
216       template<typename _Tp1, typename _Arg1>
217         static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one())
218         __test(int);
219
220       template<typename, typename>
221         static __two __test(...);
222
223     public:
224       static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1;
225     };
226
227   /// is_constructible
228   // XXX FIXME
229   // The C++0x specifications require front-end support, see N2255.
230   template<typename _Tp, typename... _Args>
231     struct is_constructible
232     : public integral_constant<bool,
233                                __is_constructible_helper<_Tp,
234                                                          _Args...>::__value>
235     { };
236
237   template<bool, typename _Tp, typename... _Args>
238     struct __is_nt_constructible_helper
239     { static const bool __value = false; };
240
241   template<typename _Tp, typename... _Args>
242     struct __is_nt_constructible_helper<true, _Tp, _Args...>
243     { static const bool __value = noexcept(_Tp(declval<_Args>()...)); };
244
245   template<typename _Tp, typename _Arg>
246     struct __is_nt_constructible_helper<true, _Tp, _Arg>
247     {
248       static const bool __value = noexcept(static_cast<_Tp>(declval<_Arg>()));
249     };
250
251   /// is_nothrow_constructible
252   template<typename _Tp, typename... _Args>
253     struct is_nothrow_constructible
254     : public integral_constant<bool,
255           __is_nt_constructible_helper<is_constructible<_Tp, _Args...>::value,
256                                        _Tp, _Args...>::__value>
257     { };
258
259   /// has_trivial_default_constructor
260   template<typename _Tp>
261     struct has_trivial_default_constructor
262     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
263     { };
264
265   /// has_trivial_copy_constructor
266   template<typename _Tp>
267     struct has_trivial_copy_constructor
268     : public integral_constant<bool, __has_trivial_copy(_Tp)>
269     { };
270
271   /// has_trivial_copy_assign
272   template<typename _Tp>
273     struct has_trivial_copy_assign
274     : public integral_constant<bool, __has_trivial_assign(_Tp)>
275     { };
276
277   /// has_trivial_destructor
278   template<typename _Tp>
279     struct has_trivial_destructor
280     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
281     { };
282
283   /// has_nothrow_default_constructor
284   template<typename _Tp>
285     struct has_nothrow_default_constructor
286     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
287     { };
288
289   /// has_nothrow_copy_constructor
290   template<typename _Tp>
291     struct has_nothrow_copy_constructor
292     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
293     { };
294
295   /// has_nothrow_copy_assign
296   template<typename _Tp>
297     struct has_nothrow_copy_assign
298     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
299     { };
300
301   // Relationships between types.
302
303   /// is_base_of
304   template<typename _Base, typename _Derived>
305     struct is_base_of
306     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
307     { };
308
309   template<typename _From, typename _To,
310            bool = (is_void<_From>::value || is_function<_To>::value
311                    || is_array<_To>::value)>
312     struct __is_convertible_helper
313     { static const bool __value = is_void<_To>::value; };
314
315   template<typename _From, typename _To>
316     class __is_convertible_helper<_From, _To, false>
317     : public __sfinae_types
318     {
319       template<typename _To1>
320         static void __test_aux(_To1);
321
322       template<typename _From1, typename _To1>
323         static decltype(__test_aux<_To1>(std::declval<_From1>()), __one())
324         __test(int);
325
326       template<typename, typename>
327         static __two __test(...);
328
329     public:
330       static const bool __value = sizeof(__test<_From, _To>(0)) == 1;
331     };
332
333   /// is_convertible
334   // XXX FIXME
335   // The C++0x specifications require front-end support, see N2255.
336   template<typename _From, typename _To>
337     struct is_convertible
338     : public integral_constant<bool,
339                                __is_convertible_helper<_From, _To>::__value>
340     { };
341
342   /// is_explicitly_convertible
343   template<typename _From, typename _To>
344     struct is_explicitly_convertible
345     : public is_constructible<_To, _From>
346     { };
347
348   template<std::size_t _Len>
349     struct __aligned_storage_msa
350     { 
351       union __type
352       {
353         unsigned char __data[_Len];
354         struct __attribute__((__aligned__)) { } __align; 
355       };
356     };
357
358   /**
359    *  @brief Alignment type.
360    *
361    *  The value of _Align is a default-alignment which shall be the
362    *  most stringent alignment requirement for any C++ object type
363    *  whose size is no greater than _Len (3.9). The member typedef
364    *  type shall be a POD type suitable for use as uninitialized
365    *  storage for any object whose size is at most _Len and whose
366    *  alignment is a divisor of _Align.
367   */
368   template<std::size_t _Len, std::size_t _Align =
369            __alignof__(typename __aligned_storage_msa<_Len>::__type)>
370     struct aligned_storage
371     { 
372       union type
373       {
374         unsigned char __data[_Len];
375         struct __attribute__((__aligned__((_Align)))) { } __align; 
376       };
377     };
378
379
380   // Define a nested type if some predicate holds.
381   // Primary template.
382   /// enable_if
383   template<bool, typename _Tp = void>
384     struct enable_if 
385     { };
386
387   // Partial specialization for true.
388   template<typename _Tp>
389     struct enable_if<true, _Tp>
390     { typedef _Tp type; };
391
392
393   // A conditional expression, but for types. If true, first, if false, second.
394   // Primary template.
395   /// conditional
396   template<bool _Cond, typename _Iftrue, typename _Iffalse>
397     struct conditional
398     { typedef _Iftrue type; };
399
400   // Partial specialization for false.
401   template<typename _Iftrue, typename _Iffalse>
402     struct conditional<false, _Iftrue, _Iffalse>
403     { typedef _Iffalse type; };
404
405
406   // Decay trait for arrays and functions, used for perfect forwarding
407   // in make_pair, make_tuple, etc.
408   template<typename _Up, 
409            bool _IsArray = is_array<_Up>::value,
410            bool _IsFunction = is_function<_Up>::value> 
411     struct __decay_selector;
412
413   // NB: DR 705.
414   template<typename _Up> 
415     struct __decay_selector<_Up, false, false>
416     { typedef typename remove_cv<_Up>::type __type; };
417
418   template<typename _Up> 
419     struct __decay_selector<_Up, true, false>
420     { typedef typename remove_extent<_Up>::type* __type; };
421
422   template<typename _Up> 
423     struct __decay_selector<_Up, false, true>
424     { typedef typename add_pointer<_Up>::type __type; };
425
426   /// decay
427   template<typename _Tp> 
428     class decay 
429     { 
430       typedef typename remove_reference<_Tp>::type __remove_type;
431
432     public:
433       typedef typename __decay_selector<__remove_type>::__type type;
434     };
435
436   template<typename _Tp>
437     class reference_wrapper;
438
439   // Helper which adds a reference to a type when given a reference_wrapper
440   template<typename _Tp>
441     struct __strip_reference_wrapper
442     {
443       typedef _Tp __type;
444     };
445
446   template<typename _Tp>
447     struct __strip_reference_wrapper<reference_wrapper<_Tp> >
448     {
449       typedef _Tp& __type;
450     };
451
452   template<typename _Tp>
453     struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
454     {
455       typedef _Tp& __type;
456     };
457
458   template<typename _Tp>
459     struct __decay_and_strip
460     {
461       typedef typename __strip_reference_wrapper<
462         typename decay<_Tp>::type>::__type __type;
463     };
464
465
466   // Utility for constructing identically cv-qualified types.
467   template<typename _Unqualified, bool _IsConst, bool _IsVol>
468     struct __cv_selector;
469
470   template<typename _Unqualified>
471     struct __cv_selector<_Unqualified, false, false>
472     { typedef _Unqualified __type; };
473
474   template<typename _Unqualified>
475     struct __cv_selector<_Unqualified, false, true>
476     { typedef volatile _Unqualified __type; };
477
478   template<typename _Unqualified>
479     struct __cv_selector<_Unqualified, true, false>
480     { typedef const _Unqualified __type; };
481
482   template<typename _Unqualified>
483     struct __cv_selector<_Unqualified, true, true>
484     { typedef const volatile _Unqualified __type; };
485
486   template<typename _Qualified, typename _Unqualified,
487            bool _IsConst = is_const<_Qualified>::value,
488            bool _IsVol = is_volatile<_Qualified>::value>
489     class __match_cv_qualifiers
490     {
491       typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
492
493     public:
494       typedef typename __match::__type __type; 
495     };
496
497
498   // Utility for finding the unsigned versions of signed integral types.
499   template<typename _Tp>
500     struct __make_unsigned
501     { typedef _Tp __type; };
502
503   template<>
504     struct __make_unsigned<char>
505     { typedef unsigned char __type; };
506
507   template<>
508     struct __make_unsigned<signed char>
509     { typedef unsigned char __type; };
510
511   template<>
512     struct __make_unsigned<short>
513     { typedef unsigned short __type; };
514
515   template<>
516     struct __make_unsigned<int>
517     { typedef unsigned int __type; };
518
519   template<>
520     struct __make_unsigned<long>
521     { typedef unsigned long __type; };
522
523   template<>
524     struct __make_unsigned<long long>
525     { typedef unsigned long long __type; };
526
527
528   // Select between integral and enum: not possible to be both.
529   template<typename _Tp, 
530            bool _IsInt = is_integral<_Tp>::value,
531            bool _IsEnum = is_enum<_Tp>::value>
532     class __make_unsigned_selector;
533
534   template<typename _Tp>
535     class __make_unsigned_selector<_Tp, true, false>
536     {
537       typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
538       typedef typename __unsignedt::__type __unsigned_type;
539       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
540
541     public:
542       typedef typename __cv_unsigned::__type __type;
543     };
544
545   template<typename _Tp>
546     class __make_unsigned_selector<_Tp, false, true>
547     {
548       // With -fshort-enums, an enum may be as small as a char.
549       typedef unsigned char __smallest;
550       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
551       static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
552       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
553       typedef conditional<__b2, unsigned int, unsigned long> __cond2;
554       typedef typename __cond2::type __cond2_type;
555       typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
556       typedef typename __cond1::type __cond1_type;
557
558     public:
559       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
560     };
561
562   // Given an integral/enum type, return the corresponding unsigned
563   // integer type.
564   // Primary template.
565   /// make_unsigned
566   template<typename _Tp>
567     struct make_unsigned 
568     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
569
570   // Integral, but don't define.
571   template<>
572     struct make_unsigned<bool>;
573
574
575   // Utility for finding the signed versions of unsigned integral types.
576   template<typename _Tp>
577     struct __make_signed
578     { typedef _Tp __type; };
579
580   template<>
581     struct __make_signed<char>
582     { typedef signed char __type; };
583
584   template<>
585     struct __make_signed<unsigned char>
586     { typedef signed char __type; };
587
588   template<>
589     struct __make_signed<unsigned short>
590     { typedef signed short __type; };
591
592   template<>
593     struct __make_signed<unsigned int>
594     { typedef signed int __type; };
595
596   template<>
597     struct __make_signed<unsigned long>
598     { typedef signed long __type; };
599
600   template<>
601     struct __make_signed<unsigned long long>
602     { typedef signed long long __type; };
603
604
605   // Select between integral and enum: not possible to be both.
606   template<typename _Tp, 
607            bool _IsInt = is_integral<_Tp>::value,
608            bool _IsEnum = is_enum<_Tp>::value>
609     class __make_signed_selector;
610
611   template<typename _Tp>
612     class __make_signed_selector<_Tp, true, false>
613     {
614       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
615       typedef typename __signedt::__type __signed_type;
616       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
617
618     public:
619       typedef typename __cv_signed::__type __type;
620     };
621
622   template<typename _Tp>
623     class __make_signed_selector<_Tp, false, true>
624     {
625       // With -fshort-enums, an enum may be as small as a char.
626       typedef signed char __smallest;
627       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
628       static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
629       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
630       typedef conditional<__b2, signed int, signed long> __cond2;
631       typedef typename __cond2::type __cond2_type;
632       typedef conditional<__b1, signed short, __cond2_type> __cond1;
633       typedef typename __cond1::type __cond1_type;
634
635     public:
636       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
637     };
638
639   // Given an integral/enum type, return the corresponding signed
640   // integer type.
641   // Primary template.
642   /// make_signed
643   template<typename _Tp>
644     struct make_signed 
645     { typedef typename __make_signed_selector<_Tp>::__type type; };
646
647   // Integral, but don't define.
648   template<>
649     struct make_signed<bool>;
650
651   /// common_type
652   template<typename... _Tp>
653     struct common_type;
654
655   template<typename _Tp>
656     struct common_type<_Tp>
657     { typedef _Tp type; };
658
659   template<typename _Tp, typename _Up>
660     struct common_type<_Tp, _Up>
661     { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
662
663   template<typename _Tp, typename _Up, typename... _Vp>
664     struct common_type<_Tp, _Up, _Vp...>
665     {
666       typedef typename
667         common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
668     };
669
670   /// declval
671   template<typename _Tp>
672     struct __declval_protector
673     {
674       static const bool __stop = false;
675       static typename add_rvalue_reference<_Tp>::type __delegate();
676     };
677
678   template<typename _Tp>
679     inline typename add_rvalue_reference<_Tp>::type
680     declval() noexcept
681     {
682       static_assert(__declval_protector<_Tp>::__stop,
683                     "declval() must not be used!");
684       return __declval_protector<_Tp>::__delegate();
685     }
686
687   /// result_of
688   template<typename _Signature>
689     class result_of;
690
691   template<typename _Functor, typename... _ArgTypes>
692     struct result_of<_Functor(_ArgTypes...)>
693     {
694       typedef
695         decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
696         type;
697     };
698
699   // @} group metaprogramming
700 }
701
702 #endif  // __GXX_EXPERIMENTAL_CXX0X__
703
704 #endif  // _GLIBCXX_TYPE_TRAITS