libstdc++
tr1_impl/type_traits
Go to the documentation of this file.
1 // TR1 type_traits -*- C++ -*-
2 
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 3, 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 // 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.
19 
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/>.
24 
25 /** @file tr1_impl/type_traits
26 * This is an internal header file, included by other library headers.
27 * You should not attempt to use it directly.
28 */
29 
30 namespace std
31 {
32 _GLIBCXX_BEGIN_NAMESPACE_TR1
33 
34  /**
35  * @defgroup metaprogramming Type Traits
36  * @ingroup utilities
37  *
38  * Compile time type transformation and information.
39  * @{
40  */
41 
42  // For use in __is_convertible_simple.
43  struct __sfinae_types
44  {
45  typedef char __one;
46  typedef struct { char __arr[2]; } __two;
47  };
48 
49 #define _DEFINE_SPEC_0_HELPER \
50  template<>
51 
52 #define _DEFINE_SPEC_1_HELPER \
53  template<typename _Tp>
54 
55 #define _DEFINE_SPEC_2_HELPER \
56  template<typename _Tp, typename _Cp>
57 
58 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \
59  _DEFINE_SPEC_##_Order##_HELPER \
60  struct _Trait<_Type> \
61  : public integral_constant<bool, _Value> { };
62 
63  // helper classes [4.3].
64 
65  /// integral_constant
66  template<typename _Tp, _Tp __v>
68  {
69  static const _Tp value = __v;
70  typedef _Tp value_type;
72  };
73 
74  /// typedef for true_type
76 
77  /// typedef for false_type
79 
80  template<typename _Tp, _Tp __v>
82 
83  /// remove_cv
84  template<typename>
85  struct remove_cv;
86 
87  template<typename>
88  struct __is_void_helper
89  : public false_type { };
90  _DEFINE_SPEC(0, __is_void_helper, void, true)
91 
92  // primary type categories [4.5.1].
93 
94  /// is_void
95  template<typename _Tp>
96  struct is_void
97  : public integral_constant<bool, (__is_void_helper<typename
98  remove_cv<_Tp>::type>::value)>
99  { };
100 
101  template<typename>
102  struct __is_integral_helper
103  : public false_type { };
104  _DEFINE_SPEC(0, __is_integral_helper, bool, true)
105  _DEFINE_SPEC(0, __is_integral_helper, char, true)
106  _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
107  _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
108 #ifdef _GLIBCXX_USE_WCHAR_T
109  _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
110 #endif
111 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
112  _DEFINE_SPEC(0, __is_integral_helper, char16_t, true)
113  _DEFINE_SPEC(0, __is_integral_helper, char32_t, true)
114 #endif
115  _DEFINE_SPEC(0, __is_integral_helper, short, true)
116  _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true)
117  _DEFINE_SPEC(0, __is_integral_helper, int, true)
118  _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true)
119  _DEFINE_SPEC(0, __is_integral_helper, long, true)
120  _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true)
121  _DEFINE_SPEC(0, __is_integral_helper, long long, true)
122  _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true)
123 
124  /// is_integral
125  template<typename _Tp>
126  struct is_integral
127  : public integral_constant<bool, (__is_integral_helper<typename
128  remove_cv<_Tp>::type>::value)>
129  { };
130 
131  template<typename>
132  struct __is_floating_point_helper
133  : public false_type { };
134  _DEFINE_SPEC(0, __is_floating_point_helper, float, true)
135  _DEFINE_SPEC(0, __is_floating_point_helper, double, true)
136  _DEFINE_SPEC(0, __is_floating_point_helper, long double, true)
137 
138  /// is_floating_point
139  template<typename _Tp>
141  : public integral_constant<bool, (__is_floating_point_helper<typename
142  remove_cv<_Tp>::type>::value)>
143  { };
144 
145  /// is_array
146  template<typename>
147  struct is_array
148  : public false_type { };
149 
150  template<typename _Tp, std::size_t _Size>
151  struct is_array<_Tp[_Size]>
152  : public true_type { };
153 
154  template<typename _Tp>
155  struct is_array<_Tp[]>
156  : public true_type { };
157 
158  template<typename>
159  struct __is_pointer_helper
160  : public false_type { };
161  _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true)
162 
163  /// is_pointer
164  template<typename _Tp>
165  struct is_pointer
166  : public integral_constant<bool, (__is_pointer_helper<typename
167  remove_cv<_Tp>::type>::value)>
168  { };
169 
170  /// is_reference
171  template<typename _Tp>
172  struct is_reference;
173 
174  /// is_function
175  template<typename _Tp>
176  struct is_function;
177 
178  template<typename>
179  struct __is_member_object_pointer_helper
180  : public false_type { };
181  _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*,
183 
184  /// is_member_object_pointer
185  template<typename _Tp>
187  : public integral_constant<bool, (__is_member_object_pointer_helper<
188  typename remove_cv<_Tp>::type>::value)>
189  { };
190 
191  template<typename>
192  struct __is_member_function_pointer_helper
193  : public false_type { };
194  _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*,
195  is_function<_Tp>::value)
196 
197  /// is_member_function_pointer
198  template<typename _Tp>
200  : public integral_constant<bool, (__is_member_function_pointer_helper<
201  typename remove_cv<_Tp>::type>::value)>
202  { };
203 
204  /// is_enum
205  template<typename _Tp>
206  struct is_enum
207  : public integral_constant<bool, __is_enum(_Tp)>
208  { };
209 
210  /// is_union
211  template<typename _Tp>
212  struct is_union
213  : public integral_constant<bool, __is_union(_Tp)>
214  { };
215 
216  /// is_class
217  template<typename _Tp>
218  struct is_class
219  : public integral_constant<bool, __is_class(_Tp)>
220  { };
221 
222  /// is_function
223  template<typename>
224  struct is_function
225  : public false_type { };
226  template<typename _Res, typename... _ArgTypes>
227  struct is_function<_Res(_ArgTypes...)>
228  : public true_type { };
229  template<typename _Res, typename... _ArgTypes>
230  struct is_function<_Res(_ArgTypes......)>
231  : public true_type { };
232  template<typename _Res, typename... _ArgTypes>
233  struct is_function<_Res(_ArgTypes...) const>
234  : public true_type { };
235  template<typename _Res, typename... _ArgTypes>
236  struct is_function<_Res(_ArgTypes......) const>
237  : public true_type { };
238  template<typename _Res, typename... _ArgTypes>
239  struct is_function<_Res(_ArgTypes...) volatile>
240  : public true_type { };
241  template<typename _Res, typename... _ArgTypes>
242  struct is_function<_Res(_ArgTypes......) volatile>
243  : public true_type { };
244  template<typename _Res, typename... _ArgTypes>
245  struct is_function<_Res(_ArgTypes...) const volatile>
246  : public true_type { };
247  template<typename _Res, typename... _ArgTypes>
248  struct is_function<_Res(_ArgTypes......) const volatile>
249  : public true_type { };
250 
251  // composite type traits [4.5.2].
252 
253  /// is_arithmetic
254  template<typename _Tp>
256  : public integral_constant<bool, (is_integral<_Tp>::value
257  || is_floating_point<_Tp>::value)>
258  { };
259 
260  /// is_fundamental
261  template<typename _Tp>
263  : public integral_constant<bool, (is_arithmetic<_Tp>::value
264  || is_void<_Tp>::value)>
265  { };
266 
267  /// is_object
268  template<typename _Tp>
269  struct is_object
270  : public integral_constant<bool, !(is_function<_Tp>::value
271  || is_reference<_Tp>::value
272  || is_void<_Tp>::value)>
273  { };
274 
275  /// is_member_pointer
276  template<typename _Tp>
278 
279  /// is_scalar
280  template<typename _Tp>
281  struct is_scalar
282  : public integral_constant<bool, (is_arithmetic<_Tp>::value
283  || is_enum<_Tp>::value
284  || is_pointer<_Tp>::value
285  || is_member_pointer<_Tp>::value)>
286  { };
287 
288  /// is_compound
289  template<typename _Tp>
290  struct is_compound
291  : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
292 
293  /// is_member_pointer
294  template<typename _Tp>
296  : public false_type { };
297  _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true)
298 
299  template<typename _Tp>
300  struct is_member_pointer
302  typename remove_cv<_Tp>::type>::value)>
303  { };
304 
305  // type properties [4.5.3].
306  /// is_const
307  template<typename>
308  struct is_const
309  : public false_type { };
310 
311  template<typename _Tp>
312  struct is_const<_Tp const>
313  : public true_type { };
314 
315  /// is_volatile
316  template<typename>
317  struct is_volatile
318  : public false_type { };
319 
320  template<typename _Tp>
321  struct is_volatile<_Tp volatile>
322  : public true_type { };
323 
324  /// is_empty
325  template<typename _Tp>
326  struct is_empty
327  : public integral_constant<bool, __is_empty(_Tp)>
328  { };
329 
330  /// is_polymorphic
331  template<typename _Tp>
333  : public integral_constant<bool, __is_polymorphic(_Tp)>
334  { };
335 
336  /// is_abstract
337  template<typename _Tp>
338  struct is_abstract
339  : public integral_constant<bool, __is_abstract(_Tp)>
340  { };
341 
342  /// has_virtual_destructor
343  template<typename _Tp>
345  : public integral_constant<bool, __has_virtual_destructor(_Tp)>
346  { };
347 
348  /// alignment_of
349  template<typename _Tp>
351  : public integral_constant<std::size_t, __alignof__(_Tp)> { };
352 
353  /// rank
354  template<typename>
355  struct rank
356  : public integral_constant<std::size_t, 0> { };
357 
358  template<typename _Tp, std::size_t _Size>
359  struct rank<_Tp[_Size]>
360  : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
361 
362  template<typename _Tp>
363  struct rank<_Tp[]>
364  : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
365 
366  /// extent
367  template<typename, unsigned _Uint = 0>
368  struct extent
369  : public integral_constant<std::size_t, 0> { };
370 
371  template<typename _Tp, unsigned _Uint, std::size_t _Size>
372  struct extent<_Tp[_Size], _Uint>
373  : public integral_constant<std::size_t,
374  _Uint == 0 ? _Size : extent<_Tp,
375  _Uint - 1>::value>
376  { };
377 
378  template<typename _Tp, unsigned _Uint>
379  struct extent<_Tp[], _Uint>
380  : public integral_constant<std::size_t,
381  _Uint == 0 ? 0 : extent<_Tp,
382  _Uint - 1>::value>
383  { };
384 
385  // relationships between types [4.6].
386 
387  /// is_same
388  template<typename, typename>
389  struct is_same
390  : public false_type { };
391 
392  template<typename _Tp>
393  struct is_same<_Tp, _Tp>
394  : public true_type { };
395 
396  // const-volatile modifications [4.7.1].
397 
398  /// remove_const
399  template<typename _Tp>
401  { typedef _Tp type; };
402 
403  template<typename _Tp>
404  struct remove_const<_Tp const>
405  { typedef _Tp type; };
406 
407  /// remove_volatile
408  template<typename _Tp>
410  { typedef _Tp type; };
411 
412  template<typename _Tp>
413  struct remove_volatile<_Tp volatile>
414  { typedef _Tp type; };
415 
416  /// remove_cv
417  template<typename _Tp>
418  struct remove_cv
419  {
420  typedef typename
421  remove_const<typename remove_volatile<_Tp>::type>::type type;
422  };
423 
424  /// add_const
425  template<typename _Tp>
426  struct add_const
427  { typedef _Tp const type; };
428 
429  /// add_volatile
430  template<typename _Tp>
432  { typedef _Tp volatile type; };
433 
434  /// add_cv
435  template<typename _Tp>
436  struct add_cv
437  {
438  typedef typename
440  };
441 
442  // array modifications [4.7.3].
443 
444  /// remove_extent
445  template<typename _Tp>
447  { typedef _Tp type; };
448 
449  template<typename _Tp, std::size_t _Size>
450  struct remove_extent<_Tp[_Size]>
451  { typedef _Tp type; };
452 
453  template<typename _Tp>
454  struct remove_extent<_Tp[]>
455  { typedef _Tp type; };
456 
457  /// remove_all_extents
458  template<typename _Tp>
460  { typedef _Tp type; };
461 
462  template<typename _Tp, std::size_t _Size>
463  struct remove_all_extents<_Tp[_Size]>
464  { typedef typename remove_all_extents<_Tp>::type type; };
465 
466  template<typename _Tp>
467  struct remove_all_extents<_Tp[]>
468  { typedef typename remove_all_extents<_Tp>::type type; };
469 
470  // pointer modifications [4.7.4].
471 
472  template<typename _Tp, typename>
473  struct __remove_pointer_helper
474  { typedef _Tp type; };
475 
476  template<typename _Tp, typename _Up>
477  struct __remove_pointer_helper<_Tp, _Up*>
478  { typedef _Up type; };
479 
480  /// remove_pointer
481  template<typename _Tp>
483  : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
484  { };
485 
486  template<typename>
487  struct remove_reference;
488 
489  /// add_pointer
490  template<typename _Tp>
491  struct add_pointer
492  { typedef typename remove_reference<_Tp>::type* type; };
493 
494 #undef _DEFINE_SPEC_0_HELPER
495 #undef _DEFINE_SPEC_1_HELPER
496 #undef _DEFINE_SPEC_2_HELPER
497 #undef _DEFINE_SPEC
498 
499  // @} group metaprogramming
500 _GLIBCXX_END_NAMESPACE_TR1
501 }