Merge -r 127928:132243 from trunk
[official-gcc.git] / libstdc++-v3 / include / tr1_impl / type_traits
blob2a6227b7c9765c69dc9178e3c807c9d11c172218
1 // TR1 type_traits -*- C++ -*-
3 // Copyright (C) 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.
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 // 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.
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.
30 /** @file tr1_impl/type_traits
31 *  This is an internal header file, included by other library headers.
32 *  You should not attempt to use it directly.
35 namespace std
37 _GLIBCXX_BEGIN_NAMESPACE_TR1
39   // For use in __is_convertible_simple.
40   struct __sfinae_types
41   {
42     typedef char __one;
43     typedef struct { char __arr[2]; } __two;
44   };
46 #define _DEFINE_SPEC_BODY(_Value)                                    \
47     : public integral_constant<bool, _Value> { };
49 #define _DEFINE_SPEC_0_HELPER(_Spec, _Value)                         \
50   template<>                                                         \
51     struct _Spec                                                     \
52     _DEFINE_SPEC_BODY(_Value)
54 #define _DEFINE_SPEC_1_HELPER(_Spec, _Value)                         \
55   template<typename _Tp>                                             \
56     struct _Spec                                                     \
57     _DEFINE_SPEC_BODY(_Value)
58       
59 #define _DEFINE_SPEC_2_HELPER(_Spec, _Value)                         \
60   template<typename _Tp, typename _Cp>                               \
61     struct _Spec                                                     \
62     _DEFINE_SPEC_BODY(_Value)
64 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)                  \
65   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type>, _Value)              \
66   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const>, _Value)        \
67   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type volatile>, _Value)     \
68   _DEFINE_SPEC_##_Order##_HELPER(_Trait<_Type const volatile>, _Value)
70   /// @brief  helper classes [4.3].
71   template<typename _Tp, _Tp __v>
72     struct integral_constant
73     {
74       static const _Tp                      value = __v;
75       typedef _Tp                           value_type;
76       typedef integral_constant<_Tp, __v>   type;
77     };
78   typedef integral_constant<bool, true>     true_type;
79   typedef integral_constant<bool, false>    false_type;
81   template<typename _Tp, _Tp __v>
82     const _Tp integral_constant<_Tp, __v>::value;
84   /// @brief  primary type categories [4.5.1].
85   template<typename>
86     struct is_void
87     : public false_type { };
88   _DEFINE_SPEC(0, is_void, void, true)
90   template<typename>
91     struct is_integral
92     : public false_type { };
93   _DEFINE_SPEC(0, is_integral, bool, true)
94   _DEFINE_SPEC(0, is_integral, char, true)
95   _DEFINE_SPEC(0, is_integral, signed char, true)
96   _DEFINE_SPEC(0, is_integral, unsigned char, true)
97 #ifdef _GLIBCXX_USE_WCHAR_T
98   _DEFINE_SPEC(0, is_integral, wchar_t, true)
99 #endif
100   _DEFINE_SPEC(0, is_integral, short, true)
101   _DEFINE_SPEC(0, is_integral, unsigned short, true)
102   _DEFINE_SPEC(0, is_integral, int, true)
103   _DEFINE_SPEC(0, is_integral, unsigned int, true)
104   _DEFINE_SPEC(0, is_integral, long, true)
105   _DEFINE_SPEC(0, is_integral, unsigned long, true)
106   _DEFINE_SPEC(0, is_integral, long long, true)
107   _DEFINE_SPEC(0, is_integral, unsigned long long, true)
109   template<typename>
110     struct is_floating_point
111     : public false_type { };
112   _DEFINE_SPEC(0, is_floating_point, float, true)
113   _DEFINE_SPEC(0, is_floating_point, double, true)
114   _DEFINE_SPEC(0, is_floating_point, long double, true)
116   template<typename>
117     struct is_array
118     : public false_type { };
120   template<typename _Tp, std::size_t _Size>
121     struct is_array<_Tp[_Size]>
122     : public true_type { };
124   template<typename _Tp>
125     struct is_array<_Tp[]>
126     : public true_type { };
128   template<typename>
129     struct is_pointer
130     : public false_type { };
131   _DEFINE_SPEC(1, is_pointer, _Tp*, true)
133   template<typename _Tp>
134     struct is_reference;
136   template<typename _Tp>
137     struct is_function;
139   template<typename>
140     struct is_member_object_pointer
141     : public false_type { };
142   _DEFINE_SPEC(2, is_member_object_pointer, _Tp _Cp::*,
143                !is_function<_Tp>::value)
145   template<typename>
146     struct is_member_function_pointer
147     : public false_type { };
148   _DEFINE_SPEC(2, is_member_function_pointer, _Tp _Cp::*,
149                is_function<_Tp>::value)
151   template<typename _Tp>
152     struct is_enum
153     : public integral_constant<bool, __is_enum(_Tp)>
154     { };
156   template<typename _Tp>
157     struct is_union
158     : public integral_constant<bool, __is_union(_Tp)>
159     { };
161   template<typename _Tp>
162     struct is_class
163     : public integral_constant<bool, __is_class(_Tp)>
164     { };
166   template<typename>
167     struct __is_function_helper
168     : public false_type { };
170   template<typename _Res, typename... _ArgTypes>
171     struct __is_function_helper<_Res(_ArgTypes...)>
172     : public true_type { };
174   template<typename _Res, typename... _ArgTypes>
175     struct __is_function_helper<_Res(_ArgTypes......)>
176     : public true_type { };
178   template<typename _Tp>
179     struct remove_cv;
181   template<typename _Tp>
182     struct is_function
183     : public integral_constant<bool, (__is_function_helper<typename
184                                       remove_cv<_Tp>::type>::value)>
185     { };
187   /// @brief  composite type traits [4.5.2].
188   template<typename _Tp>
189     struct is_arithmetic
190     : public integral_constant<bool, (is_integral<_Tp>::value
191                                       || is_floating_point<_Tp>::value)>
192     { };
194   template<typename _Tp>
195     struct is_fundamental
196     : public integral_constant<bool, (is_arithmetic<_Tp>::value
197                                       || is_void<_Tp>::value)>
198     { };
200   template<typename _Tp>
201     struct is_object
202     : public integral_constant<bool, !(is_function<_Tp>::value
203                                        || is_reference<_Tp>::value
204                                        || is_void<_Tp>::value)>
205     { };
207   template<typename _Tp>
208     struct is_member_pointer;
210   template<typename _Tp>
211     struct is_scalar
212     : public integral_constant<bool, (is_arithmetic<_Tp>::value
213                                       || is_enum<_Tp>::value
214                                       || is_pointer<_Tp>::value
215                                       || is_member_pointer<_Tp>::value)>
216     { };
218   template<typename _Tp>
219     struct is_compound
220     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
222   template<typename _Tp>
223     struct is_member_pointer
224     : public integral_constant<bool,
225                                (is_member_object_pointer<_Tp>::value
226                                 || is_member_function_pointer<_Tp>::value)>
227     { };
229   /// @brief  type properties [4.5.3].
230   template<typename>
231     struct is_const
232     : public false_type { };
234   template<typename _Tp>
235     struct is_const<_Tp const>
236     : public true_type { };
237   
238   template<typename>
239     struct is_volatile
240     : public false_type { };
242   template<typename _Tp>
243     struct is_volatile<_Tp volatile>
244     : public true_type { };
246   template<typename _Tp>
247     struct is_empty
248     : public integral_constant<bool, __is_empty(_Tp)>
249     { };
251   template<typename _Tp>
252     struct is_polymorphic
253     : public integral_constant<bool, __is_polymorphic(_Tp)>
254     { };
256   template<typename _Tp>
257     struct is_abstract
258     : public integral_constant<bool, __is_abstract(_Tp)>
259     { };
261   template<typename _Tp>
262     struct has_virtual_destructor
263     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
264     { };
266   template<typename _Tp>
267     struct alignment_of
268     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
269   
270   template<typename>
271     struct rank
272     : public integral_constant<std::size_t, 0> { };
273    
274   template<typename _Tp, std::size_t _Size>
275     struct rank<_Tp[_Size]>
276     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
278   template<typename _Tp>
279     struct rank<_Tp[]>
280     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
282   template<typename, unsigned _Uint = 0>
283     struct extent
284     : public integral_constant<std::size_t, 0> { };
285   
286   template<typename _Tp, unsigned _Uint, std::size_t _Size>
287     struct extent<_Tp[_Size], _Uint>
288     : public integral_constant<std::size_t,
289                                _Uint == 0 ? _Size : extent<_Tp,
290                                                            _Uint - 1>::value>
291     { };
293   template<typename _Tp, unsigned _Uint>
294     struct extent<_Tp[], _Uint>
295     : public integral_constant<std::size_t,
296                                _Uint == 0 ? 0 : extent<_Tp,
297                                                        _Uint - 1>::value>
298     { };
300   /// @brief  relationships between types [4.6].
301   template<typename, typename>
302     struct is_same
303     : public false_type { };
305   template<typename _Tp>
306     struct is_same<_Tp, _Tp>
307     : public true_type { };
309   /// @brief  const-volatile modifications [4.7.1].
310   template<typename _Tp>
311     struct remove_const
312     { typedef _Tp     type; };
314   template<typename _Tp>
315     struct remove_const<_Tp const>
316     { typedef _Tp     type; };
317   
318   template<typename _Tp>
319     struct remove_volatile
320     { typedef _Tp     type; };
322   template<typename _Tp>
323     struct remove_volatile<_Tp volatile>
324     { typedef _Tp     type; };
325   
326   template<typename _Tp>
327     struct remove_cv
328     {
329       typedef typename
330       remove_const<typename remove_volatile<_Tp>::type>::type     type;
331     };
332   
333   template<typename _Tp>
334     struct add_const
335     { typedef _Tp const     type; };
336    
337   template<typename _Tp>
338     struct add_volatile
339     { typedef _Tp volatile     type; };
340   
341   template<typename _Tp>
342     struct add_cv
343     {
344       typedef typename
345       add_const<typename add_volatile<_Tp>::type>::type     type;
346     };
348   /// @brief  array modifications [4.7.3].
349   template<typename _Tp>
350     struct remove_extent
351     { typedef _Tp     type; };
353   template<typename _Tp, std::size_t _Size>
354     struct remove_extent<_Tp[_Size]>
355     { typedef _Tp     type; };
357   template<typename _Tp>
358     struct remove_extent<_Tp[]>
359     { typedef _Tp     type; };
361   template<typename _Tp>
362     struct remove_all_extents
363     { typedef _Tp     type; };
365   template<typename _Tp, std::size_t _Size>
366     struct remove_all_extents<_Tp[_Size]>
367     { typedef typename remove_all_extents<_Tp>::type     type; };
369   template<typename _Tp>
370     struct remove_all_extents<_Tp[]>
371     { typedef typename remove_all_extents<_Tp>::type     type; };
373   /// @brief  pointer modifications [4.7.4].
374 #undef _DEFINE_SPEC_BODY
375 #define _DEFINE_SPEC_BODY(_Value)      \
376     { typedef _Tp     type; };
378   template<typename _Tp>
379     struct remove_pointer
380     { typedef _Tp     type; };
381   _DEFINE_SPEC(1, remove_pointer, _Tp*, false)
383   template<typename _Tp>
384     struct remove_reference;
386   template<typename _Tp>
387     struct add_pointer
388     { typedef typename remove_reference<_Tp>::type*     type; };
390 #undef _DEFINE_SPEC_0_HELPER
391 #undef _DEFINE_SPEC_1_HELPER
392 #undef _DEFINE_SPEC_2_HELPER
393 #undef _DEFINE_SPEC
394 #undef _DEFINE_SPEC_BODY
396 _GLIBCXX_END_NAMESPACE_TR1