source: Daodan/MSYS2/mingw32/include/c++/11.2.0/tuple@ 1177

Last change on this file since 1177 was 1166, checked in by rossy, 3 years ago

Daodan: Replace MinGW build env with an up-to-date MSYS2 env

File size: 61.2 KB
Line 
1// <tuple> -*- C++ -*-
2
3// Copyright (C) 2007-2021 Free Software Foundation, Inc.
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
8// Free Software Foundation; either version 3, or (at your option)
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
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/>.
24
25/** @file include/tuple
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_TUPLE
30#define _GLIBCXX_TUPLE 1
31
32#pragma GCC system_header
33
34#if __cplusplus < 201103L
35# include <bits/c++0x_warning.h>
36#else
37
38#include <utility>
39#include <array>
40#include <bits/uses_allocator.h>
41#include <bits/invoke.h>
42#if __cplusplus > 201703L
43# include <compare>
44# define __cpp_lib_constexpr_tuple 201811L
45#endif
46
47namespace std _GLIBCXX_VISIBILITY(default)
48{
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
50
51 /**
52 * @addtogroup utilities
53 * @{
54 */
55
56 template<typename... _Elements>
57 class tuple;
58
59 template<typename _Tp>
60 struct __is_empty_non_tuple : is_empty<_Tp> { };
61
62 // Using EBO for elements that are tuples causes ambiguous base errors.
63 template<typename _El0, typename... _El>
64 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
65
66 // Use the Empty Base-class Optimization for empty, non-final types.
67 template<typename _Tp>
68 using __empty_not_final
69 = typename conditional<__is_final(_Tp), false_type,
70 __is_empty_non_tuple<_Tp>>::type;
71
72 template<size_t _Idx, typename _Head,
73 bool = __empty_not_final<_Head>::value>
74 struct _Head_base;
75
76#if __has_cpp_attribute(__no_unique_address__)
77 template<size_t _Idx, typename _Head>
78 struct _Head_base<_Idx, _Head, true>
79 {
80 constexpr _Head_base()
81 : _M_head_impl() { }
82
83 constexpr _Head_base(const _Head& __h)
84 : _M_head_impl(__h) { }
85
86 constexpr _Head_base(const _Head_base&) = default;
87 constexpr _Head_base(_Head_base&&) = default;
88
89 template<typename _UHead>
90 constexpr _Head_base(_UHead&& __h)
91 : _M_head_impl(std::forward<_UHead>(__h)) { }
92
93 _GLIBCXX20_CONSTEXPR
94 _Head_base(allocator_arg_t, __uses_alloc0)
95 : _M_head_impl() { }
96
97 template<typename _Alloc>
98 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
99 : _M_head_impl(allocator_arg, *__a._M_a) { }
100
101 template<typename _Alloc>
102 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
103 : _M_head_impl(*__a._M_a) { }
104
105 template<typename _UHead>
106 _GLIBCXX20_CONSTEXPR
107 _Head_base(__uses_alloc0, _UHead&& __uhead)
108 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
109
110 template<typename _Alloc, typename _UHead>
111 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
112 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
113 { }
114
115 template<typename _Alloc, typename _UHead>
116 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
117 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
118
119 static constexpr _Head&
120 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
121
122 static constexpr const _Head&
123 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
124
125 [[__no_unique_address__]] _Head _M_head_impl;
126 };
127#else
128 template<size_t _Idx, typename _Head>
129 struct _Head_base<_Idx, _Head, true>
130 : public _Head
131 {
132 constexpr _Head_base()
133 : _Head() { }
134
135 constexpr _Head_base(const _Head& __h)
136 : _Head(__h) { }
137
138 constexpr _Head_base(const _Head_base&) = default;
139 constexpr _Head_base(_Head_base&&) = default;
140
141 template<typename _UHead>
142 constexpr _Head_base(_UHead&& __h)
143 : _Head(std::forward<_UHead>(__h)) { }
144
145 _Head_base(allocator_arg_t, __uses_alloc0)
146 : _Head() { }
147
148 template<typename _Alloc>
149 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
150 : _Head(allocator_arg, *__a._M_a) { }
151
152 template<typename _Alloc>
153 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
154 : _Head(*__a._M_a) { }
155
156 template<typename _UHead>
157 _Head_base(__uses_alloc0, _UHead&& __uhead)
158 : _Head(std::forward<_UHead>(__uhead)) { }
159
160 template<typename _Alloc, typename _UHead>
161 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
162 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
163
164 template<typename _Alloc, typename _UHead>
165 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
166 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
167
168 static constexpr _Head&
169 _M_head(_Head_base& __b) noexcept { return __b; }
170
171 static constexpr const _Head&
172 _M_head(const _Head_base& __b) noexcept { return __b; }
173 };
174#endif
175
176 template<size_t _Idx, typename _Head>
177 struct _Head_base<_Idx, _Head, false>
178 {
179 constexpr _Head_base()
180 : _M_head_impl() { }
181
182 constexpr _Head_base(const _Head& __h)
183 : _M_head_impl(__h) { }
184
185 constexpr _Head_base(const _Head_base&) = default;
186 constexpr _Head_base(_Head_base&&) = default;
187
188 template<typename _UHead>
189 constexpr _Head_base(_UHead&& __h)
190 : _M_head_impl(std::forward<_UHead>(__h)) { }
191
192 _GLIBCXX20_CONSTEXPR
193 _Head_base(allocator_arg_t, __uses_alloc0)
194 : _M_head_impl() { }
195
196 template<typename _Alloc>
197 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
198 : _M_head_impl(allocator_arg, *__a._M_a) { }
199
200 template<typename _Alloc>
201 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
202 : _M_head_impl(*__a._M_a) { }
203
204 template<typename _UHead>
205 _GLIBCXX20_CONSTEXPR
206 _Head_base(__uses_alloc0, _UHead&& __uhead)
207 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
208
209 template<typename _Alloc, typename _UHead>
210 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
211 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
212 { }
213
214 template<typename _Alloc, typename _UHead>
215 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
216 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
217
218 static constexpr _Head&
219 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
220
221 static constexpr const _Head&
222 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
223
224 _Head _M_head_impl;
225 };
226
227 /**
228 * Contains the actual implementation of the @c tuple template, stored
229 * as a recursive inheritance hierarchy from the first element (most
230 * derived class) to the last (least derived class). The @c Idx
231 * parameter gives the 0-based index of the element stored at this
232 * point in the hierarchy; we use it to implement a constant-time
233 * get() operation.
234 */
235 template<size_t _Idx, typename... _Elements>
236 struct _Tuple_impl;
237
238 /**
239 * Recursive tuple implementation. Here we store the @c Head element
240 * and derive from a @c Tuple_impl containing the remaining elements
241 * (which contains the @c Tail).
242 */
243 template<size_t _Idx, typename _Head, typename... _Tail>
244 struct _Tuple_impl<_Idx, _Head, _Tail...>
245 : public _Tuple_impl<_Idx + 1, _Tail...>,
246 private _Head_base<_Idx, _Head>
247 {
248 template<size_t, typename...> friend struct _Tuple_impl;
249
250 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
251 typedef _Head_base<_Idx, _Head> _Base;
252
253 static constexpr _Head&
254 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
255
256 static constexpr const _Head&
257 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
258
259 static constexpr _Inherited&
260 _M_tail(_Tuple_impl& __t) noexcept { return __t; }
261
262 static constexpr const _Inherited&
263 _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
264
265 constexpr _Tuple_impl()
266 : _Inherited(), _Base() { }
267
268 explicit constexpr
269 _Tuple_impl(const _Head& __head, const _Tail&... __tail)
270 : _Inherited(__tail...), _Base(__head)
271 { }
272
273 template<typename _UHead, typename... _UTail,
274 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
275 explicit constexpr
276 _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
277 : _Inherited(std::forward<_UTail>(__tail)...),
278 _Base(std::forward<_UHead>(__head))
279 { }
280
281 constexpr _Tuple_impl(const _Tuple_impl&) = default;
282
283 // _GLIBCXX_RESOLVE_LIB_DEFECTS
284 // 2729. Missing SFINAE on std::pair::operator=
285 _Tuple_impl& operator=(const _Tuple_impl&) = delete;
286
287 constexpr
288 _Tuple_impl(_Tuple_impl&& __in)
289 noexcept(__and_<is_nothrow_move_constructible<_Head>,
290 is_nothrow_move_constructible<_Inherited>>::value)
291 : _Inherited(std::move(_M_tail(__in))),
292 _Base(std::forward<_Head>(_M_head(__in)))
293 { }
294
295 template<typename... _UElements>
296 constexpr
297 _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
298 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
299 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
300 { }
301
302 template<typename _UHead, typename... _UTails>
303 constexpr
304 _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
305 : _Inherited(std::move
306 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
307 _Base(std::forward<_UHead>
308 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
309 { }
310
311 template<typename _Alloc>
312 _GLIBCXX20_CONSTEXPR
313 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
314 : _Inherited(__tag, __a),
315 _Base(__tag, __use_alloc<_Head>(__a))
316 { }
317
318 template<typename _Alloc>
319 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
320 const _Head& __head, const _Tail&... __tail)
321 : _Inherited(__tag, __a, __tail...),
322 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head)
323 { }
324
325 template<typename _Alloc, typename _UHead, typename... _UTail,
326 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
327 _GLIBCXX20_CONSTEXPR
328 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
329 _UHead&& __head, _UTail&&... __tail)
330 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
331 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
332 std::forward<_UHead>(__head))
333 { }
334
335 template<typename _Alloc>
336 _GLIBCXX20_CONSTEXPR
337 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
338 const _Tuple_impl& __in)
339 : _Inherited(__tag, __a, _M_tail(__in)),
340 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in))
341 { }
342
343 template<typename _Alloc>
344 _GLIBCXX20_CONSTEXPR
345 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
346 _Tuple_impl&& __in)
347 : _Inherited(__tag, __a, std::move(_M_tail(__in))),
348 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
349 std::forward<_Head>(_M_head(__in)))
350 { }
351
352 template<typename _Alloc, typename _UHead, typename... _UTails>
353 _GLIBCXX20_CONSTEXPR
354 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
355 const _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
356 : _Inherited(__tag, __a,
357 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
358 _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
359 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
360 { }
361
362 template<typename _Alloc, typename _UHead, typename... _UTails>
363 _GLIBCXX20_CONSTEXPR
364 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
365 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
366 : _Inherited(__tag, __a, std::move
367 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
368 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
369 std::forward<_UHead>
370 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
371 { }
372
373 template<typename... _UElements>
374 _GLIBCXX20_CONSTEXPR
375 void
376 _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
377 {
378 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
379 _M_tail(*this)._M_assign(
380 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
381 }
382
383 template<typename _UHead, typename... _UTails>
384 _GLIBCXX20_CONSTEXPR
385 void
386 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
387 {
388 _M_head(*this) = std::forward<_UHead>
389 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
390 _M_tail(*this)._M_assign(
391 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
392 }
393
394 protected:
395 _GLIBCXX20_CONSTEXPR
396 void
397 _M_swap(_Tuple_impl& __in)
398 {
399 using std::swap;
400 swap(_M_head(*this), _M_head(__in));
401 _Inherited::_M_swap(_M_tail(__in));
402 }
403 };
404
405 // Basis case of inheritance recursion.
406 template<size_t _Idx, typename _Head>
407 struct _Tuple_impl<_Idx, _Head>
408 : private _Head_base<_Idx, _Head>
409 {
410 template<size_t, typename...> friend struct _Tuple_impl;
411
412 typedef _Head_base<_Idx, _Head> _Base;
413
414 static constexpr _Head&
415 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
416
417 static constexpr const _Head&
418 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
419
420 constexpr
421 _Tuple_impl()
422 : _Base() { }
423
424 explicit constexpr
425 _Tuple_impl(const _Head& __head)
426 : _Base(__head)
427 { }
428
429 template<typename _UHead>
430 explicit constexpr
431 _Tuple_impl(_UHead&& __head)
432 : _Base(std::forward<_UHead>(__head))
433 { }
434
435 constexpr _Tuple_impl(const _Tuple_impl&) = default;
436
437 // _GLIBCXX_RESOLVE_LIB_DEFECTS
438 // 2729. Missing SFINAE on std::pair::operator=
439 _Tuple_impl& operator=(const _Tuple_impl&) = delete;
440
441 constexpr
442 _Tuple_impl(_Tuple_impl&& __in)
443 noexcept(is_nothrow_move_constructible<_Head>::value)
444 : _Base(std::forward<_Head>(_M_head(__in)))
445 { }
446
447 template<typename _UHead>
448 constexpr
449 _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
450 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
451 { }
452
453 template<typename _UHead>
454 constexpr
455 _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
456 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
457 { }
458
459 template<typename _Alloc>
460 _GLIBCXX20_CONSTEXPR
461 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
462 : _Base(__tag, __use_alloc<_Head>(__a))
463 { }
464
465 template<typename _Alloc>
466 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
467 const _Head& __head)
468 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head)
469 { }
470
471 template<typename _Alloc, typename _UHead>
472 _GLIBCXX20_CONSTEXPR
473 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
474 _UHead&& __head)
475 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
476 std::forward<_UHead>(__head))
477 { }
478
479 template<typename _Alloc>
480 _GLIBCXX20_CONSTEXPR
481 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
482 const _Tuple_impl& __in)
483 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in))
484 { }
485
486 template<typename _Alloc>
487 _GLIBCXX20_CONSTEXPR
488 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
489 _Tuple_impl&& __in)
490 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
491 std::forward<_Head>(_M_head(__in)))
492 { }
493
494 template<typename _Alloc, typename _UHead>
495 _GLIBCXX20_CONSTEXPR
496 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
497 const _Tuple_impl<_Idx, _UHead>& __in)
498 : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
499 _Tuple_impl<_Idx, _UHead>::_M_head(__in))
500 { }
501
502 template<typename _Alloc, typename _UHead>
503 _GLIBCXX20_CONSTEXPR
504 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
505 _Tuple_impl<_Idx, _UHead>&& __in)
506 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
507 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
508 { }
509
510 template<typename _UHead>
511 _GLIBCXX20_CONSTEXPR
512 void
513 _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
514 {
515 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
516 }
517
518 template<typename _UHead>
519 _GLIBCXX20_CONSTEXPR
520 void
521 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
522 {
523 _M_head(*this)
524 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
525 }
526
527 protected:
528 _GLIBCXX20_CONSTEXPR
529 void
530 _M_swap(_Tuple_impl& __in)
531 {
532 using std::swap;
533 swap(_M_head(*this), _M_head(__in));
534 }
535 };
536
537 // Concept utility functions, reused in conditionally-explicit
538 // constructors.
539 template<bool, typename... _Types>
540 struct _TupleConstraints
541 {
542 template<typename _Tp, typename _Up> // Workaround for PR 96592
543 using is_constructible
544 = __bool_constant<__is_constructible(_Tp, _Up)>;
545
546 // Constraint for a non-explicit constructor.
547 // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
548 // and every Ui is implicitly convertible to Ti.
549 template<typename... _UTypes>
550 static constexpr bool __is_implicitly_constructible()
551 {
552 return __and_<is_constructible<_Types, _UTypes>...,
553 is_convertible<_UTypes, _Types>...
554 >::value;
555 }
556
557 // Constraint for a non-explicit constructor.
558 // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
559 // but not every Ui is implicitly convertible to Ti.
560 template<typename... _UTypes>
561 static constexpr bool __is_explicitly_constructible()
562 {
563 return __and_<is_constructible<_Types, _UTypes>...,
564 __not_<__and_<is_convertible<_UTypes, _Types>...>>
565 >::value;
566 }
567
568 static constexpr bool __is_implicitly_default_constructible()
569 {
570 return __and_<std::__is_implicitly_default_constructible<_Types>...
571 >::value;
572 }
573
574 static constexpr bool __is_explicitly_default_constructible()
575 {
576 return __and_<is_default_constructible<_Types>...,
577 __not_<__and_<
578 std::__is_implicitly_default_constructible<_Types>...>
579 >>::value;
580 }
581 };
582
583 // Partial specialization used when a required precondition isn't met,
584 // e.g. when sizeof...(_Types) != sizeof...(_UTypes).
585 template<typename... _Types>
586 struct _TupleConstraints<false, _Types...>
587 {
588 template<typename... _UTypes>
589 static constexpr bool __is_implicitly_constructible()
590 { return false; }
591
592 template<typename... _UTypes>
593 static constexpr bool __is_explicitly_constructible()
594 { return false; }
595 };
596
597 /// Primary class template, tuple
598 template<typename... _Elements>
599 class tuple : public _Tuple_impl<0, _Elements...>
600 {
601 typedef _Tuple_impl<0, _Elements...> _Inherited;
602
603 template<bool _Cond>
604 using _TCC = _TupleConstraints<_Cond, _Elements...>;
605
606 // Constraint for non-explicit default constructor
607 template<bool _Dummy>
608 using _ImplicitDefaultCtor = __enable_if_t<
609 _TCC<_Dummy>::__is_implicitly_default_constructible(),
610 bool>;
611
612 // Constraint for explicit default constructor
613 template<bool _Dummy>
614 using _ExplicitDefaultCtor = __enable_if_t<
615 _TCC<_Dummy>::__is_explicitly_default_constructible(),
616 bool>;
617
618 // Constraint for non-explicit constructors
619 template<bool _Cond, typename... _Args>
620 using _ImplicitCtor = __enable_if_t<
621 _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
622 bool>;
623
624 // Constraint for non-explicit constructors
625 template<bool _Cond, typename... _Args>
626 using _ExplicitCtor = __enable_if_t<
627 _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
628 bool>;
629
630 template<typename... _UElements>
631 static constexpr
632 __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
633 __assignable()
634 { return __and_<is_assignable<_Elements&, _UElements>...>::value; }
635
636 // Condition for noexcept-specifier of an assignment operator.
637 template<typename... _UElements>
638 static constexpr bool __nothrow_assignable()
639 {
640 return
641 __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
642 }
643
644 // Condition for noexcept-specifier of a constructor.
645 template<typename... _UElements>
646 static constexpr bool __nothrow_constructible()
647 {
648 return
649 __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;
650 }
651
652 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1.
653 template<typename _Up>
654 static constexpr bool __valid_args()
655 {
656 return sizeof...(_Elements) == 1
657 && !is_same<tuple, __remove_cvref_t<_Up>>::value;
658 }
659
660 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1.
661 template<typename, typename, typename... _Tail>
662 static constexpr bool __valid_args()
663 { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); }
664
665 /* Constraint for constructors with a tuple<UTypes...> parameter ensures
666 * that the constructor is only viable when it would not interfere with
667 * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&).
668 * Such constructors are only viable if:
669 * either sizeof...(Types) != 1,
670 * or (when Types... expands to T and UTypes... expands to U)
671 * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>,
672 * and is_same_v<T, U> are all false.
673 */
674 template<typename _Tuple, typename = tuple,
675 typename = __remove_cvref_t<_Tuple>>
676 struct _UseOtherCtor
677 : false_type
678 { };
679 // If TUPLE is convertible to the single element in *this,
680 // then TUPLE should match tuple(UTypes&&...) instead.
681 template<typename _Tuple, typename _Tp, typename _Up>
682 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
683 : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>
684 { };
685 // If TUPLE and *this each have a single element of the same type,
686 // then TUPLE should match a copy/move constructor instead.
687 template<typename _Tuple, typename _Tp>
688 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>
689 : true_type
690 { };
691
692 // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
693 // and the single element in Types can be initialized from TUPLE,
694 // or is the same type as tuple_element_t<0, TUPLE>.
695 template<typename _Tuple>
696 static constexpr bool __use_other_ctor()
697 { return _UseOtherCtor<_Tuple>::value; }
698
699 public:
700 template<typename _Dummy = void,
701 _ImplicitDefaultCtor<is_void<_Dummy>::value> = true>
702 constexpr
703 tuple()
704 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
705 : _Inherited() { }
706
707 template<typename _Dummy = void,
708 _ExplicitDefaultCtor<is_void<_Dummy>::value> = false>
709 explicit constexpr
710 tuple()
711 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
712 : _Inherited() { }
713
714 template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
715 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
716 constexpr
717 tuple(const _Elements&... __elements)
718 noexcept(__nothrow_constructible<const _Elements&...>())
719 : _Inherited(__elements...) { }
720
721 template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
722 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
723 explicit constexpr
724 tuple(const _Elements&... __elements)
725 noexcept(__nothrow_constructible<const _Elements&...>())
726 : _Inherited(__elements...) { }
727
728 template<typename... _UElements,
729 bool _Valid = __valid_args<_UElements...>(),
730 _ImplicitCtor<_Valid, _UElements...> = true>
731 constexpr
732 tuple(_UElements&&... __elements)
733 noexcept(__nothrow_constructible<_UElements...>())
734 : _Inherited(std::forward<_UElements>(__elements)...) { }
735
736 template<typename... _UElements,
737 bool _Valid = __valid_args<_UElements...>(),
738 _ExplicitCtor<_Valid, _UElements...> = false>
739 explicit constexpr
740 tuple(_UElements&&... __elements)
741 noexcept(__nothrow_constructible<_UElements...>())
742 : _Inherited(std::forward<_UElements>(__elements)...) { }
743
744 constexpr tuple(const tuple&) = default;
745
746 constexpr tuple(tuple&&) = default;
747
748 template<typename... _UElements,
749 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
750 && !__use_other_ctor<const tuple<_UElements...>&>(),
751 _ImplicitCtor<_Valid, const _UElements&...> = true>
752 constexpr
753 tuple(const tuple<_UElements...>& __in)
754 noexcept(__nothrow_constructible<const _UElements&...>())
755 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
756 { }
757
758 template<typename... _UElements,
759 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
760 && !__use_other_ctor<const tuple<_UElements...>&>(),
761 _ExplicitCtor<_Valid, const _UElements&...> = false>
762 explicit constexpr
763 tuple(const tuple<_UElements...>& __in)
764 noexcept(__nothrow_constructible<const _UElements&...>())
765 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
766 { }
767
768 template<typename... _UElements,
769 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
770 && !__use_other_ctor<tuple<_UElements...>&&>(),
771 _ImplicitCtor<_Valid, _UElements...> = true>
772 constexpr
773 tuple(tuple<_UElements...>&& __in)
774 noexcept(__nothrow_constructible<_UElements...>())
775 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
776
777 template<typename... _UElements,
778 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
779 && !__use_other_ctor<tuple<_UElements...>&&>(),
780 _ExplicitCtor<_Valid, _UElements...> = false>
781 explicit constexpr
782 tuple(tuple<_UElements...>&& __in)
783 noexcept(__nothrow_constructible<_UElements...>())
784 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
785
786 // Allocator-extended constructors.
787
788 template<typename _Alloc,
789 _ImplicitDefaultCtor<is_object<_Alloc>::value> = true>
790 _GLIBCXX20_CONSTEXPR
791 tuple(allocator_arg_t __tag, const _Alloc& __a)
792 : _Inherited(__tag, __a) { }
793
794 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
795 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
796 _GLIBCXX20_CONSTEXPR
797 tuple(allocator_arg_t __tag, const _Alloc& __a,
798 const _Elements&... __elements)
799 : _Inherited(__tag, __a, __elements...) { }
800
801 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
802 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
803 _GLIBCXX20_CONSTEXPR
804 explicit
805 tuple(allocator_arg_t __tag, const _Alloc& __a,
806 const _Elements&... __elements)
807 : _Inherited(__tag, __a, __elements...) { }
808
809 template<typename _Alloc, typename... _UElements,
810 bool _Valid = __valid_args<_UElements...>(),
811 _ImplicitCtor<_Valid, _UElements...> = true>
812 _GLIBCXX20_CONSTEXPR
813 tuple(allocator_arg_t __tag, const _Alloc& __a,
814 _UElements&&... __elements)
815 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
816 { }
817
818 template<typename _Alloc, typename... _UElements,
819 bool _Valid = __valid_args<_UElements...>(),
820 _ExplicitCtor<_Valid, _UElements...> = false>
821 _GLIBCXX20_CONSTEXPR
822 explicit
823 tuple(allocator_arg_t __tag, const _Alloc& __a,
824 _UElements&&... __elements)
825 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
826 { }
827
828 template<typename _Alloc>
829 _GLIBCXX20_CONSTEXPR
830 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
831 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
832
833 template<typename _Alloc>
834 _GLIBCXX20_CONSTEXPR
835 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
836 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
837
838 template<typename _Alloc, typename... _UElements,
839 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
840 && !__use_other_ctor<const tuple<_UElements...>&>(),
841 _ImplicitCtor<_Valid, const _UElements&...> = true>
842 _GLIBCXX20_CONSTEXPR
843 tuple(allocator_arg_t __tag, const _Alloc& __a,
844 const tuple<_UElements...>& __in)
845 : _Inherited(__tag, __a,
846 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
847 { }
848
849 template<typename _Alloc, typename... _UElements,
850 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
851 && !__use_other_ctor<const tuple<_UElements...>&>(),
852 _ExplicitCtor<_Valid, const _UElements&...> = false>
853 _GLIBCXX20_CONSTEXPR
854 explicit
855 tuple(allocator_arg_t __tag, const _Alloc& __a,
856 const tuple<_UElements...>& __in)
857 : _Inherited(__tag, __a,
858 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
859 { }
860
861 template<typename _Alloc, typename... _UElements,
862 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
863 && !__use_other_ctor<tuple<_UElements...>&&>(),
864 _ImplicitCtor<_Valid, _UElements...> = true>
865 _GLIBCXX20_CONSTEXPR
866 tuple(allocator_arg_t __tag, const _Alloc& __a,
867 tuple<_UElements...>&& __in)
868 : _Inherited(__tag, __a,
869 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
870 { }
871
872 template<typename _Alloc, typename... _UElements,
873 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
874 && !__use_other_ctor<tuple<_UElements...>&&>(),
875 _ExplicitCtor<_Valid, _UElements...> = false>
876 _GLIBCXX20_CONSTEXPR
877 explicit
878 tuple(allocator_arg_t __tag, const _Alloc& __a,
879 tuple<_UElements...>&& __in)
880 : _Inherited(__tag, __a,
881 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
882 { }
883
884 // tuple assignment
885
886 _GLIBCXX20_CONSTEXPR
887 tuple&
888 operator=(typename conditional<__assignable<const _Elements&...>(),
889 const tuple&,
890 const __nonesuch&>::type __in)
891 noexcept(__nothrow_assignable<const _Elements&...>())
892 {
893 this->_M_assign(__in);
894 return *this;
895 }
896
897 _GLIBCXX20_CONSTEXPR
898 tuple&
899 operator=(typename conditional<__assignable<_Elements...>(),
900 tuple&&,
901 __nonesuch&&>::type __in)
902 noexcept(__nothrow_assignable<_Elements...>())
903 {
904 this->_M_assign(std::move(__in));
905 return *this;
906 }
907
908 template<typename... _UElements>
909 _GLIBCXX20_CONSTEXPR
910 __enable_if_t<__assignable<const _UElements&...>(), tuple&>
911 operator=(const tuple<_UElements...>& __in)
912 noexcept(__nothrow_assignable<const _UElements&...>())
913 {
914 this->_M_assign(__in);
915 return *this;
916 }
917
918 template<typename... _UElements>
919 _GLIBCXX20_CONSTEXPR
920 __enable_if_t<__assignable<_UElements...>(), tuple&>
921 operator=(tuple<_UElements...>&& __in)
922 noexcept(__nothrow_assignable<_UElements...>())
923 {
924 this->_M_assign(std::move(__in));
925 return *this;
926 }
927
928 // tuple swap
929 _GLIBCXX20_CONSTEXPR
930 void
931 swap(tuple& __in)
932 noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
933 { _Inherited::_M_swap(__in); }
934 };
935
936#if __cpp_deduction_guides >= 201606
937 template<typename... _UTypes>
938 tuple(_UTypes...) -> tuple<_UTypes...>;
939 template<typename _T1, typename _T2>
940 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
941 template<typename _Alloc, typename... _UTypes>
942 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
943 template<typename _Alloc, typename _T1, typename _T2>
944 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
945 template<typename _Alloc, typename... _UTypes>
946 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
947#endif
948
949 // Explicit specialization, zero-element tuple.
950 template<>
951 class tuple<>
952 {
953 public:
954 void swap(tuple&) noexcept { /* no-op */ }
955 // We need the default since we're going to define no-op
956 // allocator constructors.
957 tuple() = default;
958 // No-op allocator constructors.
959 template<typename _Alloc>
960 _GLIBCXX20_CONSTEXPR
961 tuple(allocator_arg_t, const _Alloc&) noexcept { }
962 template<typename _Alloc>
963 _GLIBCXX20_CONSTEXPR
964 tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
965 };
966
967 /// Partial specialization, 2-element tuple.
968 /// Includes construction and assignment from a pair.
969 template<typename _T1, typename _T2>
970 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
971 {
972 typedef _Tuple_impl<0, _T1, _T2> _Inherited;
973
974 // Constraint for non-explicit default constructor
975 template<bool _Dummy, typename _U1, typename _U2>
976 using _ImplicitDefaultCtor = __enable_if_t<
977 _TupleConstraints<_Dummy, _U1, _U2>::
978 __is_implicitly_default_constructible(),
979 bool>;
980
981 // Constraint for explicit default constructor
982 template<bool _Dummy, typename _U1, typename _U2>
983 using _ExplicitDefaultCtor = __enable_if_t<
984 _TupleConstraints<_Dummy, _U1, _U2>::
985 __is_explicitly_default_constructible(),
986 bool>;
987
988 template<bool _Dummy>
989 using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
990
991 // Constraint for non-explicit constructors
992 template<bool _Cond, typename _U1, typename _U2>
993 using _ImplicitCtor = __enable_if_t<
994 _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
995 bool>;
996
997 // Constraint for non-explicit constructors
998 template<bool _Cond, typename _U1, typename _U2>
999 using _ExplicitCtor = __enable_if_t<
1000 _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
1001 bool>;
1002
1003 template<typename _U1, typename _U2>
1004 static constexpr bool __assignable()
1005 {
1006 return __and_<is_assignable<_T1&, _U1>,
1007 is_assignable<_T2&, _U2>>::value;
1008 }
1009
1010 template<typename _U1, typename _U2>
1011 static constexpr bool __nothrow_assignable()
1012 {
1013 return __and_<is_nothrow_assignable<_T1&, _U1>,
1014 is_nothrow_assignable<_T2&, _U2>>::value;
1015 }
1016
1017 template<typename _U1, typename _U2>
1018 static constexpr bool __nothrow_constructible()
1019 {
1020 return __and_<is_nothrow_constructible<_T1, _U1>,
1021 is_nothrow_constructible<_T2, _U2>>::value;
1022 }
1023
1024 static constexpr bool __nothrow_default_constructible()
1025 {
1026 return __and_<is_nothrow_default_constructible<_T1>,
1027 is_nothrow_default_constructible<_T2>>::value;
1028 }
1029
1030 template<typename _U1>
1031 static constexpr bool __is_alloc_arg()
1032 { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
1033
1034 public:
1035 template<bool _Dummy = true,
1036 _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
1037 constexpr
1038 tuple()
1039 noexcept(__nothrow_default_constructible())
1040 : _Inherited() { }
1041
1042 template<bool _Dummy = true,
1043 _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>
1044 explicit constexpr
1045 tuple()
1046 noexcept(__nothrow_default_constructible())
1047 : _Inherited() { }
1048
1049 template<bool _Dummy = true,
1050 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
1051 constexpr
1052 tuple(const _T1& __a1, const _T2& __a2)
1053 noexcept(__nothrow_constructible<const _T1&, const _T2&>())
1054 : _Inherited(__a1, __a2) { }
1055
1056 template<bool _Dummy = true,
1057 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
1058 explicit constexpr
1059 tuple(const _T1& __a1, const _T2& __a2)
1060 noexcept(__nothrow_constructible<const _T1&, const _T2&>())
1061 : _Inherited(__a1, __a2) { }
1062
1063 template<typename _U1, typename _U2,
1064 _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>
1065 constexpr
1066 tuple(_U1&& __a1, _U2&& __a2)
1067 noexcept(__nothrow_constructible<_U1, _U2>())
1068 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
1069
1070 template<typename _U1, typename _U2,
1071 _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>
1072 explicit constexpr
1073 tuple(_U1&& __a1, _U2&& __a2)
1074 noexcept(__nothrow_constructible<_U1, _U2>())
1075 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
1076
1077 constexpr tuple(const tuple&) = default;
1078
1079 constexpr tuple(tuple&&) = default;
1080
1081 template<typename _U1, typename _U2,
1082 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1083 constexpr
1084 tuple(const tuple<_U1, _U2>& __in)
1085 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1086 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1087
1088 template<typename _U1, typename _U2,
1089 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1090 explicit constexpr
1091 tuple(const tuple<_U1, _U2>& __in)
1092 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1093 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1094
1095 template<typename _U1, typename _U2,
1096 _ImplicitCtor<true, _U1, _U2> = true>
1097 constexpr
1098 tuple(tuple<_U1, _U2>&& __in)
1099 noexcept(__nothrow_constructible<_U1, _U2>())
1100 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1101
1102 template<typename _U1, typename _U2,
1103 _ExplicitCtor<true, _U1, _U2> = false>
1104 explicit constexpr
1105 tuple(tuple<_U1, _U2>&& __in)
1106 noexcept(__nothrow_constructible<_U1, _U2>())
1107 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1108
1109 template<typename _U1, typename _U2,
1110 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1111 constexpr
1112 tuple(const pair<_U1, _U2>& __in)
1113 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1114 : _Inherited(__in.first, __in.second) { }
1115
1116 template<typename _U1, typename _U2,
1117 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1118 explicit constexpr
1119 tuple(const pair<_U1, _U2>& __in)
1120 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1121 : _Inherited(__in.first, __in.second) { }
1122
1123 template<typename _U1, typename _U2,
1124 _ImplicitCtor<true, _U1, _U2> = true>
1125 constexpr
1126 tuple(pair<_U1, _U2>&& __in)
1127 noexcept(__nothrow_constructible<_U1, _U2>())
1128 : _Inherited(std::forward<_U1>(__in.first),
1129 std::forward<_U2>(__in.second)) { }
1130
1131 template<typename _U1, typename _U2,
1132 _ExplicitCtor<true, _U1, _U2> = false>
1133 explicit constexpr
1134 tuple(pair<_U1, _U2>&& __in)
1135 noexcept(__nothrow_constructible<_U1, _U2>())
1136 : _Inherited(std::forward<_U1>(__in.first),
1137 std::forward<_U2>(__in.second)) { }
1138
1139 // Allocator-extended constructors.
1140
1141 template<typename _Alloc,
1142 _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>
1143 _GLIBCXX20_CONSTEXPR
1144 tuple(allocator_arg_t __tag, const _Alloc& __a)
1145 : _Inherited(__tag, __a) { }
1146
1147 template<typename _Alloc, bool _Dummy = true,
1148 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
1149 _GLIBCXX20_CONSTEXPR
1150 tuple(allocator_arg_t __tag, const _Alloc& __a,
1151 const _T1& __a1, const _T2& __a2)
1152 : _Inherited(__tag, __a, __a1, __a2) { }
1153
1154 template<typename _Alloc, bool _Dummy = true,
1155 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
1156 explicit
1157 _GLIBCXX20_CONSTEXPR
1158 tuple(allocator_arg_t __tag, const _Alloc& __a,
1159 const _T1& __a1, const _T2& __a2)
1160 : _Inherited(__tag, __a, __a1, __a2) { }
1161
1162 template<typename _Alloc, typename _U1, typename _U2,
1163 _ImplicitCtor<true, _U1, _U2> = true>
1164 _GLIBCXX20_CONSTEXPR
1165 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1166 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1167 std::forward<_U2>(__a2)) { }
1168
1169 template<typename _Alloc, typename _U1, typename _U2,
1170 _ExplicitCtor<true, _U1, _U2> = false>
1171 explicit
1172 _GLIBCXX20_CONSTEXPR
1173 tuple(allocator_arg_t __tag, const _Alloc& __a,
1174 _U1&& __a1, _U2&& __a2)
1175 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1176 std::forward<_U2>(__a2)) { }
1177
1178 template<typename _Alloc>
1179 _GLIBCXX20_CONSTEXPR
1180 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1181 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1182
1183 template<typename _Alloc>
1184 _GLIBCXX20_CONSTEXPR
1185 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1186 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1187
1188 template<typename _Alloc, typename _U1, typename _U2,
1189 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1190 _GLIBCXX20_CONSTEXPR
1191 tuple(allocator_arg_t __tag, const _Alloc& __a,
1192 const tuple<_U1, _U2>& __in)
1193 : _Inherited(__tag, __a,
1194 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1195 { }
1196
1197 template<typename _Alloc, typename _U1, typename _U2,
1198 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1199 explicit
1200 _GLIBCXX20_CONSTEXPR
1201 tuple(allocator_arg_t __tag, const _Alloc& __a,
1202 const tuple<_U1, _U2>& __in)
1203 : _Inherited(__tag, __a,
1204 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1205 { }
1206
1207 template<typename _Alloc, typename _U1, typename _U2,
1208 _ImplicitCtor<true, _U1, _U2> = true>
1209 _GLIBCXX20_CONSTEXPR
1210 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1211 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1212 { }
1213
1214 template<typename _Alloc, typename _U1, typename _U2,
1215 _ExplicitCtor<true, _U1, _U2> = false>
1216 explicit
1217 _GLIBCXX20_CONSTEXPR
1218 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1219 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1220 { }
1221
1222 template<typename _Alloc, typename _U1, typename _U2,
1223 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1224 _GLIBCXX20_CONSTEXPR
1225 tuple(allocator_arg_t __tag, const _Alloc& __a,
1226 const pair<_U1, _U2>& __in)
1227 : _Inherited(__tag, __a, __in.first, __in.second) { }
1228
1229 template<typename _Alloc, typename _U1, typename _U2,
1230 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1231 explicit
1232 _GLIBCXX20_CONSTEXPR
1233 tuple(allocator_arg_t __tag, const _Alloc& __a,
1234 const pair<_U1, _U2>& __in)
1235 : _Inherited(__tag, __a, __in.first, __in.second) { }
1236
1237 template<typename _Alloc, typename _U1, typename _U2,
1238 _ImplicitCtor<true, _U1, _U2> = true>
1239 _GLIBCXX20_CONSTEXPR
1240 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1241 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1242 std::forward<_U2>(__in.second)) { }
1243
1244 template<typename _Alloc, typename _U1, typename _U2,
1245 _ExplicitCtor<true, _U1, _U2> = false>
1246 explicit
1247 _GLIBCXX20_CONSTEXPR
1248 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1249 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1250 std::forward<_U2>(__in.second)) { }
1251
1252 // Tuple assignment.
1253
1254 _GLIBCXX20_CONSTEXPR
1255 tuple&
1256 operator=(typename conditional<__assignable<const _T1&, const _T2&>(),
1257 const tuple&,
1258 const __nonesuch&>::type __in)
1259 noexcept(__nothrow_assignable<const _T1&, const _T2&>())
1260 {
1261 this->_M_assign(__in);
1262 return *this;
1263 }
1264
1265 _GLIBCXX20_CONSTEXPR
1266 tuple&
1267 operator=(typename conditional<__assignable<_T1, _T2>(),
1268 tuple&&,
1269 __nonesuch&&>::type __in)
1270 noexcept(__nothrow_assignable<_T1, _T2>())
1271 {
1272 this->_M_assign(std::move(__in));
1273 return *this;
1274 }
1275
1276 template<typename _U1, typename _U2>
1277 _GLIBCXX20_CONSTEXPR
1278 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
1279 operator=(const tuple<_U1, _U2>& __in)
1280 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1281 {
1282 this->_M_assign(__in);
1283 return *this;
1284 }
1285
1286 template<typename _U1, typename _U2>
1287 _GLIBCXX20_CONSTEXPR
1288 __enable_if_t<__assignable<_U1, _U2>(), tuple&>
1289 operator=(tuple<_U1, _U2>&& __in)
1290 noexcept(__nothrow_assignable<_U1, _U2>())
1291 {
1292 this->_M_assign(std::move(__in));
1293 return *this;
1294 }
1295
1296 template<typename _U1, typename _U2>
1297 _GLIBCXX20_CONSTEXPR
1298 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
1299 operator=(const pair<_U1, _U2>& __in)
1300 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1301 {
1302 this->_M_head(*this) = __in.first;
1303 this->_M_tail(*this)._M_head(*this) = __in.second;
1304 return *this;
1305 }
1306
1307 template<typename _U1, typename _U2>
1308 _GLIBCXX20_CONSTEXPR
1309 __enable_if_t<__assignable<_U1, _U2>(), tuple&>
1310 operator=(pair<_U1, _U2>&& __in)
1311 noexcept(__nothrow_assignable<_U1, _U2>())
1312 {
1313 this->_M_head(*this) = std::forward<_U1>(__in.first);
1314 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1315 return *this;
1316 }
1317
1318 _GLIBCXX20_CONSTEXPR
1319 void
1320 swap(tuple& __in)
1321 noexcept(__and_<__is_nothrow_swappable<_T1>,
1322 __is_nothrow_swappable<_T2>>::value)
1323 { _Inherited::_M_swap(__in); }
1324 };
1325
1326
1327 /// class tuple_size
1328 template<typename... _Elements>
1329 struct tuple_size<tuple<_Elements...>>
1330 : public integral_constant<size_t, sizeof...(_Elements)> { };
1331
1332#if __cplusplus > 201402L
1333 template <typename _Tp>
1334 inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1335#endif
1336
1337 /**
1338 * Recursive case for tuple_element: strip off the first element in
1339 * the tuple and retrieve the (i-1)th element of the remaining tuple.
1340 */
1341 template<size_t __i, typename _Head, typename... _Tail>
1342 struct tuple_element<__i, tuple<_Head, _Tail...> >
1343 : tuple_element<__i - 1, tuple<_Tail...> > { };
1344
1345 /**
1346 * Basis case for tuple_element: The first element is the one we're seeking.
1347 */
1348 template<typename _Head, typename... _Tail>
1349 struct tuple_element<0, tuple<_Head, _Tail...> >
1350 {
1351 typedef _Head type;
1352 };
1353
1354 /**
1355 * Error case for tuple_element: invalid index.
1356 */
1357 template<size_t __i>
1358 struct tuple_element<__i, tuple<>>
1359 {
1360 static_assert(__i < tuple_size<tuple<>>::value,
1361 "tuple index must be in range");
1362 };
1363
1364 template<size_t __i, typename _Head, typename... _Tail>
1365 constexpr _Head&
1366 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1367 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1368
1369 template<size_t __i, typename _Head, typename... _Tail>
1370 constexpr const _Head&
1371 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1372 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1373
1374 // Deleted overload to improve diagnostics for invalid indices
1375 template<size_t __i, typename... _Types>
1376 __enable_if_t<(__i >= sizeof...(_Types))>
1377 __get_helper(const tuple<_Types...>&) = delete;
1378
1379 /// Return a reference to the ith element of a tuple.
1380 template<size_t __i, typename... _Elements>
1381 constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1382 get(tuple<_Elements...>& __t) noexcept
1383 { return std::__get_helper<__i>(__t); }
1384
1385 /// Return a const reference to the ith element of a const tuple.
1386 template<size_t __i, typename... _Elements>
1387 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1388 get(const tuple<_Elements...>& __t) noexcept
1389 { return std::__get_helper<__i>(__t); }
1390
1391 /// Return an rvalue reference to the ith element of a tuple rvalue.
1392 template<size_t __i, typename... _Elements>
1393 constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1394 get(tuple<_Elements...>&& __t) noexcept
1395 {
1396 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1397 return std::forward<__element_type>(std::__get_helper<__i>(__t));
1398 }
1399
1400 /// Return a const rvalue reference to the ith element of a const tuple rvalue.
1401 template<size_t __i, typename... _Elements>
1402 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
1403 get(const tuple<_Elements...>&& __t) noexcept
1404 {
1405 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1406 return std::forward<const __element_type>(std::__get_helper<__i>(__t));
1407 }
1408
1409#if __cplusplus >= 201402L
1410
1411#define __cpp_lib_tuples_by_type 201304
1412
1413 // Return the index of _Tp in _Types, if it occurs exactly once.
1414 // Otherwise, return sizeof...(_Types).
1415 // TODO reuse this for __detail::__variant::__exactly_once.
1416 template<typename _Tp, typename... _Types>
1417 constexpr size_t
1418 __find_uniq_type_in_pack()
1419 {
1420 constexpr size_t __sz = sizeof...(_Types);
1421 constexpr bool __found[__sz] = { __is_same(_Tp, _Types) ... };
1422 size_t __n = __sz;
1423 for (size_t __i = 0; __i < __sz; ++__i)
1424 {
1425 if (__found[__i])
1426 {
1427 if (__n < __sz) // more than one _Tp found
1428 return __sz;
1429 __n = __i;
1430 }
1431 }
1432 return __n;
1433 }
1434
1435 /// Return a reference to the unique element of type _Tp of a tuple.
1436 template <typename _Tp, typename... _Types>
1437 constexpr _Tp&
1438 get(tuple<_Types...>& __t) noexcept
1439 {
1440 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1441 static_assert(__idx < sizeof...(_Types),
1442 "the type T in std::get<T> must occur exactly once in the tuple");
1443 return std::__get_helper<__idx>(__t);
1444 }
1445
1446 /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1447 template <typename _Tp, typename... _Types>
1448 constexpr _Tp&&
1449 get(tuple<_Types...>&& __t) noexcept
1450 {
1451 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1452 static_assert(__idx < sizeof...(_Types),
1453 "the type T in std::get<T> must occur exactly once in the tuple");
1454 return std::forward<_Tp>(std::__get_helper<__idx>(__t));
1455 }
1456
1457 /// Return a const reference to the unique element of type _Tp of a tuple.
1458 template <typename _Tp, typename... _Types>
1459 constexpr const _Tp&
1460 get(const tuple<_Types...>& __t) noexcept
1461 {
1462 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1463 static_assert(__idx < sizeof...(_Types),
1464 "the type T in std::get<T> must occur exactly once in the tuple");
1465 return std::__get_helper<__idx>(__t);
1466 }
1467
1468 /// Return a const reference to the unique element of type _Tp of
1469 /// a const tuple rvalue.
1470 template <typename _Tp, typename... _Types>
1471 constexpr const _Tp&&
1472 get(const tuple<_Types...>&& __t) noexcept
1473 {
1474 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1475 static_assert(__idx < sizeof...(_Types),
1476 "the type T in std::get<T> must occur exactly once in the tuple");
1477 return std::forward<const _Tp>(std::__get_helper<__idx>(__t));
1478 }
1479#endif
1480
1481 // This class performs the comparison operations on tuples
1482 template<typename _Tp, typename _Up, size_t __i, size_t __size>
1483 struct __tuple_compare
1484 {
1485 static constexpr bool
1486 __eq(const _Tp& __t, const _Up& __u)
1487 {
1488 return bool(std::get<__i>(__t) == std::get<__i>(__u))
1489 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1490 }
1491
1492 static constexpr bool
1493 __less(const _Tp& __t, const _Up& __u)
1494 {
1495 return bool(std::get<__i>(__t) < std::get<__i>(__u))
1496 || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1497 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1498 }
1499 };
1500
1501 template<typename _Tp, typename _Up, size_t __size>
1502 struct __tuple_compare<_Tp, _Up, __size, __size>
1503 {
1504 static constexpr bool
1505 __eq(const _Tp&, const _Up&) { return true; }
1506
1507 static constexpr bool
1508 __less(const _Tp&, const _Up&) { return false; }
1509 };
1510
1511 template<typename... _TElements, typename... _UElements>
1512 constexpr bool
1513 operator==(const tuple<_TElements...>& __t,
1514 const tuple<_UElements...>& __u)
1515 {
1516 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1517 "tuple objects can only be compared if they have equal sizes.");
1518 using __compare = __tuple_compare<tuple<_TElements...>,
1519 tuple<_UElements...>,
1520 0, sizeof...(_TElements)>;
1521 return __compare::__eq(__t, __u);
1522 }
1523
1524#if __cpp_lib_three_way_comparison
1525 template<typename _Cat, typename _Tp, typename _Up>
1526 constexpr _Cat
1527 __tuple_cmp(const _Tp&, const _Up&, index_sequence<>)
1528 { return _Cat::equivalent; }
1529
1530 template<typename _Cat, typename _Tp, typename _Up,
1531 size_t _Idx0, size_t... _Idxs>
1532 constexpr _Cat
1533 __tuple_cmp(const _Tp& __t, const _Up& __u,
1534 index_sequence<_Idx0, _Idxs...>)
1535 {
1536 auto __c
1537 = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u));
1538 if (__c != 0)
1539 return __c;
1540 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>());
1541 }
1542
1543 template<typename... _Tps, typename... _Ups>
1544 constexpr
1545 common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
1546 operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
1547 {
1548 using _Cat
1549 = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
1550 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
1551 }
1552#else
1553 template<typename... _TElements, typename... _UElements>
1554 constexpr bool
1555 operator<(const tuple<_TElements...>& __t,
1556 const tuple<_UElements...>& __u)
1557 {
1558 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1559 "tuple objects can only be compared if they have equal sizes.");
1560 using __compare = __tuple_compare<tuple<_TElements...>,
1561 tuple<_UElements...>,
1562 0, sizeof...(_TElements)>;
1563 return __compare::__less(__t, __u);
1564 }
1565
1566 template<typename... _TElements, typename... _UElements>
1567 constexpr bool
1568 operator!=(const tuple<_TElements...>& __t,
1569 const tuple<_UElements...>& __u)
1570 { return !(__t == __u); }
1571
1572 template<typename... _TElements, typename... _UElements>
1573 constexpr bool
1574 operator>(const tuple<_TElements...>& __t,
1575 const tuple<_UElements...>& __u)
1576 { return __u < __t; }
1577
1578 template<typename... _TElements, typename... _UElements>
1579 constexpr bool
1580 operator<=(const tuple<_TElements...>& __t,
1581 const tuple<_UElements...>& __u)
1582 { return !(__u < __t); }
1583
1584 template<typename... _TElements, typename... _UElements>
1585 constexpr bool
1586 operator>=(const tuple<_TElements...>& __t,
1587 const tuple<_UElements...>& __u)
1588 { return !(__t < __u); }
1589#endif // three_way_comparison
1590
1591 // NB: DR 705.
1592 template<typename... _Elements>
1593 constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1594 make_tuple(_Elements&&... __args)
1595 {
1596 typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1597 __result_type;
1598 return __result_type(std::forward<_Elements>(__args)...);
1599 }
1600
1601 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1602 // 2275. Why is forward_as_tuple not constexpr?
1603 /// std::forward_as_tuple
1604 template<typename... _Elements>
1605 constexpr tuple<_Elements&&...>
1606 forward_as_tuple(_Elements&&... __args) noexcept
1607 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1608
1609 template<size_t, typename, typename, size_t>
1610 struct __make_tuple_impl;
1611
1612 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1613 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1614 : __make_tuple_impl<_Idx + 1,
1615 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1616 _Tuple, _Nm>
1617 { };
1618
1619 template<size_t _Nm, typename _Tuple, typename... _Tp>
1620 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1621 {
1622 typedef tuple<_Tp...> __type;
1623 };
1624
1625 template<typename _Tuple>
1626 struct __do_make_tuple
1627 : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value>
1628 { };
1629
1630 // Returns the std::tuple equivalent of a tuple-like type.
1631 template<typename _Tuple>
1632 struct __make_tuple
1633 : public __do_make_tuple<__remove_cvref_t<_Tuple>>
1634 { };
1635
1636 // Combines several std::tuple's into a single one.
1637 template<typename...>
1638 struct __combine_tuples;
1639
1640 template<>
1641 struct __combine_tuples<>
1642 {
1643 typedef tuple<> __type;
1644 };
1645
1646 template<typename... _Ts>
1647 struct __combine_tuples<tuple<_Ts...>>
1648 {
1649 typedef tuple<_Ts...> __type;
1650 };
1651
1652 template<typename... _T1s, typename... _T2s, typename... _Rem>
1653 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1654 {
1655 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1656 _Rem...>::__type __type;
1657 };
1658
1659 // Computes the result type of tuple_cat given a set of tuple-like types.
1660 template<typename... _Tpls>
1661 struct __tuple_cat_result
1662 {
1663 typedef typename __combine_tuples
1664 <typename __make_tuple<_Tpls>::__type...>::__type __type;
1665 };
1666
1667 // Helper to determine the index set for the first tuple-like
1668 // type of a given set.
1669 template<typename...>
1670 struct __make_1st_indices;
1671
1672 template<>
1673 struct __make_1st_indices<>
1674 {
1675 typedef _Index_tuple<> __type;
1676 };
1677
1678 template<typename _Tp, typename... _Tpls>
1679 struct __make_1st_indices<_Tp, _Tpls...>
1680 {
1681 typedef typename _Build_index_tuple<tuple_size<
1682 typename remove_reference<_Tp>::type>::value>::__type __type;
1683 };
1684
1685 // Performs the actual concatenation by step-wise expanding tuple-like
1686 // objects into the elements, which are finally forwarded into the
1687 // result tuple.
1688 template<typename _Ret, typename _Indices, typename... _Tpls>
1689 struct __tuple_concater;
1690
1691 template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls>
1692 struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...>
1693 {
1694 template<typename... _Us>
1695 static constexpr _Ret
1696 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1697 {
1698 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1699 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1700 return __next::_S_do(std::forward<_Tpls>(__tps)...,
1701 std::forward<_Us>(__us)...,
1702 std::get<_Is>(std::forward<_Tp>(__tp))...);
1703 }
1704 };
1705
1706 template<typename _Ret>
1707 struct __tuple_concater<_Ret, _Index_tuple<>>
1708 {
1709 template<typename... _Us>
1710 static constexpr _Ret
1711 _S_do(_Us&&... __us)
1712 {
1713 return _Ret(std::forward<_Us>(__us)...);
1714 }
1715 };
1716
1717 /// tuple_cat
1718 template<typename... _Tpls, typename = typename
1719 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1720 constexpr auto
1721 tuple_cat(_Tpls&&... __tpls)
1722 -> typename __tuple_cat_result<_Tpls...>::__type
1723 {
1724 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1725 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1726 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1727 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1728 }
1729
1730 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1731 // 2301. Why is tie not constexpr?
1732 /// tie
1733 template<typename... _Elements>
1734 constexpr tuple<_Elements&...>
1735 tie(_Elements&... __args) noexcept
1736 { return tuple<_Elements&...>(__args...); }
1737
1738 /// swap
1739 template<typename... _Elements>
1740 _GLIBCXX20_CONSTEXPR
1741 inline
1742#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1743 // Constrained free swap overload, see p0185r1
1744 typename enable_if<__and_<__is_swappable<_Elements>...>::value
1745 >::type
1746#else
1747 void
1748#endif
1749 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1750 noexcept(noexcept(__x.swap(__y)))
1751 { __x.swap(__y); }
1752
1753#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1754 template<typename... _Elements>
1755 _GLIBCXX20_CONSTEXPR
1756 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
1757 swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
1758#endif
1759
1760 // A class (and instance) which can be used in 'tie' when an element
1761 // of a tuple is not required.
1762 // _GLIBCXX14_CONSTEXPR
1763 // 2933. PR for LWG 2773 could be clearer
1764 struct _Swallow_assign
1765 {
1766 template<class _Tp>
1767 _GLIBCXX14_CONSTEXPR const _Swallow_assign&
1768 operator=(const _Tp&) const
1769 { return *this; }
1770 };
1771
1772 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1773 // 2773. Making std::ignore constexpr
1774 _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
1775
1776 /// Partial specialization for tuples
1777 template<typename... _Types, typename _Alloc>
1778 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1779
1780 // See stl_pair.h...
1781 /** "piecewise construction" using a tuple of arguments for each member.
1782 *
1783 * @param __first Arguments for the first member of the pair.
1784 * @param __second Arguments for the second member of the pair.
1785 *
1786 * The elements of each tuple will be used as the constructor arguments
1787 * for the data members of the pair.
1788 */
1789 template<class _T1, class _T2>
1790 template<typename... _Args1, typename... _Args2>
1791 _GLIBCXX20_CONSTEXPR
1792 inline
1793 pair<_T1, _T2>::
1794 pair(piecewise_construct_t,
1795 tuple<_Args1...> __first, tuple<_Args2...> __second)
1796 : pair(__first, __second,
1797 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1798 typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1799 { }
1800
1801 template<class _T1, class _T2>
1802 template<typename... _Args1, size_t... _Indexes1,
1803 typename... _Args2, size_t... _Indexes2>
1804 _GLIBCXX20_CONSTEXPR inline
1805 pair<_T1, _T2>::
1806 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1807 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1808 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1809 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1810 { }
1811
1812#if __cplusplus >= 201703L
1813
1814 // Unpack a std::tuple into a type trait and use its value.
1815 // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
1816 // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
1817 // Otherwise the result is false (because we don't know if std::get throws).
1818 template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
1819 inline constexpr bool __unpack_std_tuple = false;
1820
1821 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1822 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
1823 = _Trait<_Tp, _Up...>::value;
1824
1825 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1826 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
1827 = _Trait<_Tp, _Up&...>::value;
1828
1829 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1830 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
1831 = _Trait<_Tp, const _Up...>::value;
1832
1833 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1834 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
1835 = _Trait<_Tp, const _Up&...>::value;
1836
1837# define __cpp_lib_apply 201603
1838
1839 template <typename _Fn, typename _Tuple, size_t... _Idx>
1840 constexpr decltype(auto)
1841 __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
1842 {
1843 return std::__invoke(std::forward<_Fn>(__f),
1844 std::get<_Idx>(std::forward<_Tuple>(__t))...);
1845 }
1846
1847 template <typename _Fn, typename _Tuple>
1848 constexpr decltype(auto)
1849 apply(_Fn&& __f, _Tuple&& __t)
1850 noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
1851 {
1852 using _Indices
1853 = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
1854 return std::__apply_impl(std::forward<_Fn>(__f),
1855 std::forward<_Tuple>(__t),
1856 _Indices{});
1857 }
1858
1859#define __cpp_lib_make_from_tuple 201606
1860
1861 template <typename _Tp, typename _Tuple, size_t... _Idx>
1862 constexpr _Tp
1863 __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
1864 { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
1865
1866 template <typename _Tp, typename _Tuple>
1867 constexpr _Tp
1868 make_from_tuple(_Tuple&& __t)
1869 noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
1870 {
1871 return __make_from_tuple_impl<_Tp>(
1872 std::forward<_Tuple>(__t),
1873 make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{});
1874 }
1875#endif // C++17
1876
1877 /// @}
1878
1879_GLIBCXX_END_NAMESPACE_VERSION
1880} // namespace std
1881
1882#endif // C++11
1883
1884#endif // _GLIBCXX_TUPLE
Note: See TracBrowser for help on using the repository browser.