Merged trunk at revision 161680 into branch.
[official-gcc.git] / libstdc++-v3 / include / tr1 / type_traits
blob33083ff9c7371ee77db331e74856163e6120167b
1 // TR1 type_traits -*- C++ -*-
3 // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
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.
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.
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.
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/>.
26 /** @file tr1/type_traits
27  *  This is a TR1 C++ Library header. 
28  */
30 #ifndef _GLIBCXX_TR1_TYPE_TRAITS
31 #define _GLIBCXX_TR1_TYPE_TRAITS 1
33 #pragma GCC system_header
35 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
36 #  error TR1 header cannot be included from C++0x header
37 #endif
39 #include <bits/c++config.h>
41 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
42 #  include <tr1_impl/type_traits>
43 #else
44 #  define _GLIBCXX_INCLUDE_AS_TR1
45 #  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
46 #  define _GLIBCXX_END_NAMESPACE_TR1 }
47 #  define _GLIBCXX_TR1 tr1::
48 #  include <tr1_impl/type_traits>
49 #  undef _GLIBCXX_TR1
50 #  undef _GLIBCXX_END_NAMESPACE_TR1
51 #  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
52 #  undef _GLIBCXX_INCLUDE_AS_TR1
53 #endif
55 namespace std
57 namespace tr1
59 #define _DEFINE_SPEC(_Trait, _Type)    \
60   template<>                           \
61     struct _Trait<_Type>               \
62     : public true_type { };
64   template<typename>
65     struct is_reference
66     : public false_type { };
68   template<typename _Tp>
69     struct is_reference<_Tp&>
70     : public true_type { };
72   template<typename _Tp>
73     struct is_pod
74     : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value>
75     { };
77   template<typename _Tp>
78     struct has_trivial_constructor
79     : public integral_constant<bool, is_pod<_Tp>::value>
80     { };
82   template<typename _Tp>
83     struct has_trivial_copy
84     : public integral_constant<bool, is_pod<_Tp>::value>
85     { };
87   template<typename _Tp>
88     struct has_trivial_assign
89     : public integral_constant<bool, is_pod<_Tp>::value>
90     { };
92   template<typename _Tp>
93     struct has_trivial_destructor
94     : public integral_constant<bool, is_pod<_Tp>::value>
95     { };
97   template<typename _Tp>
98     struct has_nothrow_constructor
99     : public integral_constant<bool, is_pod<_Tp>::value>
100     { };
102   template<typename _Tp>
103     struct has_nothrow_copy
104     : public integral_constant<bool, is_pod<_Tp>::value>
105     { };
107   template<typename _Tp>
108     struct has_nothrow_assign
109     : public integral_constant<bool, is_pod<_Tp>::value>
110     { };
112   template<typename>
113     struct __is_signed_helper
114     : public false_type { };
115   _DEFINE_SPEC(__is_signed_helper, signed char)
116   _DEFINE_SPEC(__is_signed_helper, short)
117   _DEFINE_SPEC(__is_signed_helper, int)
118   _DEFINE_SPEC(__is_signed_helper, long)
119   _DEFINE_SPEC(__is_signed_helper, long long)
121   template<typename _Tp>
122     struct is_signed
123     : public integral_constant<bool, (__is_signed_helper<typename
124                                       remove_cv<_Tp>::type>::value)>
125     { };
127   template<typename>
128     struct __is_unsigned_helper
129     : public false_type { };
130   _DEFINE_SPEC(__is_unsigned_helper, unsigned char)
131   _DEFINE_SPEC(__is_unsigned_helper, unsigned short)
132   _DEFINE_SPEC(__is_unsigned_helper, unsigned int)
133   _DEFINE_SPEC(__is_unsigned_helper, unsigned long)
134   _DEFINE_SPEC(__is_unsigned_helper, unsigned long long)
136   template<typename _Tp>
137     struct is_unsigned
138     : public integral_constant<bool, (__is_unsigned_helper<typename
139                                       remove_cv<_Tp>::type>::value)>
140     { };
142   template<typename _Base, typename _Derived>
143     struct __is_base_of_helper
144     {
145       typedef typename remove_cv<_Base>::type    _NoCv_Base;
146       typedef typename remove_cv<_Derived>::type _NoCv_Derived;
147       static const bool __value = (is_same<_Base, _Derived>::value
148                                    || (__is_base_of(_Base, _Derived)
149                                        && !is_same<_NoCv_Base,
150                                                    _NoCv_Derived>::value));
151     };
153   template<typename _Base, typename _Derived>
154     struct is_base_of
155     : public integral_constant<bool,
156                                __is_base_of_helper<_Base, _Derived>::__value>
157     { };
159   template<typename _From, typename _To>
160     struct __is_convertible_simple
161     : public __sfinae_types
162     {
163     private:
164       static __one __test(_To);
165       static __two __test(...);
166       static _From __makeFrom();
167     
168     public:
169       static const bool __value = sizeof(__test(__makeFrom())) == 1;
170     };
172   template<typename _Tp>
173     struct add_reference;
175   template<typename _Tp>
176     struct __is_int_or_cref
177     {
178       typedef typename remove_reference<_Tp>::type __rr_Tp;
179       static const bool __value = (is_integral<_Tp>::value
180                                    || (is_integral<__rr_Tp>::value
181                                        && is_const<__rr_Tp>::value
182                                        && !is_volatile<__rr_Tp>::value));
183     };
185   template<typename _From, typename _To,
186            bool = (is_void<_From>::value || is_void<_To>::value
187                    || is_function<_To>::value || is_array<_To>::value
188                    // This special case is here only to avoid warnings. 
189                    || (is_floating_point<typename
190                        remove_reference<_From>::type>::value
191                        && __is_int_or_cref<_To>::__value))>
192     struct __is_convertible_helper
193     {
194       // "An imaginary lvalue of type From...".
195       static const bool __value = (__is_convertible_simple<typename
196                                    add_reference<_From>::type, _To>::__value);
197     };
199   template<typename _From, typename _To>
200     struct __is_convertible_helper<_From, _To, true>
201     { static const bool __value = (is_void<_To>::value
202                                    || (__is_int_or_cref<_To>::__value
203                                        && !is_void<_From>::value)); };
205   template<typename _From, typename _To>
206     struct is_convertible
207     : public integral_constant<bool,
208                                __is_convertible_helper<_From, _To>::__value>
209     { };
211   // reference modifications [4.7.2].
212   template<typename _Tp>
213     struct remove_reference
214     { typedef _Tp     type; };
216   template<typename _Tp>
217     struct remove_reference<_Tp&>
218     { typedef _Tp     type; };
220   // NB: Careful with reference to void.
221   template<typename _Tp, bool = (is_void<_Tp>::value
222                                  || is_reference<_Tp>::value)>
223     struct __add_reference_helper
224     { typedef _Tp&    type; };
226   template<typename _Tp>
227     struct __add_reference_helper<_Tp, true>
228     { typedef _Tp     type; };
230   template<typename _Tp>
231     struct add_reference
232     : public __add_reference_helper<_Tp>
233     { };
235   // other transformations [4.8].
236   template<std::size_t _Len, std::size_t _Align>
237     struct aligned_storage
238     { 
239       union type
240       {
241         unsigned char __data[_Len];
242         struct __attribute__((__aligned__((_Align)))) { } __align; 
243       };
244     };
246 #undef _DEFINE_SPEC
250 #endif // _GLIBCXX_TR1_TYPE_TRAITS