Merged revisions 143552,143554,143557,143560,143562,143564-143567,143570-143573,14357...
[official-gcc.git] / libstdc++-v3 / include / tr1_impl / type_traits
blobcb0ad44a5ff82ef5553e22d390ca4dc5f4ca8116
1 // TR1 type_traits -*- C++ -*-
3 // Copyright (C) 2007, 2008, 2009 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   /**
40    * @defgroup metaprogramming Type Traits
41    * @ingroup utilities
42    *
43    * Compile time type transformation and information.
44    * @{
45    */
47   // For use in __is_convertible_simple.
48   struct __sfinae_types
49   {
50     typedef char __one;
51     typedef struct { char __arr[2]; } __two;
52   };
54 #define _DEFINE_SPEC_0_HELPER                          \
55   template<>
57 #define _DEFINE_SPEC_1_HELPER                          \
58   template<typename _Tp>
60 #define _DEFINE_SPEC_2_HELPER                          \
61   template<typename _Tp, typename _Cp>
63 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)    \
64   _DEFINE_SPEC_##_Order##_HELPER                       \
65     struct _Trait<_Type>                               \
66     : public integral_constant<bool, _Value> { };
68   // helper classes [4.3].
70   /// integral_constant
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   
79   /// typedef for true_type
80   typedef integral_constant<bool, true>     true_type;
82   /// typedef for false_type
83   typedef integral_constant<bool, false>    false_type;
85   template<typename _Tp, _Tp __v>
86     const _Tp integral_constant<_Tp, __v>::value;
88   /// remove_cv
89   template<typename>
90     struct remove_cv;
92   template<typename>
93     struct __is_void_helper
94     : public false_type { };
95   _DEFINE_SPEC(0, __is_void_helper, void, true)
97   // primary type categories [4.5.1].
99   /// is_void
100   template<typename _Tp>
101     struct is_void
102     : public integral_constant<bool, (__is_void_helper<typename
103                                       remove_cv<_Tp>::type>::value)>
104     { };
106   template<typename>
107     struct __is_integral_helper
108     : public false_type { };
109   _DEFINE_SPEC(0, __is_integral_helper, bool, true)
110   _DEFINE_SPEC(0, __is_integral_helper, char, true)
111   _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
112   _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
113 #ifdef _GLIBCXX_USE_WCHAR_T
114   _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
115 #endif
116 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
117   _DEFINE_SPEC(0, __is_integral_helper, char16_t, true)
118   _DEFINE_SPEC(0, __is_integral_helper, char32_t, true)
119 #endif
120   _DEFINE_SPEC(0, __is_integral_helper, short, true)
121   _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true)
122   _DEFINE_SPEC(0, __is_integral_helper, int, true)
123   _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true)
124   _DEFINE_SPEC(0, __is_integral_helper, long, true)
125   _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true)
126   _DEFINE_SPEC(0, __is_integral_helper, long long, true)
127   _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true)
129   /// is_integral
130   template<typename _Tp>
131     struct is_integral
132     : public integral_constant<bool, (__is_integral_helper<typename
133                                       remove_cv<_Tp>::type>::value)>
134     { };
136   template<typename>
137     struct __is_floating_point_helper
138     : public false_type { };
139   _DEFINE_SPEC(0, __is_floating_point_helper, float, true)
140   _DEFINE_SPEC(0, __is_floating_point_helper, double, true)
141   _DEFINE_SPEC(0, __is_floating_point_helper, long double, true)
143   /// is_floating_point
144   template<typename _Tp>
145     struct is_floating_point
146     : public integral_constant<bool, (__is_floating_point_helper<typename
147                                       remove_cv<_Tp>::type>::value)>
148     { };
150   /// is_array
151   template<typename>
152     struct is_array
153     : public false_type { };
155   template<typename _Tp, std::size_t _Size>
156     struct is_array<_Tp[_Size]>
157     : public true_type { };
159   template<typename _Tp>
160     struct is_array<_Tp[]>
161     : public true_type { };
163   template<typename>
164     struct __is_pointer_helper
165     : public false_type { };
166   _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true)
168   /// is_pointer
169   template<typename _Tp>
170     struct is_pointer
171     : public integral_constant<bool, (__is_pointer_helper<typename
172                                       remove_cv<_Tp>::type>::value)>
173     { };
175   /// is_reference
176   template<typename _Tp>
177     struct is_reference;
179   /// is_function
180   template<typename _Tp>
181     struct is_function;
183   template<typename>
184     struct __is_member_object_pointer_helper
185     : public false_type { };
186   _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*,
187                !is_function<_Tp>::value)
189   /// is_member_object_pointer
190   template<typename _Tp>
191     struct is_member_object_pointer
192     : public integral_constant<bool, (__is_member_object_pointer_helper<
193                                       typename remove_cv<_Tp>::type>::value)>
194     { };
196   template<typename>
197     struct __is_member_function_pointer_helper
198     : public false_type { };
199   _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*,
200                is_function<_Tp>::value)
202   /// is_member_function_pointer
203   template<typename _Tp>
204     struct is_member_function_pointer
205     : public integral_constant<bool, (__is_member_function_pointer_helper<
206                                       typename remove_cv<_Tp>::type>::value)>
207     { };
209   /// is_enum
210   template<typename _Tp>
211     struct is_enum
212     : public integral_constant<bool, __is_enum(_Tp)>
213     { };
215   /// is_union
216   template<typename _Tp>
217     struct is_union
218     : public integral_constant<bool, __is_union(_Tp)>
219     { };
221   /// is_class
222   template<typename _Tp>
223     struct is_class
224     : public integral_constant<bool, __is_class(_Tp)>
225     { };
227   template<typename>
228     struct __is_function_helper
229     : public false_type { };
231   template<typename _Res, typename... _ArgTypes>
232     struct __is_function_helper<_Res(_ArgTypes...)>
233     : public true_type { };
235   template<typename _Res, typename... _ArgTypes>
236     struct __is_function_helper<_Res(_ArgTypes......)>
237     : public true_type { };
239   /// is_function
240   template<typename _Tp>
241     struct is_function
242     : public integral_constant<bool, (__is_function_helper<typename
243                                       remove_cv<_Tp>::type>::value)>
244     { };
246   // composite type traits [4.5.2].
247   
248   /// is_arithmetic
249   template<typename _Tp>
250     struct is_arithmetic
251     : public integral_constant<bool, (is_integral<_Tp>::value
252                                       || is_floating_point<_Tp>::value)>
253     { };
255   /// is_fundamental
256   template<typename _Tp>
257     struct is_fundamental
258     : public integral_constant<bool, (is_arithmetic<_Tp>::value
259                                       || is_void<_Tp>::value)>
260     { };
262   /// is_object
263   template<typename _Tp>
264     struct is_object
265     : public integral_constant<bool, !(is_function<_Tp>::value
266                                        || is_reference<_Tp>::value
267                                        || is_void<_Tp>::value)>
268     { };
270   /// is_member_pointer
271   template<typename _Tp>
272     struct is_member_pointer;
274   /// is_scalar
275   template<typename _Tp>
276     struct is_scalar
277     : public integral_constant<bool, (is_arithmetic<_Tp>::value
278                                       || is_enum<_Tp>::value
279                                       || is_pointer<_Tp>::value
280                                       || is_member_pointer<_Tp>::value)>
281     { };
283   /// is_compound
284   template<typename _Tp>
285     struct is_compound
286     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
288   /// is_member_pointer
289   template<typename _Tp>
290     struct is_member_pointer
291     : public integral_constant<bool,
292                                (is_member_object_pointer<_Tp>::value
293                                 || is_member_function_pointer<_Tp>::value)>
294     { };
296   // type properties [4.5.3].
297   /// is_const
298   template<typename>
299     struct is_const
300     : public false_type { };
302   template<typename _Tp>
303     struct is_const<_Tp const>
304     : public true_type { };
305   
306   /// is_volatile
307   template<typename>
308     struct is_volatile
309     : public false_type { };
311   template<typename _Tp>
312     struct is_volatile<_Tp volatile>
313     : public true_type { };
315   /// is_empty
316   template<typename _Tp>
317     struct is_empty
318     : public integral_constant<bool, __is_empty(_Tp)>
319     { };
321   /// is_polymorphic
322   template<typename _Tp>
323     struct is_polymorphic
324     : public integral_constant<bool, __is_polymorphic(_Tp)>
325     { };
327   /// is_abstract
328   template<typename _Tp>
329     struct is_abstract
330     : public integral_constant<bool, __is_abstract(_Tp)>
331     { };
333   /// has_virtual_destructor
334   template<typename _Tp>
335     struct has_virtual_destructor
336     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
337     { };
339   /// alignment_of
340   template<typename _Tp>
341     struct alignment_of
342     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
343   
344   /// rank
345   template<typename>
346     struct rank
347     : public integral_constant<std::size_t, 0> { };
348    
349   template<typename _Tp, std::size_t _Size>
350     struct rank<_Tp[_Size]>
351     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
353   template<typename _Tp>
354     struct rank<_Tp[]>
355     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
357   /// extent
358   template<typename, unsigned _Uint = 0>
359     struct extent
360     : public integral_constant<std::size_t, 0> { };
361   
362   template<typename _Tp, unsigned _Uint, std::size_t _Size>
363     struct extent<_Tp[_Size], _Uint>
364     : public integral_constant<std::size_t,
365                                _Uint == 0 ? _Size : extent<_Tp,
366                                                            _Uint - 1>::value>
367     { };
369   template<typename _Tp, unsigned _Uint>
370     struct extent<_Tp[], _Uint>
371     : public integral_constant<std::size_t,
372                                _Uint == 0 ? 0 : extent<_Tp,
373                                                        _Uint - 1>::value>
374     { };
376   // relationships between types [4.6].
378   /// is_same
379   template<typename, typename>
380     struct is_same
381     : public false_type { };
383   template<typename _Tp>
384     struct is_same<_Tp, _Tp>
385     : public true_type { };
387   // const-volatile modifications [4.7.1].
389   /// remove_const
390   template<typename _Tp>
391     struct remove_const
392     { typedef _Tp     type; };
394   template<typename _Tp>
395     struct remove_const<_Tp const>
396     { typedef _Tp     type; };
397   
398   /// remove_volatile
399   template<typename _Tp>
400     struct remove_volatile
401     { typedef _Tp     type; };
403   template<typename _Tp>
404     struct remove_volatile<_Tp volatile>
405     { typedef _Tp     type; };
406   
407   /// remove_cv
408   template<typename _Tp>
409     struct remove_cv
410     {
411       typedef typename
412       remove_const<typename remove_volatile<_Tp>::type>::type     type;
413     };
414   
415   /// add_const
416   template<typename _Tp>
417     struct add_const
418     { typedef _Tp const     type; };
419    
420   /// add_volatile
421   template<typename _Tp>
422     struct add_volatile
423     { typedef _Tp volatile     type; };
424   
425   /// add_cv
426   template<typename _Tp>
427     struct add_cv
428     {
429       typedef typename
430       add_const<typename add_volatile<_Tp>::type>::type     type;
431     };
433   // array modifications [4.7.3].
435   /// remove_extent
436   template<typename _Tp>
437     struct remove_extent
438     { typedef _Tp     type; };
440   template<typename _Tp, std::size_t _Size>
441     struct remove_extent<_Tp[_Size]>
442     { typedef _Tp     type; };
444   template<typename _Tp>
445     struct remove_extent<_Tp[]>
446     { typedef _Tp     type; };
448   /// remove_all_extents
449   template<typename _Tp>
450     struct remove_all_extents
451     { typedef _Tp     type; };
453   template<typename _Tp, std::size_t _Size>
454     struct remove_all_extents<_Tp[_Size]>
455     { typedef typename remove_all_extents<_Tp>::type     type; };
457   template<typename _Tp>
458     struct remove_all_extents<_Tp[]>
459     { typedef typename remove_all_extents<_Tp>::type     type; };
461   // pointer modifications [4.7.4].
463   template<typename _Tp, typename>
464     struct __remove_pointer_helper
465     { typedef _Tp     type; };
467   template<typename _Tp, typename _Up>
468     struct __remove_pointer_helper<_Tp, _Up*>
469     { typedef _Up     type; };
471   /// remove_pointer
472   template<typename _Tp>
473     struct remove_pointer
474     : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
475     { };
477   template<typename>
478     struct remove_reference;
480   /// add_pointer
481   template<typename _Tp>
482     struct add_pointer
483     { typedef typename remove_reference<_Tp>::type*     type; };
485 #undef _DEFINE_SPEC_0_HELPER
486 #undef _DEFINE_SPEC_1_HELPER
487 #undef _DEFINE_SPEC_2_HELPER
488 #undef _DEFINE_SPEC
490   // @} group metaprogramming
491 _GLIBCXX_END_NAMESPACE_TR1