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