1 // C++0x type_traits -*- C++ -*-
3 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
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)
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 // 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.
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/>.
25 /** @file include/type_traits
26 * This is a Standard C++ Library header.
29 #ifndef _GLIBCXX_TYPE_TRAITS
30 #define _GLIBCXX_TYPE_TRAITS 1
32 #pragma GCC system_header
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
38 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
39 # error C++0x header cannot be included from TR1 header
42 #include <bits/c++config.h>
44 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
45 # include <tr1_impl/type_traits>
47 # define _GLIBCXX_INCLUDE_AS_CXX0X
48 # define _GLIBCXX_BEGIN_NAMESPACE_TR1
49 # define _GLIBCXX_END_NAMESPACE_TR1
51 # include <tr1_impl/type_traits>
53 # undef _GLIBCXX_END_NAMESPACE_TR1
54 # undef _GLIBCXX_BEGIN_NAMESPACE_TR1
55 # undef _GLIBCXX_INCLUDE_AS_CXX0X
61 * @addtogroup metaprogramming
65 // Primary classification traits.
67 /// is_lvalue_reference
69 struct is_lvalue_reference
70 : public false_type { };
72 template<typename _Tp>
73 struct is_lvalue_reference<_Tp&>
74 : public true_type { };
76 /// is_rvalue_reference
78 struct is_rvalue_reference
79 : public false_type { };
81 template<typename _Tp>
82 struct is_rvalue_reference<_Tp&&>
83 : public true_type { };
85 // Secondary classification traits.
88 template<typename _Tp>
90 : public integral_constant<bool, (is_lvalue_reference<_Tp>::value
91 || is_rvalue_reference<_Tp>::value)>
94 // Reference transformations.
97 template<typename _Tp>
98 struct remove_reference
99 { typedef _Tp type; };
101 template<typename _Tp>
102 struct remove_reference<_Tp&>
103 { typedef _Tp type; };
105 template<typename _Tp>
106 struct remove_reference<_Tp&&>
107 { typedef _Tp type; };
109 template<typename _Tp,
110 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
111 bool = is_rvalue_reference<_Tp>::value>
112 struct __add_lvalue_reference_helper
113 { typedef _Tp type; };
115 template<typename _Tp>
116 struct __add_lvalue_reference_helper<_Tp, true, false>
117 { typedef _Tp& type; };
119 template<typename _Tp>
120 struct __add_lvalue_reference_helper<_Tp, false, true>
121 { typedef typename remove_reference<_Tp>::type& type; };
123 /// add_lvalue_reference
124 template<typename _Tp>
125 struct add_lvalue_reference
126 : public __add_lvalue_reference_helper<_Tp>
129 template<typename _Tp,
130 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
131 struct __add_rvalue_reference_helper
132 { typedef _Tp type; };
134 template<typename _Tp>
135 struct __add_rvalue_reference_helper<_Tp, true>
136 { typedef _Tp&& type; };
138 /// add_rvalue_reference
139 template<typename _Tp>
140 struct add_rvalue_reference
141 : public __add_rvalue_reference_helper<_Tp>
144 // Scalar properties and transformations.
146 template<typename _Tp,
147 bool = is_integral<_Tp>::value,
148 bool = is_floating_point<_Tp>::value>
149 struct __is_signed_helper
150 : public false_type { };
152 template<typename _Tp>
153 struct __is_signed_helper<_Tp, false, true>
154 : public true_type { };
156 template<typename _Tp>
157 struct __is_signed_helper<_Tp, true, false>
158 : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))>
162 template<typename _Tp>
164 : public integral_constant<bool, __is_signed_helper<_Tp>::value>
168 template<typename _Tp>
170 : public integral_constant<bool, (is_arithmetic<_Tp>::value
171 && !is_signed<_Tp>::value)>
174 // Member introspection.
177 template<typename _Tp>
179 : public integral_constant<bool, __is_trivial(_Tp)>
182 /// is_standard_layout
183 template<typename _Tp>
184 struct is_standard_layout
185 : public integral_constant<bool, __is_standard_layout(_Tp)>
189 // Could use is_standard_layout && is_trivial instead of the builtin.
190 template<typename _Tp>
192 : public integral_constant<bool, __is_pod(_Tp)>
196 template<typename _Tp>
197 struct is_literal_type
198 : public integral_constant<bool, __is_literal_type(_Tp)>
201 template<typename _Tp>
202 typename add_rvalue_reference<_Tp>::type declval() noexcept;
204 template<typename _Tp, typename... _Args>
205 class __is_constructible_helper
206 : public __sfinae_types
208 template<typename _Tp1, typename... _Args1>
209 static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int);
211 template<typename, typename...>
212 static __two __test(...);
215 static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1;
218 template<typename _Tp, typename _Arg>
219 class __is_constructible_helper<_Tp, _Arg>
220 : public __sfinae_types
222 template<typename _Tp1, typename _Arg1>
223 static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one())
226 template<typename, typename>
227 static __two __test(...);
230 static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1;
235 // The C++0x specifications require front-end support, see N2255.
236 template<typename _Tp, typename... _Args>
237 struct is_constructible
238 : public integral_constant<bool,
239 __is_constructible_helper<_Tp,
243 template<bool, typename _Tp, typename... _Args>
244 struct __is_nt_constructible_helper
245 { static const bool __value = false; };
247 template<typename _Tp, typename... _Args>
248 struct __is_nt_constructible_helper<true, _Tp, _Args...>
249 { static const bool __value = noexcept(_Tp(declval<_Args>()...)); };
251 template<typename _Tp, typename _Arg>
252 struct __is_nt_constructible_helper<true, _Tp, _Arg>
254 static const bool __value = noexcept(static_cast<_Tp>(declval<_Arg>()));
257 /// is_nothrow_constructible
258 template<typename _Tp, typename... _Args>
259 struct is_nothrow_constructible
260 : public integral_constant<bool,
261 __is_nt_constructible_helper<is_constructible<_Tp, _Args...>::value,
262 _Tp, _Args...>::__value>
265 /// has_trivial_default_constructor
266 template<typename _Tp>
267 struct has_trivial_default_constructor
268 : public integral_constant<bool, __has_trivial_constructor(_Tp)>
271 /// has_trivial_copy_constructor
272 template<typename _Tp>
273 struct has_trivial_copy_constructor
274 : public integral_constant<bool, __has_trivial_copy(_Tp)>
277 /// has_trivial_copy_assign
278 template<typename _Tp>
279 struct has_trivial_copy_assign
280 : public integral_constant<bool, __has_trivial_assign(_Tp)>
283 /// has_trivial_destructor
284 template<typename _Tp>
285 struct has_trivial_destructor
286 : public integral_constant<bool, __has_trivial_destructor(_Tp)>
289 /// has_nothrow_default_constructor
290 template<typename _Tp>
291 struct has_nothrow_default_constructor
292 : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
295 /// has_nothrow_copy_constructor
296 template<typename _Tp>
297 struct has_nothrow_copy_constructor
298 : public integral_constant<bool, __has_nothrow_copy(_Tp)>
301 /// has_nothrow_copy_assign
302 template<typename _Tp>
303 struct has_nothrow_copy_assign
304 : public integral_constant<bool, __has_nothrow_assign(_Tp)>
307 // Relationships between types.
310 template<typename _Base, typename _Derived>
312 : public integral_constant<bool, __is_base_of(_Base, _Derived)>
315 template<typename _From, typename _To,
316 bool = (is_void<_From>::value || is_function<_To>::value
317 || is_array<_To>::value)>
318 struct __is_convertible_helper
319 { static const bool __value = is_void<_To>::value; };
321 template<typename _From, typename _To>
322 class __is_convertible_helper<_From, _To, false>
323 : public __sfinae_types
325 template<typename _To1>
326 static void __test_aux(_To1);
328 template<typename _From1, typename _To1>
329 static decltype(__test_aux<_To1>(std::declval<_From1>()), __one())
332 template<typename, typename>
333 static __two __test(...);
336 static const bool __value = sizeof(__test<_From, _To>(0)) == 1;
341 // The C++0x specifications require front-end support, see N2255.
342 template<typename _From, typename _To>
343 struct is_convertible
344 : public integral_constant<bool,
345 __is_convertible_helper<_From, _To>::__value>
348 /// is_explicitly_convertible
349 template<typename _From, typename _To>
350 struct is_explicitly_convertible
351 : public is_constructible<_To, _From>
354 template<std::size_t _Len>
355 struct __aligned_storage_msa
359 unsigned char __data[_Len];
360 struct __attribute__((__aligned__)) { } __align;
365 * @brief Alignment type.
367 * The value of _Align is a default-alignment which shall be the
368 * most stringent alignment requirement for any C++ object type
369 * whose size is no greater than _Len (3.9). The member typedef
370 * type shall be a POD type suitable for use as uninitialized
371 * storage for any object whose size is at most _Len and whose
372 * alignment is a divisor of _Align.
374 template<std::size_t _Len, std::size_t _Align =
375 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
376 struct aligned_storage
380 unsigned char __data[_Len];
381 struct __attribute__((__aligned__((_Align)))) { } __align;
386 // Define a nested type if some predicate holds.
389 template<bool, typename _Tp = void>
393 // Partial specialization for true.
394 template<typename _Tp>
395 struct enable_if<true, _Tp>
396 { typedef _Tp type; };
399 // A conditional expression, but for types. If true, first, if false, second.
402 template<bool _Cond, typename _Iftrue, typename _Iffalse>
404 { typedef _Iftrue type; };
406 // Partial specialization for false.
407 template<typename _Iftrue, typename _Iffalse>
408 struct conditional<false, _Iftrue, _Iffalse>
409 { typedef _Iffalse type; };
412 // Decay trait for arrays and functions, used for perfect forwarding
413 // in make_pair, make_tuple, etc.
414 template<typename _Up,
415 bool _IsArray = is_array<_Up>::value,
416 bool _IsFunction = is_function<_Up>::value>
417 struct __decay_selector;
420 template<typename _Up>
421 struct __decay_selector<_Up, false, false>
422 { typedef typename remove_cv<_Up>::type __type; };
424 template<typename _Up>
425 struct __decay_selector<_Up, true, false>
426 { typedef typename remove_extent<_Up>::type* __type; };
428 template<typename _Up>
429 struct __decay_selector<_Up, false, true>
430 { typedef typename add_pointer<_Up>::type __type; };
433 template<typename _Tp>
436 typedef typename remove_reference<_Tp>::type __remove_type;
439 typedef typename __decay_selector<__remove_type>::__type type;
442 template<typename _Tp>
443 class reference_wrapper;
445 // Helper which adds a reference to a type when given a reference_wrapper
446 template<typename _Tp>
447 struct __strip_reference_wrapper
452 template<typename _Tp>
453 struct __strip_reference_wrapper<reference_wrapper<_Tp> >
458 template<typename _Tp>
459 struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
464 template<typename _Tp>
465 struct __decay_and_strip
467 typedef typename __strip_reference_wrapper<
468 typename decay<_Tp>::type>::__type __type;
472 // Utility for constructing identically cv-qualified types.
473 template<typename _Unqualified, bool _IsConst, bool _IsVol>
474 struct __cv_selector;
476 template<typename _Unqualified>
477 struct __cv_selector<_Unqualified, false, false>
478 { typedef _Unqualified __type; };
480 template<typename _Unqualified>
481 struct __cv_selector<_Unqualified, false, true>
482 { typedef volatile _Unqualified __type; };
484 template<typename _Unqualified>
485 struct __cv_selector<_Unqualified, true, false>
486 { typedef const _Unqualified __type; };
488 template<typename _Unqualified>
489 struct __cv_selector<_Unqualified, true, true>
490 { typedef const volatile _Unqualified __type; };
492 template<typename _Qualified, typename _Unqualified,
493 bool _IsConst = is_const<_Qualified>::value,
494 bool _IsVol = is_volatile<_Qualified>::value>
495 class __match_cv_qualifiers
497 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
500 typedef typename __match::__type __type;
504 // Utility for finding the unsigned versions of signed integral types.
505 template<typename _Tp>
506 struct __make_unsigned
507 { typedef _Tp __type; };
510 struct __make_unsigned<char>
511 { typedef unsigned char __type; };
514 struct __make_unsigned<signed char>
515 { typedef unsigned char __type; };
518 struct __make_unsigned<short>
519 { typedef unsigned short __type; };
522 struct __make_unsigned<int>
523 { typedef unsigned int __type; };
526 struct __make_unsigned<long>
527 { typedef unsigned long __type; };
530 struct __make_unsigned<long long>
531 { typedef unsigned long long __type; };
534 // Select between integral and enum: not possible to be both.
535 template<typename _Tp,
536 bool _IsInt = is_integral<_Tp>::value,
537 bool _IsEnum = is_enum<_Tp>::value>
538 class __make_unsigned_selector;
540 template<typename _Tp>
541 class __make_unsigned_selector<_Tp, true, false>
543 typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
544 typedef typename __unsignedt::__type __unsigned_type;
545 typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
548 typedef typename __cv_unsigned::__type __type;
551 template<typename _Tp>
552 class __make_unsigned_selector<_Tp, false, true>
554 // With -fshort-enums, an enum may be as small as a char.
555 typedef unsigned char __smallest;
556 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
557 static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
558 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
559 typedef conditional<__b2, unsigned int, unsigned long> __cond2;
560 typedef typename __cond2::type __cond2_type;
561 typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
562 typedef typename __cond1::type __cond1_type;
565 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
568 // Given an integral/enum type, return the corresponding unsigned
572 template<typename _Tp>
574 { typedef typename __make_unsigned_selector<_Tp>::__type type; };
576 // Integral, but don't define.
578 struct make_unsigned<bool>;
581 // Utility for finding the signed versions of unsigned integral types.
582 template<typename _Tp>
584 { typedef _Tp __type; };
587 struct __make_signed<char>
588 { typedef signed char __type; };
591 struct __make_signed<unsigned char>
592 { typedef signed char __type; };
595 struct __make_signed<unsigned short>
596 { typedef signed short __type; };
599 struct __make_signed<unsigned int>
600 { typedef signed int __type; };
603 struct __make_signed<unsigned long>
604 { typedef signed long __type; };
607 struct __make_signed<unsigned long long>
608 { typedef signed long long __type; };
611 // Select between integral and enum: not possible to be both.
612 template<typename _Tp,
613 bool _IsInt = is_integral<_Tp>::value,
614 bool _IsEnum = is_enum<_Tp>::value>
615 class __make_signed_selector;
617 template<typename _Tp>
618 class __make_signed_selector<_Tp, true, false>
620 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
621 typedef typename __signedt::__type __signed_type;
622 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
625 typedef typename __cv_signed::__type __type;
628 template<typename _Tp>
629 class __make_signed_selector<_Tp, false, true>
631 // With -fshort-enums, an enum may be as small as a char.
632 typedef signed char __smallest;
633 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
634 static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
635 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
636 typedef conditional<__b2, signed int, signed long> __cond2;
637 typedef typename __cond2::type __cond2_type;
638 typedef conditional<__b1, signed short, __cond2_type> __cond1;
639 typedef typename __cond1::type __cond1_type;
642 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
645 // Given an integral/enum type, return the corresponding signed
649 template<typename _Tp>
651 { typedef typename __make_signed_selector<_Tp>::__type type; };
653 // Integral, but don't define.
655 struct make_signed<bool>;
658 template<typename... _Tp>
661 template<typename _Tp>
662 struct common_type<_Tp>
663 { typedef _Tp type; };
665 template<typename _Tp, typename _Up>
666 struct common_type<_Tp, _Up>
667 { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
669 template<typename _Tp, typename _Up, typename... _Vp>
670 struct common_type<_Tp, _Up, _Vp...>
673 common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
677 template<typename _Tp>
678 struct __declval_protector
680 static const bool __stop = false;
681 static typename add_rvalue_reference<_Tp>::type __delegate();
684 template<typename _Tp>
685 inline typename add_rvalue_reference<_Tp>::type
688 static_assert(__declval_protector<_Tp>::__stop,
689 "declval() must not be used!");
690 return __declval_protector<_Tp>::__delegate();
694 template<typename _Signature>
697 template<typename _Functor, typename... _ArgTypes>
698 struct result_of<_Functor(_ArgTypes...)>
701 decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
706 * Use SFINAE to determine if the type _Tp has a publicly-accessible
707 * member type _NTYPE.
709 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
710 template<typename _Tp> \
711 class __has_##_NTYPE##_helper \
714 template<typename _Up> \
718 template<typename _Up> \
719 static __one __test(_Wrap_type<typename _Up::_NTYPE>*); \
721 template<typename _Up> \
722 static __two __test(...); \
725 static const bool value = sizeof(__test<_Tp>(0)) == 1; \
728 template<typename _Tp> \
729 struct __has_##_NTYPE \
730 : integral_constant<bool, __has_##_NTYPE##_helper \
731 <typename remove_cv<_Tp>::type>::value> \
734 // @} group metaprogramming
737 #endif // __GXX_EXPERIMENTAL_CXX0X__
739 #endif // _GLIBCXX_TYPE_TRAITS