]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/type_traits
libstdc++: invalid default init in _CachedPosition [PR101231]
[thirdparty/gcc.git] / libstdc++-v3 / include / std / type_traits
CommitLineData
c0ffa2ba 1// C++11 <type_traits> -*- C++ -*-
af13a7a6 2
99dee823 3// Copyright (C) 2007-2021 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
734f5023 34#if __cplusplus < 201103L
ab65a4c7 35# include <bits/c++0x_warning.h>
57317d2a 36#else
af13a7a6 37
8fc81078 38#include <bits/c++config.h>
e133ace8 39
21e2806a
JW
40namespace std _GLIBCXX_VISIBILITY(default)
41{
42_GLIBCXX_BEGIN_NAMESPACE_VERSION
43
6963c3b9
JW
44 template<typename... _Elements>
45 class tuple;
46
47 template<typename _Tp>
48 class reference_wrapper;
49
8e32aa11 50 /**
c0ffa2ba 51 * @defgroup metaprogramming Metaprogramming
13901e4b
JW
52 * @ingroup utilities
53 *
54 * Template utilities for compile-time introspection and modification,
55 * including type classification traits, type property inspection traits
56 * and type transformation traits.
57 *
6963c3b9
JW
58 * @since C++11
59 *
5b9daa7e
BK
60 * @{
61 */
ac65b7d2
DK
62
63 /// integral_constant
64 template<typename _Tp, _Tp __v>
65 struct integral_constant
66 {
67 static constexpr _Tp value = __v;
68 typedef _Tp value_type;
69 typedef integral_constant<_Tp, __v> type;
352111c5 70 constexpr operator value_type() const noexcept { return value; }
db113eda 71#if __cplusplus > 201103L
a15f7cb8
ESR
72
73#define __cpp_lib_integral_constant_callable 201304
74
352111c5 75 constexpr value_type operator()() const noexcept { return value; }
db113eda 76#endif
ac65b7d2 77 };
33ac58d5 78
c0ffa2ba
BK
79 template<typename _Tp, _Tp __v>
80 constexpr _Tp integral_constant<_Tp, __v>::value;
81
13901e4b 82 /// The type used as a compile-time boolean with true value.
6963c3b9 83 using true_type = integral_constant<bool, true>;
ac65b7d2 84
13901e4b 85 /// The type used as a compile-time boolean with false value.
6963c3b9 86 using false_type = integral_constant<bool, false>;
ac65b7d2 87
6963c3b9
JW
88 /// @cond undocumented
89 /// bool_constant for C++11
f6b640be
JW
90 template<bool __v>
91 using __bool_constant = integral_constant<bool, __v>;
6963c3b9 92 /// @endcond
f6b640be 93
6963c3b9 94#if __cplusplus >= 201703L
f9badf71 95# define __cpp_lib_bool_constant 201505
6963c3b9
JW
96 /// Alias template for compile-time boolean constant types.
97 /// @since C++17
46ba1281
JW
98 template<bool __v>
99 using bool_constant = integral_constant<bool, __v>;
100#endif
101
6963c3b9 102 // Metaprogramming helper types.
53dc5044 103
123c516a
PC
104 template<bool, typename, typename>
105 struct conditional;
53dc5044 106
6963c3b9 107 /// @cond undocumented
608a080c 108 template <typename _Type>
0d67cd38
JW
109 struct __type_identity
110 { using type = _Type; };
111
112 template<typename _Tp>
113 using __type_identity_t = typename __type_identity<_Tp>::type;
608a080c 114
dd7b175e 115 template<typename...>
123c516a
PC
116 struct __or_;
117
ac65b7d2
DK
118 template<>
119 struct __or_<>
120 : public false_type
121 { };
122
dd7b175e
PC
123 template<typename _B1>
124 struct __or_<_B1>
125 : public _B1
126 { };
127
123c516a
PC
128 template<typename _B1, typename _B2>
129 struct __or_<_B1, _B2>
130 : public conditional<_B1::value, _B1, _B2>::type
131 { };
132
133 template<typename _B1, typename _B2, typename _B3, typename... _Bn>
134 struct __or_<_B1, _B2, _B3, _Bn...>
135 : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type
136 { };
53dc5044 137
dd7b175e 138 template<typename...>
123c516a 139 struct __and_;
53dc5044 140
ac65b7d2
DK
141 template<>
142 struct __and_<>
143 : public true_type
144 { };
145
dd7b175e
PC
146 template<typename _B1>
147 struct __and_<_B1>
148 : public _B1
149 { };
150
123c516a
PC
151 template<typename _B1, typename _B2>
152 struct __and_<_B1, _B2>
153 : public conditional<_B1::value, _B2, _B1>::type
154 { };
155
156 template<typename _B1, typename _B2, typename _B3, typename... _Bn>
157 struct __and_<_B1, _B2, _B3, _Bn...>
158 : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type
159 { };
160
161 template<typename _Pp>
162 struct __not_
4b9840f2 163 : public __bool_constant<!bool(_Pp::value)>
123c516a 164 { };
6963c3b9 165 /// @endcond
123c516a 166
4b9840f2 167#if __cplusplus >= 201703L
c3a6648b 168
6963c3b9 169 /// @cond undocumented
b655b8fc
JW
170 template<typename... _Bn>
171 inline constexpr bool __or_v = __or_<_Bn...>::value;
172 template<typename... _Bn>
173 inline constexpr bool __and_v = __and_<_Bn...>::value;
6963c3b9 174 /// @endcond
b655b8fc 175
068c8ac1 176#define __cpp_lib_logical_traits 201510
c3a6648b
VV
177
178 template<typename... _Bn>
179 struct conjunction
180 : __and_<_Bn...>
181 { };
182
183 template<typename... _Bn>
184 struct disjunction
185 : __or_<_Bn...>
186 { };
187
188 template<typename _Pp>
189 struct negation
190 : __not_<_Pp>
191 { };
137422c8 192
6963c3b9
JW
193 /** @ingroup variable_templates
194 * @{
195 */
137422c8 196 template<typename... _Bn>
4b9840f2 197 inline constexpr bool conjunction_v = conjunction<_Bn...>::value;
42183d03 198
137422c8 199 template<typename... _Bn>
4b9840f2 200 inline constexpr bool disjunction_v = disjunction<_Bn...>::value;
42183d03 201
137422c8 202 template<typename _Pp>
4b9840f2 203 inline constexpr bool negation_v = negation<_Pp>::value;
6963c3b9 204 /// @}
137422c8 205
4b9840f2 206#endif // C++17
c3a6648b 207
608a080c
AP
208 // Forward declarations
209 template<typename>
210 struct is_reference;
211 template<typename>
212 struct is_function;
213 template<typename>
214 struct is_void;
6963c3b9
JW
215 template<typename>
216 struct remove_cv;
217 template<typename>
218 struct is_const;
219
220 /// @cond undocumented
608a080c
AP
221 template<typename>
222 struct __is_array_unknown_bounds;
223
224 // Helper functions that return false_type for incomplete classes,
225 // incomplete unions and arrays of known bound from those.
226
070b4df8
JW
227 template <typename _Tp, size_t = sizeof(_Tp)>
228 constexpr true_type __is_complete_or_unbounded(__type_identity<_Tp>)
608a080c
AP
229 { return {}; }
230
231 template <typename _TypeIdentity,
232 typename _NestedType = typename _TypeIdentity::type>
233 constexpr typename __or_<
234 is_reference<_NestedType>,
235 is_function<_NestedType>,
236 is_void<_NestedType>,
237 __is_array_unknown_bounds<_NestedType>
238 >::type __is_complete_or_unbounded(_TypeIdentity)
239 { return {}; }
240
b3618b71
DK
241 // For several sfinae-friendly trait implementations we transport both the
242 // result information (as the member type) and the failure information (no
243 // member type). This is very similar to std::enable_if, but we cannot use
244 // them, because we need to derive from them as an implementation detail.
245
246 template<typename _Tp>
247 struct __success_type
248 { typedef _Tp type; };
249
250 struct __failure_type
251 { };
252
391d5d2e
JW
253 // __remove_cv_t (std::remove_cv_t for C++11).
254 template<typename _Tp>
255 using __remove_cv_t = typename remove_cv<_Tp>::type;
256
72459cfd
JW
257 // Primary type categories.
258
53dc5044
PC
259 template<typename>
260 struct __is_void_helper
261 : public false_type { };
53dc5044 262
123c516a
PC
263 template<>
264 struct __is_void_helper<void>
265 : public true_type { };
6963c3b9 266 /// @endcond
53dc5044
PC
267
268 /// is_void
269 template<typename _Tp>
270 struct is_void
391d5d2e 271 : public __is_void_helper<__remove_cv_t<_Tp>>::type
53dc5044
PC
272 { };
273
6963c3b9 274 /// @cond undocumented
53dc5044
PC
275 template<typename>
276 struct __is_integral_helper
277 : public false_type { };
123c516a
PC
278
279 template<>
280 struct __is_integral_helper<bool>
281 : public true_type { };
33ac58d5 282
123c516a
PC
283 template<>
284 struct __is_integral_helper<char>
285 : public true_type { };
286
287 template<>
288 struct __is_integral_helper<signed char>
289 : public true_type { };
290
291 template<>
292 struct __is_integral_helper<unsigned char>
293 : public true_type { };
294
29e41848
JW
295 // We want is_integral<wchar_t> to be true (and make_signed/unsigned to work)
296 // even when libc doesn't provide working <wchar.h> and related functions,
297 // so check __WCHAR_TYPE__ instead of _GLIBCXX_USE_WCHAR_T.
298#ifdef __WCHAR_TYPE__
123c516a
PC
299 template<>
300 struct __is_integral_helper<wchar_t>
301 : public true_type { };
53dc5044 302#endif
123c516a 303
c124af93
TH
304#ifdef _GLIBCXX_USE_CHAR8_T
305 template<>
306 struct __is_integral_helper<char8_t>
307 : public true_type { };
308#endif
309
123c516a
PC
310 template<>
311 struct __is_integral_helper<char16_t>
312 : public true_type { };
313
314 template<>
315 struct __is_integral_helper<char32_t>
316 : public true_type { };
317
318 template<>
319 struct __is_integral_helper<short>
320 : public true_type { };
321
322 template<>
323 struct __is_integral_helper<unsigned short>
324 : public true_type { };
325
326 template<>
327 struct __is_integral_helper<int>
328 : public true_type { };
329
330 template<>
331 struct __is_integral_helper<unsigned int>
332 : public true_type { };
333
334 template<>
335 struct __is_integral_helper<long>
336 : public true_type { };
337
338 template<>
339 struct __is_integral_helper<unsigned long>
340 : public true_type { };
341
342 template<>
343 struct __is_integral_helper<long long>
344 : public true_type { };
345
346 template<>
347 struct __is_integral_helper<unsigned long long>
348 : public true_type { };
53dc5044 349
c1676651
JW
350#pragma GCC diagnostic push
351#pragma GCC diagnostic ignored "-Wpedantic"
352
78a7c317
DD
353 // Conditionalizing on __STRICT_ANSI__ here will break any port that
354 // uses one of these types for size_t.
355#if defined(__GLIBCXX_TYPE_INT_N_0)
6d585f01 356 template<>
78a7c317 357 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0>
6d585f01
PC
358 : public true_type { };
359
360 template<>
78a7c317
DD
361 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_0>
362 : public true_type { };
363#endif
364#if defined(__GLIBCXX_TYPE_INT_N_1)
365 template<>
366 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1>
367 : public true_type { };
368
369 template<>
370 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_1>
371 : public true_type { };
372#endif
373#if defined(__GLIBCXX_TYPE_INT_N_2)
374 template<>
375 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2>
376 : public true_type { };
377
378 template<>
379 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_2>
380 : public true_type { };
381#endif
382#if defined(__GLIBCXX_TYPE_INT_N_3)
383 template<>
384 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3>
385 : public true_type { };
386
387 template<>
388 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_3>
6d585f01
PC
389 : public true_type { };
390#endif
c1676651 391#pragma GCC diagnostic pop
6963c3b9 392 /// @endcond
6d585f01 393
53dc5044
PC
394 /// is_integral
395 template<typename _Tp>
396 struct is_integral
391d5d2e 397 : public __is_integral_helper<__remove_cv_t<_Tp>>::type
53dc5044
PC
398 { };
399
6963c3b9 400 /// @cond undocumented
53dc5044
PC
401 template<typename>
402 struct __is_floating_point_helper
403 : public false_type { };
123c516a
PC
404
405 template<>
406 struct __is_floating_point_helper<float>
407 : public true_type { };
408
409 template<>
410 struct __is_floating_point_helper<double>
411 : public true_type { };
412
413 template<>
414 struct __is_floating_point_helper<long double>
415 : public true_type { };
53dc5044 416
6d585f01
PC
417#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
418 template<>
419 struct __is_floating_point_helper<__float128>
420 : public true_type { };
421#endif
6963c3b9 422 /// @endcond
6d585f01 423
53dc5044
PC
424 /// is_floating_point
425 template<typename _Tp>
426 struct is_floating_point
391d5d2e 427 : public __is_floating_point_helper<__remove_cv_t<_Tp>>::type
53dc5044
PC
428 { };
429
430 /// is_array
431 template<typename>
432 struct is_array
433 : public false_type { };
434
435 template<typename _Tp, std::size_t _Size>
436 struct is_array<_Tp[_Size]>
437 : public true_type { };
438
439 template<typename _Tp>
440 struct is_array<_Tp[]>
441 : public true_type { };
442
443 template<typename>
444 struct __is_pointer_helper
445 : public false_type { };
123c516a
PC
446
447 template<typename _Tp>
448 struct __is_pointer_helper<_Tp*>
449 : public true_type { };
53dc5044
PC
450
451 /// is_pointer
452 template<typename _Tp>
453 struct is_pointer
391d5d2e 454 : public __is_pointer_helper<__remove_cv_t<_Tp>>::type
53dc5044
PC
455 { };
456
123c516a
PC
457 /// is_lvalue_reference
458 template<typename>
459 struct is_lvalue_reference
460 : public false_type { };
461
53dc5044 462 template<typename _Tp>
123c516a
PC
463 struct is_lvalue_reference<_Tp&>
464 : public true_type { };
465
466 /// is_rvalue_reference
467 template<typename>
468 struct is_rvalue_reference
469 : public false_type { };
53dc5044 470
53dc5044 471 template<typename _Tp>
123c516a
PC
472 struct is_rvalue_reference<_Tp&&>
473 : public true_type { };
474
53dc5044
PC
475 template<typename>
476 struct __is_member_object_pointer_helper
477 : public false_type { };
123c516a
PC
478
479 template<typename _Tp, typename _Cp>
480 struct __is_member_object_pointer_helper<_Tp _Cp::*>
c01f9216 481 : public __not_<is_function<_Tp>>::type { };
53dc5044
PC
482
483 /// is_member_object_pointer
484 template<typename _Tp>
485 struct is_member_object_pointer
391d5d2e 486 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
53dc5044
PC
487 { };
488
489 template<typename>
490 struct __is_member_function_pointer_helper
491 : public false_type { };
123c516a
PC
492
493 template<typename _Tp, typename _Cp>
494 struct __is_member_function_pointer_helper<_Tp _Cp::*>
c01f9216 495 : public is_function<_Tp>::type { };
53dc5044
PC
496
497 /// is_member_function_pointer
498 template<typename _Tp>
499 struct is_member_function_pointer
391d5d2e 500 : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type
53dc5044
PC
501 { };
502
503 /// is_enum
504 template<typename _Tp>
505 struct is_enum
506 : public integral_constant<bool, __is_enum(_Tp)>
507 { };
508
509 /// is_union
510 template<typename _Tp>
511 struct is_union
512 : public integral_constant<bool, __is_union(_Tp)>
513 { };
514
515 /// is_class
516 template<typename _Tp>
517 struct is_class
518 : public integral_constant<bool, __is_class(_Tp)>
519 { };
520
521 /// is_function
72459cfd 522 template<typename _Tp>
53dc5044 523 struct is_function
72459cfd 524 : public __bool_constant<!is_const<const _Tp>::value> { };
89898034 525
72459cfd
JW
526 template<typename _Tp>
527 struct is_function<_Tp&>
528 : public false_type { };
89898034 529
72459cfd
JW
530 template<typename _Tp>
531 struct is_function<_Tp&&>
532 : public false_type { };
89898034 533
a15f7cb8
ESR
534#define __cpp_lib_is_null_pointer 201309
535
1e673415 536 template<typename>
aa940ab5 537 struct __is_null_pointer_helper
1e673415 538 : public false_type { };
123c516a
PC
539
540 template<>
aa940ab5 541 struct __is_null_pointer_helper<std::nullptr_t>
123c516a 542 : public true_type { };
1e673415 543
aa940ab5
PC
544 /// is_null_pointer (LWG 2247).
545 template<typename _Tp>
546 struct is_null_pointer
391d5d2e 547 : public __is_null_pointer_helper<__remove_cv_t<_Tp>>::type
aa940ab5
PC
548 { };
549
07fd852f 550 /// __is_nullptr_t (deprecated extension).
6963c3b9 551 /// @deprecated Use `is_null_pointer` instead.
1e673415
PC
552 template<typename _Tp>
553 struct __is_nullptr_t
aa940ab5 554 : public is_null_pointer<_Tp>
eef9bf4c 555 { } _GLIBCXX_DEPRECATED_SUGGEST("std::is_null_pointer");
1e673415 556
c0ffa2ba 557 // Composite type categories.
123c516a
PC
558
559 /// is_reference
560 template<typename _Tp>
561 struct is_reference
562 : public __or_<is_lvalue_reference<_Tp>,
563 is_rvalue_reference<_Tp>>::type
564 { };
565
53dc5044
PC
566 /// is_arithmetic
567 template<typename _Tp>
568 struct is_arithmetic
123c516a 569 : public __or_<is_integral<_Tp>, is_floating_point<_Tp>>::type
53dc5044
PC
570 { };
571
572 /// is_fundamental
573 template<typename _Tp>
574 struct is_fundamental
aa940ab5
PC
575 : public __or_<is_arithmetic<_Tp>, is_void<_Tp>,
576 is_null_pointer<_Tp>>::type
53dc5044
PC
577 { };
578
579 /// is_object
580 template<typename _Tp>
581 struct is_object
123c516a
PC
582 : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>,
583 is_void<_Tp>>>::type
53dc5044
PC
584 { };
585
123c516a 586 template<typename>
53dc5044
PC
587 struct is_member_pointer;
588
589 /// is_scalar
590 template<typename _Tp>
591 struct is_scalar
123c516a 592 : public __or_<is_arithmetic<_Tp>, is_enum<_Tp>, is_pointer<_Tp>,
aa940ab5 593 is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type
53dc5044
PC
594 { };
595
596 /// is_compound
597 template<typename _Tp>
598 struct is_compound
c01f9216 599 : public __not_<is_fundamental<_Tp>>::type { };
53dc5044 600
6963c3b9 601 /// @cond undocumented
53dc5044
PC
602 template<typename _Tp>
603 struct __is_member_pointer_helper
604 : public false_type { };
123c516a
PC
605
606 template<typename _Tp, typename _Cp>
607 struct __is_member_pointer_helper<_Tp _Cp::*>
608 : public true_type { };
6963c3b9 609 /// @endcond
53dc5044 610
13901e4b 611 /// is_member_pointer
53dc5044 612 template<typename _Tp>
123c516a 613 struct is_member_pointer
391d5d2e 614 : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type
53dc5044
PC
615 { };
616
47f79054
JW
617 template<typename, typename>
618 struct is_same;
619
6963c3b9 620 /// @cond undocumented
47f79054
JW
621 template<typename _Tp, typename... _Types>
622 using __is_one_of = __or_<is_same<_Tp, _Types>...>;
623
c1676651
JW
624#pragma GCC diagnostic push
625#pragma GCC diagnostic ignored "-Wpedantic"
626
47f79054
JW
627 // Check if a type is one of the signed integer types.
628 template<typename _Tp>
391d5d2e 629 using __is_signed_integer = __is_one_of<__remove_cv_t<_Tp>,
47f79054
JW
630 signed char, signed short, signed int, signed long,
631 signed long long
632#if defined(__GLIBCXX_TYPE_INT_N_0)
633 , signed __GLIBCXX_TYPE_INT_N_0
634#endif
635#if defined(__GLIBCXX_TYPE_INT_N_1)
636 , signed __GLIBCXX_TYPE_INT_N_1
637#endif
638#if defined(__GLIBCXX_TYPE_INT_N_2)
639 , signed __GLIBCXX_TYPE_INT_N_2
640#endif
641#if defined(__GLIBCXX_TYPE_INT_N_3)
642 , signed __GLIBCXX_TYPE_INT_N_3
643#endif
644 >;
645
646 // Check if a type is one of the unsigned integer types.
647 template<typename _Tp>
391d5d2e 648 using __is_unsigned_integer = __is_one_of<__remove_cv_t<_Tp>,
47f79054
JW
649 unsigned char, unsigned short, unsigned int, unsigned long,
650 unsigned long long
651#if defined(__GLIBCXX_TYPE_INT_N_0)
652 , unsigned __GLIBCXX_TYPE_INT_N_0
653#endif
654#if defined(__GLIBCXX_TYPE_INT_N_1)
655 , unsigned __GLIBCXX_TYPE_INT_N_1
656#endif
657#if defined(__GLIBCXX_TYPE_INT_N_2)
658 , unsigned __GLIBCXX_TYPE_INT_N_2
659#endif
660#if defined(__GLIBCXX_TYPE_INT_N_3)
661 , unsigned __GLIBCXX_TYPE_INT_N_3
662#endif
663 >;
c1676651 664#pragma GCC diagnostic pop
47f79054 665
98cf2c26
JW
666 // Check if a type is one of the signed or unsigned integer types.
667 template<typename _Tp>
668 using __is_standard_integer
669 = __or_<__is_signed_integer<_Tp>, __is_unsigned_integer<_Tp>>;
47f79054 670
72459cfd
JW
671 // __void_t (std::void_t for C++11)
672 template<typename...> using __void_t = void;
673
89898034
DK
674 // Utility to detect referenceable types ([defns.referenceable]).
675
72459cfd 676 template<typename _Tp, typename = void>
89898034 677 struct __is_referenceable
72459cfd 678 : public false_type
89898034
DK
679 { };
680
72459cfd
JW
681 template<typename _Tp>
682 struct __is_referenceable<_Tp, __void_t<_Tp&>>
89898034
DK
683 : public true_type
684 { };
6963c3b9 685 /// @endcond
89898034 686
c0ffa2ba 687 // Type properties.
123c516a 688
53dc5044
PC
689 /// is_const
690 template<typename>
691 struct is_const
692 : public false_type { };
693
694 template<typename _Tp>
695 struct is_const<_Tp const>
696 : public true_type { };
33ac58d5 697
53dc5044
PC
698 /// is_volatile
699 template<typename>
700 struct is_volatile
701 : public false_type { };
702
703 template<typename _Tp>
704 struct is_volatile<_Tp volatile>
705 : public true_type { };
706
123c516a
PC
707 /// is_trivial
708 template<typename _Tp>
709 struct is_trivial
710 : public integral_constant<bool, __is_trivial(_Tp)>
608a080c
AP
711 {
712 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
713 "template argument must be a complete class or an unbounded array");
714 };
123c516a 715
6963c3b9 716 /// is_trivially_copyable
f5e523b7
VV
717 template<typename _Tp>
718 struct is_trivially_copyable
719 : public integral_constant<bool, __is_trivially_copyable(_Tp)>
608a080c
AP
720 {
721 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
722 "template argument must be a complete class or an unbounded array");
723 };
123c516a
PC
724
725 /// is_standard_layout
726 template<typename _Tp>
727 struct is_standard_layout
728 : public integral_constant<bool, __is_standard_layout(_Tp)>
608a080c
AP
729 {
730 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
731 "template argument must be a complete class or an unbounded array");
732 };
123c516a 733
6963c3b9
JW
734 /** is_pod (deprecated in C++20)
735 * @deprecated Use `is_standard_layout && is_trivial` instead.
736 */
123c516a
PC
737 // Could use is_standard_layout && is_trivial instead of the builtin.
738 template<typename _Tp>
1a6c5064
JTM
739 struct
740 _GLIBCXX20_DEPRECATED("use is_standard_layout && is_trivial instead")
741 is_pod
123c516a 742 : public integral_constant<bool, __is_pod(_Tp)>
608a080c
AP
743 {
744 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
745 "template argument must be a complete class or an unbounded array");
746 };
123c516a 747
6963c3b9
JW
748 /** is_literal_type
749 * @deprecated Deprecated in C++20. The idea of a literal type isn't useful.
750 */
123c516a 751 template<typename _Tp>
24b54628
VV
752 struct
753 _GLIBCXX17_DEPRECATED
754 is_literal_type
123c516a 755 : public integral_constant<bool, __is_literal_type(_Tp)>
608a080c
AP
756 {
757 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
758 "template argument must be a complete class or an unbounded array");
759 };
123c516a 760
53dc5044
PC
761 /// is_empty
762 template<typename _Tp>
763 struct is_empty
764 : public integral_constant<bool, __is_empty(_Tp)>
209ee624 765 { };
53dc5044
PC
766
767 /// is_polymorphic
768 template<typename _Tp>
769 struct is_polymorphic
770 : public integral_constant<bool, __is_polymorphic(_Tp)>
209ee624 771 { };
53dc5044 772
4db7fcb9
ESR
773#if __cplusplus >= 201402L
774#define __cpp_lib_is_final 201402L
775 /// is_final
6963c3b9 776 /// @since C++14
4db7fcb9
ESR
777 template<typename _Tp>
778 struct is_final
779 : public integral_constant<bool, __is_final(_Tp)>
209ee624 780 { };
4db7fcb9
ESR
781#endif
782
53dc5044
PC
783 /// is_abstract
784 template<typename _Tp>
785 struct is_abstract
786 : public integral_constant<bool, __is_abstract(_Tp)>
209ee624 787 { };
53dc5044 788
6963c3b9 789 /// @cond undocumented
123c516a 790 template<typename _Tp,
6a4b1a00 791 bool = is_arithmetic<_Tp>::value>
123c516a
PC
792 struct __is_signed_helper
793 : public false_type { };
794
53dc5044 795 template<typename _Tp>
6a4b1a00
PC
796 struct __is_signed_helper<_Tp, true>
797 : public integral_constant<bool, _Tp(-1) < _Tp(0)>
53dc5044 798 { };
6963c3b9 799 /// @endcond
53dc5044 800
123c516a 801 /// is_signed
53dc5044 802 template<typename _Tp>
123c516a 803 struct is_signed
82b12c4b 804 : public __is_signed_helper<_Tp>::type
123c516a
PC
805 { };
806
807 /// is_unsigned
808 template<typename _Tp>
809 struct is_unsigned
f7632193 810 : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>>
123c516a
PC
811 { };
812
6963c3b9 813 /// @cond undocumented
ec26ff5a
JW
814 template<typename _Tp, typename _Up = _Tp&&>
815 _Up
816 __declval(int);
817
818 template<typename _Tp>
819 _Tp
820 __declval(long);
6963c3b9 821 /// @endcond
ec26ff5a 822
53dc5044 823 template<typename _Tp>
ec26ff5a 824 auto declval() noexcept -> decltype(__declval<_Tp>(0));
53dc5044 825
123c516a
PC
826 template<typename, unsigned = 0>
827 struct extent;
828
829 template<typename>
830 struct remove_all_extents;
831
6963c3b9 832 /// @cond undocumented
123c516a
PC
833 template<typename _Tp>
834 struct __is_array_known_bounds
835 : public integral_constant<bool, (extent<_Tp>::value > 0)>
53dc5044
PC
836 { };
837
123c516a
PC
838 template<typename _Tp>
839 struct __is_array_unknown_bounds
f7632193 840 : public __and_<is_array<_Tp>, __not_<extent<_Tp>>>
53dc5044 841 { };
33ac58d5 842
6963c3b9
JW
843 // Destructible and constructible type properties.
844
62fa805f 845 // In N3290 is_destructible does not say anything about function
2c7a09d7 846 // types and abstract types, see LWG 2049. This implementation
62fa805f
DK
847 // describes function types as non-destructible and all complete
848 // object types as destructible, iff the explicit destructor
2c7a09d7 849 // call expression is wellformed.
62fa805f 850 struct __do_is_destructible_impl
123c516a 851 {
62fa805f 852 template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())>
123c516a
PC
853 static true_type __test(int);
854
855 template<typename>
856 static false_type __test(...);
857 };
53dc5044
PC
858
859 template<typename _Tp>
62fa805f
DK
860 struct __is_destructible_impl
861 : public __do_is_destructible_impl
123c516a
PC
862 {
863 typedef decltype(__test<_Tp>(0)) type;
864 };
53dc5044 865
62fa805f
DK
866 template<typename _Tp,
867 bool = __or_<is_void<_Tp>,
868 __is_array_unknown_bounds<_Tp>,
869 is_function<_Tp>>::value,
870 bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value>
871 struct __is_destructible_safe;
872
873 template<typename _Tp>
874 struct __is_destructible_safe<_Tp, false, false>
875 : public __is_destructible_impl<typename
876 remove_all_extents<_Tp>::type>::type
877 { };
878
879 template<typename _Tp>
880 struct __is_destructible_safe<_Tp, true, false>
881 : public false_type { };
882
883 template<typename _Tp>
884 struct __is_destructible_safe<_Tp, false, true>
885 : public true_type { };
6963c3b9 886 /// @endcond
62fa805f
DK
887
888 /// is_destructible
889 template<typename _Tp>
890 struct is_destructible
82b12c4b 891 : public __is_destructible_safe<_Tp>::type
608a080c
AP
892 {
893 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
894 "template argument must be a complete class or an unbounded array");
895 };
62fa805f 896
6963c3b9
JW
897 /// @cond undocumented
898
62fa805f
DK
899 // is_nothrow_destructible requires that is_destructible is
900 // satisfied as well. We realize that by mimicing the
901 // implementation of is_destructible but refer to noexcept(expr)
902 // instead of decltype(expr).
903 struct __do_is_nt_destructible_impl
123c516a 904 {
62fa805f 905 template<typename _Tp>
c01f9216
JW
906 static __bool_constant<noexcept(declval<_Tp&>().~_Tp())>
907 __test(int);
123c516a
PC
908
909 template<typename>
910 static false_type __test(...);
911 };
53dc5044 912
53dc5044 913 template<typename _Tp>
62fa805f
DK
914 struct __is_nt_destructible_impl
915 : public __do_is_nt_destructible_impl
123c516a
PC
916 {
917 typedef decltype(__test<_Tp>(0)) type;
918 };
919
920 template<typename _Tp,
921 bool = __or_<is_void<_Tp>,
62fa805f
DK
922 __is_array_unknown_bounds<_Tp>,
923 is_function<_Tp>>::value,
924 bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value>
925 struct __is_nt_destructible_safe;
53dc5044
PC
926
927 template<typename _Tp>
62fa805f
DK
928 struct __is_nt_destructible_safe<_Tp, false, false>
929 : public __is_nt_destructible_impl<typename
930 remove_all_extents<_Tp>::type>::type
123c516a
PC
931 { };
932
53dc5044 933 template<typename _Tp>
62fa805f 934 struct __is_nt_destructible_safe<_Tp, true, false>
123c516a 935 : public false_type { };
53dc5044
PC
936
937 template<typename _Tp>
62fa805f 938 struct __is_nt_destructible_safe<_Tp, false, true>
123c516a 939 : public true_type { };
6963c3b9 940 /// @endcond
123c516a 941
62fa805f 942 /// is_nothrow_destructible
53dc5044 943 template<typename _Tp>
62fa805f 944 struct is_nothrow_destructible
82b12c4b 945 : public __is_nt_destructible_safe<_Tp>::type
608a080c
AP
946 {
947 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
948 "template argument must be a complete class or an unbounded array");
949 };
950
6963c3b9 951 /// @cond undocumented
608a080c
AP
952 template<typename _Tp, typename... _Args>
953 struct __is_constructible_impl
954 : public __bool_constant<__is_constructible(_Tp, _Args...)>
123c516a 955 { };
6963c3b9 956 /// @endcond
123c516a 957
58487c21
JW
958 /// is_constructible
959 template<typename _Tp, typename... _Args>
960 struct is_constructible
608a080c
AP
961 : public __is_constructible_impl<_Tp, _Args...>
962 {
963 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
964 "template argument must be a complete class or an unbounded array");
965 };
4a27a739 966
123c516a 967 /// is_default_constructible
4a27a739 968 template<typename _Tp>
123c516a 969 struct is_default_constructible
608a080c
AP
970 : public __is_constructible_impl<_Tp>::type
971 {
972 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
973 "template argument must be a complete class or an unbounded array");
974 };
c32097d8 975
6963c3b9 976 /// @cond undocumented
89898034 977 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
65cee9bd 978 struct __is_copy_constructible_impl;
123c516a 979
65cee9bd 980 template<typename _Tp>
89898034 981 struct __is_copy_constructible_impl<_Tp, false>
65cee9bd
PC
982 : public false_type { };
983
984 template<typename _Tp>
89898034 985 struct __is_copy_constructible_impl<_Tp, true>
608a080c 986 : public __is_constructible_impl<_Tp, const _Tp&>
65cee9bd 987 { };
6963c3b9 988 /// @endcond
65cee9bd
PC
989
990 /// is_copy_constructible
991 template<typename _Tp>
992 struct is_copy_constructible
993 : public __is_copy_constructible_impl<_Tp>
608a080c
AP
994 {
995 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
996 "template argument must be a complete class or an unbounded array");
997 };
65cee9bd 998
6963c3b9 999 /// @cond undocumented
89898034 1000 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
65cee9bd
PC
1001 struct __is_move_constructible_impl;
1002
1003 template<typename _Tp>
89898034 1004 struct __is_move_constructible_impl<_Tp, false>
65cee9bd
PC
1005 : public false_type { };
1006
1007 template<typename _Tp>
89898034 1008 struct __is_move_constructible_impl<_Tp, true>
608a080c 1009 : public __is_constructible_impl<_Tp, _Tp&&>
65cee9bd 1010 { };
6963c3b9 1011 /// @endcond
65cee9bd
PC
1012
1013 /// is_move_constructible
1014 template<typename _Tp>
1015 struct is_move_constructible
1016 : public __is_move_constructible_impl<_Tp>
608a080c
AP
1017 {
1018 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1019 "template argument must be a complete class or an unbounded array");
1020 };
65cee9bd 1021
6963c3b9 1022 /// @cond undocumented
b3341826
JW
1023 template<typename _Tp, typename... _Args>
1024 using __is_nothrow_constructible_impl
9e2256dc 1025 = __bool_constant<__is_nothrow_constructible(_Tp, _Args...)>;
6963c3b9 1026 /// @endcond
b3341826 1027
608a080c
AP
1028 /// is_nothrow_constructible
1029 template<typename _Tp, typename... _Args>
1030 struct is_nothrow_constructible
1031 : public __is_nothrow_constructible_impl<_Tp, _Args...>::type
1032 {
1033 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1034 "template argument must be a complete class or an unbounded array");
1035 };
1036
b3341826
JW
1037 /// is_nothrow_default_constructible
1038 template<typename _Tp>
1039 struct is_nothrow_default_constructible
9e2256dc 1040 : public __bool_constant<__is_nothrow_constructible(_Tp)>
b3341826
JW
1041 {
1042 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1043 "template argument must be a complete class or an unbounded array");
1044 };
1045
6963c3b9 1046 /// @cond undocumented
89898034 1047 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
65cee9bd
PC
1048 struct __is_nothrow_copy_constructible_impl;
1049
1050 template<typename _Tp>
89898034 1051 struct __is_nothrow_copy_constructible_impl<_Tp, false>
65cee9bd
PC
1052 : public false_type { };
1053
1054 template<typename _Tp>
89898034 1055 struct __is_nothrow_copy_constructible_impl<_Tp, true>
608a080c 1056 : public __is_nothrow_constructible_impl<_Tp, const _Tp&>
65cee9bd 1057 { };
6963c3b9 1058 /// @endcond
65cee9bd
PC
1059
1060 /// is_nothrow_copy_constructible
1061 template<typename _Tp>
1062 struct is_nothrow_copy_constructible
608a080c
AP
1063 : public __is_nothrow_copy_constructible_impl<_Tp>::type
1064 {
1065 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1066 "template argument must be a complete class or an unbounded array");
1067 };
65cee9bd 1068
6963c3b9 1069 /// @cond undocumented
89898034 1070 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
65cee9bd
PC
1071 struct __is_nothrow_move_constructible_impl;
1072
1073 template<typename _Tp>
89898034 1074 struct __is_nothrow_move_constructible_impl<_Tp, false>
65cee9bd
PC
1075 : public false_type { };
1076
1077 template<typename _Tp>
89898034 1078 struct __is_nothrow_move_constructible_impl<_Tp, true>
608a080c 1079 : public __is_nothrow_constructible_impl<_Tp, _Tp&&>
65cee9bd 1080 { };
6963c3b9 1081 /// @endcond
65cee9bd
PC
1082
1083 /// is_nothrow_move_constructible
1084 template<typename _Tp>
1085 struct is_nothrow_move_constructible
608a080c
AP
1086 : public __is_nothrow_move_constructible_impl<_Tp>::type
1087 {
1088 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1089 "template argument must be a complete class or an unbounded array");
1090 };
65cee9bd 1091
f263981a
PC
1092 /// is_assignable
1093 template<typename _Tp, typename _Up>
1094 struct is_assignable
608a080c
AP
1095 : public __bool_constant<__is_assignable(_Tp, _Up)>
1096 {
1097 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1098 "template argument must be a complete class or an unbounded array");
1099 };
f263981a 1100
89898034 1101 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
f263981a
PC
1102 struct __is_copy_assignable_impl;
1103
1104 template<typename _Tp>
89898034 1105 struct __is_copy_assignable_impl<_Tp, false>
f263981a
PC
1106 : public false_type { };
1107
1108 template<typename _Tp>
89898034 1109 struct __is_copy_assignable_impl<_Tp, true>
608a080c 1110 : public __bool_constant<__is_assignable(_Tp&, const _Tp&)>
f263981a
PC
1111 { };
1112
1113 /// is_copy_assignable
1114 template<typename _Tp>
1115 struct is_copy_assignable
608a080c
AP
1116 : public __is_copy_assignable_impl<_Tp>::type
1117 {
1118 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1119 "template argument must be a complete class or an unbounded array");
1120 };
f263981a 1121
89898034 1122 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
f263981a
PC
1123 struct __is_move_assignable_impl;
1124
1125 template<typename _Tp>
89898034 1126 struct __is_move_assignable_impl<_Tp, false>
f263981a
PC
1127 : public false_type { };
1128
1129 template<typename _Tp>
89898034 1130 struct __is_move_assignable_impl<_Tp, true>
608a080c 1131 : public __bool_constant<__is_assignable(_Tp&, _Tp&&)>
f263981a
PC
1132 { };
1133
1134 /// is_move_assignable
1135 template<typename _Tp>
1136 struct is_move_assignable
608a080c
AP
1137 : public __is_move_assignable_impl<_Tp>::type
1138 {
1139 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1140 "template argument must be a complete class or an unbounded array");
1141 };
f263981a
PC
1142
1143 template<typename _Tp, typename _Up>
9e2256dc
VV
1144 using __is_nothrow_assignable_impl
1145 = __bool_constant<__is_nothrow_assignable(_Tp, _Up)>;
f263981a 1146
608a080c
AP
1147 /// is_nothrow_assignable
1148 template<typename _Tp, typename _Up>
1149 struct is_nothrow_assignable
1150 : public __is_nothrow_assignable_impl<_Tp, _Up>
1151 {
1152 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1153 "template argument must be a complete class or an unbounded array");
1154 };
1155
89898034 1156 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
f263981a
PC
1157 struct __is_nt_copy_assignable_impl;
1158
1159 template<typename _Tp>
89898034 1160 struct __is_nt_copy_assignable_impl<_Tp, false>
f263981a
PC
1161 : public false_type { };
1162
1163 template<typename _Tp>
89898034 1164 struct __is_nt_copy_assignable_impl<_Tp, true>
608a080c 1165 : public __is_nothrow_assignable_impl<_Tp&, const _Tp&>
f263981a
PC
1166 { };
1167
1168 /// is_nothrow_copy_assignable
1169 template<typename _Tp>
1170 struct is_nothrow_copy_assignable
1171 : public __is_nt_copy_assignable_impl<_Tp>
608a080c
AP
1172 {
1173 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1174 "template argument must be a complete class or an unbounded array");
1175 };
f263981a 1176
89898034 1177 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
f263981a
PC
1178 struct __is_nt_move_assignable_impl;
1179
1180 template<typename _Tp>
89898034 1181 struct __is_nt_move_assignable_impl<_Tp, false>
f263981a
PC
1182 : public false_type { };
1183
1184 template<typename _Tp>
89898034 1185 struct __is_nt_move_assignable_impl<_Tp, true>
608a080c 1186 : public __is_nothrow_assignable_impl<_Tp&, _Tp&&>
f263981a
PC
1187 { };
1188
1189 /// is_nothrow_move_assignable
65cee9bd 1190 template<typename _Tp>
f263981a
PC
1191 struct is_nothrow_move_assignable
1192 : public __is_nt_move_assignable_impl<_Tp>
608a080c
AP
1193 {
1194 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1195 "template argument must be a complete class or an unbounded array");
1196 };
e4f32cb0 1197
f5e523b7
VV
1198 /// is_trivially_constructible
1199 template<typename _Tp, typename... _Args>
1200 struct is_trivially_constructible
c01f9216 1201 : public __bool_constant<__is_trivially_constructible(_Tp, _Args...)>
608a080c
AP
1202 {
1203 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1204 "template argument must be a complete class or an unbounded array");
1205 };
33ac58d5 1206
f5e523b7
VV
1207 /// is_trivially_default_constructible
1208 template<typename _Tp>
1209 struct is_trivially_default_constructible
608a080c
AP
1210 : public __bool_constant<__is_trivially_constructible(_Tp)>
1211 {
1212 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1213 "template argument must be a complete class or an unbounded array");
1214 };
6a9ecd34 1215
f7632193
VV
1216 struct __do_is_implicitly_default_constructible_impl
1217 {
1218 template <typename _Tp>
1219 static void __helper(const _Tp&);
1220
1221 template <typename _Tp>
1222 static true_type __test(const _Tp&,
1223 decltype(__helper<const _Tp&>({}))* = 0);
1224
1225 static false_type __test(...);
1226 };
1227
1228 template<typename _Tp>
1229 struct __is_implicitly_default_constructible_impl
e9029d55
JW
1230 : public __do_is_implicitly_default_constructible_impl
1231 {
1232 typedef decltype(__test(declval<_Tp>())) type;
1233 };
f7632193
VV
1234
1235 template<typename _Tp>
1236 struct __is_implicitly_default_constructible_safe
e9029d55
JW
1237 : public __is_implicitly_default_constructible_impl<_Tp>::type
1238 { };
f7632193
VV
1239
1240 template <typename _Tp>
1241 struct __is_implicitly_default_constructible
608a080c 1242 : public __and_<__is_constructible_impl<_Tp>,
e9029d55
JW
1243 __is_implicitly_default_constructible_safe<_Tp>>
1244 { };
f7632193 1245
b42cc3ca
VV
1246 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
1247 struct __is_trivially_copy_constructible_impl;
1248
f5e523b7 1249 template<typename _Tp>
b42cc3ca
VV
1250 struct __is_trivially_copy_constructible_impl<_Tp, false>
1251 : public false_type { };
1252
1253 template<typename _Tp>
1254 struct __is_trivially_copy_constructible_impl<_Tp, true>
608a080c 1255 : public __and_<__is_copy_constructible_impl<_Tp>,
f5e523b7 1256 integral_constant<bool,
f7632193 1257 __is_trivially_constructible(_Tp, const _Tp&)>>
f5e523b7 1258 { };
33ac58d5 1259
608a080c 1260 /// is_trivially_copy_constructible
b42cc3ca
VV
1261 template<typename _Tp>
1262 struct is_trivially_copy_constructible
1263 : public __is_trivially_copy_constructible_impl<_Tp>
608a080c
AP
1264 {
1265 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1266 "template argument must be a complete class or an unbounded array");
1267 };
b42cc3ca
VV
1268
1269 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
1270 struct __is_trivially_move_constructible_impl;
1271
f5e523b7 1272 template<typename _Tp>
b42cc3ca
VV
1273 struct __is_trivially_move_constructible_impl<_Tp, false>
1274 : public false_type { };
1275
1276 template<typename _Tp>
1277 struct __is_trivially_move_constructible_impl<_Tp, true>
608a080c 1278 : public __and_<__is_move_constructible_impl<_Tp>,
f5e523b7 1279 integral_constant<bool,
f7632193 1280 __is_trivially_constructible(_Tp, _Tp&&)>>
f5e523b7 1281 { };
6a9ecd34 1282
608a080c 1283 /// is_trivially_move_constructible
b42cc3ca
VV
1284 template<typename _Tp>
1285 struct is_trivially_move_constructible
1286 : public __is_trivially_move_constructible_impl<_Tp>
608a080c
AP
1287 {
1288 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1289 "template argument must be a complete class or an unbounded array");
1290 };
b42cc3ca 1291
f5e523b7
VV
1292 /// is_trivially_assignable
1293 template<typename _Tp, typename _Up>
1294 struct is_trivially_assignable
b42cc3ca 1295 : public __bool_constant<__is_trivially_assignable(_Tp, _Up)>
608a080c
AP
1296 {
1297 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1298 "template argument must be a complete class or an unbounded array");
1299 };
b42cc3ca
VV
1300
1301 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
1302 struct __is_trivially_copy_assignable_impl;
1303
f5e523b7 1304 template<typename _Tp>
b42cc3ca
VV
1305 struct __is_trivially_copy_assignable_impl<_Tp, false>
1306 : public false_type { };
1307
1308 template<typename _Tp>
1309 struct __is_trivially_copy_assignable_impl<_Tp, true>
c01f9216 1310 : public __bool_constant<__is_trivially_assignable(_Tp&, const _Tp&)>
f5e523b7 1311 { };
6a9ecd34 1312
608a080c 1313 /// is_trivially_copy_assignable
b42cc3ca
VV
1314 template<typename _Tp>
1315 struct is_trivially_copy_assignable
1316 : public __is_trivially_copy_assignable_impl<_Tp>
608a080c
AP
1317 {
1318 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1319 "template argument must be a complete class or an unbounded array");
1320 };
b42cc3ca
VV
1321
1322 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
1323 struct __is_trivially_move_assignable_impl;
1324
f5e523b7 1325 template<typename _Tp>
b42cc3ca
VV
1326 struct __is_trivially_move_assignable_impl<_Tp, false>
1327 : public false_type { };
1328
1329 template<typename _Tp>
1330 struct __is_trivially_move_assignable_impl<_Tp, true>
c01f9216 1331 : public __bool_constant<__is_trivially_assignable(_Tp&, _Tp&&)>
f5e523b7 1332 { };
6a9ecd34 1333
608a080c 1334 /// is_trivially_move_assignable
b42cc3ca
VV
1335 template<typename _Tp>
1336 struct is_trivially_move_assignable
1337 : public __is_trivially_move_assignable_impl<_Tp>
608a080c
AP
1338 {
1339 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1340 "template argument must be a complete class or an unbounded array");
1341 };
b42cc3ca 1342
6a9ecd34
PC
1343 /// is_trivially_destructible
1344 template<typename _Tp>
1345 struct is_trivially_destructible
608a080c 1346 : public __and_<__is_destructible_safe<_Tp>,
c01f9216 1347 __bool_constant<__has_trivial_destructor(_Tp)>>
608a080c
AP
1348 {
1349 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1350 "template argument must be a complete class or an unbounded array");
1351 };
6a9ecd34 1352
e133ace8 1353
123c516a
PC
1354 /// has_virtual_destructor
1355 template<typename _Tp>
1356 struct has_virtual_destructor
1357 : public integral_constant<bool, __has_virtual_destructor(_Tp)>
608a080c
AP
1358 {
1359 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1360 "template argument must be a complete class or an unbounded array");
1361 };
123c516a 1362
33ac58d5 1363
123c516a
PC
1364 // type property queries.
1365
1366 /// alignment_of
1367 template<typename _Tp>
1368 struct alignment_of
608a080c
AP
1369 : public integral_constant<std::size_t, alignof(_Tp)>
1370 {
1371 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1372 "template argument must be a complete class or an unbounded array");
1373 };
33ac58d5 1374
123c516a
PC
1375 /// rank
1376 template<typename>
1377 struct rank
1378 : public integral_constant<std::size_t, 0> { };
33ac58d5 1379
123c516a
PC
1380 template<typename _Tp, std::size_t _Size>
1381 struct rank<_Tp[_Size]>
1382 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
1383
1384 template<typename _Tp>
1385 struct rank<_Tp[]>
1386 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
1387
1388 /// extent
1389 template<typename, unsigned _Uint>
1390 struct extent
1391 : public integral_constant<std::size_t, 0> { };
33ac58d5 1392
123c516a
PC
1393 template<typename _Tp, unsigned _Uint, std::size_t _Size>
1394 struct extent<_Tp[_Size], _Uint>
1395 : public integral_constant<std::size_t,
1396 _Uint == 0 ? _Size : extent<_Tp,
1397 _Uint - 1>::value>
1398 { };
1399
1400 template<typename _Tp, unsigned _Uint>
1401 struct extent<_Tp[], _Uint>
1402 : public integral_constant<std::size_t,
1403 _Uint == 0 ? 0 : extent<_Tp,
1404 _Uint - 1>::value>
1405 { };
1406
1407
c0ffa2ba 1408 // Type relations.
123c516a
PC
1409
1410 /// is_same
02f6fdff 1411 template<typename _Tp, typename _Up>
123c516a 1412 struct is_same
73ae6eb5
JW
1413#ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME
1414 : public integral_constant<bool, __is_same(_Tp, _Up)>
44af818f
JW
1415#else
1416 : public false_type
1417#endif
02f6fdff 1418 { };
b0302c68 1419
73ae6eb5 1420#ifndef _GLIBCXX_HAVE_BUILTIN_IS_SAME
44af818f
JW
1421 template<typename _Tp>
1422 struct is_same<_Tp, _Tp>
1423 : public true_type
1424 { };
1425#endif
1426
939759fc 1427 /// is_base_of
e133ace8
PC
1428 template<typename _Base, typename _Derived>
1429 struct is_base_of
1430 : public integral_constant<bool, __is_base_of(_Base, _Derived)>
1431 { };
1432
297f34d7 1433 template<typename _From, typename _To,
123c516a
PC
1434 bool = __or_<is_void<_From>, is_function<_To>,
1435 is_array<_To>>::value>
297f34d7 1436 struct __is_convertible_helper
8df27fcb
JW
1437 {
1438 typedef typename is_void<_To>::type type;
8df27fcb 1439 };
297f34d7 1440
cc28d234
JW
1441#pragma GCC diagnostic push
1442#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
e133ace8 1443 template<typename _From, typename _To>
b0302c68 1444 class __is_convertible_helper<_From, _To, false>
e133ace8 1445 {
8df27fcb
JW
1446 template<typename _To1>
1447 static void __test_aux(_To1) noexcept;
8e7d962a 1448
82b12c4b
FD
1449 template<typename _From1, typename _To1,
1450 typename = decltype(__test_aux<_To1>(std::declval<_From1>()))>
1451 static true_type
8e7d962a
PC
1452 __test(int);
1453
1454 template<typename, typename>
82b12c4b
FD
1455 static false_type
1456 __test(...);
297f34d7 1457
e133ace8 1458 public:
82b12c4b 1459 typedef decltype(__test<_From, _To>(0)) type;
e133ace8 1460 };
cc28d234 1461#pragma GCC diagnostic pop
82b12c4b 1462
b0302c68 1463 /// is_convertible
e133ace8
PC
1464 template<typename _From, typename _To>
1465 struct is_convertible
82b12c4b 1466 : public __is_convertible_helper<_From, _To>::type
e133ace8
PC
1467 { };
1468
0302a2de
JW
1469 // helper trait for unique_ptr<T[]>, shared_ptr<T[]>, and span<T, N>
1470 template<typename _ToElementType, typename _FromElementType>
1471 using __is_array_convertible
1472 = is_convertible<_FromElementType(*)[], _ToElementType(*)[]>;
1473
608a080c 1474 template<typename _From, typename _To,
ed99e818
JW
1475 bool = __or_<is_void<_From>, is_function<_To>,
1476 is_array<_To>>::value>
1477 struct __is_nt_convertible_helper
1478 : is_void<_To>
1479 { };
1480
cc28d234
JW
1481#pragma GCC diagnostic push
1482#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
ed99e818
JW
1483 template<typename _From, typename _To>
1484 class __is_nt_convertible_helper<_From, _To, false>
1485 {
1486 template<typename _To1>
1487 static void __test_aux(_To1) noexcept;
1488
1489 template<typename _From1, typename _To1>
ce9f305e
JW
1490 static
1491 __bool_constant<noexcept(__test_aux<_To1>(std::declval<_From1>()))>
ed99e818
JW
1492 __test(int);
1493
1494 template<typename, typename>
1495 static false_type
1496 __test(...);
1497
1498 public:
1499 using type = decltype(__test<_From, _To>(0));
1500 };
cc28d234 1501#pragma GCC diagnostic pop
ed99e818 1502
ce9f305e
JW
1503 // is_nothrow_convertible for C++11
1504 template<typename _From, typename _To>
1505 struct __is_nothrow_convertible
1506 : public __is_nt_convertible_helper<_From, _To>::type
1507 { };
1508
1509#if __cplusplus > 201703L
56772f62 1510#define __cpp_lib_is_nothrow_convertible 201806L
8df27fcb
JW
1511 /// is_nothrow_convertible
1512 template<typename _From, typename _To>
1513 struct is_nothrow_convertible
ed99e818 1514 : public __is_nt_convertible_helper<_From, _To>::type
8df27fcb
JW
1515 { };
1516
1517 /// is_nothrow_convertible_v
1518 template<typename _From, typename _To>
1519 inline constexpr bool is_nothrow_convertible_v
1520 = is_nothrow_convertible<_From, _To>::value;
1521#endif // C++2a
fd735b6a 1522
c0ffa2ba 1523 // Const-volatile modifications.
7b50cdef 1524
123c516a 1525 /// remove_const
7b50cdef 1526 template<typename _Tp>
123c516a
PC
1527 struct remove_const
1528 { typedef _Tp type; };
7b50cdef 1529
123c516a
PC
1530 template<typename _Tp>
1531 struct remove_const<_Tp const>
1532 { typedef _Tp type; };
33ac58d5 1533
123c516a
PC
1534 /// remove_volatile
1535 template<typename _Tp>
1536 struct remove_volatile
1537 { typedef _Tp type; };
7b50cdef 1538
123c516a
PC
1539 template<typename _Tp>
1540 struct remove_volatile<_Tp volatile>
1541 { typedef _Tp type; };
33ac58d5 1542
123c516a
PC
1543 /// remove_cv
1544 template<typename _Tp>
1545 struct remove_cv
391d5d2e
JW
1546 { using type = _Tp; };
1547
1548 template<typename _Tp>
1549 struct remove_cv<const _Tp>
1550 { using type = _Tp; };
1551
1552 template<typename _Tp>
1553 struct remove_cv<volatile _Tp>
1554 { using type = _Tp; };
1555
1556 template<typename _Tp>
1557 struct remove_cv<const volatile _Tp>
1558 { using type = _Tp; };
33ac58d5 1559
123c516a
PC
1560 /// add_const
1561 template<typename _Tp>
1562 struct add_const
1563 { typedef _Tp const type; };
33ac58d5 1564
123c516a
PC
1565 /// add_volatile
1566 template<typename _Tp>
1567 struct add_volatile
1568 { typedef _Tp volatile type; };
33ac58d5 1569
123c516a
PC
1570 /// add_cv
1571 template<typename _Tp>
1572 struct add_cv
1573 {
1574 typedef typename
1575 add_const<typename add_volatile<_Tp>::type>::type type;
1576 };
7b50cdef 1577
4457e88c 1578#if __cplusplus > 201103L
a15f7cb8
ESR
1579
1580#define __cpp_lib_transformation_trait_aliases 201304
1581
4457e88c
JW
1582 /// Alias template for remove_const
1583 template<typename _Tp>
1584 using remove_const_t = typename remove_const<_Tp>::type;
1585
1586 /// Alias template for remove_volatile
1587 template<typename _Tp>
1588 using remove_volatile_t = typename remove_volatile<_Tp>::type;
1589
1590 /// Alias template for remove_cv
1591 template<typename _Tp>
1592 using remove_cv_t = typename remove_cv<_Tp>::type;
1593
1594 /// Alias template for add_const
1595 template<typename _Tp>
1596 using add_const_t = typename add_const<_Tp>::type;
1597
1598 /// Alias template for add_volatile
1599 template<typename _Tp>
1600 using add_volatile_t = typename add_volatile<_Tp>::type;
1601
1602 /// Alias template for add_cv
1603 template<typename _Tp>
1604 using add_cv_t = typename add_cv<_Tp>::type;
1605#endif
7b50cdef 1606
123c516a 1607 // Reference transformations.
7b50cdef 1608
123c516a
PC
1609 /// remove_reference
1610 template<typename _Tp>
1611 struct remove_reference
1612 { typedef _Tp type; };
7b50cdef 1613
123c516a
PC
1614 template<typename _Tp>
1615 struct remove_reference<_Tp&>
1616 { typedef _Tp type; };
7b50cdef 1617
123c516a
PC
1618 template<typename _Tp>
1619 struct remove_reference<_Tp&&>
1620 { typedef _Tp type; };
1621
89898034 1622 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
123c516a
PC
1623 struct __add_lvalue_reference_helper
1624 { typedef _Tp type; };
7b50cdef 1625
5e108459 1626 template<typename _Tp>
89898034 1627 struct __add_lvalue_reference_helper<_Tp, true>
123c516a 1628 { typedef _Tp& type; };
5e108459 1629
123c516a 1630 /// add_lvalue_reference
5e108459 1631 template<typename _Tp>
123c516a
PC
1632 struct add_lvalue_reference
1633 : public __add_lvalue_reference_helper<_Tp>
1634 { };
1635
89898034 1636 template<typename _Tp, bool = __is_referenceable<_Tp>::value>
123c516a
PC
1637 struct __add_rvalue_reference_helper
1638 { typedef _Tp type; };
5e108459
PC
1639
1640 template<typename _Tp>
123c516a
PC
1641 struct __add_rvalue_reference_helper<_Tp, true>
1642 { typedef _Tp&& type; };
5e108459 1643
123c516a 1644 /// add_rvalue_reference
5e108459 1645 template<typename _Tp>
123c516a
PC
1646 struct add_rvalue_reference
1647 : public __add_rvalue_reference_helper<_Tp>
1648 { };
5e108459 1649
4457e88c
JW
1650#if __cplusplus > 201103L
1651 /// Alias template for remove_reference
1652 template<typename _Tp>
1653 using remove_reference_t = typename remove_reference<_Tp>::type;
1654
1655 /// Alias template for add_lvalue_reference
1656 template<typename _Tp>
1657 using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type;
1658
1659 /// Alias template for add_rvalue_reference
1660 template<typename _Tp>
1661 using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;
1662#endif
7b50cdef 1663
c0ffa2ba 1664 // Sign modifications.
123c516a 1665
6963c3b9
JW
1666 /// @cond undocumented
1667
7b50cdef
BK
1668 // Utility for constructing identically cv-qualified types.
1669 template<typename _Unqualified, bool _IsConst, bool _IsVol>
1670 struct __cv_selector;
1671
1672 template<typename _Unqualified>
1673 struct __cv_selector<_Unqualified, false, false>
1674 { typedef _Unqualified __type; };
1675
1676 template<typename _Unqualified>
1677 struct __cv_selector<_Unqualified, false, true>
1678 { typedef volatile _Unqualified __type; };
1679
1680 template<typename _Unqualified>
1681 struct __cv_selector<_Unqualified, true, false>
1682 { typedef const _Unqualified __type; };
1683
1684 template<typename _Unqualified>
1685 struct __cv_selector<_Unqualified, true, true>
1686 { typedef const volatile _Unqualified __type; };
1687
1688 template<typename _Qualified, typename _Unqualified,
1689 bool _IsConst = is_const<_Qualified>::value,
1690 bool _IsVol = is_volatile<_Qualified>::value>
b0302c68 1691 class __match_cv_qualifiers
7b50cdef 1692 {
7b50cdef
BK
1693 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
1694
1695 public:
33ac58d5 1696 typedef typename __match::__type __type;
7b50cdef
BK
1697 };
1698
7b50cdef
BK
1699 // Utility for finding the unsigned versions of signed integral types.
1700 template<typename _Tp>
e133ace8
PC
1701 struct __make_unsigned
1702 { typedef _Tp __type; };
7b50cdef
BK
1703
1704 template<>
1705 struct __make_unsigned<char>
1706 { typedef unsigned char __type; };
1707
1708 template<>
1709 struct __make_unsigned<signed char>
1710 { typedef unsigned char __type; };
1711
7b50cdef
BK
1712 template<>
1713 struct __make_unsigned<short>
1714 { typedef unsigned short __type; };
1715
1716 template<>
1717 struct __make_unsigned<int>
1718 { typedef unsigned int __type; };
1719
1720 template<>
1721 struct __make_unsigned<long>
1722 { typedef unsigned long __type; };
1723
1724 template<>
1725 struct __make_unsigned<long long>
1726 { typedef unsigned long long __type; };
1727
c1676651
JW
1728#pragma GCC diagnostic push
1729#pragma GCC diagnostic ignored "-Wpedantic"
1730
78a7c317
DD
1731#if defined(__GLIBCXX_TYPE_INT_N_0)
1732 template<>
1733 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0>
1734 { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; };
1735#endif
1736#if defined(__GLIBCXX_TYPE_INT_N_1)
1737 template<>
1738 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1>
1739 { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; };
1740#endif
1741#if defined(__GLIBCXX_TYPE_INT_N_2)
6d585f01 1742 template<>
78a7c317
DD
1743 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2>
1744 { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; };
1745#endif
1746#if defined(__GLIBCXX_TYPE_INT_N_3)
1747 template<>
1748 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3>
1749 { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; };
6d585f01
PC
1750#endif
1751
c1676651
JW
1752#pragma GCC diagnostic pop
1753
7b50cdef 1754 // Select between integral and enum: not possible to be both.
33ac58d5 1755 template<typename _Tp,
7b50cdef 1756 bool _IsInt = is_integral<_Tp>::value,
7b50cdef 1757 bool _IsEnum = is_enum<_Tp>::value>
b0302c68
PC
1758 class __make_unsigned_selector;
1759
7b50cdef 1760 template<typename _Tp>
b0302c68 1761 class __make_unsigned_selector<_Tp, true, false>
7b50cdef 1762 {
22f1f4c7 1763 using __unsigned_type
391d5d2e 1764 = typename __make_unsigned<__remove_cv_t<_Tp>>::__type;
7b50cdef
BK
1765
1766 public:
22f1f4c7
JW
1767 using __type
1768 = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type;
7b50cdef
BK
1769 };
1770
22f1f4c7
JW
1771 class __make_unsigned_selector_base
1772 {
1773 protected:
1774 template<typename...> struct _List { };
1775
1776 template<typename _Tp, typename... _Up>
1777 struct _List<_Tp, _Up...> : _List<_Up...>
1778 { static constexpr size_t __size = sizeof(_Tp); };
1779
1780 template<size_t _Sz, typename _Tp, bool = (_Sz <= _Tp::__size)>
1781 struct __select;
1782
1783 template<size_t _Sz, typename _Uint, typename... _UInts>
1784 struct __select<_Sz, _List<_Uint, _UInts...>, true>
1785 { using __type = _Uint; };
1786
1787 template<size_t _Sz, typename _Uint, typename... _UInts>
1788 struct __select<_Sz, _List<_Uint, _UInts...>, false>
1789 : __select<_Sz, _List<_UInts...>>
1790 { };
1791 };
1792
1793 // Choose unsigned integer type with the smallest rank and same size as _Tp
7b50cdef 1794 template<typename _Tp>
b0302c68 1795 class __make_unsigned_selector<_Tp, false, true>
22f1f4c7 1796 : __make_unsigned_selector_base
7b50cdef 1797 {
a0230468 1798 // With -fshort-enums, an enum may be as small as a char.
22f1f4c7
JW
1799 using _UInts = _List<unsigned char, unsigned short, unsigned int,
1800 unsigned long, unsigned long long>;
1801
1802 using __unsigned_type = typename __select<sizeof(_Tp), _UInts>::__type;
73d81d3a 1803
7b50cdef 1804 public:
22f1f4c7
JW
1805 using __type
1806 = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type;
1807 };
1808
c124af93
TH
1809 // wchar_t, char8_t, char16_t and char32_t are integral types but are
1810 // neither signed integer types nor unsigned integer types, so must be
22f1f4c7
JW
1811 // transformed to the unsigned integer type with the smallest rank.
1812 // Use the partial specialization for enumeration types to do that.
29e41848 1813#ifdef __WCHAR_TYPE__
22f1f4c7
JW
1814 template<>
1815 struct __make_unsigned<wchar_t>
1816 {
1817 using __type
1818 = typename __make_unsigned_selector<wchar_t, false, true>::__type;
1819 };
1820#endif
1821
c124af93
TH
1822#ifdef _GLIBCXX_USE_CHAR8_T
1823 template<>
1824 struct __make_unsigned<char8_t>
1825 {
1826 using __type
1827 = typename __make_unsigned_selector<char8_t, false, true>::__type;
1828 };
1829#endif
1830
22f1f4c7
JW
1831 template<>
1832 struct __make_unsigned<char16_t>
1833 {
1834 using __type
1835 = typename __make_unsigned_selector<char16_t, false, true>::__type;
1836 };
1837
1838 template<>
1839 struct __make_unsigned<char32_t>
1840 {
1841 using __type
1842 = typename __make_unsigned_selector<char32_t, false, true>::__type;
7b50cdef 1843 };
6963c3b9 1844 /// @endcond
7b50cdef 1845
7b50cdef
BK
1846 // Given an integral/enum type, return the corresponding unsigned
1847 // integer type.
5b9daa7e
BK
1848 // Primary template.
1849 /// make_unsigned
7b50cdef 1850 template<typename _Tp>
33ac58d5 1851 struct make_unsigned
7b50cdef
BK
1852 { typedef typename __make_unsigned_selector<_Tp>::__type type; };
1853
1854 // Integral, but don't define.
1855 template<>
1856 struct make_unsigned<bool>;
1857
6963c3b9 1858 /// @cond undocumented
7b50cdef
BK
1859
1860 // Utility for finding the signed versions of unsigned integral types.
1861 template<typename _Tp>
e133ace8
PC
1862 struct __make_signed
1863 { typedef _Tp __type; };
7b50cdef
BK
1864
1865 template<>
1866 struct __make_signed<char>
1867 { typedef signed char __type; };
1868
1869 template<>
1870 struct __make_signed<unsigned char>
1871 { typedef signed char __type; };
1872
7b50cdef
BK
1873 template<>
1874 struct __make_signed<unsigned short>
1875 { typedef signed short __type; };
1876
1877 template<>
1878 struct __make_signed<unsigned int>
1879 { typedef signed int __type; };
1880
1881 template<>
1882 struct __make_signed<unsigned long>
1883 { typedef signed long __type; };
1884
1885 template<>
1886 struct __make_signed<unsigned long long>
1887 { typedef signed long long __type; };
1888
c1676651
JW
1889#pragma GCC diagnostic push
1890#pragma GCC diagnostic ignored "-Wpedantic"
1891
78a7c317
DD
1892#if defined(__GLIBCXX_TYPE_INT_N_0)
1893 template<>
1894 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0>
1895 { typedef __GLIBCXX_TYPE_INT_N_0 __type; };
1896#endif
1897#if defined(__GLIBCXX_TYPE_INT_N_1)
1898 template<>
1899 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_1>
1900 { typedef __GLIBCXX_TYPE_INT_N_1 __type; };
1901#endif
1902#if defined(__GLIBCXX_TYPE_INT_N_2)
1903 template<>
1904 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_2>
1905 { typedef __GLIBCXX_TYPE_INT_N_2 __type; };
1906#endif
1907#if defined(__GLIBCXX_TYPE_INT_N_3)
6d585f01 1908 template<>
78a7c317
DD
1909 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_3>
1910 { typedef __GLIBCXX_TYPE_INT_N_3 __type; };
6d585f01
PC
1911#endif
1912
c1676651
JW
1913#pragma GCC diagnostic pop
1914
fb8ffd10 1915 // Select between integral and enum: not possible to be both.
33ac58d5 1916 template<typename _Tp,
7b50cdef 1917 bool _IsInt = is_integral<_Tp>::value,
7b50cdef 1918 bool _IsEnum = is_enum<_Tp>::value>
b0302c68
PC
1919 class __make_signed_selector;
1920
7b50cdef 1921 template<typename _Tp>
b0302c68 1922 class __make_signed_selector<_Tp, true, false>
7b50cdef 1923 {
22f1f4c7 1924 using __signed_type
391d5d2e 1925 = typename __make_signed<__remove_cv_t<_Tp>>::__type;
7b50cdef
BK
1926
1927 public:
22f1f4c7
JW
1928 using __type
1929 = typename __match_cv_qualifiers<_Tp, __signed_type>::__type;
7b50cdef
BK
1930 };
1931
22f1f4c7 1932 // Choose signed integer type with the smallest rank and same size as _Tp
7b50cdef 1933 template<typename _Tp>
b0302c68 1934 class __make_signed_selector<_Tp, false, true>
7b50cdef 1935 {
73d81d3a 1936 typedef typename __make_unsigned_selector<_Tp>::__type __unsigned_type;
7b50cdef
BK
1937
1938 public:
73d81d3a 1939 typedef typename __make_signed_selector<__unsigned_type>::__type __type;
7b50cdef
BK
1940 };
1941
22f1f4c7 1942 // wchar_t, char16_t and char32_t are integral types but are neither
d4b695e4 1943 // signed integer types nor unsigned integer types, so must be
22f1f4c7
JW
1944 // transformed to the signed integer type with the smallest rank.
1945 // Use the partial specialization for enumeration types to do that.
29e41848 1946#if defined(__WCHAR_TYPE__)
22f1f4c7
JW
1947 template<>
1948 struct __make_signed<wchar_t>
1949 {
1950 using __type
1951 = typename __make_signed_selector<wchar_t, false, true>::__type;
1952 };
1953#endif
1954
c124af93
TH
1955#if defined(_GLIBCXX_USE_CHAR8_T)
1956 template<>
1957 struct __make_signed<char8_t>
1958 {
1959 using __type
1960 = typename __make_signed_selector<char8_t, false, true>::__type;
1961 };
1962#endif
1963
22f1f4c7
JW
1964 template<>
1965 struct __make_signed<char16_t>
1966 {
1967 using __type
1968 = typename __make_signed_selector<char16_t, false, true>::__type;
1969 };
1970
1971 template<>
1972 struct __make_signed<char32_t>
1973 {
1974 using __type
1975 = typename __make_signed_selector<char32_t, false, true>::__type;
1976 };
6963c3b9 1977 /// @endcond
22f1f4c7 1978
7b50cdef
BK
1979 // Given an integral/enum type, return the corresponding signed
1980 // integer type.
5b9daa7e
BK
1981 // Primary template.
1982 /// make_signed
7b50cdef 1983 template<typename _Tp>
33ac58d5 1984 struct make_signed
7b50cdef
BK
1985 { typedef typename __make_signed_selector<_Tp>::__type type; };
1986
1987 // Integral, but don't define.
1988 template<>
1989 struct make_signed<bool>;
cfa9a96b 1990
4457e88c
JW
1991#if __cplusplus > 201103L
1992 /// Alias template for make_signed
1993 template<typename _Tp>
1994 using make_signed_t = typename make_signed<_Tp>::type;
1995
1996 /// Alias template for make_unsigned
1997 template<typename _Tp>
1998 using make_unsigned_t = typename make_unsigned<_Tp>::type;
1999#endif
123c516a 2000
c0ffa2ba 2001 // Array modifications.
123c516a
PC
2002
2003 /// remove_extent
2004 template<typename _Tp>
2005 struct remove_extent
2006 { typedef _Tp type; };
2007
2008 template<typename _Tp, std::size_t _Size>
2009 struct remove_extent<_Tp[_Size]>
2010 { typedef _Tp type; };
2011
2012 template<typename _Tp>
2013 struct remove_extent<_Tp[]>
2014 { typedef _Tp type; };
2015
2016 /// remove_all_extents
2017 template<typename _Tp>
2018 struct remove_all_extents
2019 { typedef _Tp type; };
2020
2021 template<typename _Tp, std::size_t _Size>
2022 struct remove_all_extents<_Tp[_Size]>
2023 { typedef typename remove_all_extents<_Tp>::type type; };
2024
2025 template<typename _Tp>
2026 struct remove_all_extents<_Tp[]>
2027 { typedef typename remove_all_extents<_Tp>::type type; };
2028
4457e88c
JW
2029#if __cplusplus > 201103L
2030 /// Alias template for remove_extent
2031 template<typename _Tp>
2032 using remove_extent_t = typename remove_extent<_Tp>::type;
2033
2034 /// Alias template for remove_all_extents
2035 template<typename _Tp>
2036 using remove_all_extents_t = typename remove_all_extents<_Tp>::type;
2037#endif
123c516a 2038
c0ffa2ba 2039 // Pointer modifications.
123c516a
PC
2040
2041 template<typename _Tp, typename>
2042 struct __remove_pointer_helper
2043 { typedef _Tp type; };
2044
2045 template<typename _Tp, typename _Up>
2046 struct __remove_pointer_helper<_Tp, _Up*>
2047 { typedef _Up type; };
2048
2049 /// remove_pointer
2050 template<typename _Tp>
2051 struct remove_pointer
391d5d2e 2052 : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
123c516a
PC
2053 { };
2054
89898034
DK
2055 template<typename _Tp, bool = __or_<__is_referenceable<_Tp>,
2056 is_void<_Tp>>::value>
2057 struct __add_pointer_helper
2058 { typedef _Tp type; };
2059
123c516a 2060 template<typename _Tp>
89898034 2061 struct __add_pointer_helper<_Tp, true>
123c516a
PC
2062 { typedef typename remove_reference<_Tp>::type* type; };
2063
6963c3b9 2064 /// add_pointer
89898034 2065 template<typename _Tp>
33ac58d5 2066 struct add_pointer
89898034
DK
2067 : public __add_pointer_helper<_Tp>
2068 { };
2069
4457e88c
JW
2070#if __cplusplus > 201103L
2071 /// Alias template for remove_pointer
2072 template<typename _Tp>
2073 using remove_pointer_t = typename remove_pointer<_Tp>::type;
2074
2075 /// Alias template for add_pointer
2076 template<typename _Tp>
2077 using add_pointer_t = typename add_pointer<_Tp>::type;
2078#endif
123c516a
PC
2079
2080 template<std::size_t _Len>
2081 struct __aligned_storage_msa
33ac58d5 2082 {
123c516a
PC
2083 union __type
2084 {
2085 unsigned char __data[_Len];
33ac58d5 2086 struct __attribute__((__aligned__)) { } __align;
123c516a
PC
2087 };
2088 };
2089
2090 /**
2091 * @brief Alignment type.
2092 *
2093 * The value of _Align is a default-alignment which shall be the
2094 * most stringent alignment requirement for any C++ object type
2095 * whose size is no greater than _Len (3.9). The member typedef
2096 * type shall be a POD type suitable for use as uninitialized
2097 * storage for any object whose size is at most _Len and whose
2098 * alignment is a divisor of _Align.
2099 */
2100 template<std::size_t _Len, std::size_t _Align =
2101 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
2102 struct aligned_storage
33ac58d5 2103 {
123c516a
PC
2104 union type
2105 {
2106 unsigned char __data[_Len];
33ac58d5 2107 struct __attribute__((__aligned__((_Align)))) { } __align;
123c516a
PC
2108 };
2109 };
2110
d3718027
RS
2111 template <typename... _Types>
2112 struct __strictest_alignment
2113 {
2114 static const size_t _S_alignment = 0;
2115 static const size_t _S_size = 0;
2116 };
2117
2118 template <typename _Tp, typename... _Types>
2119 struct __strictest_alignment<_Tp, _Types...>
2120 {
2121 static const size_t _S_alignment =
2122 alignof(_Tp) > __strictest_alignment<_Types...>::_S_alignment
2123 ? alignof(_Tp) : __strictest_alignment<_Types...>::_S_alignment;
2124 static const size_t _S_size =
2125 sizeof(_Tp) > __strictest_alignment<_Types...>::_S_size
2126 ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size;
2127 };
2128
2129 /**
2130 * @brief Provide aligned storage for types.
2131 *
2132 * [meta.trans.other]
2133 *
2134 * Provides aligned storage for any of the provided types of at
2135 * least size _Len.
2136 *
2137 * @see aligned_storage
2138 */
2139 template <size_t _Len, typename... _Types>
2140 struct aligned_union
2141 {
2142 private:
2143 static_assert(sizeof...(_Types) != 0, "At least one type is required");
2144
2145 using __strictest = __strictest_alignment<_Types...>;
2146 static const size_t _S_len = _Len > __strictest::_S_size
2147 ? _Len : __strictest::_S_size;
2148 public:
2149 /// The value of the strictest alignment of _Types.
2150 static const size_t alignment_value = __strictest::_S_alignment;
2151 /// The storage.
2152 typedef typename aligned_storage<_S_len, alignment_value>::type type;
2153 };
2154
2155 template <size_t _Len, typename... _Types>
2156 const size_t aligned_union<_Len, _Types...>::alignment_value;
123c516a 2157
6963c3b9
JW
2158 /// @cond undocumented
2159
123c516a
PC
2160 // Decay trait for arrays and functions, used for perfect forwarding
2161 // in make_pair, make_tuple, etc.
33ac58d5 2162 template<typename _Up,
123c516a 2163 bool _IsArray = is_array<_Up>::value,
33ac58d5 2164 bool _IsFunction = is_function<_Up>::value>
123c516a
PC
2165 struct __decay_selector;
2166
2167 // NB: DR 705.
33ac58d5 2168 template<typename _Up>
123c516a 2169 struct __decay_selector<_Up, false, false>
391d5d2e 2170 { typedef __remove_cv_t<_Up> __type; };
123c516a 2171
33ac58d5 2172 template<typename _Up>
123c516a
PC
2173 struct __decay_selector<_Up, true, false>
2174 { typedef typename remove_extent<_Up>::type* __type; };
2175
33ac58d5 2176 template<typename _Up>
123c516a
PC
2177 struct __decay_selector<_Up, false, true>
2178 { typedef typename add_pointer<_Up>::type __type; };
6963c3b9 2179 /// @endcond
123c516a
PC
2180
2181 /// decay
33ac58d5
JW
2182 template<typename _Tp>
2183 class decay
2184 {
123c516a
PC
2185 typedef typename remove_reference<_Tp>::type __remove_type;
2186
2187 public:
2188 typedef typename __decay_selector<__remove_type>::__type type;
2189 };
2190
6963c3b9 2191 /// @cond undocumented
123c516a
PC
2192
2193 // Helper which adds a reference to a type when given a reference_wrapper
2194 template<typename _Tp>
2195 struct __strip_reference_wrapper
2196 {
2197 typedef _Tp __type;
2198 };
2199
2200 template<typename _Tp>
2201 struct __strip_reference_wrapper<reference_wrapper<_Tp> >
2202 {
2203 typedef _Tp& __type;
2204 };
2205
6963c3b9 2206 // __decay_t (std::decay_t for C++11).
123c516a 2207 template<typename _Tp>
6963c3b9 2208 using __decay_t = typename decay<_Tp>::type;
123c516a 2209
6963c3b9
JW
2210 template<typename _Tp>
2211 using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>;
2212 /// @endcond
123c516a 2213
123c516a 2214 // Primary template.
6963c3b9 2215 /// Define a member typedef `type` only if a boolean constant is true.
123c516a 2216 template<bool, typename _Tp = void>
33ac58d5 2217 struct enable_if
123c516a
PC
2218 { };
2219
2220 // Partial specialization for true.
2221 template<typename _Tp>
2222 struct enable_if<true, _Tp>
2223 { typedef _Tp type; };
2224
6963c3b9
JW
2225 /// @cond undocumented
2226
391d5d2e
JW
2227 // __enable_if_t (std::enable_if_t for C++11)
2228 template<bool _Cond, typename _Tp = void>
2229 using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
2230
6963c3b9 2231 // Helper for SFINAE constraints
23df8534 2232 template<typename... _Cond>
391d5d2e 2233 using _Require = __enable_if_t<__and_<_Cond...>::value>;
123c516a 2234
6963c3b9
JW
2235 // __remove_cvref_t (std::remove_cvref_t for C++11).
2236 template<typename _Tp>
2237 using __remove_cvref_t
2238 = typename remove_cv<typename remove_reference<_Tp>::type>::type;
2239 /// @endcond
2240
123c516a 2241 // Primary template.
13901e4b 2242 /// Define a member typedef @c type to one of two argument types.
123c516a
PC
2243 template<bool _Cond, typename _Iftrue, typename _Iffalse>
2244 struct conditional
2245 { typedef _Iftrue type; };
2246
2247 // Partial specialization for false.
2248 template<typename _Iftrue, typename _Iffalse>
2249 struct conditional<false, _Iftrue, _Iffalse>
2250 { typedef _Iffalse type; };
2251
5b9daa7e 2252 /// common_type
cfa9a96b
CF
2253 template<typename... _Tp>
2254 struct common_type;
2255
c0ffa2ba 2256 // Sfinae-friendly common_type implementation:
b3618b71 2257
6963c3b9 2258 /// @cond undocumented
b3618b71
DK
2259 struct __do_common_type_impl
2260 {
2261 template<typename _Tp, typename _Up>
f61a12b3
JW
2262 using __cond_t
2263 = decltype(true ? std::declval<_Tp>() : std::declval<_Up>());
2264
0f8b14ee
JW
2265 // if decay_t<decltype(false ? declval<D1>() : declval<D2>())>
2266 // denotes a valid type, let C denote that type.
f61a12b3 2267 template<typename _Tp, typename _Up>
0f8b14ee 2268 static __success_type<__decay_t<__cond_t<_Tp, _Up>>>
f61a12b3 2269 _S_test(int);
b3618b71 2270
0f8b14ee
JW
2271#if __cplusplus > 201703L
2272 // Otherwise, if COND-RES(CREF(D1), CREF(D2)) denotes a type,
2273 // let C denote the type decay_t<COND-RES(CREF(D1), CREF(D2))>.
2274 template<typename _Tp, typename _Up>
2275 static __success_type<__remove_cvref_t<__cond_t<const _Tp&, const _Up&>>>
2276 _S_test_2(int);
2277#endif
2278
b3618b71 2279 template<typename, typename>
f61a12b3 2280 static __failure_type
0f8b14ee
JW
2281 _S_test_2(...);
2282
2283 template<typename _Tp, typename _Up>
2284 static decltype(_S_test_2<_Tp, _Up>(0))
f61a12b3 2285 _S_test(...);
b3618b71
DK
2286 };
2287
f61a12b3
JW
2288 // If sizeof...(T) is zero, there shall be no member type.
2289 template<>
2290 struct common_type<>
2291 { };
b3618b71 2292
f61a12b3
JW
2293 // If sizeof...(T) is one, the same type, if any, as common_type_t<T0, T0>.
2294 template<typename _Tp0>
2295 struct common_type<_Tp0>
2296 : public common_type<_Tp0, _Tp0>
2297 { };
b3618b71 2298
f61a12b3
JW
2299 // If sizeof...(T) is two, ...
2300 template<typename _Tp1, typename _Tp2,
391d5d2e 2301 typename _Dp1 = __decay_t<_Tp1>, typename _Dp2 = __decay_t<_Tp2>>
f61a12b3 2302 struct __common_type_impl
b3618b71 2303 {
f61a12b3
JW
2304 // If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false,
2305 // let C denote the same type, if any, as common_type_t<D1, D2>.
2306 using type = common_type<_Dp1, _Dp2>;
b3618b71
DK
2307 };
2308
f61a12b3
JW
2309 template<typename _Tp1, typename _Tp2>
2310 struct __common_type_impl<_Tp1, _Tp2, _Tp1, _Tp2>
2311 : private __do_common_type_impl
b3618b71 2312 {
f61a12b3
JW
2313 // Otherwise, if decay_t<decltype(false ? declval<D1>() : declval<D2>())>
2314 // denotes a valid type, let C denote that type.
2315 using type = decltype(_S_test<_Tp1, _Tp2>(0));
b3618b71
DK
2316 };
2317
f61a12b3
JW
2318 // If sizeof...(T) is two, ...
2319 template<typename _Tp1, typename _Tp2>
2320 struct common_type<_Tp1, _Tp2>
2321 : public __common_type_impl<_Tp1, _Tp2>::type
2322 { };
b3618b71 2323
f61a12b3
JW
2324 template<typename...>
2325 struct __common_type_pack
373c726e
JW
2326 { };
2327
f61a12b3
JW
2328 template<typename, typename, typename = void>
2329 struct __common_type_fold;
2330
2331 // If sizeof...(T) is greater than two, ...
2332 template<typename _Tp1, typename _Tp2, typename... _Rp>
2333 struct common_type<_Tp1, _Tp2, _Rp...>
2334 : public __common_type_fold<common_type<_Tp1, _Tp2>,
2335 __common_type_pack<_Rp...>>
373c726e 2336 { };
cfa9a96b 2337
f61a12b3
JW
2338 // Let C denote the same type, if any, as common_type_t<T1, T2>.
2339 // If there is such a type C, type shall denote the same type, if any,
2340 // as common_type_t<C, R...>.
2341 template<typename _CTp, typename... _Rp>
2342 struct __common_type_fold<_CTp, __common_type_pack<_Rp...>,
2343 __void_t<typename _CTp::type>>
2344 : public common_type<typename _CTp::type, _Rp...>
b3618b71 2345 { };
cfa9a96b 2346
f61a12b3
JW
2347 // Otherwise, there shall be no member type.
2348 template<typename _CTp, typename _Rp>
2349 struct __common_type_fold<_CTp, _Rp, void>
b3618b71 2350 { };
7274deff 2351
3c26b759
JW
2352 template<typename _Tp, bool = is_enum<_Tp>::value>
2353 struct __underlying_type_impl
2354 {
2355 using type = __underlying_type(_Tp);
2356 };
2357
2358 template<typename _Tp>
2359 struct __underlying_type_impl<_Tp, false>
2360 { };
6963c3b9 2361 /// @endcond
3c26b759 2362
13901e4b 2363 /// The underlying type of an enum.
a47407f6
PC
2364 template<typename _Tp>
2365 struct underlying_type
3c26b759
JW
2366 : public __underlying_type_impl<_Tp>
2367 { };
123c516a 2368
6963c3b9 2369 /// @cond undocumented
7274deff
PC
2370 template<typename _Tp>
2371 struct __declval_protector
2372 {
2373 static const bool __stop = false;
7274deff 2374 };
6963c3b9 2375 /// @endcond
7274deff 2376
6963c3b9
JW
2377 /** Utility to simplify expressions used in unevaluated operands
2378 * @since C++11
2379 * @ingroup utilities
2380 */
7274deff 2381 template<typename _Tp>
ec26ff5a 2382 auto declval() noexcept -> decltype(__declval<_Tp>(0))
7274deff
PC
2383 {
2384 static_assert(__declval_protector<_Tp>::__stop,
2385 "declval() must not be used!");
ec26ff5a 2386 return __declval<_Tp>(0);
7274deff 2387 }
1041daba 2388
be7f7822
JW
2389 /// result_of
2390 template<typename _Signature>
0e5abeb0 2391 struct result_of;
be7f7822 2392
c0ffa2ba 2393 // Sfinae-friendly result_of implementation:
83ddb39f 2394
a15f7cb8
ESR
2395#define __cpp_lib_result_of_sfinae 201210
2396
6963c3b9 2397 /// @cond undocumented
93e95400
JW
2398 struct __invoke_memfun_ref { };
2399 struct __invoke_memfun_deref { };
2400 struct __invoke_memobj_ref { };
2401 struct __invoke_memobj_deref { };
2402 struct __invoke_other { };
2403
2404 // Associate a tag type with a specialization of __success_type.
2405 template<typename _Tp, typename _Tag>
2406 struct __result_of_success : __success_type<_Tp>
2407 { using __invoke_type = _Tag; };
2408
83ddb39f
DK
2409 // [func.require] paragraph 1 bullet 1:
2410 struct __result_of_memfun_ref_impl
2411 {
2412 template<typename _Fp, typename _Tp1, typename... _Args>
93e95400 2413 static __result_of_success<decltype(
83ddb39f 2414 (std::declval<_Tp1>().*std::declval<_Fp>())(std::declval<_Args>()...)
93e95400 2415 ), __invoke_memfun_ref> _S_test(int);
83ddb39f
DK
2416
2417 template<typename...>
2418 static __failure_type _S_test(...);
2419 };
2420
2421 template<typename _MemPtr, typename _Arg, typename... _Args>
2422 struct __result_of_memfun_ref
2423 : private __result_of_memfun_ref_impl
2424 {
2425 typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type;
2426 };
2427
2428 // [func.require] paragraph 1 bullet 2:
2429 struct __result_of_memfun_deref_impl
2430 {
2431 template<typename _Fp, typename _Tp1, typename... _Args>
93e95400 2432 static __result_of_success<decltype(
83ddb39f 2433 ((*std::declval<_Tp1>()).*std::declval<_Fp>())(std::declval<_Args>()...)
93e95400 2434 ), __invoke_memfun_deref> _S_test(int);
83ddb39f
DK
2435
2436 template<typename...>
2437 static __failure_type _S_test(...);
2438 };
2439
2440 template<typename _MemPtr, typename _Arg, typename... _Args>
2441 struct __result_of_memfun_deref
2442 : private __result_of_memfun_deref_impl
2443 {
2444 typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type;
2445 };
2446
2447 // [func.require] paragraph 1 bullet 3:
2448 struct __result_of_memobj_ref_impl
2449 {
2450 template<typename _Fp, typename _Tp1>
93e95400 2451 static __result_of_success<decltype(
83ddb39f 2452 std::declval<_Tp1>().*std::declval<_Fp>()
93e95400 2453 ), __invoke_memobj_ref> _S_test(int);
83ddb39f
DK
2454
2455 template<typename, typename>
2456 static __failure_type _S_test(...);
2457 };
2458
2459 template<typename _MemPtr, typename _Arg>
2460 struct __result_of_memobj_ref
2461 : private __result_of_memobj_ref_impl
2462 {
2463 typedef decltype(_S_test<_MemPtr, _Arg>(0)) type;
2464 };
2465
2466 // [func.require] paragraph 1 bullet 4:
2467 struct __result_of_memobj_deref_impl
2468 {
2469 template<typename _Fp, typename _Tp1>
93e95400 2470 static __result_of_success<decltype(
83ddb39f 2471 (*std::declval<_Tp1>()).*std::declval<_Fp>()
93e95400 2472 ), __invoke_memobj_deref> _S_test(int);
83ddb39f
DK
2473
2474 template<typename, typename>
2475 static __failure_type _S_test(...);
2476 };
2477
be7f7822 2478 template<typename _MemPtr, typename _Arg>
83ddb39f
DK
2479 struct __result_of_memobj_deref
2480 : private __result_of_memobj_deref_impl
2481 {
2482 typedef decltype(_S_test<_MemPtr, _Arg>(0)) type;
2483 };
2484
2485 template<typename _MemPtr, typename _Arg>
2486 struct __result_of_memobj;
be7f7822
JW
2487
2488 template<typename _Res, typename _Class, typename _Arg>
83ddb39f 2489 struct __result_of_memobj<_Res _Class::*, _Arg>
be7f7822 2490 {
6791489e 2491 typedef __remove_cvref_t<_Arg> _Argval;
83ddb39f
DK
2492 typedef _Res _Class::* _MemPtr;
2493 typedef typename conditional<__or_<is_same<_Argval, _Class>,
2494 is_base_of<_Class, _Argval>>::value,
2495 __result_of_memobj_ref<_MemPtr, _Arg>,
2496 __result_of_memobj_deref<_MemPtr, _Arg>
2497 >::type::type type;
be7f7822
JW
2498 };
2499
83ddb39f
DK
2500 template<typename _MemPtr, typename _Arg, typename... _Args>
2501 struct __result_of_memfun;
be7f7822
JW
2502
2503 template<typename _Res, typename _Class, typename _Arg, typename... _Args>
83ddb39f 2504 struct __result_of_memfun<_Res _Class::*, _Arg, _Args...>
be7f7822 2505 {
81c7cf71 2506 typedef typename remove_reference<_Arg>::type _Argval;
83ddb39f 2507 typedef _Res _Class::* _MemPtr;
81c7cf71 2508 typedef typename conditional<is_base_of<_Class, _Argval>::value,
83ddb39f
DK
2509 __result_of_memfun_ref<_MemPtr, _Arg, _Args...>,
2510 __result_of_memfun_deref<_MemPtr, _Arg, _Args...>
2511 >::type::type type;
be7f7822
JW
2512 };
2513
93e95400
JW
2514 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2515 // 2219. INVOKE-ing a pointer to member with a reference_wrapper
2516 // as the object expression
93e95400 2517
7dcc645c 2518 // Used by result_of, invoke etc. to unwrap a reference_wrapper.
81c7cf71 2519 template<typename _Tp, typename _Up = __remove_cvref_t<_Tp>>
7dcc645c
JW
2520 struct __inv_unwrap
2521 {
2522 using type = _Tp;
2523 };
f3d7dd52 2524
7dcc645c
JW
2525 template<typename _Tp, typename _Up>
2526 struct __inv_unwrap<_Tp, reference_wrapper<_Up>>
2527 {
2528 using type = _Up&;
2529 };
93e95400 2530
be7f7822 2531 template<bool, bool, typename _Functor, typename... _ArgTypes>
83ddb39f 2532 struct __result_of_impl
be7f7822 2533 {
83ddb39f 2534 typedef __failure_type type;
be7f7822
JW
2535 };
2536
2537 template<typename _MemPtr, typename _Arg>
83ddb39f 2538 struct __result_of_impl<true, false, _MemPtr, _Arg>
391d5d2e 2539 : public __result_of_memobj<__decay_t<_MemPtr>,
7dcc645c 2540 typename __inv_unwrap<_Arg>::type>
c4db9a77 2541 { };
be7f7822 2542
83ddb39f
DK
2543 template<typename _MemPtr, typename _Arg, typename... _Args>
2544 struct __result_of_impl<false, true, _MemPtr, _Arg, _Args...>
391d5d2e 2545 : public __result_of_memfun<__decay_t<_MemPtr>,
7dcc645c 2546 typename __inv_unwrap<_Arg>::type, _Args...>
c4db9a77 2547 { };
be7f7822 2548
83ddb39f
DK
2549 // [func.require] paragraph 1 bullet 5:
2550 struct __result_of_other_impl
2551 {
2552 template<typename _Fn, typename... _Args>
93e95400 2553 static __result_of_success<decltype(
83ddb39f 2554 std::declval<_Fn>()(std::declval<_Args>()...)
93e95400 2555 ), __invoke_other> _S_test(int);
83ddb39f
DK
2556
2557 template<typename...>
2558 static __failure_type _S_test(...);
2559 };
2560
be7f7822 2561 template<typename _Functor, typename... _ArgTypes>
83ddb39f
DK
2562 struct __result_of_impl<false, false, _Functor, _ArgTypes...>
2563 : private __result_of_other_impl
be7f7822 2564 {
83ddb39f 2565 typedef decltype(_S_test<_Functor, _ArgTypes...>(0)) type;
be7f7822
JW
2566 };
2567
7dcc645c 2568 // __invoke_result (std::invoke_result for C++11)
83ddb39f 2569 template<typename _Functor, typename... _ArgTypes>
7dcc645c 2570 struct __invoke_result
83ddb39f
DK
2571 : public __result_of_impl<
2572 is_member_object_pointer<
2573 typename remove_reference<_Functor>::type
2574 >::value,
2575 is_member_function_pointer<
2576 typename remove_reference<_Functor>::type
2577 >::value,
7dcc645c 2578 _Functor, _ArgTypes...
83ddb39f
DK
2579 >::type
2580 { };
6963c3b9 2581 /// @endcond
c0ffa2ba 2582
7dcc645c
JW
2583 template<typename _Functor, typename... _ArgTypes>
2584 struct result_of<_Functor(_ArgTypes...)>
2585 : public __invoke_result<_Functor, _ArgTypes...>
2586 { };
2587
e112d53a 2588#if __cplusplus >= 201402L
4457e88c
JW
2589 /// Alias template for aligned_storage
2590 template<size_t _Len, size_t _Align =
2591 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
2592 using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
2593
d3718027
RS
2594 template <size_t _Len, typename... _Types>
2595 using aligned_union_t = typename aligned_union<_Len, _Types...>::type;
2596
4457e88c
JW
2597 /// Alias template for decay
2598 template<typename _Tp>
2599 using decay_t = typename decay<_Tp>::type;
2600
2601 /// Alias template for enable_if
2602 template<bool _Cond, typename _Tp = void>
2603 using enable_if_t = typename enable_if<_Cond, _Tp>::type;
2604
2605 /// Alias template for conditional
2606 template<bool _Cond, typename _Iftrue, typename _Iffalse>
2607 using conditional_t = typename conditional<_Cond, _Iftrue, _Iffalse>::type;
2608
2609 /// Alias template for common_type
2610 template<typename... _Tp>
2611 using common_type_t = typename common_type<_Tp...>::type;
2612
2613 /// Alias template for underlying_type
2614 template<typename _Tp>
2615 using underlying_type_t = typename underlying_type<_Tp>::type;
2616
2617 /// Alias template for result_of
2618 template<typename _Tp>
2619 using result_of_t = typename result_of<_Tp>::type;
e112d53a
JW
2620#endif // C++14
2621
e112d53a 2622#if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++11
bd1eb5e0
JW
2623#define __cpp_lib_void_t 201411
2624 /// A metafunction that always yields void, used for detecting valid types.
2625 template<typename...> using void_t = void;
2626#endif
2627
6963c3b9
JW
2628 /// @cond undocumented
2629
6af6bef4
JW
2630 /// Implementation of the detection idiom (negative case).
2631 template<typename _Default, typename _AlwaysVoid,
2632 template<typename...> class _Op, typename... _Args>
2633 struct __detector
2634 {
2635 using value_t = false_type;
2636 using type = _Default;
2637 };
2638
2639 /// Implementation of the detection idiom (positive case).
2640 template<typename _Default, template<typename...> class _Op,
2641 typename... _Args>
2642 struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...>
2643 {
2644 using value_t = true_type;
2645 using type = _Op<_Args...>;
2646 };
2647
2648 // Detect whether _Op<_Args...> is a valid type, use _Default if not.
2649 template<typename _Default, template<typename...> class _Op,
2650 typename... _Args>
2651 using __detected_or = __detector<_Default, void, _Op, _Args...>;
2652
2653 // _Op<_Args...> if that is a valid type, otherwise _Default.
2654 template<typename _Default, template<typename...> class _Op,
2655 typename... _Args>
2656 using __detected_or_t
2657 = typename __detected_or<_Default, _Op, _Args...>::type;
2658
033b71ce
PC
2659 /**
2660 * Use SFINAE to determine if the type _Tp has a publicly-accessible
2661 * member type _NTYPE.
2662 */
82b12c4b 2663#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
847e9cf8 2664 template<typename _Tp, typename = __void_t<>> \
82b12c4b 2665 struct __has_##_NTYPE \
847e9cf8
JW
2666 : false_type \
2667 { }; \
2668 template<typename _Tp> \
2669 struct __has_##_NTYPE<_Tp, __void_t<typename _Tp::_NTYPE>> \
2670 : true_type \
033b71ce
PC
2671 { };
2672
26b5ace7
DK
2673 template <typename _Tp>
2674 struct __is_swappable;
ddb63209 2675
26b5ace7
DK
2676 template <typename _Tp>
2677 struct __is_nothrow_swappable;
ddb63209 2678
a2863bde
VV
2679 template<typename>
2680 struct __is_tuple_like_impl : false_type
2681 { };
2682
2683 template<typename... _Tps>
2684 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
2685 { };
2686
2687 // Internal type trait that allows us to sfinae-protect tuple_cat.
2688 template<typename _Tp>
2689 struct __is_tuple_like
6791489e 2690 : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type
a2863bde 2691 { };
6963c3b9 2692 /// @endcond
a2863bde 2693
ddb63209 2694 template<typename _Tp>
7a91c710 2695 _GLIBCXX20_CONSTEXPR
ddb63209 2696 inline
391d5d2e
JW
2697 _Require<__not_<__is_tuple_like<_Tp>>,
2698 is_move_constructible<_Tp>,
2699 is_move_assignable<_Tp>>
ddb63209
VV
2700 swap(_Tp&, _Tp&)
2701 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
2702 is_nothrow_move_assignable<_Tp>>::value);
2703
2704 template<typename _Tp, size_t _Nm>
7a91c710 2705 _GLIBCXX20_CONSTEXPR
ddb63209 2706 inline
391d5d2e 2707 __enable_if_t<__is_swappable<_Tp>::value>
ddb63209 2708 swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
26b5ace7 2709 noexcept(__is_nothrow_swappable<_Tp>::value);
ddb63209 2710
6963c3b9 2711 /// @cond undocumented
26b5ace7 2712 namespace __swappable_details {
ddb63209
VV
2713 using std::swap;
2714
26b5ace7
DK
2715 struct __do_is_swappable_impl
2716 {
2717 template<typename _Tp, typename
2718 = decltype(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))>
2719 static true_type __test(int);
2720
2721 template<typename>
2722 static false_type __test(...);
2723 };
2724
2725 struct __do_is_nothrow_swappable_impl
2726 {
2727 template<typename _Tp>
2728 static __bool_constant<
2729 noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))
2730 > __test(int);
2731
2732 template<typename>
2733 static false_type __test(...);
2734 };
2735
6b9539e2 2736 } // namespace __swappable_details
ddb63209 2737
26b5ace7
DK
2738 template<typename _Tp>
2739 struct __is_swappable_impl
2740 : public __swappable_details::__do_is_swappable_impl
2741 {
2742 typedef decltype(__test<_Tp>(0)) type;
2743 };
2744
2745 template<typename _Tp>
ddb63209 2746 struct __is_nothrow_swappable_impl
26b5ace7
DK
2747 : public __swappable_details::__do_is_nothrow_swappable_impl
2748 {
2749 typedef decltype(__test<_Tp>(0)) type;
2750 };
ddb63209 2751
26b5ace7
DK
2752 template<typename _Tp>
2753 struct __is_swappable
2754 : public __is_swappable_impl<_Tp>::type
ddb63209
VV
2755 { };
2756
26b5ace7 2757 template<typename _Tp>
ddb63209 2758 struct __is_nothrow_swappable
26b5ace7 2759 : public __is_nothrow_swappable_impl<_Tp>::type
ddb63209 2760 { };
6963c3b9 2761 /// @endcond
ddb63209 2762
6b9539e2
DK
2763#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
2764#define __cpp_lib_is_swappable 201603
2765 /// Metafunctions used for detecting swappable types: p0185r1
2766
2767 /// is_swappable
2768 template<typename _Tp>
2769 struct is_swappable
2770 : public __is_swappable_impl<_Tp>::type
608a080c
AP
2771 {
2772 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
2773 "template argument must be a complete class or an unbounded array");
2774 };
6b9539e2
DK
2775
2776 /// is_nothrow_swappable
2777 template<typename _Tp>
2778 struct is_nothrow_swappable
2779 : public __is_nothrow_swappable_impl<_Tp>::type
608a080c
AP
2780 {
2781 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
2782 "template argument must be a complete class or an unbounded array");
2783 };
6b9539e2
DK
2784
2785#if __cplusplus >= 201402L
2786 /// is_swappable_v
2787 template<typename _Tp>
288695f7
DK
2788 _GLIBCXX17_INLINE constexpr bool is_swappable_v =
2789 is_swappable<_Tp>::value;
6b9539e2
DK
2790
2791 /// is_nothrow_swappable_v
2792 template<typename _Tp>
288695f7
DK
2793 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_v =
2794 is_nothrow_swappable<_Tp>::value;
6b9539e2
DK
2795#endif // __cplusplus >= 201402L
2796
6963c3b9 2797 /// @cond undocumented
6b9539e2
DK
2798 namespace __swappable_with_details {
2799 using std::swap;
2800
2801 struct __do_is_swappable_with_impl
2802 {
2803 template<typename _Tp, typename _Up, typename
2804 = decltype(swap(std::declval<_Tp>(), std::declval<_Up>())),
2805 typename
2806 = decltype(swap(std::declval<_Up>(), std::declval<_Tp>()))>
2807 static true_type __test(int);
2808
2809 template<typename, typename>
2810 static false_type __test(...);
2811 };
2812
2813 struct __do_is_nothrow_swappable_with_impl
2814 {
2815 template<typename _Tp, typename _Up>
2816 static __bool_constant<
2817 noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))
2818 &&
2819 noexcept(swap(std::declval<_Up>(), std::declval<_Tp>()))
2820 > __test(int);
2821
2822 template<typename, typename>
2823 static false_type __test(...);
2824 };
2825
2826 } // namespace __swappable_with_details
2827
2828 template<typename _Tp, typename _Up>
2829 struct __is_swappable_with_impl
2830 : public __swappable_with_details::__do_is_swappable_with_impl
2831 {
2832 typedef decltype(__test<_Tp, _Up>(0)) type;
2833 };
2834
2835 // Optimization for the homogenous lvalue case, not required:
2836 template<typename _Tp>
2837 struct __is_swappable_with_impl<_Tp&, _Tp&>
2838 : public __swappable_details::__do_is_swappable_impl
2839 {
2840 typedef decltype(__test<_Tp&>(0)) type;
2841 };
2842
2843 template<typename _Tp, typename _Up>
2844 struct __is_nothrow_swappable_with_impl
2845 : public __swappable_with_details::__do_is_nothrow_swappable_with_impl
2846 {
2847 typedef decltype(__test<_Tp, _Up>(0)) type;
2848 };
2849
2850 // Optimization for the homogenous lvalue case, not required:
2851 template<typename _Tp>
2852 struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&>
2853 : public __swappable_details::__do_is_nothrow_swappable_impl
2854 {
2855 typedef decltype(__test<_Tp&>(0)) type;
2856 };
6963c3b9 2857 /// @endcond
6b9539e2
DK
2858
2859 /// is_swappable_with
2860 template<typename _Tp, typename _Up>
2861 struct is_swappable_with
2862 : public __is_swappable_with_impl<_Tp, _Up>::type
69f571ff
AP
2863 {
2864 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
2865 "first template argument must be a complete class or an unbounded array");
2866 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}),
2867 "second template argument must be a complete class or an unbounded array");
2868 };
6b9539e2
DK
2869
2870 /// is_nothrow_swappable_with
2871 template<typename _Tp, typename _Up>
2872 struct is_nothrow_swappable_with
2873 : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type
69f571ff
AP
2874 {
2875 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
2876 "first template argument must be a complete class or an unbounded array");
2877 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}),
2878 "second template argument must be a complete class or an unbounded array");
2879 };
6b9539e2
DK
2880
2881#if __cplusplus >= 201402L
2882 /// is_swappable_with_v
2883 template<typename _Tp, typename _Up>
288695f7
DK
2884 _GLIBCXX17_INLINE constexpr bool is_swappable_with_v =
2885 is_swappable_with<_Tp, _Up>::value;
6b9539e2
DK
2886
2887 /// is_nothrow_swappable_with_v
2888 template<typename _Tp, typename _Up>
288695f7 2889 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_with_v =
6b9539e2
DK
2890 is_nothrow_swappable_with<_Tp, _Up>::value;
2891#endif // __cplusplus >= 201402L
137422c8 2892
42183d03
JW
2893#endif// c++1z or gnu++11
2894
6963c3b9
JW
2895 /// @cond undocumented
2896
7dcc645c 2897 // __is_invocable (std::is_invocable for C++11)
42183d03 2898
d91f618d
JW
2899 // The primary template is used for invalid INVOKE expressions.
2900 template<typename _Result, typename _Ret,
2901 bool = is_void<_Ret>::value, typename = void>
7dcc645c 2902 struct __is_invocable_impl : false_type { };
42183d03 2903
d91f618d 2904 // Used for valid INVOKE and INVOKE<void> expressions.
42183d03 2905 template<typename _Result, typename _Ret>
d91f618d
JW
2906 struct __is_invocable_impl<_Result, _Ret,
2907 /* is_void<_Ret> = */ true,
2908 __void_t<typename _Result::type>>
2909 : true_type
42183d03
JW
2910 { };
2911
d91f618d
JW
2912#pragma GCC diagnostic push
2913#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
2914 // Used for INVOKE<R> expressions to check the implicit conversion to R.
2915 template<typename _Result, typename _Ret>
2916 struct __is_invocable_impl<_Result, _Ret,
2917 /* is_void<_Ret> = */ false,
2918 __void_t<typename _Result::type>>
2919 {
2920 private:
2921 // The type of the INVOKE expression.
2922 // Unlike declval, this doesn't add_rvalue_reference.
2923 static typename _Result::type _S_get();
2924
2925 template<typename _Tp>
2926 static void _S_conv(_Tp);
2927
2928 // This overload is viable if INVOKE(f, args...) can convert to _Tp.
2929 template<typename _Tp, typename = decltype(_S_conv<_Tp>(_S_get()))>
2930 static true_type
2931 _S_test(int);
2932
2933 template<typename _Tp>
2934 static false_type
2935 _S_test(...);
2936
2937 public:
2938 using type = decltype(_S_test<_Ret>(1));
2939 };
2940#pragma GCC diagnostic pop
2941
7dcc645c
JW
2942 template<typename _Fn, typename... _ArgTypes>
2943 struct __is_invocable
2944 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
42183d03
JW
2945 { };
2946
42183d03
JW
2947 template<typename _Fn, typename _Tp, typename... _Args>
2948 constexpr bool __call_is_nt(__invoke_memfun_ref)
2949 {
2950 using _Up = typename __inv_unwrap<_Tp>::type;
2951 return noexcept((std::declval<_Up>().*std::declval<_Fn>())(
2952 std::declval<_Args>()...));
2953 }
2954
2955 template<typename _Fn, typename _Tp, typename... _Args>
2956 constexpr bool __call_is_nt(__invoke_memfun_deref)
2957 {
2958 return noexcept(((*std::declval<_Tp>()).*std::declval<_Fn>())(
2959 std::declval<_Args>()...));
2960 }
2961
2962 template<typename _Fn, typename _Tp>
2963 constexpr bool __call_is_nt(__invoke_memobj_ref)
2964 {
2965 using _Up = typename __inv_unwrap<_Tp>::type;
2966 return noexcept(std::declval<_Up>().*std::declval<_Fn>());
2967 }
2968
2969 template<typename _Fn, typename _Tp>
2970 constexpr bool __call_is_nt(__invoke_memobj_deref)
2971 {
2972 return noexcept((*std::declval<_Tp>()).*std::declval<_Fn>());
2973 }
2974
2975 template<typename _Fn, typename... _Args>
2976 constexpr bool __call_is_nt(__invoke_other)
2977 {
2978 return noexcept(std::declval<_Fn>()(std::declval<_Args>()...));
2979 }
2980
7dcc645c 2981 template<typename _Result, typename _Fn, typename... _Args>
42183d03
JW
2982 struct __call_is_nothrow
2983 : __bool_constant<
7dcc645c
JW
2984 std::__call_is_nt<_Fn, _Args...>(typename _Result::__invoke_type{})
2985 >
42183d03
JW
2986 { };
2987
7dcc645c
JW
2988 template<typename _Fn, typename... _Args>
2989 using __call_is_nothrow_
2990 = __call_is_nothrow<__invoke_result<_Fn, _Args...>, _Fn, _Args...>;
42183d03 2991
7dcc645c
JW
2992 // __is_nothrow_invocable (std::is_nothrow_invocable for C++11)
2993 template<typename _Fn, typename... _Args>
2994 struct __is_nothrow_invocable
2995 : __and_<__is_invocable<_Fn, _Args...>,
2996 __call_is_nothrow_<_Fn, _Args...>>::type
42183d03
JW
2997 { };
2998
cc28d234
JW
2999#pragma GCC diagnostic push
3000#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
a73d2fa8
NDR
3001 struct __nonesuchbase {};
3002 struct __nonesuch : private __nonesuchbase {
f524d5b3
VV
3003 ~__nonesuch() = delete;
3004 __nonesuch(__nonesuch const&) = delete;
3005 void operator=(__nonesuch const&) = delete;
3006 };
cc28d234 3007#pragma GCC diagnostic pop
6963c3b9 3008 /// @endcond
f524d5b3 3009
e641ee43 3010#if __cplusplus >= 201703L
7dcc645c
JW
3011# define __cpp_lib_is_invocable 201703
3012
3013 /// std::invoke_result
3014 template<typename _Functor, typename... _ArgTypes>
3015 struct invoke_result
3016 : public __invoke_result<_Functor, _ArgTypes...>
69f571ff
AP
3017 {
3018 static_assert(std::__is_complete_or_unbounded(__type_identity<_Functor>{}),
3019 "_Functor must be a complete class or an unbounded array");
c1fc9f6e
AP
3020 static_assert((std::__is_complete_or_unbounded(
3021 __type_identity<_ArgTypes>{}) && ...),
3022 "each argument type must be a complete class or an unbounded array");
69f571ff 3023 };
7dcc645c
JW
3024
3025 /// std::invoke_result_t
3026 template<typename _Fn, typename... _Args>
3027 using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
42183d03 3028
7dcc645c
JW
3029 /// std::is_invocable
3030 template<typename _Fn, typename... _ArgTypes>
3031 struct is_invocable
3032 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
608a080c
AP
3033 {
3034 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3035 "_Fn must be a complete class or an unbounded array");
c1fc9f6e
AP
3036 static_assert((std::__is_complete_or_unbounded(
3037 __type_identity<_ArgTypes>{}) && ...),
3038 "each argument type must be a complete class or an unbounded array");
608a080c 3039 };
42183d03 3040
7dcc645c
JW
3041 /// std::is_invocable_r
3042 template<typename _Ret, typename _Fn, typename... _ArgTypes>
3043 struct is_invocable_r
3044 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>::type
608a080c
AP
3045 {
3046 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3047 "_Fn must be a complete class or an unbounded array");
c1fc9f6e
AP
3048 static_assert((std::__is_complete_or_unbounded(
3049 __type_identity<_ArgTypes>{}) && ...),
3050 "each argument type must be a complete class or an unbounded array");
3051 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}),
3052 "_Ret must be a complete class or an unbounded array");
608a080c 3053 };
42183d03 3054
7dcc645c
JW
3055 /// std::is_nothrow_invocable
3056 template<typename _Fn, typename... _ArgTypes>
3057 struct is_nothrow_invocable
3058 : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>,
608a080c
AP
3059 __call_is_nothrow_<_Fn, _ArgTypes...>>::type
3060 {
3061 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3062 "_Fn must be a complete class or an unbounded array");
c1fc9f6e
AP
3063 static_assert((std::__is_complete_or_unbounded(
3064 __type_identity<_ArgTypes>{}) && ...),
3065 "each argument type must be a complete class or an unbounded array");
608a080c 3066 };
42183d03 3067
6963c3b9 3068 /// @cond undocumented
c4b06e7f
JW
3069 template<typename _Result, typename _Ret, typename = void>
3070 struct __is_nt_invocable_impl : false_type { };
3071
3072 template<typename _Result, typename _Ret>
3073 struct __is_nt_invocable_impl<_Result, _Ret,
3074 __void_t<typename _Result::type>>
91d01b33 3075 : __or_<is_void<_Ret>,
ce9f305e 3076 __is_nothrow_convertible<typename _Result::type, _Ret>>
c4b06e7f 3077 { };
6963c3b9 3078 /// @endcond
c4b06e7f 3079
7dcc645c
JW
3080 /// std::is_nothrow_invocable_r
3081 template<typename _Ret, typename _Fn, typename... _ArgTypes>
3082 struct is_nothrow_invocable_r
c4b06e7f 3083 : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>,
7dcc645c 3084 __call_is_nothrow_<_Fn, _ArgTypes...>>::type
69f571ff
AP
3085 {
3086 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3087 "_Fn must be a complete class or an unbounded array");
c1fc9f6e
AP
3088 static_assert((std::__is_complete_or_unbounded(
3089 __type_identity<_ArgTypes>{}) && ...),
3090 "each argument type must be a complete class or an unbounded array");
3091 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}),
3092 "_Ret must be a complete class or an unbounded array");
69f571ff 3093 };
7dcc645c 3094#endif // C++17
42183d03 3095
e641ee43 3096#if __cplusplus >= 201703L
068c8ac1 3097# define __cpp_lib_type_trait_variable_templates 201510L
6963c3b9 3098 /**
da89dfc2 3099 * @defgroup variable_templates Variable templates for type traits
6963c3b9
JW
3100 * @ingroup metaprogramming
3101 *
da89dfc2
JW
3102 * Each variable `is_xxx_v<T>` is a boolean constant with the same value
3103 * as the `value` member of the corresponding type trait `is_xxx<T>`.
6963c3b9
JW
3104 *
3105 * @since C++17
3106 */
3107
da89dfc2 3108 /**
6963c3b9 3109 * @{
da89dfc2 3110 * @ingroup variable_templates
6963c3b9 3111 */
137422c8 3112template <typename _Tp>
288695f7 3113 inline constexpr bool is_void_v = is_void<_Tp>::value;
137422c8 3114template <typename _Tp>
288695f7 3115 inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value;
137422c8 3116template <typename _Tp>
288695f7 3117 inline constexpr bool is_integral_v = is_integral<_Tp>::value;
137422c8 3118template <typename _Tp>
288695f7 3119 inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
137422c8 3120template <typename _Tp>
288695f7 3121 inline constexpr bool is_array_v = is_array<_Tp>::value;
137422c8 3122template <typename _Tp>
288695f7 3123 inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
137422c8 3124template <typename _Tp>
288695f7
DK
3125 inline constexpr bool is_lvalue_reference_v =
3126 is_lvalue_reference<_Tp>::value;
137422c8 3127template <typename _Tp>
288695f7
DK
3128 inline constexpr bool is_rvalue_reference_v =
3129 is_rvalue_reference<_Tp>::value;
137422c8 3130template <typename _Tp>
288695f7 3131 inline constexpr bool is_member_object_pointer_v =
137422c8
VV
3132 is_member_object_pointer<_Tp>::value;
3133template <typename _Tp>
288695f7 3134 inline constexpr bool is_member_function_pointer_v =
137422c8
VV
3135 is_member_function_pointer<_Tp>::value;
3136template <typename _Tp>
288695f7 3137 inline constexpr bool is_enum_v = is_enum<_Tp>::value;
137422c8 3138template <typename _Tp>
288695f7 3139 inline constexpr bool is_union_v = is_union<_Tp>::value;
137422c8 3140template <typename _Tp>
288695f7 3141 inline constexpr bool is_class_v = is_class<_Tp>::value;
137422c8 3142template <typename _Tp>
288695f7 3143 inline constexpr bool is_function_v = is_function<_Tp>::value;
137422c8 3144template <typename _Tp>
288695f7 3145 inline constexpr bool is_reference_v = is_reference<_Tp>::value;
137422c8 3146template <typename _Tp>
288695f7 3147 inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
137422c8 3148template <typename _Tp>
288695f7 3149 inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
137422c8 3150template <typename _Tp>
288695f7 3151 inline constexpr bool is_object_v = is_object<_Tp>::value;
137422c8 3152template <typename _Tp>
288695f7 3153 inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
137422c8 3154template <typename _Tp>
288695f7 3155 inline constexpr bool is_compound_v = is_compound<_Tp>::value;
137422c8 3156template <typename _Tp>
288695f7 3157 inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
137422c8 3158template <typename _Tp>
288695f7 3159 inline constexpr bool is_const_v = is_const<_Tp>::value;
137422c8 3160template <typename _Tp>
288695f7 3161 inline constexpr bool is_volatile_v = is_volatile<_Tp>::value;
137422c8 3162template <typename _Tp>
288695f7 3163 inline constexpr bool is_trivial_v = is_trivial<_Tp>::value;
137422c8 3164template <typename _Tp>
288695f7
DK
3165 inline constexpr bool is_trivially_copyable_v =
3166 is_trivially_copyable<_Tp>::value;
137422c8 3167template <typename _Tp>
288695f7 3168 inline constexpr bool is_standard_layout_v = is_standard_layout<_Tp>::value;
caa39b2e
JW
3169#pragma GCC diagnostic push
3170#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
137422c8 3171template <typename _Tp>
1a6c5064 3172 _GLIBCXX20_DEPRECATED("use is_standard_layout_v && is_trivial_v instead")
288695f7 3173 inline constexpr bool is_pod_v = is_pod<_Tp>::value;
137422c8 3174template <typename _Tp>
24b54628 3175 _GLIBCXX17_DEPRECATED
288695f7 3176 inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value;
24b54628
VV
3177#pragma GCC diagnostic pop
3178 template <typename _Tp>
288695f7 3179 inline constexpr bool is_empty_v = is_empty<_Tp>::value;
137422c8 3180template <typename _Tp>
288695f7 3181 inline constexpr bool is_polymorphic_v = is_polymorphic<_Tp>::value;
137422c8 3182template <typename _Tp>
288695f7 3183 inline constexpr bool is_abstract_v = is_abstract<_Tp>::value;
137422c8 3184template <typename _Tp>
288695f7 3185 inline constexpr bool is_final_v = is_final<_Tp>::value;
137422c8 3186template <typename _Tp>
288695f7 3187 inline constexpr bool is_signed_v = is_signed<_Tp>::value;
137422c8 3188template <typename _Tp>
288695f7 3189 inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
137422c8 3190template <typename _Tp, typename... _Args>
288695f7
DK
3191 inline constexpr bool is_constructible_v =
3192 is_constructible<_Tp, _Args...>::value;
137422c8 3193template <typename _Tp>
288695f7 3194 inline constexpr bool is_default_constructible_v =
137422c8
VV
3195 is_default_constructible<_Tp>::value;
3196template <typename _Tp>
288695f7
DK
3197 inline constexpr bool is_copy_constructible_v =
3198 is_copy_constructible<_Tp>::value;
137422c8 3199template <typename _Tp>
288695f7
DK
3200 inline constexpr bool is_move_constructible_v =
3201 is_move_constructible<_Tp>::value;
137422c8 3202template <typename _Tp, typename _Up>
288695f7 3203 inline constexpr bool is_assignable_v = is_assignable<_Tp, _Up>::value;
137422c8 3204template <typename _Tp>
288695f7 3205 inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
137422c8 3206template <typename _Tp>
288695f7 3207 inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value;
137422c8 3208template <typename _Tp>
288695f7 3209 inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
137422c8 3210template <typename _Tp, typename... _Args>
288695f7 3211 inline constexpr bool is_trivially_constructible_v =
137422c8
VV
3212 is_trivially_constructible<_Tp, _Args...>::value;
3213template <typename _Tp>
288695f7 3214 inline constexpr bool is_trivially_default_constructible_v =
137422c8
VV
3215 is_trivially_default_constructible<_Tp>::value;
3216template <typename _Tp>
288695f7 3217 inline constexpr bool is_trivially_copy_constructible_v =
137422c8
VV
3218 is_trivially_copy_constructible<_Tp>::value;
3219template <typename _Tp>
288695f7 3220 inline constexpr bool is_trivially_move_constructible_v =
137422c8
VV
3221 is_trivially_move_constructible<_Tp>::value;
3222template <typename _Tp, typename _Up>
288695f7 3223 inline constexpr bool is_trivially_assignable_v =
137422c8
VV
3224 is_trivially_assignable<_Tp, _Up>::value;
3225template <typename _Tp>
288695f7 3226 inline constexpr bool is_trivially_copy_assignable_v =
137422c8
VV
3227 is_trivially_copy_assignable<_Tp>::value;
3228template <typename _Tp>
288695f7 3229 inline constexpr bool is_trivially_move_assignable_v =
137422c8
VV
3230 is_trivially_move_assignable<_Tp>::value;
3231template <typename _Tp>
288695f7 3232 inline constexpr bool is_trivially_destructible_v =
137422c8
VV
3233 is_trivially_destructible<_Tp>::value;
3234template <typename _Tp, typename... _Args>
288695f7 3235 inline constexpr bool is_nothrow_constructible_v =
137422c8
VV
3236 is_nothrow_constructible<_Tp, _Args...>::value;
3237template <typename _Tp>
288695f7 3238 inline constexpr bool is_nothrow_default_constructible_v =
137422c8
VV
3239 is_nothrow_default_constructible<_Tp>::value;
3240template <typename _Tp>
288695f7 3241 inline constexpr bool is_nothrow_copy_constructible_v =
137422c8
VV
3242 is_nothrow_copy_constructible<_Tp>::value;
3243template <typename _Tp>
288695f7 3244 inline constexpr bool is_nothrow_move_constructible_v =
137422c8
VV
3245 is_nothrow_move_constructible<_Tp>::value;
3246template <typename _Tp, typename _Up>
288695f7 3247 inline constexpr bool is_nothrow_assignable_v =
137422c8
VV
3248 is_nothrow_assignable<_Tp, _Up>::value;
3249template <typename _Tp>
288695f7 3250 inline constexpr bool is_nothrow_copy_assignable_v =
137422c8
VV
3251 is_nothrow_copy_assignable<_Tp>::value;
3252template <typename _Tp>
288695f7 3253 inline constexpr bool is_nothrow_move_assignable_v =
137422c8
VV
3254 is_nothrow_move_assignable<_Tp>::value;
3255template <typename _Tp>
288695f7 3256 inline constexpr bool is_nothrow_destructible_v =
137422c8
VV
3257 is_nothrow_destructible<_Tp>::value;
3258template <typename _Tp>
288695f7 3259 inline constexpr bool has_virtual_destructor_v =
137422c8
VV
3260 has_virtual_destructor<_Tp>::value;
3261template <typename _Tp>
288695f7 3262 inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value;
137422c8 3263template <typename _Tp>
288695f7 3264 inline constexpr size_t rank_v = rank<_Tp>::value;
137422c8 3265template <typename _Tp, unsigned _Idx = 0>
288695f7 3266 inline constexpr size_t extent_v = extent<_Tp, _Idx>::value;
73ae6eb5 3267#ifdef _GLIBCXX_HAVE_BUILTIN_IS_SAME
137422c8 3268template <typename _Tp, typename _Up>
73ae6eb5 3269 inline constexpr bool is_same_v = __is_same(_Tp, _Up);
44af818f
JW
3270#else
3271template <typename _Tp, typename _Up>
3272 inline constexpr bool is_same_v = std::is_same<_Tp, _Up>::value;
3273#endif
137422c8 3274template <typename _Base, typename _Derived>
288695f7 3275 inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value;
137422c8 3276template <typename _From, typename _To>
288695f7 3277 inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
6963c3b9
JW
3278template<typename _Fn, typename... _Args>
3279 inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
3280template<typename _Fn, typename... _Args>
3281 inline constexpr bool is_nothrow_invocable_v
3282 = is_nothrow_invocable<_Fn, _Args...>::value;
3283template<typename _Ret, typename _Fn, typename... _Args>
3284 inline constexpr bool is_invocable_r_v
3285 = is_invocable_r<_Ret, _Fn, _Args...>::value;
3286template<typename _Ret, typename _Fn, typename... _Args>
3287 inline constexpr bool is_nothrow_invocable_r_v
3288 = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
3289/// @}
873c7d5a 3290
2d763763 3291#ifdef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP
873c7d5a
JW
3292# define __cpp_lib_has_unique_object_representations 201606
3293 /// has_unique_object_representations
3294 template<typename _Tp>
3295 struct has_unique_object_representations
3296 : bool_constant<__has_unique_object_representations(
3297 remove_cv_t<remove_all_extents_t<_Tp>>
3298 )>
608a080c
AP
3299 {
3300 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3301 "template argument must be a complete class or an unbounded array");
3302 };
b0e63d94 3303
6963c3b9 3304 /// @ingroup variable_templates
b0e63d94
JW
3305 template<typename _Tp>
3306 inline constexpr bool has_unique_object_representations_v
3307 = has_unique_object_representations<_Tp>::value;
1f5700e9 3308#endif
e2ac6765 3309
afa56c17 3310#ifdef _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE
ff273400 3311# define __cpp_lib_is_aggregate 201703
e2ac6765
VV
3312 /// is_aggregate
3313 template<typename _Tp>
3314 struct is_aggregate
608a080c 3315 : bool_constant<__is_aggregate(remove_cv_t<_Tp>)>
209ee624 3316 { };
e2ac6765 3317
6963c3b9 3318 /// @ingroup variable_templates
e2ac6765
VV
3319 template<typename _Tp>
3320 inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value;
3321#endif
137422c8 3322#endif // C++17
6b9539e2 3323
e641ee43 3324#if __cplusplus > 201703L
56772f62
JW
3325#define __cpp_lib_remove_cvref 201711L
3326
6791489e
JW
3327 /// Remove references and cv-qualifiers.
3328 template<typename _Tp>
3329 struct remove_cvref
0e79e630
JW
3330 : remove_cv<_Tp>
3331 { };
3332
3333 template<typename _Tp>
3334 struct remove_cvref<_Tp&>
3335 : remove_cv<_Tp>
3336 { };
3337
3338 template<typename _Tp>
3339 struct remove_cvref<_Tp&&>
3340 : remove_cv<_Tp>
3341 { };
6791489e
JW
3342
3343 template<typename _Tp>
0e79e630 3344 using remove_cvref_t = typename remove_cvref<_Tp>::type;
6791489e 3345
56772f62 3346#define __cpp_lib_type_identity 201806L
ee896276
JW
3347 /// Identity metafunction.
3348 template<typename _Tp>
3349 struct type_identity { using type = _Tp; };
3350
3351 template<typename _Tp>
3352 using type_identity_t = typename type_identity<_Tp>::type;
3353
bb54e0b8
JW
3354#define __cpp_lib_unwrap_ref 201811L
3355
3d18dc9d
JW
3356 /// Unwrap a reference_wrapper
3357 template<typename _Tp>
3358 struct unwrap_reference { using type = _Tp; };
3359
3360 template<typename _Tp>
3361 struct unwrap_reference<reference_wrapper<_Tp>> { using type = _Tp&; };
3362
82e8c3da
JW
3363 template<typename _Tp>
3364 using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
3365
3d18dc9d
JW
3366 /// Decay type and if it's a reference_wrapper, unwrap it
3367 template<typename _Tp>
82e8c3da 3368 struct unwrap_ref_decay { using type = unwrap_reference_t<decay_t<_Tp>>; };
3d18dc9d
JW
3369
3370 template<typename _Tp>
3371 using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
3372
46610940
JW
3373#define __cpp_lib_bounded_array_traits 201902L
3374
28d85efb
JW
3375 /// True for a type that is an array of known bound.
3376 template<typename _Tp>
3377 struct is_bounded_array
3378 : public __is_array_known_bounds<_Tp>
3379 { };
3380
3381 /// True for a type that is an array of unknown bound.
3382 template<typename _Tp>
3383 struct is_unbounded_array
3384 : public __is_array_unknown_bounds<_Tp>
3385 { };
3386
6963c3b9 3387 /// @ingroup variable_templates
28d85efb
JW
3388 template<typename _Tp>
3389 inline constexpr bool is_bounded_array_v
3390 = is_bounded_array<_Tp>::value;
3391
6963c3b9 3392 /// @ingroup variable_templates
28d85efb
JW
3393 template<typename _Tp>
3394 inline constexpr bool is_unbounded_array_v
3395 = is_unbounded_array<_Tp>::value;
3396
b8ecdc77
JW
3397#if __cplusplus > 202002L
3398#define __cpp_lib_is_scoped_enum 202011L
3399
6963c3b9
JW
3400 /// @since C++23
3401 //@{
3402
b8ecdc77
JW
3403 template<typename _Tp>
3404 struct is_scoped_enum
3405 : false_type
3406 { };
3407
43ab1dc2
JW
3408 template<typename _Tp>
3409 requires __is_enum(_Tp)
3410 && requires(_Tp __t) { __t = __t; } // fails if incomplete
b8ecdc77 3411 struct is_scoped_enum<_Tp>
43ab1dc2
JW
3412 : bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }>
3413 { };
3414
3415 // FIXME remove this partial specialization and use remove_cv_t<_Tp> above
3416 // when PR c++/99968 is fixed.
3417 template<typename _Tp>
3418 requires __is_enum(_Tp)
3419 && requires(_Tp __t) { __t = __t; } // fails if incomplete
3420 struct is_scoped_enum<const _Tp>
3421 : bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }>
b8ecdc77
JW
3422 { };
3423
6963c3b9
JW
3424 /**
3425 * @ingroup variable_templates
3426 */
b8ecdc77
JW
3427 template<typename _Tp>
3428 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
3429#endif // C++23
3430
0d7924f2 3431#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
134a6f7b 3432
8aa1550e 3433#define __cpp_lib_is_constant_evaluated 201811L
134a6f7b 3434
6963c3b9 3435 /// Returns true only when called during constant evaluation.
0d7924f2
JJ
3436 constexpr inline bool
3437 is_constant_evaluated() noexcept
3438 { return __builtin_is_constant_evaluated(); }
6963c3b9 3439 /// @}
0d7924f2
JJ
3440#endif
3441
6963c3b9 3442 /// @cond undocumented
0f8b14ee
JW
3443 template<typename _From, typename _To>
3444 using __copy_cv = typename __match_cv_qualifiers<_From, _To>::__type;
3445
3446 template<typename _Xp, typename _Yp>
3447 using __cond_res
3448 = decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()());
3449
3450 template<typename _Ap, typename _Bp, typename = void>
3451 struct __common_ref_impl
3452 { };
3453
3454 // [meta.trans.other], COMMON-REF(A, B)
3455 template<typename _Ap, typename _Bp>
3456 using __common_ref = typename __common_ref_impl<_Ap, _Bp>::type;
3457
c37b5ddc
JW
3458 // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &)
3459 template<typename _Xp, typename _Yp>
3460 using __condres_cvref
3461 = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>;
3462
0f8b14ee
JW
3463 // If A and B are both lvalue reference types, ...
3464 template<typename _Xp, typename _Yp>
c37b5ddc
JW
3465 struct __common_ref_impl<_Xp&, _Yp&, __void_t<__condres_cvref<_Xp, _Yp>>>
3466 : enable_if<is_reference_v<__condres_cvref<_Xp, _Yp>>,
3467 __condres_cvref<_Xp, _Yp>>
3468 { };
0f8b14ee
JW
3469
3470 // let C be remove_reference_t<COMMON-REF(X&, Y&)>&&
3471 template<typename _Xp, typename _Yp>
3472 using __common_ref_C = remove_reference_t<__common_ref<_Xp&, _Yp&>>&&;
3473
3474 // If A and B are both rvalue reference types, ...
3475 template<typename _Xp, typename _Yp>
3476 struct __common_ref_impl<_Xp&&, _Yp&&,
3477 _Require<is_convertible<_Xp&&, __common_ref_C<_Xp, _Yp>>,
3478 is_convertible<_Yp&&, __common_ref_C<_Xp, _Yp>>>>
3479 { using type = __common_ref_C<_Xp, _Yp>; };
3480
3481 // let D be COMMON-REF(const X&, Y&)
3482 template<typename _Xp, typename _Yp>
3483 using __common_ref_D = __common_ref<const _Xp&, _Yp&>;
3484
3485 // If A is an rvalue reference and B is an lvalue reference, ...
3486 template<typename _Xp, typename _Yp>
3487 struct __common_ref_impl<_Xp&&, _Yp&,
3488 _Require<is_convertible<_Xp&&, __common_ref_D<_Xp, _Yp>>>>
3489 { using type = __common_ref_D<_Xp, _Yp>; };
3490
3491 // If A is an lvalue reference and B is an rvalue reference, ...
3492 template<typename _Xp, typename _Yp>
3493 struct __common_ref_impl<_Xp&, _Yp&&>
3494 : __common_ref_impl<_Yp&&, _Xp&>
3495 { };
6963c3b9 3496 /// @endcond
0f8b14ee
JW
3497
3498 template<typename _Tp, typename _Up,
3499 template<typename> class _TQual, template<typename> class _UQual>
3500 struct basic_common_reference
3501 { };
3502
6963c3b9 3503 /// @cond undocumented
0f8b14ee
JW
3504 template<typename _Tp>
3505 struct __xref
3506 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>; };
3507
3508 template<typename _Tp>
3509 struct __xref<_Tp&>
3510 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&; };
3511
3512 template<typename _Tp>
3513 struct __xref<_Tp&&>
3514 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&&; };
3515
3516 template<typename _Tp1, typename _Tp2>
3517 using __basic_common_ref
3518 = typename basic_common_reference<remove_cvref_t<_Tp1>,
3519 remove_cvref_t<_Tp2>,
3520 __xref<_Tp1>::template __type,
3521 __xref<_Tp2>::template __type>::type;
6963c3b9 3522 /// @endcond
0f8b14ee
JW
3523
3524 template<typename... _Tp>
3525 struct common_reference;
3526
3527 template<typename... _Tp>
3528 using common_reference_t = typename common_reference<_Tp...>::type;
3529
3530 // If sizeof...(T) is zero, there shall be no member type.
3531 template<>
3532 struct common_reference<>
3533 { };
3534
3535 // If sizeof...(T) is one ...
3536 template<typename _Tp0>
3537 struct common_reference<_Tp0>
3538 { using type = _Tp0; };
3539
6963c3b9 3540 /// @cond undocumented
0f8b14ee
JW
3541 template<typename _Tp1, typename _Tp2, int _Bullet = 1, typename = void>
3542 struct __common_reference_impl
3543 : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1>
3544 { };
3545
3546 // If sizeof...(T) is two ...
3547 template<typename _Tp1, typename _Tp2>
3548 struct common_reference<_Tp1, _Tp2>
3549 : __common_reference_impl<_Tp1, _Tp2>
3550 { };
3551
3552 // If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, ...
3553 template<typename _Tp1, typename _Tp2>
3554 struct __common_reference_impl<_Tp1&, _Tp2&, 1,
3555 void_t<__common_ref<_Tp1&, _Tp2&>>>
3556 { using type = __common_ref<_Tp1&, _Tp2&>; };
3557
3558 template<typename _Tp1, typename _Tp2>
3559 struct __common_reference_impl<_Tp1&&, _Tp2&&, 1,
3560 void_t<__common_ref<_Tp1&&, _Tp2&&>>>
3561 { using type = __common_ref<_Tp1&&, _Tp2&&>; };
3562
3563 template<typename _Tp1, typename _Tp2>
3564 struct __common_reference_impl<_Tp1&, _Tp2&&, 1,
3565 void_t<__common_ref<_Tp1&, _Tp2&&>>>
3566 { using type = __common_ref<_Tp1&, _Tp2&&>; };
3567
3568 template<typename _Tp1, typename _Tp2>
3569 struct __common_reference_impl<_Tp1&&, _Tp2&, 1,
3570 void_t<__common_ref<_Tp1&&, _Tp2&>>>
3571 { using type = __common_ref<_Tp1&&, _Tp2&>; };
3572
3573 // Otherwise, if basic_common_reference<...>::type is well-formed, ...
3574 template<typename _Tp1, typename _Tp2>
3575 struct __common_reference_impl<_Tp1, _Tp2, 2,
3576 void_t<__basic_common_ref<_Tp1, _Tp2>>>
3577 { using type = __basic_common_ref<_Tp1, _Tp2>; };
3578
3579 // Otherwise, if COND-RES(T1, T2) is well-formed, ...
3580 template<typename _Tp1, typename _Tp2>
3581 struct __common_reference_impl<_Tp1, _Tp2, 3,
3582 void_t<__cond_res<_Tp1, _Tp2>>>
3583 { using type = __cond_res<_Tp1, _Tp2>; };
3584
3585 // Otherwise, if common_type_t<T1, T2> is well-formed, ...
3586 template<typename _Tp1, typename _Tp2>
3587 struct __common_reference_impl<_Tp1, _Tp2, 4,
3588 void_t<common_type_t<_Tp1, _Tp2>>>
3589 { using type = common_type_t<_Tp1, _Tp2>; };
3590
3591 // Otherwise, there shall be no member type.
3592 template<typename _Tp1, typename _Tp2>
3593 struct __common_reference_impl<_Tp1, _Tp2, 5, void>
3594 { };
3595
3596 // Otherwise, if sizeof...(T) is greater than two, ...
3597 template<typename _Tp1, typename _Tp2, typename... _Rest>
3598 struct common_reference<_Tp1, _Tp2, _Rest...>
3599 : __common_type_fold<common_reference<_Tp1, _Tp2>,
3600 __common_type_pack<_Rest...>>
3601 { };
3602
3603 // Reuse __common_type_fold for common_reference<T1, T2, Rest...>
3604 template<typename _Tp1, typename _Tp2, typename... _Rest>
3605 struct __common_type_fold<common_reference<_Tp1, _Tp2>,
3606 __common_type_pack<_Rest...>,
3607 void_t<common_reference_t<_Tp1, _Tp2>>>
3608 : public common_reference<common_reference_t<_Tp1, _Tp2>, _Rest...>
3609 { };
6963c3b9 3610 /// @endcond
0f8b14ee 3611
e641ee43
JW
3612#endif // C++2a
3613
6963c3b9
JW
3614 /// @} group metaprogramming
3615
12ffa228 3616_GLIBCXX_END_NAMESPACE_VERSION
c0ffa2ba 3617} // namespace std
7b50cdef 3618
734f5023 3619#endif // C++11
57317d2a 3620
7274deff 3621#endif // _GLIBCXX_TYPE_TRAITS