OSDN Git Service

2007-10-09 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / tr1 / type_traits
1 // TR1 type_traits -*- C++ -*-
2
3 // Copyright (C) 2004, 2005, 2006, 2007 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 2, 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 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 /** @file tr1/type_traits
31  *  This is a TR1 C++ Library header. 
32  */
33
34 #ifndef _GLIBCXX_TR1_TYPE_TRAITS
35 #define _GLIBCXX_TR1_TYPE_TRAITS 1
36
37 #pragma GCC system_header
38
39 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
40 #  error TR1 header cannot be included from C++0x header
41 #endif
42
43 #include <cstddef>
44
45 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
46 #  include <tr1_impl/type_traits>
47 #else
48 #  define _GLIBCXX_INCLUDE_AS_TR1
49 #  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
50 #  define _GLIBCXX_END_NAMESPACE_TR1 }
51 #  define _GLIBCXX_TR1 tr1::
52 #  include <tr1_impl/type_traits>
53 #  undef _GLIBCXX_TR1
54 #  undef _GLIBCXX_END_NAMESPACE_TR1
55 #  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
56 #  undef _GLIBCXX_INCLUDE_AS_TR1
57 #endif
58
59 namespace std
60 {
61 namespace tr1
62 {
63 #define _DEFINE_SPEC_BODY(_Value)                                    \
64     : public integral_constant<bool, _Value> { };
65
66 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value)                         \
67   template<>                                                         \
68     struct _Spec                                                     \
69     _DEFINE_SPEC_BODY(_Value)
70
71 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)                  \
72   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value)              \
73   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value)        \
74   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value)     \
75   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value)
76
77   template<typename>
78     struct is_reference
79     : public false_type { };
80
81   template<typename _Tp>
82     struct is_reference<_Tp&>
83     : public true_type { };
84
85   template<typename _Tp>
86     struct is_pod
87     : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value>
88     { };
89
90   template<typename _Tp>
91     struct has_trivial_constructor
92     : public integral_constant<bool, is_pod<_Tp>::value>
93     { };
94
95   template<typename _Tp>
96     struct has_trivial_copy
97     : public integral_constant<bool, is_pod<_Tp>::value>
98     { };
99
100   template<typename _Tp>
101     struct has_trivial_assign
102     : public integral_constant<bool, is_pod<_Tp>::value>
103     { };
104
105   template<typename _Tp>
106     struct has_trivial_destructor
107     : public integral_constant<bool, is_pod<_Tp>::value>
108     { };
109
110   template<typename _Tp>
111     struct has_nothrow_constructor
112     : public integral_constant<bool, is_pod<_Tp>::value>
113     { };
114
115   template<typename _Tp>
116     struct has_nothrow_copy
117     : public integral_constant<bool, is_pod<_Tp>::value>
118     { };
119
120   template<typename _Tp>
121     struct has_nothrow_assign
122     : public integral_constant<bool, is_pod<_Tp>::value>
123     { };
124
125   template<typename>
126     struct is_signed
127     : public false_type { };
128   _DEFINE_SPEC(0, is_signed, signed char, true)
129   _DEFINE_SPEC(0, is_signed, short, true)
130   _DEFINE_SPEC(0, is_signed, int, true)
131   _DEFINE_SPEC(0, is_signed, long, true)
132   _DEFINE_SPEC(0, is_signed, long long, true)
133
134   template<typename>
135     struct is_unsigned
136     : public false_type { };
137   _DEFINE_SPEC(0, is_unsigned, unsigned char, true)
138   _DEFINE_SPEC(0, is_unsigned, unsigned short, true)
139   _DEFINE_SPEC(0, is_unsigned, unsigned int, true)
140   _DEFINE_SPEC(0, is_unsigned, unsigned long, true)
141   _DEFINE_SPEC(0, is_unsigned, unsigned long long, true)
142
143   template<typename _Base, typename _Derived>
144     struct __is_base_of_helper
145     {
146       typedef typename remove_cv<_Base>::type    _NoCv_Base;
147       typedef typename remove_cv<_Derived>::type _NoCv_Derived;
148       static const bool __value = (is_same<_Base, _Derived>::value
149                                    || (__is_base_of(_Base, _Derived)
150                                        && !is_same<_NoCv_Base,
151                                                    _NoCv_Derived>::value));
152     };
153  
154   template<typename _Base, typename _Derived>
155     struct is_base_of
156     : public integral_constant<bool,
157                                __is_base_of_helper<_Base, _Derived>::__value>
158     { };
159
160   template<typename _From, typename _To>
161     struct __is_convertible_simple
162     : public __sfinae_types
163     {
164     private:
165       static __one __test(_To);
166       static __two __test(...);
167       static _From __makeFrom();
168     
169     public:
170       static const bool __value = sizeof(__test(__makeFrom())) == 1;
171     };
172
173   template<typename _Tp>
174     struct add_reference;
175
176   template<typename _Tp>
177     struct __is_int_or_cref
178     {
179       typedef typename remove_reference<_Tp>::type __rr_Tp;
180       static const bool __value = (is_integral<_Tp>::value
181                                    || (is_integral<__rr_Tp>::value
182                                        && is_const<__rr_Tp>::value
183                                        && !is_volatile<__rr_Tp>::value));
184     };
185
186   template<typename _From, typename _To,
187            bool = (is_void<_From>::value || is_void<_To>::value
188                    || is_function<_To>::value || is_array<_To>::value
189                    // This special case is here only to avoid warnings.            
190                    || (is_floating_point<typename
191                        remove_reference<_From>::type>::value
192                        && __is_int_or_cref<_To>::__value))>
193     struct __is_convertible_helper
194     {
195       // "An imaginary lvalue of type From...".
196       static const bool __value = (__is_convertible_simple<typename
197                                    add_reference<_From>::type, _To>::__value);
198     };
199
200   template<typename _From, typename _To>
201     struct __is_convertible_helper<_From, _To, true>
202     { static const bool __value = (is_void<_To>::value
203                                    || (__is_int_or_cref<_To>::__value
204                                        && !is_void<_From>::value)); };
205
206   template<typename _From, typename _To>
207     struct is_convertible
208     : public integral_constant<bool,
209                                __is_convertible_helper<_From, _To>::__value>
210     { };
211
212   /// @brief  reference modifications [4.7.2].
213   template<typename _Tp>
214     struct remove_reference
215     { typedef _Tp     type; };
216
217   template<typename _Tp>
218     struct remove_reference<_Tp&>
219     { typedef _Tp     type; };
220
221   // NB: Careful with reference to void.
222   template<typename _Tp, bool = (is_void<_Tp>::value
223                                  || is_reference<_Tp>::value)>
224     struct __add_reference_helper
225     { typedef _Tp&    type; };
226
227   template<typename _Tp>
228     struct __add_reference_helper<_Tp, true>
229     { typedef _Tp     type; };
230
231   template<typename _Tp>
232     struct add_reference
233     : public __add_reference_helper<_Tp>
234     { };
235
236   /// @brief  other transformations [4.8].
237   template<std::size_t _Len, std::size_t _Align>
238     struct aligned_storage
239     { 
240       union type
241       {
242         unsigned char __data[_Len];
243         struct __attribute__((__aligned__((_Align)))) { } __align; 
244       };
245     };
246
247 #undef _DEFINE_SPEC_0_HELPER
248 #undef _DEFINE_SPEC
249 #undef _DEFINE_SPEC_BODY
250 }
251 }
252
253 #endif // _GLIBCXX_TR1_TYPE_TRAITS