]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/type_traits
extend.texi: Follow spelling conventions.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / type_traits
CommitLineData
5b9daa7e 1// C++0x type_traits -*- C++ -*-
af13a7a6 2
ab65a4c7 3// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
af13a7a6
BK
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
748086b7 8// Free Software Foundation; either version 3, or (at your option)
af13a7a6
BK
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
748086b7
JJ
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/>.
af13a7a6
BK
24
25/** @file include/type_traits
26 * This is a Standard C++ Library header.
27 */
28
4514bed6
BK
29#ifndef _GLIBCXX_TYPE_TRAITS
30#define _GLIBCXX_TYPE_TRAITS 1
af13a7a6
BK
31
32#pragma GCC system_header
33
57317d2a 34#ifndef __GXX_EXPERIMENTAL_CXX0X__
ab65a4c7 35# include <bits/c++0x_warning.h>
57317d2a 36#else
af13a7a6 37
8fc81078 38#include <bits/c++config.h>
e133ace8 39
53dc5044 40_GLIBCXX_BEGIN_NAMESPACE(std)
e133ace8 41
8e32aa11
BK
42 /**
43 * @addtogroup metaprogramming
5b9daa7e
BK
44 * @{
45 */
53dc5044
PC
46 struct __sfinae_types
47 {
48 typedef char __one;
49 typedef struct { char __arr[2]; } __two;
50 };
51
52#define _DEFINE_SPEC_0_HELPER \
53 template<>
54
55#define _DEFINE_SPEC_1_HELPER \
56 template<typename _Tp>
57
58#define _DEFINE_SPEC_2_HELPER \
59 template<typename _Tp, typename _Cp>
60
61#define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \
62 _DEFINE_SPEC_##_Order##_HELPER \
63 struct _Trait<_Type> \
64 : public integral_constant<bool, _Value> { };
65
66 // helper classes.
67
68 /// integral_constant
69 template<typename _Tp, _Tp __v>
70 struct integral_constant
71 {
72 static constexpr _Tp value = __v;
73 typedef _Tp value_type;
74 typedef integral_constant<_Tp, __v> type;
75 constexpr operator value_type() { return value; }
76 };
77
78 /// typedef for true_type
79 typedef integral_constant<bool, true> true_type;
80
81 /// typedef for false_type
82 typedef integral_constant<bool, false> false_type;
83
84 template<typename _Tp, _Tp __v>
85 constexpr _Tp integral_constant<_Tp, __v>::value;
86
87 /// remove_cv
88 template<typename>
89 struct remove_cv;
90
91 template<typename>
92 struct __is_void_helper
93 : public false_type { };
94 _DEFINE_SPEC(0, __is_void_helper, void, true)
95
96 // primary type categories.
97
98 /// is_void
99 template<typename _Tp>
100 struct is_void
101 : public integral_constant<bool, (__is_void_helper<typename
102 remove_cv<_Tp>::type>::value)>
103 { };
104
105 template<typename>
106 struct __is_integral_helper
107 : public false_type { };
108 _DEFINE_SPEC(0, __is_integral_helper, bool, true)
109 _DEFINE_SPEC(0, __is_integral_helper, char, true)
110 _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
111 _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
112#ifdef _GLIBCXX_USE_WCHAR_T
113 _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
114#endif
115 _DEFINE_SPEC(0, __is_integral_helper, char16_t, true)
116 _DEFINE_SPEC(0, __is_integral_helper, char32_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)
125
126 /// is_integral
127 template<typename _Tp>
128 struct is_integral
129 : public integral_constant<bool, (__is_integral_helper<typename
130 remove_cv<_Tp>::type>::value)>
131 { };
132
133 template<typename>
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)
139
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)>
145 { };
146
147 /// is_array
148 template<typename>
149 struct is_array
150 : public false_type { };
151
152 template<typename _Tp, std::size_t _Size>
153 struct is_array<_Tp[_Size]>
154 : public true_type { };
155
156 template<typename _Tp>
157 struct is_array<_Tp[]>
158 : public true_type { };
159
160 template<typename>
161 struct __is_pointer_helper
162 : public false_type { };
163 _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true)
164
165 /// is_pointer
166 template<typename _Tp>
167 struct is_pointer
168 : public integral_constant<bool, (__is_pointer_helper<typename
169 remove_cv<_Tp>::type>::value)>
170 { };
171
172 /// is_reference
173 template<typename _Tp>
174 struct is_reference;
175
176 /// is_function
177 template<typename _Tp>
178 struct is_function;
179
180 template<typename>
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)
185
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)>
191 { };
192
193 template<typename>
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)
198
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)>
204 { };
205
206 /// is_enum
207 template<typename _Tp>
208 struct is_enum
209 : public integral_constant<bool, __is_enum(_Tp)>
210 { };
211
212 /// is_union
213 template<typename _Tp>
214 struct is_union
215 : public integral_constant<bool, __is_union(_Tp)>
216 { };
217
218 /// is_class
219 template<typename _Tp>
220 struct is_class
221 : public integral_constant<bool, __is_class(_Tp)>
222 { };
223
224 /// is_function
225 template<typename>
226 struct is_function
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 { };
252
1e673415
PC
253 template<typename>
254 struct __is_nullptr_t_helper
255 : public false_type { };
256 _DEFINE_SPEC(0, __is_nullptr_t_helper, std::nullptr_t, true)
257
258 // __is_nullptr_t (extension).
259 template<typename _Tp>
260 struct __is_nullptr_t
261 : public integral_constant<bool, (__is_nullptr_t_helper<typename
262 remove_cv<_Tp>::type>::value)>
263 { };
264
53dc5044
PC
265 // composite type traits.
266
267 /// is_arithmetic
268 template<typename _Tp>
269 struct is_arithmetic
270 : public integral_constant<bool, (is_integral<_Tp>::value
271 || is_floating_point<_Tp>::value)>
272 { };
273
274 /// is_fundamental
275 template<typename _Tp>
276 struct is_fundamental
277 : public integral_constant<bool, (is_arithmetic<_Tp>::value
278 || is_void<_Tp>::value)>
279 { };
280
281 /// is_object
282 template<typename _Tp>
283 struct is_object
284 : public integral_constant<bool, !(is_function<_Tp>::value
285 || is_reference<_Tp>::value
286 || is_void<_Tp>::value)>
287 { };
288
289 /// is_member_pointer
290 template<typename _Tp>
291 struct is_member_pointer;
292
293 /// is_scalar
294 template<typename _Tp>
295 struct is_scalar
296 : public integral_constant<bool, (is_arithmetic<_Tp>::value
297 || is_enum<_Tp>::value
298 || is_pointer<_Tp>::value
1e673415
PC
299 || is_member_pointer<_Tp>::value
300 || __is_nullptr_t<_Tp>::value)>
53dc5044
PC
301 { };
302
303 /// is_compound
304 template<typename _Tp>
305 struct is_compound
306 : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
307
308 /// is_member_pointer
309 template<typename _Tp>
310 struct __is_member_pointer_helper
311 : public false_type { };
312 _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true)
313
314 template<typename _Tp>
315 struct is_member_pointer
316 : public integral_constant<bool, (__is_member_pointer_helper<
317 typename remove_cv<_Tp>::type>::value)>
318 { };
319
320 // type properties.
321 /// is_const
322 template<typename>
323 struct is_const
324 : public false_type { };
325
326 template<typename _Tp>
327 struct is_const<_Tp const>
328 : public true_type { };
329
330 /// is_volatile
331 template<typename>
332 struct is_volatile
333 : public false_type { };
334
335 template<typename _Tp>
336 struct is_volatile<_Tp volatile>
337 : public true_type { };
338
339 /// is_empty
340 template<typename _Tp>
341 struct is_empty
342 : public integral_constant<bool, __is_empty(_Tp)>
343 { };
344
345 /// is_polymorphic
346 template<typename _Tp>
347 struct is_polymorphic
348 : public integral_constant<bool, __is_polymorphic(_Tp)>
349 { };
350
351 /// is_abstract
352 template<typename _Tp>
353 struct is_abstract
354 : public integral_constant<bool, __is_abstract(_Tp)>
355 { };
356
357 /// has_virtual_destructor
358 template<typename _Tp>
359 struct has_virtual_destructor
360 : public integral_constant<bool, __has_virtual_destructor(_Tp)>
361 { };
362
363 /// alignment_of
364 template<typename _Tp>
365 struct alignment_of
366 : public integral_constant<std::size_t, __alignof__(_Tp)> { };
367
368 /// rank
369 template<typename>
370 struct rank
371 : public integral_constant<std::size_t, 0> { };
372
373 template<typename _Tp, std::size_t _Size>
374 struct rank<_Tp[_Size]>
375 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
376
377 template<typename _Tp>
378 struct rank<_Tp[]>
379 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
380
381 /// extent
382 template<typename, unsigned _Uint = 0>
383 struct extent
384 : public integral_constant<std::size_t, 0> { };
385
386 template<typename _Tp, unsigned _Uint, std::size_t _Size>
387 struct extent<_Tp[_Size], _Uint>
388 : public integral_constant<std::size_t,
389 _Uint == 0 ? _Size : extent<_Tp,
390 _Uint - 1>::value>
391 { };
392
393 template<typename _Tp, unsigned _Uint>
394 struct extent<_Tp[], _Uint>
395 : public integral_constant<std::size_t,
396 _Uint == 0 ? 0 : extent<_Tp,
397 _Uint - 1>::value>
398 { };
399
400 // relationships between types [4.6].
401
402 /// is_same
403 template<typename, typename>
404 struct is_same
405 : public false_type { };
406
407 template<typename _Tp>
408 struct is_same<_Tp, _Tp>
409 : public true_type { };
410
411 // const-volatile modifications [4.7.1].
412
413 /// remove_const
414 template<typename _Tp>
415 struct remove_const
416 { typedef _Tp type; };
417
418 template<typename _Tp>
419 struct remove_const<_Tp const>
420 { typedef _Tp type; };
421
422 /// remove_volatile
423 template<typename _Tp>
424 struct remove_volatile
425 { typedef _Tp type; };
426
427 template<typename _Tp>
428 struct remove_volatile<_Tp volatile>
429 { typedef _Tp type; };
430
431 /// remove_cv
432 template<typename _Tp>
433 struct remove_cv
434 {
435 typedef typename
436 remove_const<typename remove_volatile<_Tp>::type>::type type;
437 };
438
439 /// add_const
440 template<typename _Tp>
441 struct add_const
442 { typedef _Tp const type; };
443
444 /// add_volatile
445 template<typename _Tp>
446 struct add_volatile
447 { typedef _Tp volatile type; };
448
449 /// add_cv
450 template<typename _Tp>
451 struct add_cv
452 {
453 typedef typename
454 add_const<typename add_volatile<_Tp>::type>::type type;
455 };
456
457 // array modifications.
458
459 /// remove_extent
460 template<typename _Tp>
461 struct remove_extent
462 { typedef _Tp type; };
463
464 template<typename _Tp, std::size_t _Size>
465 struct remove_extent<_Tp[_Size]>
466 { typedef _Tp type; };
467
468 template<typename _Tp>
469 struct remove_extent<_Tp[]>
470 { typedef _Tp type; };
471
472 /// remove_all_extents
473 template<typename _Tp>
474 struct remove_all_extents
475 { typedef _Tp type; };
476
477 template<typename _Tp, std::size_t _Size>
478 struct remove_all_extents<_Tp[_Size]>
479 { typedef typename remove_all_extents<_Tp>::type type; };
480
481 template<typename _Tp>
482 struct remove_all_extents<_Tp[]>
483 { typedef typename remove_all_extents<_Tp>::type type; };
484
485 // pointer modifications.
486
487 template<typename _Tp, typename>
488 struct __remove_pointer_helper
489 { typedef _Tp type; };
490
491 template<typename _Tp, typename _Up>
492 struct __remove_pointer_helper<_Tp, _Up*>
493 { typedef _Up type; };
494
495 /// remove_pointer
496 template<typename _Tp>
497 struct remove_pointer
498 : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
499 { };
500
501 template<typename>
502 struct remove_reference;
503
504 /// add_pointer
505 template<typename _Tp>
506 struct add_pointer
507 { typedef typename remove_reference<_Tp>::type* type; };
5b9daa7e 508
4a27a739 509 // Primary classification traits.
939759fc
BK
510
511 /// is_lvalue_reference
4a27a739
PC
512 template<typename>
513 struct is_lvalue_reference
514 : public false_type { };
515
516 template<typename _Tp>
517 struct is_lvalue_reference<_Tp&>
518 : public true_type { };
519
939759fc 520 /// is_rvalue_reference
4a27a739
PC
521 template<typename>
522 struct is_rvalue_reference
523 : public false_type { };
524
525 template<typename _Tp>
526 struct is_rvalue_reference<_Tp&&>
527 : public true_type { };
528
529 // Secondary classification traits.
939759fc
BK
530
531 /// is_reference
4a27a739
PC
532 template<typename _Tp>
533 struct is_reference
534 : public integral_constant<bool, (is_lvalue_reference<_Tp>::value
535 || is_rvalue_reference<_Tp>::value)>
536 { };
537
538 // Reference transformations.
939759fc
BK
539
540 /// remove_reference
4a27a739
PC
541 template<typename _Tp>
542 struct remove_reference
543 { typedef _Tp type; };
544
545 template<typename _Tp>
546 struct remove_reference<_Tp&>
547 { typedef _Tp type; };
548
549 template<typename _Tp>
550 struct remove_reference<_Tp&&>
551 { typedef _Tp type; };
552
553 template<typename _Tp,
58366b08 554 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
4a27a739
PC
555 bool = is_rvalue_reference<_Tp>::value>
556 struct __add_lvalue_reference_helper
557 { typedef _Tp type; };
558
559 template<typename _Tp>
560 struct __add_lvalue_reference_helper<_Tp, true, false>
561 { typedef _Tp& type; };
562
563 template<typename _Tp>
564 struct __add_lvalue_reference_helper<_Tp, false, true>
565 { typedef typename remove_reference<_Tp>::type& type; };
566
939759fc 567 /// add_lvalue_reference
4a27a739
PC
568 template<typename _Tp>
569 struct add_lvalue_reference
570 : public __add_lvalue_reference_helper<_Tp>
571 { };
572
573 template<typename _Tp,
58366b08 574 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
4a27a739
PC
575 struct __add_rvalue_reference_helper
576 { typedef _Tp type; };
577
578 template<typename _Tp>
579 struct __add_rvalue_reference_helper<_Tp, true>
580 { typedef _Tp&& type; };
581
939759fc 582 /// add_rvalue_reference
4a27a739
PC
583 template<typename _Tp>
584 struct add_rvalue_reference
585 : public __add_rvalue_reference_helper<_Tp>
586 { };
587
588 // Scalar properties and transformations.
939759fc 589
e133ace8
PC
590 template<typename _Tp,
591 bool = is_integral<_Tp>::value,
592 bool = is_floating_point<_Tp>::value>
593 struct __is_signed_helper
594 : public false_type { };
595
596 template<typename _Tp>
597 struct __is_signed_helper<_Tp, false, true>
598 : public true_type { };
599
600 template<typename _Tp>
601 struct __is_signed_helper<_Tp, true, false>
8e32aa11 602 : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))>
e133ace8
PC
603 { };
604
939759fc 605 /// is_signed
e133ace8
PC
606 template<typename _Tp>
607 struct is_signed
608 : public integral_constant<bool, __is_signed_helper<_Tp>::value>
609 { };
610
939759fc 611 /// is_unsigned
e133ace8
PC
612 template<typename _Tp>
613 struct is_unsigned
614 : public integral_constant<bool, (is_arithmetic<_Tp>::value
615 && !is_signed<_Tp>::value)>
616 { };
617
4a27a739 618 // Member introspection.
939759fc 619
b0302c68
PC
620 /// is_trivial
621 template<typename _Tp>
622 struct is_trivial
623 : public integral_constant<bool, __is_trivial(_Tp)>
624 { };
625
626 /// is_standard_layout
627 template<typename _Tp>
628 struct is_standard_layout
629 : public integral_constant<bool, __is_standard_layout(_Tp)>
630 { };
631
939759fc 632 /// is_pod
c32097d8 633 // Could use is_standard_layout && is_trivial instead of the builtin.
e133ace8
PC
634 template<typename _Tp>
635 struct is_pod
636 : public integral_constant<bool, __is_pod(_Tp)>
637 { };
638
2b08f2c5
JM
639 /// is_literal_type
640 template<typename _Tp>
641 struct is_literal_type
642 : public integral_constant<bool, __is_literal_type(_Tp)>
643 { };
644
c32097d8 645 template<typename _Tp>
e4f32cb0 646 typename add_rvalue_reference<_Tp>::type declval() noexcept;
b0302c68
PC
647
648 template<typename _Tp, typename... _Args>
649 class __is_constructible_helper
650 : public __sfinae_types
651 {
4b3d7a7e
PC
652 template<typename _Tp1, typename... _Args1>
653 static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int);
b0302c68
PC
654
655 template<typename, typename...>
656 static __two __test(...);
657
658 public:
659 static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1;
660 };
661
662 template<typename _Tp, typename _Arg>
663 class __is_constructible_helper<_Tp, _Arg>
664 : public __sfinae_types
665 {
666 template<typename _Tp1, typename _Arg1>
667 static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one())
668 __test(int);
669
670 template<typename, typename>
671 static __two __test(...);
672
673 public:
674 static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1;
675 };
676
677 /// is_constructible
678 // XXX FIXME
679 // The C++0x specifications require front-end support, see N2255.
680 template<typename _Tp, typename... _Args>
681 struct is_constructible
682 : public integral_constant<bool,
683 __is_constructible_helper<_Tp,
684 _Args...>::__value>
c32097d8
JM
685 { };
686
e4f32cb0
PC
687 template<bool, typename _Tp, typename... _Args>
688 struct __is_nt_constructible_helper
689 { static const bool __value = false; };
690
691 template<typename _Tp, typename... _Args>
692 struct __is_nt_constructible_helper<true, _Tp, _Args...>
693 { static const bool __value = noexcept(_Tp(declval<_Args>()...)); };
694
695 template<typename _Tp, typename _Arg>
696 struct __is_nt_constructible_helper<true, _Tp, _Arg>
697 {
698 static const bool __value = noexcept(static_cast<_Tp>(declval<_Arg>()));
699 };
700
701 /// is_nothrow_constructible
702 template<typename _Tp, typename... _Args>
703 struct is_nothrow_constructible
704 : public integral_constant<bool,
705 __is_nt_constructible_helper<is_constructible<_Tp, _Args...>::value,
706 _Tp, _Args...>::__value>
707 { };
708
939759fc 709 /// has_trivial_default_constructor
e133ace8
PC
710 template<typename _Tp>
711 struct has_trivial_default_constructor
712 : public integral_constant<bool, __has_trivial_constructor(_Tp)>
713 { };
714
939759fc 715 /// has_trivial_copy_constructor
e133ace8
PC
716 template<typename _Tp>
717 struct has_trivial_copy_constructor
718 : public integral_constant<bool, __has_trivial_copy(_Tp)>
719 { };
720
6f5e9b8d 721 /// has_trivial_copy_assign
e133ace8 722 template<typename _Tp>
6f5e9b8d 723 struct has_trivial_copy_assign
e133ace8
PC
724 : public integral_constant<bool, __has_trivial_assign(_Tp)>
725 { };
726
939759fc 727 /// has_trivial_destructor
e133ace8
PC
728 template<typename _Tp>
729 struct has_trivial_destructor
730 : public integral_constant<bool, __has_trivial_destructor(_Tp)>
731 { };
732
a7543cfd 733 /// has_nothrow_default_constructor
e133ace8
PC
734 template<typename _Tp>
735 struct has_nothrow_default_constructor
736 : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
737 { };
738
a7543cfd 739 /// has_nothrow_copy_constructor
e133ace8
PC
740 template<typename _Tp>
741 struct has_nothrow_copy_constructor
742 : public integral_constant<bool, __has_nothrow_copy(_Tp)>
743 { };
744
6f5e9b8d 745 /// has_nothrow_copy_assign
e133ace8 746 template<typename _Tp>
6f5e9b8d 747 struct has_nothrow_copy_assign
e133ace8
PC
748 : public integral_constant<bool, __has_nothrow_assign(_Tp)>
749 { };
750
b0302c68
PC
751 // Relationships between types.
752
939759fc 753 /// is_base_of
e133ace8
PC
754 template<typename _Base, typename _Derived>
755 struct is_base_of
756 : public integral_constant<bool, __is_base_of(_Base, _Derived)>
757 { };
758
297f34d7 759 template<typename _From, typename _To,
8e7d962a
PC
760 bool = (is_void<_From>::value || is_function<_To>::value
761 || is_array<_To>::value)>
297f34d7 762 struct __is_convertible_helper
8e7d962a 763 { static const bool __value = is_void<_To>::value; };
297f34d7 764
e133ace8 765 template<typename _From, typename _To>
b0302c68 766 class __is_convertible_helper<_From, _To, false>
e133ace8
PC
767 : public __sfinae_types
768 {
8e7d962a
PC
769 template<typename _To1>
770 static void __test_aux(_To1);
771
772 template<typename _From1, typename _To1>
773 static decltype(__test_aux<_To1>(std::declval<_From1>()), __one())
774 __test(int);
775
776 template<typename, typename>
777 static __two __test(...);
297f34d7 778
e133ace8 779 public:
8e7d962a 780 static const bool __value = sizeof(__test<_From, _To>(0)) == 1;
e133ace8
PC
781 };
782
b0302c68 783 /// is_convertible
4a27a739 784 // XXX FIXME
2d0269f6 785 // The C++0x specifications require front-end support, see N2255.
e133ace8
PC
786 template<typename _From, typename _To>
787 struct is_convertible
788 : public integral_constant<bool,
789 __is_convertible_helper<_From, _To>::__value>
790 { };
791
b0302c68 792 /// is_explicitly_convertible
75995f37
PC
793 template<typename _From, typename _To>
794 struct is_explicitly_convertible
795 : public is_constructible<_To, _From>
796 { };
797
fd735b6a
PC
798 template<std::size_t _Len>
799 struct __aligned_storage_msa
800 {
801 union __type
802 {
803 unsigned char __data[_Len];
804 struct __attribute__((__aligned__)) { } __align;
805 };
806 };
807
939759fc
BK
808 /**
809 * @brief Alignment type.
810 *
811 * The value of _Align is a default-alignment which shall be the
812 * most stringent alignment requirement for any C++ object type
813 * whose size is no greater than _Len (3.9). The member typedef
814 * type shall be a POD type suitable for use as uninitialized
815 * storage for any object whose size is at most _Len and whose
816 * alignment is a divisor of _Align.
817 */
fd735b6a
PC
818 template<std::size_t _Len, std::size_t _Align =
819 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
820 struct aligned_storage
821 {
822 union type
823 {
824 unsigned char __data[_Len];
825 struct __attribute__((__aligned__((_Align)))) { } __align;
826 };
827 };
828
7b50cdef
BK
829
830 // Define a nested type if some predicate holds.
5b9daa7e
BK
831 // Primary template.
832 /// enable_if
7b50cdef
BK
833 template<bool, typename _Tp = void>
834 struct enable_if
835 { };
836
5b9daa7e 837 // Partial specialization for true.
7b50cdef
BK
838 template<typename _Tp>
839 struct enable_if<true, _Tp>
840 { typedef _Tp type; };
841
842
5b9daa7e
BK
843 // A conditional expression, but for types. If true, first, if false, second.
844 // Primary template.
845 /// conditional
7b50cdef
BK
846 template<bool _Cond, typename _Iftrue, typename _Iffalse>
847 struct conditional
848 { typedef _Iftrue type; };
849
5b9daa7e 850 // Partial specialization for false.
7b50cdef
BK
851 template<typename _Iftrue, typename _Iffalse>
852 struct conditional<false, _Iftrue, _Iffalse>
853 { typedef _Iffalse type; };
854
855
856 // Decay trait for arrays and functions, used for perfect forwarding
857 // in make_pair, make_tuple, etc.
858 template<typename _Up,
859 bool _IsArray = is_array<_Up>::value,
860 bool _IsFunction = is_function<_Up>::value>
861 struct __decay_selector;
862
ce796131 863 // NB: DR 705.
7b50cdef
BK
864 template<typename _Up>
865 struct __decay_selector<_Up, false, false>
ce796131 866 { typedef typename remove_cv<_Up>::type __type; };
7b50cdef
BK
867
868 template<typename _Up>
869 struct __decay_selector<_Up, true, false>
870 { typedef typename remove_extent<_Up>::type* __type; };
871
7b50cdef
BK
872 template<typename _Up>
873 struct __decay_selector<_Up, false, true>
874 { typedef typename add_pointer<_Up>::type __type; };
875
939759fc 876 /// decay
7b50cdef 877 template<typename _Tp>
b0302c68 878 class decay
7b50cdef 879 {
7b50cdef
BK
880 typedef typename remove_reference<_Tp>::type __remove_type;
881
882 public:
883 typedef typename __decay_selector<__remove_type>::__type type;
884 };
885
5e108459
PC
886 template<typename _Tp>
887 class reference_wrapper;
888
889 // Helper which adds a reference to a type when given a reference_wrapper
890 template<typename _Tp>
891 struct __strip_reference_wrapper
892 {
893 typedef _Tp __type;
894 };
895
896 template<typename _Tp>
897 struct __strip_reference_wrapper<reference_wrapper<_Tp> >
898 {
899 typedef _Tp& __type;
900 };
901
902 template<typename _Tp>
903 struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
904 {
905 typedef _Tp& __type;
906 };
907
908 template<typename _Tp>
909 struct __decay_and_strip
910 {
911 typedef typename __strip_reference_wrapper<
912 typename decay<_Tp>::type>::__type __type;
913 };
914
7b50cdef
BK
915
916 // Utility for constructing identically cv-qualified types.
917 template<typename _Unqualified, bool _IsConst, bool _IsVol>
918 struct __cv_selector;
919
920 template<typename _Unqualified>
921 struct __cv_selector<_Unqualified, false, false>
922 { typedef _Unqualified __type; };
923
924 template<typename _Unqualified>
925 struct __cv_selector<_Unqualified, false, true>
926 { typedef volatile _Unqualified __type; };
927
928 template<typename _Unqualified>
929 struct __cv_selector<_Unqualified, true, false>
930 { typedef const _Unqualified __type; };
931
932 template<typename _Unqualified>
933 struct __cv_selector<_Unqualified, true, true>
934 { typedef const volatile _Unqualified __type; };
935
936 template<typename _Qualified, typename _Unqualified,
937 bool _IsConst = is_const<_Qualified>::value,
938 bool _IsVol = is_volatile<_Qualified>::value>
b0302c68 939 class __match_cv_qualifiers
7b50cdef 940 {
7b50cdef
BK
941 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
942
943 public:
944 typedef typename __match::__type __type;
945 };
946
947
948 // Utility for finding the unsigned versions of signed integral types.
949 template<typename _Tp>
e133ace8
PC
950 struct __make_unsigned
951 { typedef _Tp __type; };
7b50cdef
BK
952
953 template<>
954 struct __make_unsigned<char>
955 { typedef unsigned char __type; };
956
957 template<>
958 struct __make_unsigned<signed char>
959 { typedef unsigned char __type; };
960
7b50cdef
BK
961 template<>
962 struct __make_unsigned<short>
963 { typedef unsigned short __type; };
964
965 template<>
966 struct __make_unsigned<int>
967 { typedef unsigned int __type; };
968
969 template<>
970 struct __make_unsigned<long>
971 { typedef unsigned long __type; };
972
973 template<>
974 struct __make_unsigned<long long>
975 { typedef unsigned long long __type; };
976
977
978 // Select between integral and enum: not possible to be both.
979 template<typename _Tp,
980 bool _IsInt = is_integral<_Tp>::value,
7b50cdef 981 bool _IsEnum = is_enum<_Tp>::value>
b0302c68
PC
982 class __make_unsigned_selector;
983
7b50cdef 984 template<typename _Tp>
b0302c68 985 class __make_unsigned_selector<_Tp, true, false>
7b50cdef 986 {
7b50cdef
BK
987 typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
988 typedef typename __unsignedt::__type __unsigned_type;
989 typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
990
991 public:
992 typedef typename __cv_unsigned::__type __type;
993 };
994
7b50cdef 995 template<typename _Tp>
b0302c68 996 class __make_unsigned_selector<_Tp, false, true>
7b50cdef 997 {
a0230468
MM
998 // With -fshort-enums, an enum may be as small as a char.
999 typedef unsigned char __smallest;
1000 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
1001 static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
ce2e6349 1002 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
a0230468
MM
1003 typedef conditional<__b2, unsigned int, unsigned long> __cond2;
1004 typedef typename __cond2::type __cond2_type;
1005 typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
1006 typedef typename __cond1::type __cond1_type;
7b50cdef
BK
1007
1008 public:
a0230468 1009 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
7b50cdef
BK
1010 };
1011
7b50cdef
BK
1012 // Given an integral/enum type, return the corresponding unsigned
1013 // integer type.
5b9daa7e
BK
1014 // Primary template.
1015 /// make_unsigned
7b50cdef
BK
1016 template<typename _Tp>
1017 struct make_unsigned
1018 { typedef typename __make_unsigned_selector<_Tp>::__type type; };
1019
1020 // Integral, but don't define.
1021 template<>
1022 struct make_unsigned<bool>;
1023
1024
1025 // Utility for finding the signed versions of unsigned integral types.
1026 template<typename _Tp>
e133ace8
PC
1027 struct __make_signed
1028 { typedef _Tp __type; };
7b50cdef
BK
1029
1030 template<>
1031 struct __make_signed<char>
1032 { typedef signed char __type; };
1033
1034 template<>
1035 struct __make_signed<unsigned char>
1036 { typedef signed char __type; };
1037
7b50cdef
BK
1038 template<>
1039 struct __make_signed<unsigned short>
1040 { typedef signed short __type; };
1041
1042 template<>
1043 struct __make_signed<unsigned int>
1044 { typedef signed int __type; };
1045
1046 template<>
1047 struct __make_signed<unsigned long>
1048 { typedef signed long __type; };
1049
1050 template<>
1051 struct __make_signed<unsigned long long>
1052 { typedef signed long long __type; };
1053
1054
fb8ffd10 1055 // Select between integral and enum: not possible to be both.
7b50cdef
BK
1056 template<typename _Tp,
1057 bool _IsInt = is_integral<_Tp>::value,
7b50cdef 1058 bool _IsEnum = is_enum<_Tp>::value>
b0302c68
PC
1059 class __make_signed_selector;
1060
7b50cdef 1061 template<typename _Tp>
b0302c68 1062 class __make_signed_selector<_Tp, true, false>
7b50cdef 1063 {
7b50cdef
BK
1064 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
1065 typedef typename __signedt::__type __signed_type;
1066 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
1067
1068 public:
1069 typedef typename __cv_signed::__type __type;
1070 };
1071
7b50cdef 1072 template<typename _Tp>
b0302c68 1073 class __make_signed_selector<_Tp, false, true>
7b50cdef 1074 {
a0230468
MM
1075 // With -fshort-enums, an enum may be as small as a char.
1076 typedef signed char __smallest;
1077 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
1078 static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
ce2e6349 1079 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
a0230468
MM
1080 typedef conditional<__b2, signed int, signed long> __cond2;
1081 typedef typename __cond2::type __cond2_type;
1082 typedef conditional<__b1, signed short, __cond2_type> __cond1;
1083 typedef typename __cond1::type __cond1_type;
7b50cdef
BK
1084
1085 public:
a0230468 1086 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
7b50cdef
BK
1087 };
1088
7b50cdef
BK
1089 // Given an integral/enum type, return the corresponding signed
1090 // integer type.
5b9daa7e
BK
1091 // Primary template.
1092 /// make_signed
7b50cdef
BK
1093 template<typename _Tp>
1094 struct make_signed
1095 { typedef typename __make_signed_selector<_Tp>::__type type; };
1096
1097 // Integral, but don't define.
1098 template<>
1099 struct make_signed<bool>;
cfa9a96b 1100
5b9daa7e 1101 /// common_type
cfa9a96b
CF
1102 template<typename... _Tp>
1103 struct common_type;
1104
1105 template<typename _Tp>
1106 struct common_type<_Tp>
7274deff 1107 { typedef _Tp type; };
cfa9a96b
CF
1108
1109 template<typename _Tp, typename _Up>
7274deff
PC
1110 struct common_type<_Tp, _Up>
1111 { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
cfa9a96b
CF
1112
1113 template<typename _Tp, typename _Up, typename... _Vp>
1114 struct common_type<_Tp, _Up, _Vp...>
1115 {
1116 typedef typename
1117 common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
1118 };
7274deff
PC
1119
1120 /// declval
1121 template<typename _Tp>
1122 struct __declval_protector
1123 {
1124 static const bool __stop = false;
1125 static typename add_rvalue_reference<_Tp>::type __delegate();
1126 };
1127
1128 template<typename _Tp>
1129 inline typename add_rvalue_reference<_Tp>::type
e4f32cb0 1130 declval() noexcept
7274deff
PC
1131 {
1132 static_assert(__declval_protector<_Tp>::__stop,
1133 "declval() must not be used!");
1134 return __declval_protector<_Tp>::__delegate();
1135 }
1041daba
PC
1136
1137 /// result_of
1138 template<typename _Signature>
1139 class result_of;
1140
1141 template<typename _Functor, typename... _ArgTypes>
1142 struct result_of<_Functor(_ArgTypes...)>
1143 {
1144 typedef
1145 decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
1146 type;
1147 };
1148
033b71ce
PC
1149 /**
1150 * Use SFINAE to determine if the type _Tp has a publicly-accessible
1151 * member type _NTYPE.
1152 */
1153#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
1154 template<typename _Tp> \
1155 class __has_##_NTYPE##_helper \
1156 : __sfinae_types \
1157 { \
1158 template<typename _Up> \
1159 struct _Wrap_type \
1160 { }; \
1161 \
1162 template<typename _Up> \
1163 static __one __test(_Wrap_type<typename _Up::_NTYPE>*); \
1164 \
1165 template<typename _Up> \
1166 static __two __test(...); \
1167 \
1168 public: \
1169 static const bool value = sizeof(__test<_Tp>(0)) == 1; \
1170 }; \
1171 \
1172 template<typename _Tp> \
1173 struct __has_##_NTYPE \
1174 : integral_constant<bool, __has_##_NTYPE##_helper \
1175 <typename remove_cv<_Tp>::type>::value> \
1176 { };
1177
53dc5044
PC
1178#undef _DEFINE_SPEC_0_HELPER
1179#undef _DEFINE_SPEC_1_HELPER
1180#undef _DEFINE_SPEC_2_HELPER
1181#undef _DEFINE_SPEC
1182
1041daba 1183 // @} group metaprogramming
53dc5044 1184_GLIBCXX_END_NAMESPACE
7b50cdef 1185
57317d2a
PC
1186#endif // __GXX_EXPERIMENTAL_CXX0X__
1187
7274deff 1188#endif // _GLIBCXX_TYPE_TRAITS