gcc/c-family/
[official-gcc.git] / libstdc++-v3 / include / std / type_traits
bloba5a62d609ebd6cfb9850a544ad300b5e8857d430
1 // C++0x type_traits -*- C++ -*-
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.
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.
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.
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/>.
25 /** @file include/type_traits
26  *  This is a Standard C++ Library header.
27  */
29 #ifndef _GLIBCXX_TYPE_TRAITS
30 #define _GLIBCXX_TYPE_TRAITS 1
32 #pragma GCC system_header
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
36 #else
38 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
39 #  error C++0x header cannot be included from TR1 header
40 #endif
42 #include <bits/c++config.h>
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
58 namespace std
60   /**
61    * @addtogroup metaprogramming
62    * @{
63    */
65   // Primary classification traits.
67   /// is_lvalue_reference
68   template<typename>
69     struct is_lvalue_reference
70     : public false_type { };
72   template<typename _Tp>
73     struct is_lvalue_reference<_Tp&>
74     : public true_type { };
76   /// is_rvalue_reference
77   template<typename>
78     struct is_rvalue_reference
79     : public false_type { };
81   template<typename _Tp>
82     struct is_rvalue_reference<_Tp&&>
83     : public true_type { };
85   // Secondary classification traits.
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     { };
94   // Reference transformations.
96   /// remove_reference
97   template<typename _Tp>
98     struct remove_reference
99     { typedef _Tp   type; };
101   template<typename _Tp>
102     struct remove_reference<_Tp&>
103     { typedef _Tp   type; };
105   template<typename _Tp>
106     struct remove_reference<_Tp&&>
107     { typedef _Tp   type; };
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; };
115   template<typename _Tp>
116     struct __add_lvalue_reference_helper<_Tp, true, false>
117     { typedef _Tp&   type; };
119   template<typename _Tp>
120     struct __add_lvalue_reference_helper<_Tp, false, true>
121     { typedef typename remove_reference<_Tp>::type&   type; };
123   /// add_lvalue_reference
124   template<typename _Tp>
125     struct add_lvalue_reference
126     : public __add_lvalue_reference_helper<_Tp>
127     { };
129   template<typename _Tp,
130            bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
131     struct __add_rvalue_reference_helper
132     { typedef _Tp   type; };
134   template<typename _Tp>
135     struct __add_rvalue_reference_helper<_Tp, true>
136     { typedef _Tp&&   type; };
138   /// add_rvalue_reference
139   template<typename _Tp>
140     struct add_rvalue_reference
141     : public __add_rvalue_reference_helper<_Tp>
142     { };
144   // Scalar properties and transformations.
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 { };
152   template<typename _Tp>
153     struct __is_signed_helper<_Tp, false, true>
154     : public true_type { };
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     { };
161   /// is_signed
162   template<typename _Tp>
163     struct is_signed
164     : public integral_constant<bool, __is_signed_helper<_Tp>::value>
165     { };
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     { };
174   // Member introspection.
176   /// is_trivial
177   template<typename _Tp>
178     struct is_trivial
179     : public integral_constant<bool, __is_trivial(_Tp)>
180     { };
182   /// is_standard_layout
183   template<typename _Tp>
184     struct is_standard_layout
185     : public integral_constant<bool, __is_standard_layout(_Tp)>
186     { };
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     { };
195   /// is_literal_type
196   template<typename _Tp>
197     struct is_literal_type
198     : public integral_constant<bool, __is_literal_type(_Tp)>
199     { };
201   template<typename _Tp>
202     typename add_rvalue_reference<_Tp>::type declval() noexcept;
204   template<typename _Tp, typename... _Args>
205     class __is_constructible_helper
206     : public __sfinae_types
207     {
208       template<typename _Tp1, typename... _Args1>
209         static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int);
211       template<typename, typename...>
212         static __two __test(...);
214     public:
215       static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1;
216     };
218   template<typename _Tp, typename _Arg>
219     class __is_constructible_helper<_Tp, _Arg>
220     : public __sfinae_types
221     {
222       template<typename _Tp1, typename _Arg1>
223         static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one())
224         __test(int);
226       template<typename, typename>
227         static __two __test(...);
229     public:
230       static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1;
231     };
233   /// is_constructible
234   // XXX FIXME
235   // The C++0x specifications require front-end support, see N2255.
236   template<typename _Tp, typename... _Args>
237     struct is_constructible
238     : public integral_constant<bool,
239                                __is_constructible_helper<_Tp,
240                                                          _Args...>::__value>
241     { };
243   template<bool, typename _Tp, typename... _Args>
244     struct __is_nt_constructible_helper
245     { static const bool __value = false; };
247   template<typename _Tp, typename... _Args>
248     struct __is_nt_constructible_helper<true, _Tp, _Args...>
249     { static const bool __value = noexcept(_Tp(declval<_Args>()...)); };
251   template<typename _Tp, typename _Arg>
252     struct __is_nt_constructible_helper<true, _Tp, _Arg>
253     {
254       static const bool __value = noexcept(static_cast<_Tp>(declval<_Arg>()));
255     };
257   /// is_nothrow_constructible
258   template<typename _Tp, typename... _Args>
259     struct is_nothrow_constructible
260     : public integral_constant<bool,
261           __is_nt_constructible_helper<is_constructible<_Tp, _Args...>::value,
262                                        _Tp, _Args...>::__value>
263     { };
265   /// has_trivial_default_constructor
266   template<typename _Tp>
267     struct has_trivial_default_constructor
268     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
269     { };
271   /// has_trivial_copy_constructor
272   template<typename _Tp>
273     struct has_trivial_copy_constructor
274     : public integral_constant<bool, __has_trivial_copy(_Tp)>
275     { };
277   /// has_trivial_copy_assign
278   template<typename _Tp>
279     struct has_trivial_copy_assign
280     : public integral_constant<bool, __has_trivial_assign(_Tp)>
281     { };
283   /// has_trivial_destructor
284   template<typename _Tp>
285     struct has_trivial_destructor
286     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
287     { };
289   /// has_nothrow_default_constructor
290   template<typename _Tp>
291     struct has_nothrow_default_constructor
292     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
293     { };
295   /// has_nothrow_copy_constructor
296   template<typename _Tp>
297     struct has_nothrow_copy_constructor
298     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
299     { };
301   /// has_nothrow_copy_assign
302   template<typename _Tp>
303     struct has_nothrow_copy_assign
304     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
305     { };
307   // Relationships between types.
309   /// is_base_of
310   template<typename _Base, typename _Derived>
311     struct is_base_of
312     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
313     { };
315   template<typename _From, typename _To,
316            bool = (is_void<_From>::value || is_function<_To>::value
317                    || is_array<_To>::value)>
318     struct __is_convertible_helper
319     { static const bool __value = is_void<_To>::value; };
321   template<typename _From, typename _To>
322     class __is_convertible_helper<_From, _To, false>
323     : public __sfinae_types
324     {
325       template<typename _To1>
326         static void __test_aux(_To1);
328       template<typename _From1, typename _To1>
329         static decltype(__test_aux<_To1>(std::declval<_From1>()), __one())
330         __test(int);
332       template<typename, typename>
333         static __two __test(...);
335     public:
336       static const bool __value = sizeof(__test<_From, _To>(0)) == 1;
337     };
339   /// is_convertible
340   // XXX FIXME
341   // The C++0x specifications require front-end support, see N2255.
342   template<typename _From, typename _To>
343     struct is_convertible
344     : public integral_constant<bool,
345                                __is_convertible_helper<_From, _To>::__value>
346     { };
348   /// is_explicitly_convertible
349   template<typename _From, typename _To>
350     struct is_explicitly_convertible
351     : public is_constructible<_To, _From>
352     { };
354   template<std::size_t _Len>
355     struct __aligned_storage_msa
356     { 
357       union __type
358       {
359         unsigned char __data[_Len];
360         struct __attribute__((__aligned__)) { } __align; 
361       };
362     };
364   /**
365    *  @brief Alignment type.
366    *
367    *  The value of _Align is a default-alignment which shall be the
368    *  most stringent alignment requirement for any C++ object type
369    *  whose size is no greater than _Len (3.9). The member typedef
370    *  type shall be a POD type suitable for use as uninitialized
371    *  storage for any object whose size is at most _Len and whose
372    *  alignment is a divisor of _Align.
373   */
374   template<std::size_t _Len, std::size_t _Align =
375            __alignof__(typename __aligned_storage_msa<_Len>::__type)>
376     struct aligned_storage
377     { 
378       union type
379       {
380         unsigned char __data[_Len];
381         struct __attribute__((__aligned__((_Align)))) { } __align; 
382       };
383     };
386   // Define a nested type if some predicate holds.
387   // Primary template.
388   /// enable_if
389   template<bool, typename _Tp = void>
390     struct enable_if 
391     { };
393   // Partial specialization for true.
394   template<typename _Tp>
395     struct enable_if<true, _Tp>
396     { typedef _Tp type; };
399   // A conditional expression, but for types. If true, first, if false, second.
400   // Primary template.
401   /// conditional
402   template<bool _Cond, typename _Iftrue, typename _Iffalse>
403     struct conditional
404     { typedef _Iftrue type; };
406   // Partial specialization for false.
407   template<typename _Iftrue, typename _Iffalse>
408     struct conditional<false, _Iftrue, _Iffalse>
409     { typedef _Iffalse type; };
412   // Decay trait for arrays and functions, used for perfect forwarding
413   // in make_pair, make_tuple, etc.
414   template<typename _Up, 
415            bool _IsArray = is_array<_Up>::value,
416            bool _IsFunction = is_function<_Up>::value> 
417     struct __decay_selector;
419   // NB: DR 705.
420   template<typename _Up> 
421     struct __decay_selector<_Up, false, false>
422     { typedef typename remove_cv<_Up>::type __type; };
424   template<typename _Up> 
425     struct __decay_selector<_Up, true, false>
426     { typedef typename remove_extent<_Up>::type* __type; };
428   template<typename _Up> 
429     struct __decay_selector<_Up, false, true>
430     { typedef typename add_pointer<_Up>::type __type; };
432   /// decay
433   template<typename _Tp> 
434     class decay 
435     { 
436       typedef typename remove_reference<_Tp>::type __remove_type;
438     public:
439       typedef typename __decay_selector<__remove_type>::__type type;
440     };
442   template<typename _Tp>
443     class reference_wrapper;
445   // Helper which adds a reference to a type when given a reference_wrapper
446   template<typename _Tp>
447     struct __strip_reference_wrapper
448     {
449       typedef _Tp __type;
450     };
452   template<typename _Tp>
453     struct __strip_reference_wrapper<reference_wrapper<_Tp> >
454     {
455       typedef _Tp& __type;
456     };
458   template<typename _Tp>
459     struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
460     {
461       typedef _Tp& __type;
462     };
464   template<typename _Tp>
465     struct __decay_and_strip
466     {
467       typedef typename __strip_reference_wrapper<
468         typename decay<_Tp>::type>::__type __type;
469     };
472   // Utility for constructing identically cv-qualified types.
473   template<typename _Unqualified, bool _IsConst, bool _IsVol>
474     struct __cv_selector;
476   template<typename _Unqualified>
477     struct __cv_selector<_Unqualified, false, false>
478     { typedef _Unqualified __type; };
480   template<typename _Unqualified>
481     struct __cv_selector<_Unqualified, false, true>
482     { typedef volatile _Unqualified __type; };
484   template<typename _Unqualified>
485     struct __cv_selector<_Unqualified, true, false>
486     { typedef const _Unqualified __type; };
488   template<typename _Unqualified>
489     struct __cv_selector<_Unqualified, true, true>
490     { typedef const volatile _Unqualified __type; };
492   template<typename _Qualified, typename _Unqualified,
493            bool _IsConst = is_const<_Qualified>::value,
494            bool _IsVol = is_volatile<_Qualified>::value>
495     class __match_cv_qualifiers
496     {
497       typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
499     public:
500       typedef typename __match::__type __type; 
501     };
504   // Utility for finding the unsigned versions of signed integral types.
505   template<typename _Tp>
506     struct __make_unsigned
507     { typedef _Tp __type; };
509   template<>
510     struct __make_unsigned<char>
511     { typedef unsigned char __type; };
513   template<>
514     struct __make_unsigned<signed char>
515     { typedef unsigned char __type; };
517   template<>
518     struct __make_unsigned<short>
519     { typedef unsigned short __type; };
521   template<>
522     struct __make_unsigned<int>
523     { typedef unsigned int __type; };
525   template<>
526     struct __make_unsigned<long>
527     { typedef unsigned long __type; };
529   template<>
530     struct __make_unsigned<long long>
531     { typedef unsigned long long __type; };
534   // Select between integral and enum: not possible to be both.
535   template<typename _Tp, 
536            bool _IsInt = is_integral<_Tp>::value,
537            bool _IsEnum = is_enum<_Tp>::value>
538     class __make_unsigned_selector;
540   template<typename _Tp>
541     class __make_unsigned_selector<_Tp, true, false>
542     {
543       typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
544       typedef typename __unsignedt::__type __unsigned_type;
545       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
547     public:
548       typedef typename __cv_unsigned::__type __type;
549     };
551   template<typename _Tp>
552     class __make_unsigned_selector<_Tp, false, true>
553     {
554       // With -fshort-enums, an enum may be as small as a char.
555       typedef unsigned char __smallest;
556       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
557       static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
558       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
559       typedef conditional<__b2, unsigned int, unsigned long> __cond2;
560       typedef typename __cond2::type __cond2_type;
561       typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
562       typedef typename __cond1::type __cond1_type;
564     public:
565       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
566     };
568   // Given an integral/enum type, return the corresponding unsigned
569   // integer type.
570   // Primary template.
571   /// make_unsigned
572   template<typename _Tp>
573     struct make_unsigned 
574     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
576   // Integral, but don't define.
577   template<>
578     struct make_unsigned<bool>;
581   // Utility for finding the signed versions of unsigned integral types.
582   template<typename _Tp>
583     struct __make_signed
584     { typedef _Tp __type; };
586   template<>
587     struct __make_signed<char>
588     { typedef signed char __type; };
590   template<>
591     struct __make_signed<unsigned char>
592     { typedef signed char __type; };
594   template<>
595     struct __make_signed<unsigned short>
596     { typedef signed short __type; };
598   template<>
599     struct __make_signed<unsigned int>
600     { typedef signed int __type; };
602   template<>
603     struct __make_signed<unsigned long>
604     { typedef signed long __type; };
606   template<>
607     struct __make_signed<unsigned long long>
608     { typedef signed long long __type; };
611   // Select between integral and enum: not possible to be both.
612   template<typename _Tp, 
613            bool _IsInt = is_integral<_Tp>::value,
614            bool _IsEnum = is_enum<_Tp>::value>
615     class __make_signed_selector;
617   template<typename _Tp>
618     class __make_signed_selector<_Tp, true, false>
619     {
620       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
621       typedef typename __signedt::__type __signed_type;
622       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
624     public:
625       typedef typename __cv_signed::__type __type;
626     };
628   template<typename _Tp>
629     class __make_signed_selector<_Tp, false, true>
630     {
631       // With -fshort-enums, an enum may be as small as a char.
632       typedef signed char __smallest;
633       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
634       static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
635       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
636       typedef conditional<__b2, signed int, signed long> __cond2;
637       typedef typename __cond2::type __cond2_type;
638       typedef conditional<__b1, signed short, __cond2_type> __cond1;
639       typedef typename __cond1::type __cond1_type;
641     public:
642       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
643     };
645   // Given an integral/enum type, return the corresponding signed
646   // integer type.
647   // Primary template.
648   /// make_signed
649   template<typename _Tp>
650     struct make_signed 
651     { typedef typename __make_signed_selector<_Tp>::__type type; };
653   // Integral, but don't define.
654   template<>
655     struct make_signed<bool>;
657   /// common_type
658   template<typename... _Tp>
659     struct common_type;
661   template<typename _Tp>
662     struct common_type<_Tp>
663     { typedef _Tp type; };
665   template<typename _Tp, typename _Up>
666     struct common_type<_Tp, _Up>
667     { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
669   template<typename _Tp, typename _Up, typename... _Vp>
670     struct common_type<_Tp, _Up, _Vp...>
671     {
672       typedef typename
673         common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
674     };
676   /// declval
677   template<typename _Tp>
678     struct __declval_protector
679     {
680       static const bool __stop = false;
681       static typename add_rvalue_reference<_Tp>::type __delegate();
682     };
684   template<typename _Tp>
685     inline typename add_rvalue_reference<_Tp>::type
686     declval() noexcept
687     {
688       static_assert(__declval_protector<_Tp>::__stop,
689                     "declval() must not be used!");
690       return __declval_protector<_Tp>::__delegate();
691     }
693   /// result_of
694   template<typename _Signature>
695     class result_of;
697   template<typename _Functor, typename... _ArgTypes>
698     struct result_of<_Functor(_ArgTypes...)>
699     {
700       typedef
701         decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
702         type;
703     };
705   /**
706    *  Use SFINAE to determine if the type _Tp has a publicly-accessible
707    *  member type _NTYPE.
708    */
709 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE)                         \
710   template<typename _Tp>                                         \
711     class __has_##_NTYPE##_helper                                \
712     : __sfinae_types                                             \
713     {                                                            \
714       template<typename _Up>                                     \
715         struct _Wrap_type                                        \
716         { };                                                     \
717                                                                  \
718       template<typename _Up>                                     \
719         static __one __test(_Wrap_type<typename _Up::_NTYPE>*);  \
720                                                                  \
721       template<typename _Up>                                     \
722         static __two __test(...);                                \
723                                                                  \
724     public:                                                      \
725       static const bool value = sizeof(__test<_Tp>(0)) == 1;     \
726     };                                                           \
727                                                                  \
728   template<typename _Tp>                                         \
729     struct __has_##_NTYPE                                        \
730     : integral_constant<bool, __has_##_NTYPE##_helper            \
731                         <typename remove_cv<_Tp>::type>::value>  \
732     { };
734   // @} group metaprogramming
737 #endif  // __GXX_EXPERIMENTAL_CXX0X__
739 #endif  // _GLIBCXX_TYPE_TRAITS