]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/type_traits
Daily bump.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / type_traits
CommitLineData
5b9daa7e 1// C++0x type_traits -*- C++ -*-
af13a7a6 2
123c516a 3// Copyright (C) 2007, 2008, 2009, 2010, 2011 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
12ffa228
BK
40namespace std _GLIBCXX_VISIBILITY(default)
41{
42_GLIBCXX_BEGIN_NAMESPACE_VERSION
e133ace8 43
8e32aa11
BK
44 /**
45 * @addtogroup metaprogramming
5b9daa7e
BK
46 * @{
47 */
53dc5044
PC
48 struct __sfinae_types
49 {
50 typedef char __one;
51 typedef struct { char __arr[2]; } __two;
52 };
53
123c516a 54 // Meta programming helper types.
53dc5044 55
123c516a
PC
56 template<bool, typename, typename>
57 struct conditional;
53dc5044 58
123c516a
PC
59 template<typename _Tp, _Tp>
60 struct integral_constant;
61
62 template<typename, typename, typename...>
63 struct __or_;
64
65 template<typename _B1, typename _B2>
66 struct __or_<_B1, _B2>
67 : public conditional<_B1::value, _B1, _B2>::type
68 { };
69
70 template<typename _B1, typename _B2, typename _B3, typename... _Bn>
71 struct __or_<_B1, _B2, _B3, _Bn...>
72 : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type
73 { };
53dc5044 74
123c516a
PC
75 template<typename, typename, typename...>
76 struct __and_;
53dc5044 77
123c516a
PC
78 template<typename _B1, typename _B2>
79 struct __and_<_B1, _B2>
80 : public conditional<_B1::value, _B2, _B1>::type
81 { };
82
83 template<typename _B1, typename _B2, typename _B3, typename... _Bn>
84 struct __and_<_B1, _B2, _B3, _Bn...>
85 : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type
86 { };
87
88 template<typename _Pp>
89 struct __not_
90 : public integral_constant<bool, !_Pp::value>
91 { };
92
93 // helper class.
53dc5044
PC
94
95 /// integral_constant
96 template<typename _Tp, _Tp __v>
97 struct integral_constant
98 {
99 static constexpr _Tp value = __v;
100 typedef _Tp value_type;
101 typedef integral_constant<_Tp, __v> type;
102 constexpr operator value_type() { return value; }
103 };
104
105 /// typedef for true_type
106 typedef integral_constant<bool, true> true_type;
107
108 /// typedef for false_type
109 typedef integral_constant<bool, false> false_type;
110
111 template<typename _Tp, _Tp __v>
112 constexpr _Tp integral_constant<_Tp, __v>::value;
113
123c516a
PC
114 // primary type categories.
115
53dc5044
PC
116 template<typename>
117 struct remove_cv;
118
119 template<typename>
120 struct __is_void_helper
121 : public false_type { };
53dc5044 122
123c516a
PC
123 template<>
124 struct __is_void_helper<void>
125 : public true_type { };
53dc5044
PC
126
127 /// is_void
128 template<typename _Tp>
129 struct is_void
130 : public integral_constant<bool, (__is_void_helper<typename
131 remove_cv<_Tp>::type>::value)>
132 { };
133
134 template<typename>
135 struct __is_integral_helper
136 : public false_type { };
123c516a
PC
137
138 template<>
139 struct __is_integral_helper<bool>
140 : public true_type { };
141
142 template<>
143 struct __is_integral_helper<char>
144 : public true_type { };
145
146 template<>
147 struct __is_integral_helper<signed char>
148 : public true_type { };
149
150 template<>
151 struct __is_integral_helper<unsigned char>
152 : public true_type { };
153
53dc5044 154#ifdef _GLIBCXX_USE_WCHAR_T
123c516a
PC
155 template<>
156 struct __is_integral_helper<wchar_t>
157 : public true_type { };
53dc5044 158#endif
123c516a
PC
159
160 template<>
161 struct __is_integral_helper<char16_t>
162 : public true_type { };
163
164 template<>
165 struct __is_integral_helper<char32_t>
166 : public true_type { };
167
168 template<>
169 struct __is_integral_helper<short>
170 : public true_type { };
171
172 template<>
173 struct __is_integral_helper<unsigned short>
174 : public true_type { };
175
176 template<>
177 struct __is_integral_helper<int>
178 : public true_type { };
179
180 template<>
181 struct __is_integral_helper<unsigned int>
182 : public true_type { };
183
184 template<>
185 struct __is_integral_helper<long>
186 : public true_type { };
187
188 template<>
189 struct __is_integral_helper<unsigned long>
190 : public true_type { };
191
192 template<>
193 struct __is_integral_helper<long long>
194 : public true_type { };
195
196 template<>
197 struct __is_integral_helper<unsigned long long>
198 : public true_type { };
53dc5044
PC
199
200 /// is_integral
201 template<typename _Tp>
202 struct is_integral
203 : public integral_constant<bool, (__is_integral_helper<typename
204 remove_cv<_Tp>::type>::value)>
205 { };
206
207 template<typename>
208 struct __is_floating_point_helper
209 : public false_type { };
123c516a
PC
210
211 template<>
212 struct __is_floating_point_helper<float>
213 : public true_type { };
214
215 template<>
216 struct __is_floating_point_helper<double>
217 : public true_type { };
218
219 template<>
220 struct __is_floating_point_helper<long double>
221 : public true_type { };
53dc5044
PC
222
223 /// is_floating_point
224 template<typename _Tp>
225 struct is_floating_point
226 : public integral_constant<bool, (__is_floating_point_helper<typename
227 remove_cv<_Tp>::type>::value)>
228 { };
229
230 /// is_array
231 template<typename>
232 struct is_array
233 : public false_type { };
234
235 template<typename _Tp, std::size_t _Size>
236 struct is_array<_Tp[_Size]>
237 : public true_type { };
238
239 template<typename _Tp>
240 struct is_array<_Tp[]>
241 : public true_type { };
242
243 template<typename>
244 struct __is_pointer_helper
245 : public false_type { };
123c516a
PC
246
247 template<typename _Tp>
248 struct __is_pointer_helper<_Tp*>
249 : public true_type { };
53dc5044
PC
250
251 /// is_pointer
252 template<typename _Tp>
253 struct is_pointer
254 : public integral_constant<bool, (__is_pointer_helper<typename
255 remove_cv<_Tp>::type>::value)>
256 { };
257
123c516a
PC
258 /// is_lvalue_reference
259 template<typename>
260 struct is_lvalue_reference
261 : public false_type { };
262
53dc5044 263 template<typename _Tp>
123c516a
PC
264 struct is_lvalue_reference<_Tp&>
265 : public true_type { };
266
267 /// is_rvalue_reference
268 template<typename>
269 struct is_rvalue_reference
270 : public false_type { };
53dc5044 271
53dc5044 272 template<typename _Tp>
123c516a
PC
273 struct is_rvalue_reference<_Tp&&>
274 : public true_type { };
275
276 template<typename>
53dc5044
PC
277 struct is_function;
278
279 template<typename>
280 struct __is_member_object_pointer_helper
281 : public false_type { };
123c516a
PC
282
283 template<typename _Tp, typename _Cp>
284 struct __is_member_object_pointer_helper<_Tp _Cp::*>
285 : public integral_constant<bool, !is_function<_Tp>::value> { };
53dc5044
PC
286
287 /// is_member_object_pointer
288 template<typename _Tp>
289 struct is_member_object_pointer
290 : public integral_constant<bool, (__is_member_object_pointer_helper<
291 typename remove_cv<_Tp>::type>::value)>
292 { };
293
294 template<typename>
295 struct __is_member_function_pointer_helper
296 : public false_type { };
123c516a
PC
297
298 template<typename _Tp, typename _Cp>
299 struct __is_member_function_pointer_helper<_Tp _Cp::*>
300 : public integral_constant<bool, is_function<_Tp>::value> { };
53dc5044
PC
301
302 /// is_member_function_pointer
303 template<typename _Tp>
304 struct is_member_function_pointer
305 : public integral_constant<bool, (__is_member_function_pointer_helper<
306 typename remove_cv<_Tp>::type>::value)>
307 { };
308
309 /// is_enum
310 template<typename _Tp>
311 struct is_enum
312 : public integral_constant<bool, __is_enum(_Tp)>
313 { };
314
315 /// is_union
316 template<typename _Tp>
317 struct is_union
318 : public integral_constant<bool, __is_union(_Tp)>
319 { };
320
321 /// is_class
322 template<typename _Tp>
323 struct is_class
324 : public integral_constant<bool, __is_class(_Tp)>
325 { };
326
327 /// is_function
328 template<typename>
329 struct is_function
330 : public false_type { };
123c516a 331
53dc5044
PC
332 template<typename _Res, typename... _ArgTypes>
333 struct is_function<_Res(_ArgTypes...)>
334 : public true_type { };
123c516a 335
53dc5044
PC
336 template<typename _Res, typename... _ArgTypes>
337 struct is_function<_Res(_ArgTypes......)>
338 : public true_type { };
123c516a 339
53dc5044
PC
340 template<typename _Res, typename... _ArgTypes>
341 struct is_function<_Res(_ArgTypes...) const>
342 : public true_type { };
123c516a 343
53dc5044
PC
344 template<typename _Res, typename... _ArgTypes>
345 struct is_function<_Res(_ArgTypes......) const>
346 : public true_type { };
123c516a 347
53dc5044
PC
348 template<typename _Res, typename... _ArgTypes>
349 struct is_function<_Res(_ArgTypes...) volatile>
350 : public true_type { };
123c516a 351
53dc5044
PC
352 template<typename _Res, typename... _ArgTypes>
353 struct is_function<_Res(_ArgTypes......) volatile>
354 : public true_type { };
123c516a 355
53dc5044
PC
356 template<typename _Res, typename... _ArgTypes>
357 struct is_function<_Res(_ArgTypes...) const volatile>
358 : public true_type { };
123c516a 359
53dc5044
PC
360 template<typename _Res, typename... _ArgTypes>
361 struct is_function<_Res(_ArgTypes......) const volatile>
362 : public true_type { };
363
1e673415
PC
364 template<typename>
365 struct __is_nullptr_t_helper
366 : public false_type { };
123c516a
PC
367
368 template<>
369 struct __is_nullptr_t_helper<std::nullptr_t>
370 : public true_type { };
1e673415
PC
371
372 // __is_nullptr_t (extension).
373 template<typename _Tp>
374 struct __is_nullptr_t
375 : public integral_constant<bool, (__is_nullptr_t_helper<typename
376 remove_cv<_Tp>::type>::value)>
377 { };
378
123c516a
PC
379 // composite type categories.
380
381 /// is_reference
382 template<typename _Tp>
383 struct is_reference
384 : public __or_<is_lvalue_reference<_Tp>,
385 is_rvalue_reference<_Tp>>::type
386 { };
387
53dc5044
PC
388 /// is_arithmetic
389 template<typename _Tp>
390 struct is_arithmetic
123c516a 391 : public __or_<is_integral<_Tp>, is_floating_point<_Tp>>::type
53dc5044
PC
392 { };
393
394 /// is_fundamental
395 template<typename _Tp>
396 struct is_fundamental
123c516a 397 : public __or_<is_arithmetic<_Tp>, is_void<_Tp>>::type
53dc5044
PC
398 { };
399
400 /// is_object
401 template<typename _Tp>
402 struct is_object
123c516a
PC
403 : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>,
404 is_void<_Tp>>>::type
53dc5044
PC
405 { };
406
123c516a 407 template<typename>
53dc5044
PC
408 struct is_member_pointer;
409
410 /// is_scalar
411 template<typename _Tp>
412 struct is_scalar
123c516a
PC
413 : public __or_<is_arithmetic<_Tp>, is_enum<_Tp>, is_pointer<_Tp>,
414 is_member_pointer<_Tp>, __is_nullptr_t<_Tp>>::type
53dc5044
PC
415 { };
416
417 /// is_compound
418 template<typename _Tp>
419 struct is_compound
420 : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
421
422 /// is_member_pointer
423 template<typename _Tp>
424 struct __is_member_pointer_helper
425 : public false_type { };
123c516a
PC
426
427 template<typename _Tp, typename _Cp>
428 struct __is_member_pointer_helper<_Tp _Cp::*>
429 : public true_type { };
53dc5044
PC
430
431 template<typename _Tp>
123c516a 432 struct is_member_pointer
53dc5044
PC
433 : public integral_constant<bool, (__is_member_pointer_helper<
434 typename remove_cv<_Tp>::type>::value)>
435 { };
436
437 // type properties.
123c516a 438
53dc5044
PC
439 /// is_const
440 template<typename>
441 struct is_const
442 : public false_type { };
443
444 template<typename _Tp>
445 struct is_const<_Tp const>
446 : public true_type { };
447
448 /// is_volatile
449 template<typename>
450 struct is_volatile
451 : public false_type { };
452
453 template<typename _Tp>
454 struct is_volatile<_Tp volatile>
455 : public true_type { };
456
123c516a
PC
457 /// is_trivial
458 template<typename _Tp>
459 struct is_trivial
460 : public integral_constant<bool, __is_trivial(_Tp)>
461 { };
462
463 /// is_trivially_copyable (still unimplemented)
464
465 /// is_standard_layout
466 template<typename _Tp>
467 struct is_standard_layout
468 : public integral_constant<bool, __is_standard_layout(_Tp)>
469 { };
470
471 /// is_pod
472 // Could use is_standard_layout && is_trivial instead of the builtin.
473 template<typename _Tp>
474 struct is_pod
475 : public integral_constant<bool, __is_pod(_Tp)>
476 { };
477
478 /// is_literal_type
479 template<typename _Tp>
480 struct is_literal_type
481 : public integral_constant<bool, __is_literal_type(_Tp)>
482 { };
483
53dc5044
PC
484 /// is_empty
485 template<typename _Tp>
486 struct is_empty
487 : public integral_constant<bool, __is_empty(_Tp)>
488 { };
489
490 /// is_polymorphic
491 template<typename _Tp>
492 struct is_polymorphic
493 : public integral_constant<bool, __is_polymorphic(_Tp)>
494 { };
495
496 /// is_abstract
497 template<typename _Tp>
498 struct is_abstract
499 : public integral_constant<bool, __is_abstract(_Tp)>
500 { };
501
123c516a
PC
502 template<typename _Tp,
503 bool = is_integral<_Tp>::value,
504 bool = is_floating_point<_Tp>::value>
505 struct __is_signed_helper
506 : public false_type { };
507
53dc5044 508 template<typename _Tp>
123c516a
PC
509 struct __is_signed_helper<_Tp, false, true>
510 : public true_type { };
511
512 template<typename _Tp>
513 struct __is_signed_helper<_Tp, true, false>
514 : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))>
53dc5044
PC
515 { };
516
123c516a 517 /// is_signed
53dc5044 518 template<typename _Tp>
123c516a
PC
519 struct is_signed
520 : public integral_constant<bool, __is_signed_helper<_Tp>::value>
521 { };
522
523 /// is_unsigned
524 template<typename _Tp>
525 struct is_unsigned
526 : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>>::type
527 { };
528
529
530 // destructible and constructible type properties
531
53dc5044 532 template<typename>
123c516a 533 struct add_rvalue_reference;
53dc5044
PC
534
535 template<typename _Tp>
123c516a 536 typename add_rvalue_reference<_Tp>::type declval() noexcept;
53dc5044 537
123c516a
PC
538 template<typename, unsigned = 0>
539 struct extent;
540
541 template<typename>
542 struct remove_all_extents;
543
544 template<typename _Tp>
545 struct __is_array_known_bounds
546 : public integral_constant<bool, (extent<_Tp>::value > 0)>
53dc5044
PC
547 { };
548
123c516a
PC
549 template<typename _Tp>
550 struct __is_array_unknown_bounds
551 : public __and_<is_array<_Tp>, __not_<extent<_Tp>>>::type
53dc5044 552 { };
2c7a09d7
PC
553
554 // In N3290 is_destructible does not say anything about function
555 // types and abstract types, see LWG 2049. This implementation
556 // describes function types as trivially nothrow destructible and
557 // abstract types as destructible, iff the explicit destructor
558 // call expression is wellformed.
123c516a
PC
559 struct __do_is_destructible_impl_1
560 {
561 template<typename _Up>
562 struct __w { _Up __u; };
53dc5044 563
123c516a
PC
564 template<typename _Tp, typename
565 = decltype(declval<__w<_Tp>&>().~__w<_Tp>())>
566 static true_type __test(int);
567
568 template<typename>
569 static false_type __test(...);
570 };
53dc5044
PC
571
572 template<typename _Tp>
123c516a
PC
573 struct __is_destructible_impl_1
574 : public __do_is_destructible_impl_1
575 {
576 typedef decltype(__test<_Tp>(0)) type;
577 };
53dc5044 578
2c7a09d7 579 // Special implementation for abstract types
123c516a
PC
580 struct __do_is_destructible_impl_2
581 {
582 template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())>
583 static true_type __test(int);
584
585 template<typename>
586 static false_type __test(...);
587 };
53dc5044 588
53dc5044 589 template<typename _Tp>
123c516a
PC
590 struct __is_destructible_impl_2
591 : public __do_is_destructible_impl_2
592 {
593 typedef decltype(__test<_Tp>(0)) type;
594 };
595
596 template<typename _Tp,
597 bool = __or_<is_void<_Tp>,
598 __is_array_unknown_bounds<_Tp>>::value,
599 bool = __or_<is_reference<_Tp>, is_function<_Tp>>::value>
600 struct __is_destructible_safe;
53dc5044
PC
601
602 template<typename _Tp>
123c516a
PC
603 struct __is_destructible_safe<_Tp, false, false>
604 : public conditional<is_abstract<_Tp>::value,
605 __is_destructible_impl_2<_Tp>,
606 __is_destructible_impl_1<_Tp>>::type::type
607 { };
608
53dc5044 609 template<typename _Tp>
123c516a
PC
610 struct __is_destructible_safe<_Tp, true, false>
611 : public false_type { };
53dc5044
PC
612
613 template<typename _Tp>
123c516a
PC
614 struct __is_destructible_safe<_Tp, false, true>
615 : public true_type { };
616
617 /// is_destructible
53dc5044 618 template<typename _Tp>
123c516a
PC
619 struct is_destructible
620 : public integral_constant<bool, (__is_destructible_safe<_Tp>::value)>
621 { };
622
623 struct __do_is_default_constructible_impl
624 {
625 template<typename _Tp, typename = decltype(_Tp())>
626 static true_type __test(int);
627
628 template<typename>
629 static false_type __test(...);
630 };
631
632 template<typename _Tp>
633 struct __is_default_constructible_impl
634 : public __do_is_default_constructible_impl
53dc5044 635 {
123c516a 636 typedef decltype(__test<_Tp>(0)) type;
53dc5044 637 };
53dc5044
PC
638
639 template<typename _Tp>
123c516a 640 struct __is_default_constructible_atom
2c7a09d7
PC
641 : public __and_<__not_<is_void<_Tp>>,
642 __is_default_constructible_impl<_Tp>>::type
123c516a 643 { };
53dc5044 644
123c516a
PC
645 template<typename _Tp, bool = is_array<_Tp>::value>
646 struct __is_default_constructible_safe;
53dc5044 647
2c7a09d7
PC
648 // The following technique is a workaround for a current core language
649 // restriction, which does not allow for array types to occur in
650 // functional casts of the form T(). Complete arrays can be default-
651 // constructed, if the element type is default-constructible, but
652 // arrays with unknown bounds are not.
53dc5044 653 template<typename _Tp>
123c516a
PC
654 struct __is_default_constructible_safe<_Tp, true>
655 : public __and_<__is_array_known_bounds<_Tp>,
656 __is_default_constructible_atom<typename
2c7a09d7 657 remove_all_extents<_Tp>::type>>::type
53dc5044
PC
658 { };
659
53dc5044 660 template<typename _Tp>
123c516a
PC
661 struct __is_default_constructible_safe<_Tp, false>
662 : public __is_default_constructible_atom<_Tp>::type
663 { };
4a27a739 664
123c516a 665 /// is_default_constructible
4a27a739 666 template<typename _Tp>
123c516a
PC
667 struct is_default_constructible
668 : public integral_constant<bool, (__is_default_constructible_safe<
669 _Tp>::value)>
670 { };
4a27a739 671
2c7a09d7
PC
672
673 // Implementation of is_constructible.
674
675 // The hardest part of this trait is the binary direct-initialization
676 // case, because we hit into a functional cast of the form T(arg).
677 // This implementation uses different strategies depending on the
678 // target type to reduce the test overhead as much as possible:
679 //
680 // a) For a reference target type, we use a static_cast expression
681 // modulo its extra cases.
682 //
683 // b) For a non-reference target type we use a ::new expression.
123c516a
PC
684 struct __do_is_static_castable_impl
685 {
686 template<typename _From, typename _To, typename
687 = decltype(static_cast<_To>(declval<_From>()))>
688 static true_type __test(int);
4a27a739 689
123c516a
PC
690 template<typename, typename>
691 static false_type __test(...);
692 };
4a27a739 693
123c516a
PC
694 template<typename _From, typename _To>
695 struct __is_static_castable_impl
696 : public __do_is_static_castable_impl
697 {
698 typedef decltype(__test<_From, _To>(0)) type;
699 };
939759fc 700
123c516a
PC
701 template<typename _From, typename _To>
702 struct __is_static_castable_safe
2c7a09d7 703 : public __is_static_castable_impl<_From, _To>::type
4a27a739
PC
704 { };
705
123c516a
PC
706 // __is_static_castable
707 template<typename _From, typename _To>
708 struct __is_static_castable
709 : public integral_constant<bool, (__is_static_castable_safe<
710 _From, _To>::value)>
711 { };
939759fc 712
2c7a09d7
PC
713 // Implementation for non-reference types. To meet the proper
714 // variable definition semantics, we also need to test for
715 // is_destructible in this case.
123c516a
PC
716 struct __do_is_direct_constructible_impl
717 {
718 template<typename _Tp, typename _Arg, typename
719 = decltype(::new _Tp(declval<_Arg>()))>
720 static true_type __test(int);
4a27a739 721
123c516a
PC
722 template<typename, typename>
723 static false_type __test(...);
724 };
4a27a739 725
123c516a
PC
726 template<typename _Tp, typename _Arg>
727 struct __is_direct_constructible_impl
728 : public __do_is_direct_constructible_impl
729 {
730 typedef decltype(__test<_Tp, _Arg>(0)) type;
731 };
4a27a739 732
123c516a
PC
733 template<typename _Tp, typename _Arg>
734 struct __is_direct_constructible_new_safe
735 : public __and_<is_destructible<_Tp>,
2c7a09d7 736 __is_direct_constructible_impl<_Tp, _Arg>>::type
123c516a 737 { };
4a27a739 738
123c516a
PC
739 template<typename, typename>
740 struct is_same;
4a27a739 741
123c516a
PC
742 template<typename, typename>
743 struct is_base_of;
4a27a739 744
123c516a
PC
745 template<typename>
746 struct remove_reference;
4a27a739 747
123c516a
PC
748 template<typename _From, typename _To, bool
749 = is_reference<_From>::value>
750 struct __is_base_to_derived_ref;
4a27a739 751
123c516a
PC
752 template<typename _From, typename _To>
753 struct __is_base_to_derived_ref<_From, _To, true>
754 {
755 typedef typename remove_cv<typename remove_reference<_From
756 >::type>::type __src_t;
757 typedef typename remove_cv<typename remove_reference<_To
758 >::type>::type __dst_t;
2c7a09d7
PC
759 typedef __and_<__not_<is_same<__src_t, __dst_t>>,
760 is_base_of<__src_t, __dst_t>> type;
123c516a
PC
761 static constexpr bool value = type::value;
762 };
4a27a739 763
123c516a
PC
764 template<typename _From, typename _To>
765 struct __is_base_to_derived_ref<_From, _To, false>
766 : public false_type
4a27a739
PC
767 { };
768
123c516a
PC
769 template<typename _From, typename _To, bool
770 = __and_<is_lvalue_reference<_From>,
771 is_rvalue_reference<_To>>::value>
772 struct __is_lvalue_to_rvalue_ref;
e133ace8 773
123c516a
PC
774 template<typename _From, typename _To>
775 struct __is_lvalue_to_rvalue_ref<_From, _To, true>
776 {
777 typedef typename remove_cv<typename remove_reference<
778 _From>::type>::type __src_t;
779 typedef typename remove_cv<typename remove_reference<
780 _To>::type>::type __dst_t;
2c7a09d7
PC
781 typedef __or_<is_same<__src_t, __dst_t>,
782 is_base_of<__dst_t, __src_t>> type;
123c516a
PC
783 static constexpr bool value = type::value;
784 };
e133ace8 785
123c516a
PC
786 template<typename _From, typename _To>
787 struct __is_lvalue_to_rvalue_ref<_From, _To, false>
788 : public false_type
e133ace8
PC
789 { };
790
2c7a09d7
PC
791 // Here we handle direct-initialization to a reference type as
792 // equivalent to a static_cast modulo overshooting conversions.
793 // These are restricted to the following conversions:
794 // a) A glvalue of a base class to a derived class reference
795 // b) An lvalue to an rvalue-reference of reference-compatible
796 // types
123c516a
PC
797 template<typename _Tp, typename _Arg>
798 struct __is_direct_constructible_ref_cast
799 : public __and_<__is_static_castable<_Arg, _Tp>,
800 __not_<__or_<__is_base_to_derived_ref<_Arg, _Tp>,
801 __is_lvalue_to_rvalue_ref<_Arg, _Tp>
2c7a09d7 802 >>>::type
e133ace8
PC
803 { };
804
123c516a
PC
805 template<typename _Tp, typename _Arg>
806 struct __is_direct_constructible_new
807 : public conditional<is_reference<_Tp>::value,
808 __is_direct_constructible_ref_cast<_Tp, _Arg>,
809 __is_direct_constructible_new_safe<_Tp, _Arg>
810 >::type
b0302c68
PC
811 { };
812
123c516a
PC
813 template<typename _Tp, typename _Arg>
814 struct __is_direct_constructible
815 : public integral_constant<bool, (__is_direct_constructible_new<
2c7a09d7 816 _Tp, _Arg>::value)>
e133ace8
PC
817 { };
818
2c7a09d7
PC
819 // Since default-construction and binary direct-initialization have
820 // been handled separately, the implementation of the remaining
821 // n-ary construction cases is rather straightforward.
123c516a
PC
822 struct __do_is_nary_constructible_impl
823 {
824 template<typename _Tp, typename... _Args, typename
825 = decltype(_Tp(declval<_Args>()...))>
826 static true_type __test(int);
2b08f2c5 827
123c516a
PC
828 template<typename, typename...>
829 static false_type __test(...);
830 };
b0302c68
PC
831
832 template<typename _Tp, typename... _Args>
123c516a
PC
833 struct __is_nary_constructible_impl
834 : public __do_is_nary_constructible_impl
b0302c68 835 {
123c516a 836 typedef decltype(__test<_Tp, _Args...>(0)) type;
b0302c68
PC
837 };
838
123c516a
PC
839 template<typename _Tp, typename... _Args>
840 struct __is_nary_constructible
2c7a09d7 841 : public __is_nary_constructible_impl<_Tp, _Args...>::type
b0302c68 842 {
123c516a
PC
843 static_assert(sizeof...(_Args) > 1,
844 "Only useful for > 1 arguments");
845 };
b0302c68 846
123c516a
PC
847 template<typename _Tp, typename... _Args>
848 struct __is_constructible_impl
849 : public __is_nary_constructible<_Tp, _Args...>
850 { };
b0302c68 851
123c516a
PC
852 template<typename _Tp, typename _Arg>
853 struct __is_constructible_impl<_Tp, _Arg>
854 : public __is_direct_constructible<_Tp, _Arg>
855 { };
856
857 template<typename _Tp>
858 struct __is_constructible_impl<_Tp>
859 : public is_default_constructible<_Tp>
860 { };
b0302c68
PC
861
862 /// is_constructible
b0302c68
PC
863 template<typename _Tp, typename... _Args>
864 struct is_constructible
123c516a
PC
865 : public integral_constant<bool, (__is_constructible_impl<_Tp,
866 _Args...>::value)>
c32097d8
JM
867 { };
868
65cee9bd
PC
869 template<typename _Tp, bool = is_void<_Tp>::value>
870 struct __is_copy_constructible_impl;
123c516a 871
65cee9bd
PC
872 template<typename _Tp>
873 struct __is_copy_constructible_impl<_Tp, true>
874 : public false_type { };
875
876 template<typename _Tp>
877 struct __is_copy_constructible_impl<_Tp, false>
878 : public is_constructible<_Tp, const _Tp&>
879 { };
880
881 /// is_copy_constructible
882 template<typename _Tp>
883 struct is_copy_constructible
884 : public __is_copy_constructible_impl<_Tp>
885 { };
886
887 template<typename _Tp, bool = is_void<_Tp>::value>
888 struct __is_move_constructible_impl;
889
890 template<typename _Tp>
891 struct __is_move_constructible_impl<_Tp, true>
892 : public false_type { };
893
894 template<typename _Tp>
895 struct __is_move_constructible_impl<_Tp, false>
896 : public is_constructible<_Tp, _Tp&&>
897 { };
898
899 /// is_move_constructible
900 template<typename _Tp>
901 struct is_move_constructible
902 : public __is_move_constructible_impl<_Tp>
903 { };
904
905 template<typename _Tp>
906 struct __is_nt_default_constructible_atom
907 : public integral_constant<bool, noexcept(_Tp())>
908 { };
909
910 template<typename _Tp, bool = is_array<_Tp>::value>
911 struct __is_nt_default_constructible_impl;
912
913 template<typename _Tp>
914 struct __is_nt_default_constructible_impl<_Tp, true>
915 : public __and_<__is_array_known_bounds<_Tp>,
916 __is_nt_default_constructible_atom<typename
917 remove_all_extents<_Tp>::type>>::type
918 { };
919
920 template<typename _Tp>
921 struct __is_nt_default_constructible_impl<_Tp, false>
922 : public __is_nt_default_constructible_atom<_Tp>
923 { };
924
925 /// is_nothrow_default_constructible
926 template<typename _Tp>
927 struct is_nothrow_default_constructible
928 : public __and_<is_default_constructible<_Tp>,
929 __is_nt_default_constructible_impl<_Tp>>::type
930 { };
e4f32cb0
PC
931
932 template<typename _Tp, typename... _Args>
65cee9bd
PC
933 struct __is_nt_constructible_impl
934 : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
935 { };
e4f32cb0
PC
936
937 template<typename _Tp, typename _Arg>
65cee9bd
PC
938 struct __is_nt_constructible_impl<_Tp, _Arg>
939 : public integral_constant<bool,
940 noexcept(static_cast<_Tp>(declval<_Arg>()))>
941 { };
942
943 template<typename _Tp>
944 struct __is_nt_constructible_impl<_Tp>
945 : public is_nothrow_default_constructible<_Tp>
946 { };
e4f32cb0
PC
947
948 /// is_nothrow_constructible
949 template<typename _Tp, typename... _Args>
950 struct is_nothrow_constructible
65cee9bd
PC
951 : public __and_<is_constructible<_Tp, _Args...>,
952 __is_nt_constructible_impl<_Tp, _Args...>>::type
953 { };
954
955 template<typename _Tp, bool = is_void<_Tp>::value>
956 struct __is_nothrow_copy_constructible_impl;
957
958 template<typename _Tp>
959 struct __is_nothrow_copy_constructible_impl<_Tp, true>
960 : public false_type { };
961
962 template<typename _Tp>
963 struct __is_nothrow_copy_constructible_impl<_Tp, false>
964 : public is_nothrow_constructible<_Tp, const _Tp&>
965 { };
966
967 /// is_nothrow_copy_constructible
968 template<typename _Tp>
969 struct is_nothrow_copy_constructible
970 : public __is_nothrow_copy_constructible_impl<_Tp>
971 { };
972
973 template<typename _Tp, bool = is_void<_Tp>::value>
974 struct __is_nothrow_move_constructible_impl;
975
976 template<typename _Tp>
977 struct __is_nothrow_move_constructible_impl<_Tp, true>
978 : public false_type { };
979
980 template<typename _Tp>
981 struct __is_nothrow_move_constructible_impl<_Tp, false>
982 : public is_nothrow_constructible<_Tp, _Tp&&>
983 { };
984
985 /// is_nothrow_move_constructible
986 template<typename _Tp>
987 struct is_nothrow_move_constructible
988 : public __is_nothrow_move_constructible_impl<_Tp>
989 { };
990
f263981a
PC
991 template<typename _Tp, typename _Up>
992 class __is_assignable_helper
993 : public __sfinae_types
994 {
995 template<typename _Tp1, typename _Up1>
996 static decltype(declval<_Tp1>() = declval<_Up1>(), __one())
997 __test(int);
998
999 template<typename, typename>
1000 static __two __test(...);
1001
1002 public:
1003 static constexpr bool value = sizeof(__test<_Tp, _Up>(0)) == 1;
1004 };
1005
1006 /// is_assignable
1007 template<typename _Tp, typename _Up>
1008 struct is_assignable
1009 : public integral_constant<bool,
1010 __is_assignable_helper<_Tp, _Up>::value>
1011 { };
1012
1013 template<typename _Tp, bool = is_void<_Tp>::value>
1014 struct __is_copy_assignable_impl;
1015
1016 template<typename _Tp>
1017 struct __is_copy_assignable_impl<_Tp, true>
1018 : public false_type { };
1019
1020 template<typename _Tp>
1021 struct __is_copy_assignable_impl<_Tp, false>
1022 : public is_assignable<_Tp&, const _Tp&&>
1023 { };
1024
1025 /// is_copy_assignable
1026 template<typename _Tp>
1027 struct is_copy_assignable
1028 : public __is_copy_assignable_impl<_Tp>
1029 { };
1030
1031 template<typename _Tp, bool = is_void<_Tp>::value>
1032 struct __is_move_assignable_impl;
1033
1034 template<typename _Tp>
1035 struct __is_move_assignable_impl<_Tp, true>
1036 : public false_type { };
1037
1038 template<typename _Tp>
1039 struct __is_move_assignable_impl<_Tp, false>
1040 : public is_assignable<_Tp&, _Tp&&>
1041 { };
1042
1043 /// is_move_assignable
1044 template<typename _Tp>
1045 struct is_move_assignable
1046 : public __is_move_assignable_impl<_Tp>
1047 { };
1048
1049 template<typename _Tp, typename _Up>
1050 struct __is_nt_assignable_impl
1051 : public integral_constant<bool, noexcept(declval<_Tp>() = declval<_Up>())>
1052 { };
1053
1054 /// is_nothrow_assignable
1055 template<typename _Tp, typename _Up>
1056 struct is_nothrow_assignable
1057 : public __and_<is_assignable<_Tp, _Up>,
1058 __is_nt_assignable_impl<_Tp, _Up>>::type
1059 { };
1060
1061 template<typename _Tp, bool = is_void<_Tp>::value>
1062 struct __is_nt_copy_assignable_impl;
1063
1064 template<typename _Tp>
1065 struct __is_nt_copy_assignable_impl<_Tp, true>
1066 : public false_type { };
1067
1068 template<typename _Tp>
1069 struct __is_nt_copy_assignable_impl<_Tp, false>
1070 : public is_nothrow_assignable<_Tp&, const _Tp&&>
1071 { };
1072
1073 /// is_nothrow_copy_assignable
1074 template<typename _Tp>
1075 struct is_nothrow_copy_assignable
1076 : public __is_nt_copy_assignable_impl<_Tp>
1077 { };
1078
1079 template<typename _Tp, bool = is_void<_Tp>::value>
1080 struct __is_nt_move_assignable_impl;
1081
1082 template<typename _Tp>
1083 struct __is_nt_move_assignable_impl<_Tp, true>
1084 : public false_type { };
1085
1086 template<typename _Tp>
1087 struct __is_nt_move_assignable_impl<_Tp, false>
1088 : public is_nothrow_assignable<_Tp&, _Tp&&>
1089 { };
1090
1091 /// is_nothrow_move_assignable
65cee9bd 1092 template<typename _Tp>
f263981a
PC
1093 struct is_nothrow_move_assignable
1094 : public __is_nt_move_assignable_impl<_Tp>
e4f32cb0
PC
1095 { };
1096
939759fc 1097 /// has_trivial_default_constructor
e133ace8
PC
1098 template<typename _Tp>
1099 struct has_trivial_default_constructor
1100 : public integral_constant<bool, __has_trivial_constructor(_Tp)>
1101 { };
1102
939759fc 1103 /// has_trivial_copy_constructor
e133ace8
PC
1104 template<typename _Tp>
1105 struct has_trivial_copy_constructor
1106 : public integral_constant<bool, __has_trivial_copy(_Tp)>
1107 { };
1108
6f5e9b8d 1109 /// has_trivial_copy_assign
e133ace8 1110 template<typename _Tp>
6f5e9b8d 1111 struct has_trivial_copy_assign
e133ace8
PC
1112 : public integral_constant<bool, __has_trivial_assign(_Tp)>
1113 { };
1114
939759fc 1115 /// has_trivial_destructor
e133ace8
PC
1116 template<typename _Tp>
1117 struct has_trivial_destructor
1118 : public integral_constant<bool, __has_trivial_destructor(_Tp)>
1119 { };
1120
123c516a
PC
1121 /// has_virtual_destructor
1122 template<typename _Tp>
1123 struct has_virtual_destructor
1124 : public integral_constant<bool, __has_virtual_destructor(_Tp)>
1125 { };
1126
1127
1128 // type property queries.
1129
1130 /// alignment_of
1131 template<typename _Tp>
1132 struct alignment_of
1133 : public integral_constant<std::size_t, __alignof__(_Tp)> { };
1134
1135 /// rank
1136 template<typename>
1137 struct rank
1138 : public integral_constant<std::size_t, 0> { };
1139
1140 template<typename _Tp, std::size_t _Size>
1141 struct rank<_Tp[_Size]>
1142 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
1143
1144 template<typename _Tp>
1145 struct rank<_Tp[]>
1146 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
1147
1148 /// extent
1149 template<typename, unsigned _Uint>
1150 struct extent
1151 : public integral_constant<std::size_t, 0> { };
1152
1153 template<typename _Tp, unsigned _Uint, std::size_t _Size>
1154 struct extent<_Tp[_Size], _Uint>
1155 : public integral_constant<std::size_t,
1156 _Uint == 0 ? _Size : extent<_Tp,
1157 _Uint - 1>::value>
1158 { };
1159
1160 template<typename _Tp, unsigned _Uint>
1161 struct extent<_Tp[], _Uint>
1162 : public integral_constant<std::size_t,
1163 _Uint == 0 ? 0 : extent<_Tp,
1164 _Uint - 1>::value>
1165 { };
1166
1167
1168 // type relations.
1169
1170 /// is_same
1171 template<typename, typename>
1172 struct is_same
1173 : public false_type { };
1174
1175 template<typename _Tp>
1176 struct is_same<_Tp, _Tp>
1177 : public true_type { };
b0302c68 1178
939759fc 1179 /// is_base_of
e133ace8
PC
1180 template<typename _Base, typename _Derived>
1181 struct is_base_of
1182 : public integral_constant<bool, __is_base_of(_Base, _Derived)>
1183 { };
1184
297f34d7 1185 template<typename _From, typename _To,
123c516a
PC
1186 bool = __or_<is_void<_From>, is_function<_To>,
1187 is_array<_To>>::value>
297f34d7 1188 struct __is_convertible_helper
f263981a 1189 { static constexpr bool value = is_void<_To>::value; };
297f34d7 1190
e133ace8 1191 template<typename _From, typename _To>
b0302c68 1192 class __is_convertible_helper<_From, _To, false>
e133ace8
PC
1193 : public __sfinae_types
1194 {
8e7d962a
PC
1195 template<typename _To1>
1196 static void __test_aux(_To1);
1197
1198 template<typename _From1, typename _To1>
1199 static decltype(__test_aux<_To1>(std::declval<_From1>()), __one())
1200 __test(int);
1201
1202 template<typename, typename>
1203 static __two __test(...);
297f34d7 1204
e133ace8 1205 public:
f263981a 1206 static constexpr bool value = sizeof(__test<_From, _To>(0)) == 1;
e133ace8
PC
1207 };
1208
b0302c68 1209 /// is_convertible
e133ace8
PC
1210 template<typename _From, typename _To>
1211 struct is_convertible
1212 : public integral_constant<bool,
f263981a 1213 __is_convertible_helper<_From, _To>::value>
e133ace8
PC
1214 { };
1215
b0302c68 1216 /// is_explicitly_convertible
75995f37
PC
1217 template<typename _From, typename _To>
1218 struct is_explicitly_convertible
1219 : public is_constructible<_To, _From>
1220 { };
1221
fd735b6a 1222
123c516a 1223 // const-volatile modifications.
7b50cdef 1224
123c516a 1225 /// remove_const
7b50cdef 1226 template<typename _Tp>
123c516a
PC
1227 struct remove_const
1228 { typedef _Tp type; };
7b50cdef 1229
123c516a
PC
1230 template<typename _Tp>
1231 struct remove_const<_Tp const>
1232 { typedef _Tp type; };
1233
1234 /// remove_volatile
1235 template<typename _Tp>
1236 struct remove_volatile
1237 { typedef _Tp type; };
7b50cdef 1238
123c516a
PC
1239 template<typename _Tp>
1240 struct remove_volatile<_Tp volatile>
1241 { typedef _Tp type; };
1242
1243 /// remove_cv
1244 template<typename _Tp>
1245 struct remove_cv
1246 {
1247 typedef typename
1248 remove_const<typename remove_volatile<_Tp>::type>::type type;
1249 };
1250
1251 /// add_const
1252 template<typename _Tp>
1253 struct add_const
1254 { typedef _Tp const type; };
1255
1256 /// add_volatile
1257 template<typename _Tp>
1258 struct add_volatile
1259 { typedef _Tp volatile type; };
1260
1261 /// add_cv
1262 template<typename _Tp>
1263 struct add_cv
1264 {
1265 typedef typename
1266 add_const<typename add_volatile<_Tp>::type>::type type;
1267 };
7b50cdef 1268
7b50cdef 1269
123c516a 1270 // Reference transformations.
7b50cdef 1271
123c516a
PC
1272 /// remove_reference
1273 template<typename _Tp>
1274 struct remove_reference
1275 { typedef _Tp type; };
7b50cdef 1276
123c516a
PC
1277 template<typename _Tp>
1278 struct remove_reference<_Tp&>
1279 { typedef _Tp type; };
7b50cdef 1280
123c516a
PC
1281 template<typename _Tp>
1282 struct remove_reference<_Tp&&>
1283 { typedef _Tp type; };
1284
1285 template<typename _Tp,
1286 bool = __and_<__not_<is_reference<_Tp>>,
1287 __not_<is_void<_Tp>>>::value,
1288 bool = is_rvalue_reference<_Tp>::value>
1289 struct __add_lvalue_reference_helper
1290 { typedef _Tp type; };
7b50cdef 1291
5e108459 1292 template<typename _Tp>
123c516a
PC
1293 struct __add_lvalue_reference_helper<_Tp, true, false>
1294 { typedef _Tp& type; };
5e108459 1295
5e108459 1296 template<typename _Tp>
123c516a
PC
1297 struct __add_lvalue_reference_helper<_Tp, false, true>
1298 { typedef typename remove_reference<_Tp>::type& type; };
5e108459 1299
123c516a 1300 /// add_lvalue_reference
5e108459 1301 template<typename _Tp>
123c516a
PC
1302 struct add_lvalue_reference
1303 : public __add_lvalue_reference_helper<_Tp>
1304 { };
1305
1306 template<typename _Tp,
1307 bool = __and_<__not_<is_reference<_Tp>>,
1308 __not_<is_void<_Tp>>>::value>
1309 struct __add_rvalue_reference_helper
1310 { typedef _Tp type; };
5e108459
PC
1311
1312 template<typename _Tp>
123c516a
PC
1313 struct __add_rvalue_reference_helper<_Tp, true>
1314 { typedef _Tp&& type; };
5e108459 1315
123c516a 1316 /// add_rvalue_reference
5e108459 1317 template<typename _Tp>
123c516a
PC
1318 struct add_rvalue_reference
1319 : public __add_rvalue_reference_helper<_Tp>
1320 { };
5e108459 1321
7b50cdef 1322
123c516a
PC
1323 // sign modifications.
1324
7b50cdef
BK
1325 // Utility for constructing identically cv-qualified types.
1326 template<typename _Unqualified, bool _IsConst, bool _IsVol>
1327 struct __cv_selector;
1328
1329 template<typename _Unqualified>
1330 struct __cv_selector<_Unqualified, false, false>
1331 { typedef _Unqualified __type; };
1332
1333 template<typename _Unqualified>
1334 struct __cv_selector<_Unqualified, false, true>
1335 { typedef volatile _Unqualified __type; };
1336
1337 template<typename _Unqualified>
1338 struct __cv_selector<_Unqualified, true, false>
1339 { typedef const _Unqualified __type; };
1340
1341 template<typename _Unqualified>
1342 struct __cv_selector<_Unqualified, true, true>
1343 { typedef const volatile _Unqualified __type; };
1344
1345 template<typename _Qualified, typename _Unqualified,
1346 bool _IsConst = is_const<_Qualified>::value,
1347 bool _IsVol = is_volatile<_Qualified>::value>
b0302c68 1348 class __match_cv_qualifiers
7b50cdef 1349 {
7b50cdef
BK
1350 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
1351
1352 public:
1353 typedef typename __match::__type __type;
1354 };
1355
7b50cdef
BK
1356 // Utility for finding the unsigned versions of signed integral types.
1357 template<typename _Tp>
e133ace8
PC
1358 struct __make_unsigned
1359 { typedef _Tp __type; };
7b50cdef
BK
1360
1361 template<>
1362 struct __make_unsigned<char>
1363 { typedef unsigned char __type; };
1364
1365 template<>
1366 struct __make_unsigned<signed char>
1367 { typedef unsigned char __type; };
1368
7b50cdef
BK
1369 template<>
1370 struct __make_unsigned<short>
1371 { typedef unsigned short __type; };
1372
1373 template<>
1374 struct __make_unsigned<int>
1375 { typedef unsigned int __type; };
1376
1377 template<>
1378 struct __make_unsigned<long>
1379 { typedef unsigned long __type; };
1380
1381 template<>
1382 struct __make_unsigned<long long>
1383 { typedef unsigned long long __type; };
1384
7b50cdef
BK
1385 // Select between integral and enum: not possible to be both.
1386 template<typename _Tp,
1387 bool _IsInt = is_integral<_Tp>::value,
7b50cdef 1388 bool _IsEnum = is_enum<_Tp>::value>
b0302c68
PC
1389 class __make_unsigned_selector;
1390
7b50cdef 1391 template<typename _Tp>
b0302c68 1392 class __make_unsigned_selector<_Tp, true, false>
7b50cdef 1393 {
7b50cdef
BK
1394 typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
1395 typedef typename __unsignedt::__type __unsigned_type;
1396 typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
1397
1398 public:
1399 typedef typename __cv_unsigned::__type __type;
1400 };
1401
7b50cdef 1402 template<typename _Tp>
b0302c68 1403 class __make_unsigned_selector<_Tp, false, true>
7b50cdef 1404 {
a0230468
MM
1405 // With -fshort-enums, an enum may be as small as a char.
1406 typedef unsigned char __smallest;
1407 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
1408 static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
ce2e6349 1409 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
a0230468
MM
1410 typedef conditional<__b2, unsigned int, unsigned long> __cond2;
1411 typedef typename __cond2::type __cond2_type;
1412 typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
1413 typedef typename __cond1::type __cond1_type;
7b50cdef
BK
1414
1415 public:
a0230468 1416 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
7b50cdef
BK
1417 };
1418
7b50cdef
BK
1419 // Given an integral/enum type, return the corresponding unsigned
1420 // integer type.
5b9daa7e
BK
1421 // Primary template.
1422 /// make_unsigned
7b50cdef
BK
1423 template<typename _Tp>
1424 struct make_unsigned
1425 { typedef typename __make_unsigned_selector<_Tp>::__type type; };
1426
1427 // Integral, but don't define.
1428 template<>
1429 struct make_unsigned<bool>;
1430
1431
1432 // Utility for finding the signed versions of unsigned integral types.
1433 template<typename _Tp>
e133ace8
PC
1434 struct __make_signed
1435 { typedef _Tp __type; };
7b50cdef
BK
1436
1437 template<>
1438 struct __make_signed<char>
1439 { typedef signed char __type; };
1440
1441 template<>
1442 struct __make_signed<unsigned char>
1443 { typedef signed char __type; };
1444
7b50cdef
BK
1445 template<>
1446 struct __make_signed<unsigned short>
1447 { typedef signed short __type; };
1448
1449 template<>
1450 struct __make_signed<unsigned int>
1451 { typedef signed int __type; };
1452
1453 template<>
1454 struct __make_signed<unsigned long>
1455 { typedef signed long __type; };
1456
1457 template<>
1458 struct __make_signed<unsigned long long>
1459 { typedef signed long long __type; };
1460
fb8ffd10 1461 // Select between integral and enum: not possible to be both.
7b50cdef
BK
1462 template<typename _Tp,
1463 bool _IsInt = is_integral<_Tp>::value,
7b50cdef 1464 bool _IsEnum = is_enum<_Tp>::value>
b0302c68
PC
1465 class __make_signed_selector;
1466
7b50cdef 1467 template<typename _Tp>
b0302c68 1468 class __make_signed_selector<_Tp, true, false>
7b50cdef 1469 {
7b50cdef
BK
1470 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
1471 typedef typename __signedt::__type __signed_type;
1472 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
1473
1474 public:
1475 typedef typename __cv_signed::__type __type;
1476 };
1477
7b50cdef 1478 template<typename _Tp>
b0302c68 1479 class __make_signed_selector<_Tp, false, true>
7b50cdef 1480 {
a0230468
MM
1481 // With -fshort-enums, an enum may be as small as a char.
1482 typedef signed char __smallest;
1483 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
1484 static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
ce2e6349 1485 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
a0230468
MM
1486 typedef conditional<__b2, signed int, signed long> __cond2;
1487 typedef typename __cond2::type __cond2_type;
1488 typedef conditional<__b1, signed short, __cond2_type> __cond1;
1489 typedef typename __cond1::type __cond1_type;
7b50cdef
BK
1490
1491 public:
a0230468 1492 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
7b50cdef
BK
1493 };
1494
7b50cdef
BK
1495 // Given an integral/enum type, return the corresponding signed
1496 // integer type.
5b9daa7e
BK
1497 // Primary template.
1498 /// make_signed
7b50cdef
BK
1499 template<typename _Tp>
1500 struct make_signed
1501 { typedef typename __make_signed_selector<_Tp>::__type type; };
1502
1503 // Integral, but don't define.
1504 template<>
1505 struct make_signed<bool>;
cfa9a96b 1506
123c516a
PC
1507
1508 // array modifications.
1509
1510 /// remove_extent
1511 template<typename _Tp>
1512 struct remove_extent
1513 { typedef _Tp type; };
1514
1515 template<typename _Tp, std::size_t _Size>
1516 struct remove_extent<_Tp[_Size]>
1517 { typedef _Tp type; };
1518
1519 template<typename _Tp>
1520 struct remove_extent<_Tp[]>
1521 { typedef _Tp type; };
1522
1523 /// remove_all_extents
1524 template<typename _Tp>
1525 struct remove_all_extents
1526 { typedef _Tp type; };
1527
1528 template<typename _Tp, std::size_t _Size>
1529 struct remove_all_extents<_Tp[_Size]>
1530 { typedef typename remove_all_extents<_Tp>::type type; };
1531
1532 template<typename _Tp>
1533 struct remove_all_extents<_Tp[]>
1534 { typedef typename remove_all_extents<_Tp>::type type; };
1535
1536
1537 // pointer modifications.
1538
1539 template<typename _Tp, typename>
1540 struct __remove_pointer_helper
1541 { typedef _Tp type; };
1542
1543 template<typename _Tp, typename _Up>
1544 struct __remove_pointer_helper<_Tp, _Up*>
1545 { typedef _Up type; };
1546
1547 /// remove_pointer
1548 template<typename _Tp>
1549 struct remove_pointer
1550 : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
1551 { };
1552
1553 /// add_pointer
1554 template<typename _Tp>
1555 struct add_pointer
1556 { typedef typename remove_reference<_Tp>::type* type; };
1557
1558
1559 template<std::size_t _Len>
1560 struct __aligned_storage_msa
1561 {
1562 union __type
1563 {
1564 unsigned char __data[_Len];
1565 struct __attribute__((__aligned__)) { } __align;
1566 };
1567 };
1568
1569 /**
1570 * @brief Alignment type.
1571 *
1572 * The value of _Align is a default-alignment which shall be the
1573 * most stringent alignment requirement for any C++ object type
1574 * whose size is no greater than _Len (3.9). The member typedef
1575 * type shall be a POD type suitable for use as uninitialized
1576 * storage for any object whose size is at most _Len and whose
1577 * alignment is a divisor of _Align.
1578 */
1579 template<std::size_t _Len, std::size_t _Align =
1580 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
1581 struct aligned_storage
1582 {
1583 union type
1584 {
1585 unsigned char __data[_Len];
1586 struct __attribute__((__aligned__((_Align)))) { } __align;
1587 };
1588 };
1589
1590
1591 // Decay trait for arrays and functions, used for perfect forwarding
1592 // in make_pair, make_tuple, etc.
1593 template<typename _Up,
1594 bool _IsArray = is_array<_Up>::value,
1595 bool _IsFunction = is_function<_Up>::value>
1596 struct __decay_selector;
1597
1598 // NB: DR 705.
1599 template<typename _Up>
1600 struct __decay_selector<_Up, false, false>
1601 { typedef typename remove_cv<_Up>::type __type; };
1602
1603 template<typename _Up>
1604 struct __decay_selector<_Up, true, false>
1605 { typedef typename remove_extent<_Up>::type* __type; };
1606
1607 template<typename _Up>
1608 struct __decay_selector<_Up, false, true>
1609 { typedef typename add_pointer<_Up>::type __type; };
1610
1611 /// decay
1612 template<typename _Tp>
1613 class decay
1614 {
1615 typedef typename remove_reference<_Tp>::type __remove_type;
1616
1617 public:
1618 typedef typename __decay_selector<__remove_type>::__type type;
1619 };
1620
1621 template<typename _Tp>
1622 class reference_wrapper;
1623
1624 // Helper which adds a reference to a type when given a reference_wrapper
1625 template<typename _Tp>
1626 struct __strip_reference_wrapper
1627 {
1628 typedef _Tp __type;
1629 };
1630
1631 template<typename _Tp>
1632 struct __strip_reference_wrapper<reference_wrapper<_Tp> >
1633 {
1634 typedef _Tp& __type;
1635 };
1636
1637 template<typename _Tp>
1638 struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
1639 {
1640 typedef _Tp& __type;
1641 };
1642
1643 template<typename _Tp>
1644 struct __decay_and_strip
1645 {
1646 typedef typename __strip_reference_wrapper<
1647 typename decay<_Tp>::type>::__type __type;
1648 };
1649
1650
1651 // Define a nested type if some predicate holds.
1652 // Primary template.
1653 /// enable_if
1654 template<bool, typename _Tp = void>
1655 struct enable_if
1656 { };
1657
1658 // Partial specialization for true.
1659 template<typename _Tp>
1660 struct enable_if<true, _Tp>
1661 { typedef _Tp type; };
1662
1663
1664 // A conditional expression, but for types. If true, first, if false, second.
1665 // Primary template.
1666 /// conditional
1667 template<bool _Cond, typename _Iftrue, typename _Iffalse>
1668 struct conditional
1669 { typedef _Iftrue type; };
1670
1671 // Partial specialization for false.
1672 template<typename _Iftrue, typename _Iffalse>
1673 struct conditional<false, _Iftrue, _Iffalse>
1674 { typedef _Iffalse type; };
1675
1676
5b9daa7e 1677 /// common_type
cfa9a96b
CF
1678 template<typename... _Tp>
1679 struct common_type;
1680
1681 template<typename _Tp>
1682 struct common_type<_Tp>
7274deff 1683 { typedef _Tp type; };
cfa9a96b
CF
1684
1685 template<typename _Tp, typename _Up>
7274deff
PC
1686 struct common_type<_Tp, _Up>
1687 { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
cfa9a96b
CF
1688
1689 template<typename _Tp, typename _Up, typename... _Vp>
1690 struct common_type<_Tp, _Up, _Vp...>
1691 {
1692 typedef typename
1693 common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
1694 };
7274deff 1695
a47407f6
PC
1696 /// underlying_type
1697 template<typename _Tp>
1698 struct underlying_type
1699 {
1700 typedef __underlying_type(_Tp) type;
1701 };
123c516a 1702
7274deff
PC
1703 /// declval
1704 template<typename _Tp>
1705 struct __declval_protector
1706 {
1707 static const bool __stop = false;
1708 static typename add_rvalue_reference<_Tp>::type __delegate();
1709 };
1710
1711 template<typename _Tp>
1712 inline typename add_rvalue_reference<_Tp>::type
e4f32cb0 1713 declval() noexcept
7274deff
PC
1714 {
1715 static_assert(__declval_protector<_Tp>::__stop,
1716 "declval() must not be used!");
1717 return __declval_protector<_Tp>::__delegate();
1718 }
1041daba 1719
be7f7822
JW
1720 /// result_of
1721 template<typename _Signature>
1722 class result_of;
1723
1724 template<typename _MemPtr, typename _Arg>
1725 struct _Result_of_memobj;
1726
1727 template<typename _Res, typename _Class, typename _Arg>
1728 struct _Result_of_memobj<_Res _Class::*, _Arg>
1729 {
1730 private:
1731 typedef _Res _Class::* _Func;
1732
1733 template<typename _Tp>
1734 static _Tp _S_get(const _Class&);
1735 template<typename _Tp>
1736 static decltype(*std::declval<_Tp>()) _S_get(...);
1737
1738 public:
1739 typedef
1740 decltype(_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>())
1741 __type;
1742 };
1743
1744 template<typename _MemPtr, typename _Arg, typename... _ArgTypes>
1745 struct _Result_of_memfun;
1746
1747 template<typename _Res, typename _Class, typename _Arg, typename... _Args>
1748 struct _Result_of_memfun<_Res _Class::*, _Arg, _Args...>
1749 {
1750 private:
1751 typedef _Res _Class::* _Func;
1752
1753 template<typename _Tp>
1754 static _Tp _S_get(const _Class&);
1755 template<typename _Tp>
1756 static decltype(*std::declval<_Tp>()) _S_get(...);
1757
1758 public:
1759 typedef
1760 decltype((_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>())
1761 (std::declval<_Args>()...) )
1762 __type;
1763 };
1764
1765 template<bool, bool, typename _Functor, typename... _ArgTypes>
1766 struct _Result_of_impl;
1767
1768 template<typename _Functor, typename... _ArgTypes>
1769 struct _Result_of_impl<false, false, _Functor, _ArgTypes...>
1770 {
1771 typedef
1772 decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
1773 __type;
1774 };
1775
1776 template<typename _MemPtr, typename _Arg>
1777 struct _Result_of_impl<true, false, _MemPtr, _Arg>
1778 : _Result_of_memobj<typename remove_reference<_MemPtr>::type, _Arg>
1779 {
1780 typedef typename _Result_of_memobj<
1781 typename remove_reference<_MemPtr>::type, _Arg>::__type
1782 __type;
1783 };
1784
1785 template<typename _MemPtr, typename _Arg, typename... _ArgTypes>
1786 struct _Result_of_impl<false, true, _MemPtr, _Arg, _ArgTypes...>
1787 : _Result_of_memfun<typename remove_reference<_MemPtr>::type, _Arg,
1788 _ArgTypes...>
1789 {
1790 typedef typename _Result_of_memfun<
1791 typename remove_reference<_MemPtr>::type, _Arg, _ArgTypes...>::__type
1792 __type;
1793 };
1794
1795 template<typename _Functor, typename... _ArgTypes>
1796 struct result_of<_Functor(_ArgTypes...)>
1797 : _Result_of_impl<is_member_object_pointer<
1798 typename remove_reference<_Functor>::type >::value,
1799 is_member_function_pointer<
1800 typename remove_reference<_Functor>::type >::value,
1801 _Functor, _ArgTypes...>
1802 {
1803 typedef typename _Result_of_impl<
1804 is_member_object_pointer<
1805 typename remove_reference<_Functor>::type >::value,
1806 is_member_function_pointer<
1807 typename remove_reference<_Functor>::type >::value,
1808 _Functor, _ArgTypes...>::__type
1809 type;
1810 };
1811
033b71ce
PC
1812 /**
1813 * Use SFINAE to determine if the type _Tp has a publicly-accessible
1814 * member type _NTYPE.
1815 */
1816#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
1817 template<typename _Tp> \
1818 class __has_##_NTYPE##_helper \
1819 : __sfinae_types \
1820 { \
1821 template<typename _Up> \
1822 struct _Wrap_type \
1823 { }; \
1824 \
1825 template<typename _Up> \
1826 static __one __test(_Wrap_type<typename _Up::_NTYPE>*); \
1827 \
1828 template<typename _Up> \
1829 static __two __test(...); \
1830 \
1831 public: \
f263981a 1832 static constexpr bool value = sizeof(__test<_Tp>(0)) == 1; \
033b71ce
PC
1833 }; \
1834 \
1835 template<typename _Tp> \
1836 struct __has_##_NTYPE \
1837 : integral_constant<bool, __has_##_NTYPE##_helper \
1838 <typename remove_cv<_Tp>::type>::value> \
1839 { };
1840
1041daba 1841 // @} group metaprogramming
12ffa228
BK
1842_GLIBCXX_END_NAMESPACE_VERSION
1843} // namespace
7b50cdef 1844
57317d2a
PC
1845#endif // __GXX_EXPERIMENTAL_CXX0X__
1846
7274deff 1847#endif // _GLIBCXX_TYPE_TRAITS