1 // TR1 type_traits -*- C++ -*-
3 // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 // Free Software Foundation, Inc.
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)
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.
30 #ifndef _GLIBCXX_TR1_TYPE_TRAITS
31 #define _GLIBCXX_TR1_TYPE_TRAITS 1
33 #pragma GCC system_header
35 #include <bits/c++config.h>
42 * @defgroup metaprogramming Type Traits
45 * Compile time type transformation and information.
52 typedef struct { char __arr[2]; } __two;
55 #define _DEFINE_SPEC_0_HELPER \
58 #define _DEFINE_SPEC_1_HELPER \
59 template<typename _Tp>
61 #define _DEFINE_SPEC_2_HELPER \
62 template<typename _Tp, typename _Cp>
64 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \
65 _DEFINE_SPEC_##_Order##_HELPER \
66 struct _Trait<_Type> \
67 : public integral_constant<bool, _Value> { };
69 // helper classes [4.3].
72 template<typename _Tp, _Tp __v>
73 struct integral_constant
75 static const _Tp value = __v;
76 typedef _Tp value_type;
77 typedef integral_constant<_Tp, __v> type;
80 /// typedef for true_type
81 typedef integral_constant<bool, true> true_type;
83 /// typedef for false_type
84 typedef integral_constant<bool, false> false_type;
86 template<typename _Tp, _Tp __v>
87 const _Tp integral_constant<_Tp, __v>::value;
94 struct __is_void_helper
95 : public false_type { };
96 _DEFINE_SPEC(0, __is_void_helper, void, true)
98 // primary type categories [4.5.1].
101 template<typename _Tp>
103 : public integral_constant<bool, (__is_void_helper<typename
104 remove_cv<_Tp>::type>::value)>
108 struct __is_integral_helper
109 : public false_type { };
110 _DEFINE_SPEC(0, __is_integral_helper, bool, true)
111 _DEFINE_SPEC(0, __is_integral_helper, char, true)
112 _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
113 _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
114 #ifdef _GLIBCXX_USE_WCHAR_T
115 _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
117 _DEFINE_SPEC(0, __is_integral_helper, short, true)
118 _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true)
119 _DEFINE_SPEC(0, __is_integral_helper, int, true)
120 _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true)
121 _DEFINE_SPEC(0, __is_integral_helper, long, true)
122 _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true)
123 _DEFINE_SPEC(0, __is_integral_helper, long long, true)
124 _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true)
127 template<typename _Tp>
129 : public integral_constant<bool, (__is_integral_helper<typename
130 remove_cv<_Tp>::type>::value)>
134 struct __is_floating_point_helper
135 : public false_type { };
136 _DEFINE_SPEC(0, __is_floating_point_helper, float, true)
137 _DEFINE_SPEC(0, __is_floating_point_helper, double, true)
138 _DEFINE_SPEC(0, __is_floating_point_helper, long double, true)
140 /// is_floating_point
141 template<typename _Tp>
142 struct is_floating_point
143 : public integral_constant<bool, (__is_floating_point_helper<typename
144 remove_cv<_Tp>::type>::value)>
150 : public false_type { };
152 template<typename _Tp, std::size_t _Size>
153 struct is_array<_Tp[_Size]>
154 : public true_type { };
156 template<typename _Tp>
157 struct is_array<_Tp[]>
158 : public true_type { };
161 struct __is_pointer_helper
162 : public false_type { };
163 _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true)
166 template<typename _Tp>
168 : public integral_constant<bool, (__is_pointer_helper<typename
169 remove_cv<_Tp>::type>::value)>
173 template<typename _Tp>
177 template<typename _Tp>
181 struct __is_member_object_pointer_helper
182 : public false_type { };
183 _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*,
184 !is_function<_Tp>::value)
186 /// is_member_object_pointer
187 template<typename _Tp>
188 struct is_member_object_pointer
189 : public integral_constant<bool, (__is_member_object_pointer_helper<
190 typename remove_cv<_Tp>::type>::value)>
194 struct __is_member_function_pointer_helper
195 : public false_type { };
196 _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*,
197 is_function<_Tp>::value)
199 /// is_member_function_pointer
200 template<typename _Tp>
201 struct is_member_function_pointer
202 : public integral_constant<bool, (__is_member_function_pointer_helper<
203 typename remove_cv<_Tp>::type>::value)>
207 template<typename _Tp>
209 : public integral_constant<bool, __is_enum(_Tp)>
213 template<typename _Tp>
215 : public integral_constant<bool, __is_union(_Tp)>
219 template<typename _Tp>
221 : public integral_constant<bool, __is_class(_Tp)>
227 : public false_type { };
228 template<typename _Res, typename... _ArgTypes>
229 struct is_function<_Res(_ArgTypes...)>
230 : public true_type { };
231 template<typename _Res, typename... _ArgTypes>
232 struct is_function<_Res(_ArgTypes......)>
233 : public true_type { };
234 template<typename _Res, typename... _ArgTypes>
235 struct is_function<_Res(_ArgTypes...) const>
236 : public true_type { };
237 template<typename _Res, typename... _ArgTypes>
238 struct is_function<_Res(_ArgTypes......) const>
239 : public true_type { };
240 template<typename _Res, typename... _ArgTypes>
241 struct is_function<_Res(_ArgTypes...) volatile>
242 : public true_type { };
243 template<typename _Res, typename... _ArgTypes>
244 struct is_function<_Res(_ArgTypes......) volatile>
245 : public true_type { };
246 template<typename _Res, typename... _ArgTypes>
247 struct is_function<_Res(_ArgTypes...) const volatile>
248 : public true_type { };
249 template<typename _Res, typename... _ArgTypes>
250 struct is_function<_Res(_ArgTypes......) const volatile>
251 : public true_type { };
253 // composite type traits [4.5.2].
256 template<typename _Tp>
258 : public integral_constant<bool, (is_integral<_Tp>::value
259 || is_floating_point<_Tp>::value)>
263 template<typename _Tp>
264 struct is_fundamental
265 : public integral_constant<bool, (is_arithmetic<_Tp>::value
266 || is_void<_Tp>::value)>
270 template<typename _Tp>
272 : public integral_constant<bool, !(is_function<_Tp>::value
273 || is_reference<_Tp>::value
274 || is_void<_Tp>::value)>
277 /// is_member_pointer
278 template<typename _Tp>
279 struct is_member_pointer;
282 template<typename _Tp>
284 : public integral_constant<bool, (is_arithmetic<_Tp>::value
285 || is_enum<_Tp>::value
286 || is_pointer<_Tp>::value
287 || is_member_pointer<_Tp>::value)>
291 template<typename _Tp>
293 : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
295 /// is_member_pointer
296 template<typename _Tp>
297 struct __is_member_pointer_helper
298 : public false_type { };
299 _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true)
301 template<typename _Tp>
302 struct is_member_pointer
303 : public integral_constant<bool, (__is_member_pointer_helper<
304 typename remove_cv<_Tp>::type>::value)>
307 // type properties [4.5.3].
311 : public false_type { };
313 template<typename _Tp>
314 struct is_const<_Tp const>
315 : public true_type { };
320 : public false_type { };
322 template<typename _Tp>
323 struct is_volatile<_Tp volatile>
324 : public true_type { };
327 template<typename _Tp>
329 : public integral_constant<bool, __is_empty(_Tp)>
333 template<typename _Tp>
334 struct is_polymorphic
335 : public integral_constant<bool, __is_polymorphic(_Tp)>
339 template<typename _Tp>
341 : public integral_constant<bool, __is_abstract(_Tp)>
344 /// has_virtual_destructor
345 template<typename _Tp>
346 struct has_virtual_destructor
347 : public integral_constant<bool, __has_virtual_destructor(_Tp)>
351 template<typename _Tp>
353 : public integral_constant<std::size_t, __alignof__(_Tp)> { };
358 : public integral_constant<std::size_t, 0> { };
360 template<typename _Tp, std::size_t _Size>
361 struct rank<_Tp[_Size]>
362 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
364 template<typename _Tp>
366 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
369 template<typename, unsigned _Uint = 0>
371 : public integral_constant<std::size_t, 0> { };
373 template<typename _Tp, unsigned _Uint, std::size_t _Size>
374 struct extent<_Tp[_Size], _Uint>
375 : public integral_constant<std::size_t,
376 _Uint == 0 ? _Size : extent<_Tp,
380 template<typename _Tp, unsigned _Uint>
381 struct extent<_Tp[], _Uint>
382 : public integral_constant<std::size_t,
383 _Uint == 0 ? 0 : extent<_Tp,
387 // relationships between types [4.6].
390 template<typename, typename>
392 : public false_type { };
394 template<typename _Tp>
395 struct is_same<_Tp, _Tp>
396 : public true_type { };
398 // const-volatile modifications [4.7.1].
401 template<typename _Tp>
403 { typedef _Tp type; };
405 template<typename _Tp>
406 struct remove_const<_Tp const>
407 { typedef _Tp type; };
410 template<typename _Tp>
411 struct remove_volatile
412 { typedef _Tp type; };
414 template<typename _Tp>
415 struct remove_volatile<_Tp volatile>
416 { typedef _Tp type; };
419 template<typename _Tp>
423 remove_const<typename remove_volatile<_Tp>::type>::type type;
427 template<typename _Tp>
429 { typedef _Tp const type; };
432 template<typename _Tp>
434 { typedef _Tp volatile type; };
437 template<typename _Tp>
441 add_const<typename add_volatile<_Tp>::type>::type type;
444 // array modifications [4.7.3].
447 template<typename _Tp>
449 { typedef _Tp type; };
451 template<typename _Tp, std::size_t _Size>
452 struct remove_extent<_Tp[_Size]>
453 { typedef _Tp type; };
455 template<typename _Tp>
456 struct remove_extent<_Tp[]>
457 { typedef _Tp type; };
459 /// remove_all_extents
460 template<typename _Tp>
461 struct remove_all_extents
462 { typedef _Tp type; };
464 template<typename _Tp, std::size_t _Size>
465 struct remove_all_extents<_Tp[_Size]>
466 { typedef typename remove_all_extents<_Tp>::type type; };
468 template<typename _Tp>
469 struct remove_all_extents<_Tp[]>
470 { typedef typename remove_all_extents<_Tp>::type type; };
472 // pointer modifications [4.7.4].
474 template<typename _Tp, typename>
475 struct __remove_pointer_helper
476 { typedef _Tp type; };
478 template<typename _Tp, typename _Up>
479 struct __remove_pointer_helper<_Tp, _Up*>
480 { typedef _Up type; };
483 template<typename _Tp>
484 struct remove_pointer
485 : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
489 struct remove_reference;
492 template<typename _Tp>
494 { typedef typename remove_reference<_Tp>::type* type; };
498 : public false_type { };
500 template<typename _Tp>
501 struct is_reference<_Tp&>
502 : public true_type { };
504 template<typename _Tp>
506 : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value>
509 template<typename _Tp>
510 struct has_trivial_constructor
511 : public integral_constant<bool, is_pod<_Tp>::value>
514 template<typename _Tp>
515 struct has_trivial_copy
516 : public integral_constant<bool, is_pod<_Tp>::value>
519 template<typename _Tp>
520 struct has_trivial_assign
521 : public integral_constant<bool, is_pod<_Tp>::value>
524 template<typename _Tp>
525 struct has_trivial_destructor
526 : public integral_constant<bool, is_pod<_Tp>::value>
529 template<typename _Tp>
530 struct has_nothrow_constructor
531 : public integral_constant<bool, is_pod<_Tp>::value>
534 template<typename _Tp>
535 struct has_nothrow_copy
536 : public integral_constant<bool, is_pod<_Tp>::value>
539 template<typename _Tp>
540 struct has_nothrow_assign
541 : public integral_constant<bool, is_pod<_Tp>::value>
545 struct __is_signed_helper
546 : public false_type { };
547 _DEFINE_SPEC(0, __is_signed_helper, signed char, true)
548 _DEFINE_SPEC(0, __is_signed_helper, short, true)
549 _DEFINE_SPEC(0, __is_signed_helper, int, true)
550 _DEFINE_SPEC(0, __is_signed_helper, long, true)
551 _DEFINE_SPEC(0, __is_signed_helper, long long, true)
553 template<typename _Tp>
555 : public integral_constant<bool, (__is_signed_helper<typename
556 remove_cv<_Tp>::type>::value)>
560 struct __is_unsigned_helper
561 : public false_type { };
562 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned char, true)
563 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned short, true)
564 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned int, true)
565 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long, true)
566 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long long, true)
568 template<typename _Tp>
570 : public integral_constant<bool, (__is_unsigned_helper<typename
571 remove_cv<_Tp>::type>::value)>
574 template<typename _Base, typename _Derived>
575 struct __is_base_of_helper
577 typedef typename remove_cv<_Base>::type _NoCv_Base;
578 typedef typename remove_cv<_Derived>::type _NoCv_Derived;
579 static const bool __value = (is_same<_Base, _Derived>::value
580 || (__is_base_of(_Base, _Derived)
581 && !is_same<_NoCv_Base,
582 _NoCv_Derived>::value));
585 template<typename _Base, typename _Derived>
587 : public integral_constant<bool,
588 __is_base_of_helper<_Base, _Derived>::__value>
591 template<typename _From, typename _To>
592 struct __is_convertible_simple
593 : public __sfinae_types
596 static __one __test(_To);
597 static __two __test(...);
598 static _From __makeFrom();
601 static const bool __value = sizeof(__test(__makeFrom())) == 1;
604 template<typename _Tp>
605 struct add_reference;
607 template<typename _Tp>
608 struct __is_int_or_cref
610 typedef typename remove_reference<_Tp>::type __rr_Tp;
611 static const bool __value = (is_integral<_Tp>::value
612 || (is_integral<__rr_Tp>::value
613 && is_const<__rr_Tp>::value
614 && !is_volatile<__rr_Tp>::value));
617 template<typename _From, typename _To,
618 bool = (is_void<_From>::value || is_void<_To>::value
619 || is_function<_To>::value || is_array<_To>::value
620 // This special case is here only to avoid warnings.
621 || (is_floating_point<typename
622 remove_reference<_From>::type>::value
623 && __is_int_or_cref<_To>::__value))>
624 struct __is_convertible_helper
626 // "An imaginary lvalue of type From...".
627 static const bool __value = (__is_convertible_simple<typename
628 add_reference<_From>::type, _To>::__value);
631 template<typename _From, typename _To>
632 struct __is_convertible_helper<_From, _To, true>
633 { static const bool __value = (is_void<_To>::value
634 || (__is_int_or_cref<_To>::__value
635 && !is_void<_From>::value)); };
637 template<typename _From, typename _To>
638 struct is_convertible
639 : public integral_constant<bool,
640 __is_convertible_helper<_From, _To>::__value>
643 // reference modifications [4.7.2].
644 template<typename _Tp>
645 struct remove_reference
646 { typedef _Tp type; };
648 template<typename _Tp>
649 struct remove_reference<_Tp&>
650 { typedef _Tp type; };
652 // NB: Careful with reference to void.
653 template<typename _Tp, bool = (is_void<_Tp>::value
654 || is_reference<_Tp>::value)>
655 struct __add_reference_helper
656 { typedef _Tp& type; };
658 template<typename _Tp>
659 struct __add_reference_helper<_Tp, true>
660 { typedef _Tp type; };
662 template<typename _Tp>
664 : public __add_reference_helper<_Tp>
667 // other transformations [4.8].
668 template<std::size_t _Len, std::size_t _Align>
669 struct aligned_storage
673 unsigned char __data[_Len];
674 struct __attribute__((__aligned__((_Align)))) { } __align;
678 #undef _DEFINE_SPEC_0_HELPER
679 #undef _DEFINE_SPEC_1_HELPER
680 #undef _DEFINE_SPEC_2_HELPER
685 #endif // _GLIBCXX_TR1_TYPE_TRAITS