3// Copyright (C) 2007-2024 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25/** @file include/tuple
26 * This is a Standard C++ Library header.
30#define _GLIBCXX_TUPLE 1
32#pragma GCC system_header
34#if __cplusplus < 201103L
35# include <bits/c++0x_warning.h>
38#include <bits/stl_pair.h> // for std::pair
39#include <bits/uses_allocator.h> // for std::allocator_arg_t
40#include <bits/utility.h> // for std::tuple_size etc.
41#include <bits/invoke.h> // for std::__invoke
42#if __cplusplus > 201703L
44# include <bits/ranges_util.h> // for std::ranges::subrange
47#define __glibcxx_want_constexpr_tuple
48#define __glibcxx_want_tuple_element_t
49#define __glibcxx_want_tuples_by_type
50#define __glibcxx_want_apply
51#define __glibcxx_want_make_from_tuple
52#define __glibcxx_want_ranges_zip
53#include <bits/version.h>
55namespace std _GLIBCXX_VISIBILITY(default)
57_GLIBCXX_BEGIN_NAMESPACE_VERSION
60 * @addtogroup utilities
64 template<typename... _Elements>
67 template<typename _Tp>
68 struct __is_empty_non_tuple : is_empty<_Tp> { };
70 // Using EBO for elements that are tuples causes ambiguous base errors.
71 template<typename _El0, typename... _El>
72 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
74 // Use the Empty Base-class Optimization for empty, non-final types.
75 template<typename _Tp>
76 using __empty_not_final
77 = __conditional_t<__is_final(_Tp), false_type,
78 __is_empty_non_tuple<_Tp>>;
80 template<size_t _Idx, typename _Head,
81 bool = __empty_not_final<_Head>::value>
84#if __has_cpp_attribute(__no_unique_address__)
85 template<size_t _Idx, typename _Head>
86 struct _Head_base<_Idx, _Head, true>
88 constexpr _Head_base()
91 constexpr _Head_base(const _Head& __h)
92 : _M_head_impl(__h) { }
94 constexpr _Head_base(const _Head_base&) = default;
95 constexpr _Head_base(_Head_base&&) = default;
97 template<typename _UHead>
98 constexpr _Head_base(_UHead&& __h)
99 : _M_head_impl(std::forward<_UHead>(__h)) { }
102 _Head_base(allocator_arg_t, __uses_alloc0)
105 template<typename _Alloc>
107 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
108 : _M_head_impl(allocator_arg, *__a._M_a) { }
110 template<typename _Alloc>
112 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
113 : _M_head_impl(*__a._M_a) { }
115 template<typename _UHead>
117 _Head_base(__uses_alloc0, _UHead&& __uhead)
118 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
120 template<typename _Alloc, typename _UHead>
122 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
123 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
126 template<typename _Alloc, typename _UHead>
128 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
129 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
131 static constexpr _Head&
132 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
134 static constexpr const _Head&
135 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
137 [[__no_unique_address__]] _Head _M_head_impl;
140 template<size_t _Idx, typename _Head>
141 struct _Head_base<_Idx, _Head, true>
144 constexpr _Head_base()
147 constexpr _Head_base(const _Head& __h)
150 constexpr _Head_base(const _Head_base&) = default;
151 constexpr _Head_base(_Head_base&&) = default;
153 template<typename _UHead>
154 constexpr _Head_base(_UHead&& __h)
155 : _Head(std::forward<_UHead>(__h)) { }
158 _Head_base(allocator_arg_t, __uses_alloc0)
161 template<typename _Alloc>
163 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
164 : _Head(allocator_arg, *__a._M_a) { }
166 template<typename _Alloc>
168 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
169 : _Head(*__a._M_a) { }
171 template<typename _UHead>
173 _Head_base(__uses_alloc0, _UHead&& __uhead)
174 : _Head(std::forward<_UHead>(__uhead)) { }
176 template<typename _Alloc, typename _UHead>
178 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
179 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
181 template<typename _Alloc, typename _UHead>
183 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
184 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
186 static constexpr _Head&
187 _M_head(_Head_base& __b) noexcept { return __b; }
189 static constexpr const _Head&
190 _M_head(const _Head_base& __b) noexcept { return __b; }
194 template<size_t _Idx, typename _Head>
195 struct _Head_base<_Idx, _Head, false>
197 constexpr _Head_base()
200 constexpr _Head_base(const _Head& __h)
201 : _M_head_impl(__h) { }
203 constexpr _Head_base(const _Head_base&) = default;
204 constexpr _Head_base(_Head_base&&) = default;
206 template<typename _UHead>
207 constexpr _Head_base(_UHead&& __h)
208 : _M_head_impl(std::forward<_UHead>(__h)) { }
211 _Head_base(allocator_arg_t, __uses_alloc0)
214 template<typename _Alloc>
216 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
217 : _M_head_impl(allocator_arg, *__a._M_a) { }
219 template<typename _Alloc>
221 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
222 : _M_head_impl(*__a._M_a) { }
224 template<typename _UHead>
226 _Head_base(__uses_alloc0, _UHead&& __uhead)
227 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
229 template<typename _Alloc, typename _UHead>
231 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
232 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
235 template<typename _Alloc, typename _UHead>
237 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
238 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
240 static constexpr _Head&
241 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
243 static constexpr const _Head&
244 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
250 * Contains the actual implementation of the @c tuple template, stored
251 * as a recursive inheritance hierarchy from the first element (most
252 * derived class) to the last (least derived class). The @c Idx
253 * parameter gives the 0-based index of the element stored at this
254 * point in the hierarchy; we use it to implement a constant-time
257 template<size_t _Idx, typename... _Elements>
261 * Recursive tuple implementation. Here we store the @c Head element
262 * and derive from a @c Tuple_impl containing the remaining elements
263 * (which contains the @c Tail).
265 template<size_t _Idx, typename _Head, typename... _Tail>
266 struct _Tuple_impl<_Idx, _Head, _Tail...>
267 : public _Tuple_impl<_Idx + 1, _Tail...>,
268 private _Head_base<_Idx, _Head>
270 template<size_t, typename...> friend struct _Tuple_impl;
272 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
273 typedef _Head_base<_Idx, _Head> _Base;
275 static constexpr _Head&
276 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
278 static constexpr const _Head&
279 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
281 static constexpr _Inherited&
282 _M_tail(_Tuple_impl& __t) noexcept { return __t; }
284 static constexpr const _Inherited&
285 _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
287 constexpr _Tuple_impl()
288 : _Inherited(), _Base() { }
291 _Tuple_impl(const _Head& __head, const _Tail&... __tail)
292 : _Inherited(__tail...), _Base(__head)
295 template<typename _UHead, typename... _UTail,
296 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
298 _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
299 : _Inherited(std::forward<_UTail>(__tail)...),
300 _Base(std::forward<_UHead>(__head))
303 constexpr _Tuple_impl(const _Tuple_impl&) = default;
305 // _GLIBCXX_RESOLVE_LIB_DEFECTS
306 // 2729. Missing SFINAE on std::pair::operator=
307 _Tuple_impl& operator=(const _Tuple_impl&) = delete;
309 _Tuple_impl(_Tuple_impl&&) = default;
311 template<typename... _UElements>
313 _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
314 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
315 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
318 template<typename _UHead, typename... _UTails>
320 _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
321 : _Inherited(std::move
322 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
323 _Base(std::forward<_UHead>
324 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
327#if __cplusplus > 202002L
328 template<typename... _UElements>
330 _Tuple_impl(_Tuple_impl<_Idx, _UElements...>& __in)
331 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
332 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
335 template<typename _UHead, typename... _UTails>
337 _Tuple_impl(const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
338 : _Inherited(std::move
339 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
340 _Base(std::forward<const _UHead>
341 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
345 template<typename _Alloc>
347 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
348 : _Inherited(__tag, __a),
349 _Base(__tag, __use_alloc<_Head>(__a))
352 template<typename _Alloc>
354 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
355 const _Head& __head, const _Tail&... __tail)
356 : _Inherited(__tag, __a, __tail...),
357 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head)
360 template<typename _Alloc, typename _UHead, typename... _UTail,
361 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
363 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
364 _UHead&& __head, _UTail&&... __tail)
365 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
366 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
367 std::forward<_UHead>(__head))
370 template<typename _Alloc>
372 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
373 const _Tuple_impl& __in)
374 : _Inherited(__tag, __a, _M_tail(__in)),
375 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in))
378 template<typename _Alloc>
380 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
382 : _Inherited(__tag, __a, std::move(_M_tail(__in))),
383 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
384 std::forward<_Head>(_M_head(__in)))
387 template<typename _Alloc, typename _UHead, typename... _UTails>
389 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
390 const _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
391 : _Inherited(__tag, __a,
392 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
393 _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
394 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
397 template<typename _Alloc, typename _UHead, typename... _UTails>
399 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
400 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
401 : _Inherited(__tag, __a, std::move
402 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
403 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
405 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
408#if __cplusplus > 202002L
409 template<typename _Alloc, typename _UHead, typename... _UTails>
411 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
412 _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
413 : _Inherited(__tag, __a,
414 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
415 _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
416 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
419 template<typename _Alloc, typename _UHead, typename... _UTails>
421 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
422 const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
423 : _Inherited(__tag, __a, std::move
424 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
425 _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
426 std::forward<const _UHead>
427 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
431 template<typename... _UElements>
434 _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
436 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
437 _M_tail(*this)._M_assign(
438 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
441 template<typename _UHead, typename... _UTails>
444 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
446 _M_head(*this) = std::forward<_UHead>
447 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
448 _M_tail(*this)._M_assign(
449 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
452#if __cplusplus > 202002L
453 template<typename... _UElements>
455 _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) const
457 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
458 _M_tail(*this)._M_assign(
459 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
462 template<typename _UHead, typename... _UTails>
464 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) const
466 _M_head(*this) = std::forward<_UHead>
467 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
468 _M_tail(*this)._M_assign(
469 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
476 _M_swap(_Tuple_impl& __in)
479 swap(_M_head(*this), _M_head(__in));
480 _Inherited::_M_swap(_M_tail(__in));
483#if __cplusplus > 202002L
485 _M_swap(const _Tuple_impl& __in) const
488 swap(_M_head(*this), _M_head(__in));
489 _Inherited::_M_swap(_M_tail(__in));
494 // Basis case of inheritance recursion.
495 template<size_t _Idx, typename _Head>
496 struct _Tuple_impl<_Idx, _Head>
497 : private _Head_base<_Idx, _Head>
499 template<size_t, typename...> friend struct _Tuple_impl;
501 typedef _Head_base<_Idx, _Head> _Base;
503 static constexpr _Head&
504 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
506 static constexpr const _Head&
507 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
514 _Tuple_impl(const _Head& __head)
518 template<typename _UHead>
520 _Tuple_impl(_UHead&& __head)
521 : _Base(std::forward<_UHead>(__head))
524 constexpr _Tuple_impl(const _Tuple_impl&) = default;
526 // _GLIBCXX_RESOLVE_LIB_DEFECTS
527 // 2729. Missing SFINAE on std::pair::operator=
528 _Tuple_impl& operator=(const _Tuple_impl&) = delete;
530#if _GLIBCXX_INLINE_VERSION
531 _Tuple_impl(_Tuple_impl&&) = default;
534 _Tuple_impl(_Tuple_impl&& __in)
535 noexcept(is_nothrow_move_constructible<_Head>::value)
536 : _Base(static_cast<_Base&&>(__in))
540 template<typename _UHead>
542 _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
543 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
546 template<typename _UHead>
548 _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
549 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
552#if __cplusplus > 202002L
553 template<typename _UHead>
555 _Tuple_impl(_Tuple_impl<_Idx, _UHead>& __in)
556 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
559 template<typename _UHead>
561 _Tuple_impl(const _Tuple_impl<_Idx, _UHead>&& __in)
562 : _Base(std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
566 template<typename _Alloc>
568 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
569 : _Base(__tag, __use_alloc<_Head>(__a))
572 template<typename _Alloc>
574 _Tuple_impl(allocator_arg_t, const _Alloc& __a,
576 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head)
579 template<typename _Alloc, typename _UHead>
581 _Tuple_impl(allocator_arg_t, const _Alloc& __a,
583 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
584 std::forward<_UHead>(__head))
587 template<typename _Alloc>
589 _Tuple_impl(allocator_arg_t, const _Alloc& __a,
590 const _Tuple_impl& __in)
591 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in))
594 template<typename _Alloc>
596 _Tuple_impl(allocator_arg_t, const _Alloc& __a,
598 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
599 std::forward<_Head>(_M_head(__in)))
602 template<typename _Alloc, typename _UHead>
604 _Tuple_impl(allocator_arg_t, const _Alloc& __a,
605 const _Tuple_impl<_Idx, _UHead>& __in)
606 : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
607 _Tuple_impl<_Idx, _UHead>::_M_head(__in))
610 template<typename _Alloc, typename _UHead>
612 _Tuple_impl(allocator_arg_t, const _Alloc& __a,
613 _Tuple_impl<_Idx, _UHead>&& __in)
614 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
615 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
618#if __cplusplus > 202002L
619 template<typename _Alloc, typename _UHead>
621 _Tuple_impl(allocator_arg_t, const _Alloc& __a,
622 _Tuple_impl<_Idx, _UHead>& __in)
623 : _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
624 _Tuple_impl<_Idx, _UHead>::_M_head(__in))
627 template<typename _Alloc, typename _UHead>
629 _Tuple_impl(allocator_arg_t, const _Alloc& __a,
630 const _Tuple_impl<_Idx, _UHead>&& __in)
631 : _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
632 std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
636 template<typename _UHead>
639 _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
641 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
644 template<typename _UHead>
647 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
650 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
653#if __cplusplus > 202002L
654 template<typename _UHead>
656 _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) const
658 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
661 template<typename _UHead>
663 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) const
666 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
673 _M_swap(_Tuple_impl& __in)
676 swap(_M_head(*this), _M_head(__in));
679#if __cplusplus > 202002L
681 _M_swap(const _Tuple_impl& __in) const
684 swap(_M_head(*this), _M_head(__in));
689 // Concept utility functions, reused in conditionally-explicit
691 template<bool, typename... _Types>
692 struct _TupleConstraints
694 template<typename... _UTypes>
695 using __constructible = __and_<is_constructible<_Types, _UTypes>...>;
697 template<typename... _UTypes>
698 using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
700 // Constraint for a non-explicit constructor.
701 // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
702 // and every Ui is implicitly convertible to Ti.
703 template<typename... _UTypes>
704 static constexpr bool __is_implicitly_constructible()
706 return __and_<__constructible<_UTypes...>,
707 __convertible<_UTypes...>
711 // Constraint for a non-explicit constructor.
712 // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
713 // but not every Ui is implicitly convertible to Ti.
714 template<typename... _UTypes>
715 static constexpr bool __is_explicitly_constructible()
717 return __and_<__constructible<_UTypes...>,
718 __not_<__convertible<_UTypes...>>
722 static constexpr bool __is_implicitly_default_constructible()
724 return __and_<std::__is_implicitly_default_constructible<_Types>...
728 static constexpr bool __is_explicitly_default_constructible()
730 return __and_<is_default_constructible<_Types>...,
732 std::__is_implicitly_default_constructible<_Types>...>
737 // Partial specialization used when a required precondition isn't met,
738 // e.g. when sizeof...(_Types) != sizeof...(_UTypes).
739 template<typename... _Types>
740 struct _TupleConstraints<false, _Types...>
742 template<typename... _UTypes>
743 static constexpr bool __is_implicitly_constructible()
746 template<typename... _UTypes>
747 static constexpr bool __is_explicitly_constructible()
751 /// Primary class template, tuple
752 template<typename... _Elements>
753 class tuple : public _Tuple_impl<0, _Elements...>
755 using _Inherited = _Tuple_impl<0, _Elements...>;
757#if __cpp_concepts && __cpp_consteval && __cpp_conditional_explicit // >= C++20
758 template<typename... _UTypes>
759 static consteval bool
762 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
763 return __and_v<is_constructible<_Elements, _UTypes>...>;
768 template<typename... _UTypes>
769 static consteval bool
770 __nothrow_constructible()
772 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
773 return __and_v<is_nothrow_constructible<_Elements, _UTypes>...>;
778 template<typename... _UTypes>
779 static consteval bool
782 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
783 return __and_v<is_convertible<_UTypes, _Elements>...>;
788 // _GLIBCXX_RESOLVE_LIB_DEFECTS
789 // 3121. tuple constructor constraints for UTypes&&... overloads
790 template<typename... _UTypes>
791 static consteval bool
792 __disambiguating_constraint()
794 if constexpr (sizeof...(_Elements) != sizeof...(_UTypes))
796 else if constexpr (sizeof...(_Elements) == 1)
798 using _U0 = typename _Nth_type<0, _UTypes...>::type;
799 return !is_same_v<remove_cvref_t<_U0>, tuple>;
801 else if constexpr (sizeof...(_Elements) < 4)
803 using _U0 = typename _Nth_type<0, _UTypes...>::type;
804 if constexpr (!is_same_v<remove_cvref_t<_U0>, allocator_arg_t>)
808 using _T0 = typename _Nth_type<0, _Elements...>::type;
809 return is_same_v<remove_cvref_t<_T0>, allocator_arg_t>;
815 // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
816 // and the single element in Types can be initialized from TUPLE,
817 // or is the same type as tuple_element_t<0, TUPLE>.
818 template<typename _Tuple>
819 static consteval bool
822 if constexpr (sizeof...(_Elements) != 1)
824 else if constexpr (is_same_v<remove_cvref_t<_Tuple>, tuple>)
825 return true; // Should use a copy/move constructor instead.
828 using _Tp = typename _Nth_type<0, _Elements...>::type;
829 if constexpr (is_convertible_v<_Tuple, _Tp>)
831 else if constexpr (is_constructible_v<_Tp, _Tuple>)
837 template<typename... _Up>
838 static consteval bool
841#if __has_builtin(__reference_constructs_from_temporary)
842 return (__reference_constructs_from_temporary(_Elements, _Up&&)
851 explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...))
853 noexcept((is_nothrow_default_constructible_v<_Elements> && ...))
854 requires (is_default_constructible_v<_Elements> && ...)
858 constexpr explicit(!__convertible<const _Elements&...>())
859 tuple(const _Elements&... __elements)
860 noexcept(__nothrow_constructible<const _Elements&...>())
861 requires (__constructible<const _Elements&...>())
862 : _Inherited(__elements...)
865 template<typename... _UTypes>
866 requires (__disambiguating_constraint<_UTypes...>())
867 && (__constructible<_UTypes...>())
868 && (!__dangles<_UTypes...>())
869 constexpr explicit(!__convertible<_UTypes...>())
870 tuple(_UTypes&&... __u)
871 noexcept(__nothrow_constructible<_UTypes...>())
872 : _Inherited(std::forward<_UTypes>(__u)...)
875 template<typename... _UTypes>
876 requires (__disambiguating_constraint<_UTypes...>())
877 && (__constructible<_UTypes...>())
878 && (__dangles<_UTypes...>())
879 tuple(_UTypes&&...) = delete;
881 constexpr tuple(const tuple&) = default;
883 constexpr tuple(tuple&&) = default;
885 template<typename... _UTypes>
886 requires (__constructible<const _UTypes&...>())
887 && (!__use_other_ctor<const tuple<_UTypes...>&>())
888 && (!__dangles<const _UTypes&...>())
889 constexpr explicit(!__convertible<const _UTypes&...>())
890 tuple(const tuple<_UTypes...>& __u)
891 noexcept(__nothrow_constructible<const _UTypes&...>())
892 : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&>(__u))
895 template<typename... _UTypes>
896 requires (__constructible<const _UTypes&...>())
897 && (!__use_other_ctor<const tuple<_UTypes...>&>())
898 && (__dangles<const _UTypes&...>())
899 tuple(const tuple<_UTypes...>&) = delete;
901 template<typename... _UTypes>
902 requires (__constructible<_UTypes...>())
903 && (!__use_other_ctor<tuple<_UTypes...>>())
904 && (!__dangles<_UTypes...>())
905 constexpr explicit(!__convertible<_UTypes...>())
906 tuple(tuple<_UTypes...>&& __u)
907 noexcept(__nothrow_constructible<_UTypes...>())
908 : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&&>(__u))
911 template<typename... _UTypes>
912 requires (__constructible<_UTypes...>())
913 && (!__use_other_ctor<tuple<_UTypes...>>())
914 && (__dangles<_UTypes...>())
915 tuple(tuple<_UTypes...>&&) = delete;
917#if __cpp_lib_ranges_zip // >= C++23
918 template<typename... _UTypes>
919 requires (__constructible<_UTypes&...>())
920 && (!__use_other_ctor<tuple<_UTypes...>&>())
921 && (!__dangles<_UTypes&...>())
922 constexpr explicit(!__convertible<_UTypes&...>())
923 tuple(tuple<_UTypes...>& __u)
924 noexcept(__nothrow_constructible<_UTypes&...>())
925 : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&>(__u))
928 template<typename... _UTypes>
929 requires (__constructible<_UTypes&...>())
930 && (!__use_other_ctor<tuple<_UTypes...>&>())
931 && (__dangles<_UTypes&...>())
932 tuple(tuple<_UTypes...>&) = delete;
934 template<typename... _UTypes>
935 requires (__constructible<const _UTypes...>())
936 && (!__use_other_ctor<const tuple<_UTypes...>>())
937 && (!__dangles<const _UTypes...>())
938 constexpr explicit(!__convertible<const _UTypes...>())
939 tuple(const tuple<_UTypes...>&& __u)
940 noexcept(__nothrow_constructible<const _UTypes...>())
941 : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u))
944 template<typename... _UTypes>
945 requires (__constructible<const _UTypes...>())
946 && (!__use_other_ctor<const tuple<_UTypes...>>())
947 && (__dangles<const _UTypes...>())
948 tuple(const tuple<_UTypes...>&&) = delete;
951 template<typename _U1, typename _U2>
952 requires (sizeof...(_Elements) == 2)
953 && (__constructible<const _U1&, const _U2&>())
954 && (!__dangles<const _U1&, const _U2&>())
955 constexpr explicit(!__convertible<const _U1&, const _U2&>())
956 tuple(const pair<_U1, _U2>& __u)
957 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
958 : _Inherited(__u.first, __u.second)
961 template<typename _U1, typename _U2>
962 requires (sizeof...(_Elements) == 2)
963 && (__constructible<const _U1&, const _U2&>())
964 && (__dangles<const _U1&, const _U2&>())
965 tuple(const pair<_U1, _U2>&) = delete;
967 template<typename _U1, typename _U2>
968 requires (sizeof...(_Elements) == 2)
969 && (__constructible<_U1, _U2>())
970 && (!__dangles<_U1, _U2>())
971 constexpr explicit(!__convertible<_U1, _U2>())
972 tuple(pair<_U1, _U2>&& __u)
973 noexcept(__nothrow_constructible<_U1, _U2>())
974 : _Inherited(std::forward<_U1>(__u.first),
975 std::forward<_U2>(__u.second))
978 template<typename _U1, typename _U2>
979 requires (sizeof...(_Elements) == 2)
980 && (__constructible<_U1, _U2>())
981 && (__dangles<_U1, _U2>())
982 tuple(pair<_U1, _U2>&&) = delete;
984#if __cpp_lib_ranges_zip // >= C++23
985 template<typename _U1, typename _U2>
986 requires (sizeof...(_Elements) == 2)
987 && (__constructible<_U1&, _U2&>())
988 && (!__dangles<_U1&, _U2&>())
989 constexpr explicit(!__convertible<_U1&, _U2&>())
990 tuple(pair<_U1, _U2>& __u)
991 noexcept(__nothrow_constructible<_U1&, _U2&>())
992 : _Inherited(__u.first, __u.second)
995 template<typename _U1, typename _U2>
996 requires (sizeof...(_Elements) == 2)
997 && (__constructible<_U1&, _U2&>())
998 && (__dangles<_U1&, _U2&>())
999 tuple(pair<_U1, _U2>&) = delete;
1001 template<typename _U1, typename _U2>
1002 requires (sizeof...(_Elements) == 2)
1003 && (__constructible<const _U1, const _U2>())
1004 && (!__dangles<const _U1, const _U2>())
1005 constexpr explicit(!__convertible<const _U1, const _U2>())
1006 tuple(const pair<_U1, _U2>&& __u)
1007 noexcept(__nothrow_constructible<const _U1, const _U2>())
1008 : _Inherited(std::forward<const _U1>(__u.first),
1009 std::forward<const _U2>(__u.second))
1012 template<typename _U1, typename _U2>
1013 requires (sizeof...(_Elements) == 2)
1014 && (__constructible<const _U1, const _U2>())
1015 && (__dangles<const _U1, const _U2>())
1016 tuple(const pair<_U1, _U2>&&) = delete;
1019#if 0 && __cpp_lib_tuple_like // >= C++23
1020 template<__tuple_like _UTuple>
1021 constexpr explicit(...)
1022 tuple(_UTuple&& __u);
1025 // Allocator-extended constructors.
1027 template<typename _Alloc>
1029 explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...))
1030 tuple(allocator_arg_t __tag, const _Alloc& __a)
1031 requires (is_default_constructible_v<_Elements> && ...)
1032 : _Inherited(__tag, __a)
1035 template<typename _Alloc>
1036 constexpr explicit(!__convertible<const _Elements&...>())
1037 tuple(allocator_arg_t __tag, const _Alloc& __a,
1038 const _Elements&... __elements)
1039 requires (__constructible<const _Elements&...>())
1040 : _Inherited(__tag, __a, __elements...)
1043 template<typename _Alloc, typename... _UTypes>
1044 requires (__disambiguating_constraint<_UTypes...>())
1045 && (__constructible<_UTypes...>())
1046 && (!__dangles<_UTypes...>())
1047 constexpr explicit(!__convertible<_UTypes...>())
1048 tuple(allocator_arg_t __tag, const _Alloc& __a, _UTypes&&... __u)
1049 : _Inherited(__tag, __a, std::forward<_UTypes>(__u)...)
1052 template<typename _Alloc, typename... _UTypes>
1053 requires (__disambiguating_constraint<_UTypes...>())
1054 && (__constructible<_UTypes...>())
1055 && (__dangles<_UTypes...>())
1056 tuple(allocator_arg_t, const _Alloc&, _UTypes&&...) = delete;
1058 template<typename _Alloc>
1060 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __u)
1061 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__u))
1064 template<typename _Alloc>
1065 requires (__constructible<_Elements...>())
1067 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __u)
1068 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__u))
1071 template<typename _Alloc, typename... _UTypes>
1072 requires (__constructible<const _UTypes&...>())
1073 && (!__use_other_ctor<const tuple<_UTypes...>&>())
1074 && (!__dangles<const _UTypes&...>())
1075 constexpr explicit(!__convertible<const _UTypes&...>())
1076 tuple(allocator_arg_t __tag, const _Alloc& __a,
1077 const tuple<_UTypes...>& __u)
1078 : _Inherited(__tag, __a,
1079 static_cast<const _Tuple_impl<0, _UTypes...>&>(__u))
1082 template<typename _Alloc, typename... _UTypes>
1083 requires (__constructible<const _UTypes&...>())
1084 && (!__use_other_ctor<const tuple<_UTypes...>&>())
1085 && (__dangles<const _UTypes&...>())
1086 tuple(allocator_arg_t, const _Alloc&, const tuple<_UTypes...>&) = delete;
1088 template<typename _Alloc, typename... _UTypes>
1089 requires (__constructible<_UTypes...>())
1090 && (!__use_other_ctor<tuple<_UTypes...>>())
1091 && (!__dangles<_UTypes...>())
1092 constexpr explicit(!__use_other_ctor<tuple<_UTypes...>>())
1093 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UTypes...>&& __u)
1094 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&&>(__u))
1097 template<typename _Alloc, typename... _UTypes>
1098 requires (__constructible<_UTypes...>())
1099 && (!__use_other_ctor<tuple<_UTypes...>>())
1100 && (__dangles<_UTypes...>())
1101 tuple(allocator_arg_t, const _Alloc&, tuple<_UTypes...>&&) = delete;
1103#if __cpp_lib_ranges_zip // >= C++23
1104 template<typename _Alloc, typename... _UTypes>
1105 requires (__constructible<_UTypes&...>())
1106 && (!__use_other_ctor<tuple<_UTypes...>&>())
1107 && (!__dangles<_UTypes&...>())
1108 constexpr explicit(!__convertible<_UTypes&...>())
1109 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UTypes...>& __u)
1110 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&>(__u))
1113 template<typename _Alloc, typename... _UTypes>
1114 requires (__constructible<_UTypes&...>())
1115 && (!__use_other_ctor<tuple<_UTypes...>&>())
1116 && (__dangles<_UTypes&...>())
1117 tuple(allocator_arg_t, const _Alloc&, tuple<_UTypes...>&) = delete;
1119 template<typename _Alloc, typename... _UTypes>
1120 requires (__constructible<const _UTypes...>())
1121 && (!__use_other_ctor<const tuple<_UTypes...>>())
1122 && (!__dangles<const _UTypes...>())
1123 constexpr explicit(!__convertible<const _UTypes...>())
1124 tuple(allocator_arg_t __tag, const _Alloc& __a,
1125 const tuple<_UTypes...>&& __u)
1126 : _Inherited(__tag, __a,
1127 static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u))
1130 template<typename _Alloc, typename... _UTypes>
1131 requires (__constructible<const _UTypes...>())
1132 && (!__use_other_ctor<const tuple<_UTypes...>>())
1133 && (__dangles<const _UTypes...>())
1134 tuple(allocator_arg_t, const _Alloc&, const tuple<_UTypes...>&&) = delete;
1137 template<typename _Alloc, typename _U1, typename _U2>
1138 requires (sizeof...(_Elements) == 2)
1139 && (__constructible<const _U1&, const _U2&>())
1140 && (!__dangles<const _U1&, const _U2&>())
1141 constexpr explicit(!__convertible<const _U1&, const _U2&>())
1142 tuple(allocator_arg_t __tag, const _Alloc& __a,
1143 const pair<_U1, _U2>& __u)
1144 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1145 : _Inherited(__tag, __a, __u.first, __u.second)
1148 template<typename _Alloc, typename _U1, typename _U2>
1149 requires (sizeof...(_Elements) == 2)
1150 && (__constructible<const _U1&, const _U2&>())
1151 && (__dangles<const _U1&, const _U2&>())
1152 tuple(allocator_arg_t, const _Alloc&, const pair<_U1, _U2>&) = delete;
1154 template<typename _Alloc, typename _U1, typename _U2>
1155 requires (sizeof...(_Elements) == 2)
1156 && (__constructible<_U1, _U2>())
1157 && (!__dangles<_U1, _U2>())
1158 constexpr explicit(!__convertible<_U1, _U2>())
1159 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __u)
1160 noexcept(__nothrow_constructible<_U1, _U2>())
1161 : _Inherited(__tag, __a, std::move(__u.first), std::move(__u.second))
1164 template<typename _Alloc, typename _U1, typename _U2>
1165 requires (sizeof...(_Elements) == 2)
1166 && (__constructible<_U1, _U2>())
1167 && (__dangles<_U1, _U2>())
1168 tuple(allocator_arg_t, const _Alloc&, pair<_U1, _U2>&&) = delete;
1170#if __cpp_lib_ranges_zip // >= C++23
1171 template<typename _Alloc, typename _U1, typename _U2>
1172 requires (sizeof...(_Elements) == 2)
1173 && (__constructible<_U1&, _U2&>())
1174 && (!__dangles<_U1&, _U2&>())
1175 constexpr explicit(!__convertible<_U1&, _U2&>())
1176 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>& __u)
1177 noexcept(__nothrow_constructible<_U1&, _U2&>())
1178 : _Inherited(__tag, __a, __u.first, __u.second)
1181 template<typename _Alloc, typename _U1, typename _U2>
1182 requires (sizeof...(_Elements) == 2)
1183 && (__constructible<_U1&, _U2&>())
1184 && (__dangles<_U1&, _U2&>())
1185 tuple(allocator_arg_t, const _Alloc&, pair<_U1, _U2>&) = delete;
1187 template<typename _Alloc, typename _U1, typename _U2>
1188 requires (sizeof...(_Elements) == 2)
1189 && (__constructible<const _U1, const _U2>())
1190 && (!__dangles<const _U1, const _U2>())
1191 constexpr explicit(!__convertible<const _U1, const _U2>())
1192 tuple(allocator_arg_t __tag, const _Alloc& __a,
1193 const pair<_U1, _U2>&& __u)
1194 noexcept(__nothrow_constructible<const _U1, const _U2>())
1195 : _Inherited(__tag, __a, std::move(__u.first), std::move(__u.second))
1198 template<typename _Alloc, typename _U1, typename _U2>
1199 requires (sizeof...(_Elements) == 2)
1200 && (__constructible<const _U1, const _U2>())
1201 && (__dangles<const _U1, const _U2>())
1202 tuple(allocator_arg_t, const _Alloc&, const pair<_U1, _U2>&&) = delete;
1205#if 0 && __cpp_lib_tuple_like // >= C++23
1206 template<typename _Alloc, __tuple_like _UTuple>
1207 constexpr explicit(...)
1208 tuple(allocator_arg_t __tag, const _Alloc& __a, _UTuple&& __u);
1211#else // !(concepts && conditional_explicit)
1213 template<bool _Cond>
1214 using _TCC = _TupleConstraints<_Cond, _Elements...>;
1216 // Constraint for non-explicit default constructor
1217 template<bool _Dummy>
1218 using _ImplicitDefaultCtor = __enable_if_t<
1219 _TCC<_Dummy>::__is_implicitly_default_constructible(),
1222 // Constraint for explicit default constructor
1223 template<bool _Dummy>
1224 using _ExplicitDefaultCtor = __enable_if_t<
1225 _TCC<_Dummy>::__is_explicitly_default_constructible(),
1228 // Constraint for non-explicit constructors
1229 template<bool _Cond, typename... _Args>
1230 using _ImplicitCtor = __enable_if_t<
1231 _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
1234 // Constraint for non-explicit constructors
1235 template<bool _Cond, typename... _Args>
1236 using _ExplicitCtor = __enable_if_t<
1237 _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
1240 template<typename... _UElements>
1242 __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
1244 { return __and_<is_assignable<_Elements&, _UElements>...>::value; }
1246 // Condition for noexcept-specifier of an assignment operator.
1247 template<typename... _UElements>
1248 static constexpr bool __nothrow_assignable()
1251 __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
1254 // Condition for noexcept-specifier of a constructor.
1255 template<typename... _UElements>
1256 static constexpr bool __nothrow_constructible()
1259 __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;
1262 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1.
1263 template<typename _Up>
1264 static constexpr bool __valid_args()
1266 return sizeof...(_Elements) == 1
1267 && !is_same<tuple, __remove_cvref_t<_Up>>::value;
1270 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1.
1271 template<typename, typename, typename... _Tail>
1272 static constexpr bool __valid_args()
1273 { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); }
1275 /* Constraint for constructors with a tuple<UTypes...> parameter ensures
1276 * that the constructor is only viable when it would not interfere with
1277 * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&).
1278 * Such constructors are only viable if:
1279 * either sizeof...(Types) != 1,
1280 * or (when Types... expands to T and UTypes... expands to U)
1281 * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>,
1282 * and is_same_v<T, U> are all false.
1284 template<typename _Tuple, typename = tuple,
1285 typename = __remove_cvref_t<_Tuple>>
1286 struct _UseOtherCtor
1289 // If TUPLE is convertible to the single element in *this,
1290 // then TUPLE should match tuple(UTypes&&...) instead.
1291 template<typename _Tuple, typename _Tp, typename _Up>
1292 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
1293 : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>::type
1295 // If TUPLE and *this each have a single element of the same type,
1296 // then TUPLE should match a copy/move constructor instead.
1297 template<typename _Tuple, typename _Tp>
1298 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>
1302 // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
1303 // and the single element in Types can be initialized from TUPLE,
1304 // or is the same type as tuple_element_t<0, TUPLE>.
1305 template<typename _Tuple>
1306 static constexpr bool __use_other_ctor()
1307 { return _UseOtherCtor<_Tuple>::value; }
1309 /// @cond undocumented
1310#undef __glibcxx_no_dangling_refs
1311#if __has_builtin(__reference_constructs_from_temporary) \
1312 && defined _GLIBCXX_DEBUG
1313 // Error if construction from U... would create a dangling ref.
1314# if __cpp_fold_expressions
1315# define __glibcxx_dangling_refs(U) \
1316 (__reference_constructs_from_temporary(_Elements, U) && ...)
1318# define __glibcxx_dangling_refs(U) \
1319 __or_<__bool_constant<__reference_constructs_from_temporary(_Elements, U) \
1322# define __glibcxx_no_dangling_refs(U) \
1323 static_assert(!__glibcxx_dangling_refs(U), \
1324 "std::tuple constructor creates a dangling reference")
1326# define __glibcxx_no_dangling_refs(U)
1331 template<typename _Dummy = void,
1332 _ImplicitDefaultCtor<is_void<_Dummy>::value> = true>
1335 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
1338 template<typename _Dummy = void,
1339 _ExplicitDefaultCtor<is_void<_Dummy>::value> = false>
1342 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
1345 template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
1346 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
1348 tuple(const _Elements&... __elements)
1349 noexcept(__nothrow_constructible<const _Elements&...>())
1350 : _Inherited(__elements...) { }
1352 template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
1353 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
1355 tuple(const _Elements&... __elements)
1356 noexcept(__nothrow_constructible<const _Elements&...>())
1357 : _Inherited(__elements...) { }
1359 template<typename... _UElements,
1360 bool _Valid = __valid_args<_UElements...>(),
1361 _ImplicitCtor<_Valid, _UElements...> = true>
1363 tuple(_UElements&&... __elements)
1364 noexcept(__nothrow_constructible<_UElements...>())
1365 : _Inherited(std::forward<_UElements>(__elements)...)
1366 { __glibcxx_no_dangling_refs(_UElements&&); }
1368 template<typename... _UElements,
1369 bool _Valid = __valid_args<_UElements...>(),
1370 _ExplicitCtor<_Valid, _UElements...> = false>
1372 tuple(_UElements&&... __elements)
1373 noexcept(__nothrow_constructible<_UElements...>())
1374 : _Inherited(std::forward<_UElements>(__elements)...)
1375 { __glibcxx_no_dangling_refs(_UElements&&); }
1377 constexpr tuple(const tuple&) = default;
1379 constexpr tuple(tuple&&) = default;
1381 template<typename... _UElements,
1382 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
1383 && !__use_other_ctor<const tuple<_UElements...>&>(),
1384 _ImplicitCtor<_Valid, const _UElements&...> = true>
1386 tuple(const tuple<_UElements...>& __in)
1387 noexcept(__nothrow_constructible<const _UElements&...>())
1388 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
1389 { __glibcxx_no_dangling_refs(const _UElements&); }
1391 template<typename... _UElements,
1392 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
1393 && !__use_other_ctor<const tuple<_UElements...>&>(),
1394 _ExplicitCtor<_Valid, const _UElements&...> = false>
1396 tuple(const tuple<_UElements...>& __in)
1397 noexcept(__nothrow_constructible<const _UElements&...>())
1398 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
1399 { __glibcxx_no_dangling_refs(const _UElements&); }
1401 template<typename... _UElements,
1402 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
1403 && !__use_other_ctor<tuple<_UElements...>&&>(),
1404 _ImplicitCtor<_Valid, _UElements...> = true>
1406 tuple(tuple<_UElements...>&& __in)
1407 noexcept(__nothrow_constructible<_UElements...>())
1408 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
1409 { __glibcxx_no_dangling_refs(_UElements&&); }
1411 template<typename... _UElements,
1412 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
1413 && !__use_other_ctor<tuple<_UElements...>&&>(),
1414 _ExplicitCtor<_Valid, _UElements...> = false>
1416 tuple(tuple<_UElements...>&& __in)
1417 noexcept(__nothrow_constructible<_UElements...>())
1418 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
1419 { __glibcxx_no_dangling_refs(_UElements&&); }
1421 // Allocator-extended constructors.
1423 template<typename _Alloc,
1424 _ImplicitDefaultCtor<is_object<_Alloc>::value> = true>
1425 _GLIBCXX20_CONSTEXPR
1426 tuple(allocator_arg_t __tag, const _Alloc& __a)
1427 : _Inherited(__tag, __a) { }
1429 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
1430 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
1431 _GLIBCXX20_CONSTEXPR
1432 tuple(allocator_arg_t __tag, const _Alloc& __a,
1433 const _Elements&... __elements)
1434 : _Inherited(__tag, __a, __elements...) { }
1436 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
1437 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
1438 _GLIBCXX20_CONSTEXPR
1440 tuple(allocator_arg_t __tag, const _Alloc& __a,
1441 const _Elements&... __elements)
1442 : _Inherited(__tag, __a, __elements...) { }
1444 template<typename _Alloc, typename... _UElements,
1445 bool _Valid = __valid_args<_UElements...>(),
1446 _ImplicitCtor<_Valid, _UElements...> = true>
1447 _GLIBCXX20_CONSTEXPR
1448 tuple(allocator_arg_t __tag, const _Alloc& __a,
1449 _UElements&&... __elements)
1450 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
1451 { __glibcxx_no_dangling_refs(_UElements&&); }
1453 template<typename _Alloc, typename... _UElements,
1454 bool _Valid = __valid_args<_UElements...>(),
1455 _ExplicitCtor<_Valid, _UElements...> = false>
1456 _GLIBCXX20_CONSTEXPR
1458 tuple(allocator_arg_t __tag, const _Alloc& __a,
1459 _UElements&&... __elements)
1460 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
1461 { __glibcxx_no_dangling_refs(_UElements&&); }
1463 template<typename _Alloc>
1464 _GLIBCXX20_CONSTEXPR
1465 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1466 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1468 template<typename _Alloc>
1469 _GLIBCXX20_CONSTEXPR
1470 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1471 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1473 template<typename _Alloc, typename... _UElements,
1474 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
1475 && !__use_other_ctor<const tuple<_UElements...>&>(),
1476 _ImplicitCtor<_Valid, const _UElements&...> = true>
1477 _GLIBCXX20_CONSTEXPR
1478 tuple(allocator_arg_t __tag, const _Alloc& __a,
1479 const tuple<_UElements...>& __in)
1480 : _Inherited(__tag, __a,
1481 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
1482 { __glibcxx_no_dangling_refs(const _UElements&); }
1484 template<typename _Alloc, typename... _UElements,
1485 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
1486 && !__use_other_ctor<const tuple<_UElements...>&>(),
1487 _ExplicitCtor<_Valid, const _UElements&...> = false>
1488 _GLIBCXX20_CONSTEXPR
1490 tuple(allocator_arg_t __tag, const _Alloc& __a,
1491 const tuple<_UElements...>& __in)
1492 : _Inherited(__tag, __a,
1493 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
1494 { __glibcxx_no_dangling_refs(const _UElements&); }
1496 template<typename _Alloc, typename... _UElements,
1497 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
1498 && !__use_other_ctor<tuple<_UElements...>&&>(),
1499 _ImplicitCtor<_Valid, _UElements...> = true>
1500 _GLIBCXX20_CONSTEXPR
1501 tuple(allocator_arg_t __tag, const _Alloc& __a,
1502 tuple<_UElements...>&& __in)
1503 : _Inherited(__tag, __a,
1504 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
1505 { __glibcxx_no_dangling_refs(_UElements&&); }
1507 template<typename _Alloc, typename... _UElements,
1508 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
1509 && !__use_other_ctor<tuple<_UElements...>&&>(),
1510 _ExplicitCtor<_Valid, _UElements...> = false>
1511 _GLIBCXX20_CONSTEXPR
1513 tuple(allocator_arg_t __tag, const _Alloc& __a,
1514 tuple<_UElements...>&& __in)
1515 : _Inherited(__tag, __a,
1516 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
1517 { __glibcxx_no_dangling_refs(_UElements&&); }
1518#endif // concepts && conditional_explicit
1522#if __cpp_concepts && __cpp_consteval // >= C++20
1524 template<typename... _UTypes>
1525 static consteval bool
1528 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
1529 return __and_v<is_assignable<_Elements&, _UTypes>...>;
1534 template<typename... _UTypes>
1535 static consteval bool
1536 __nothrow_assignable()
1538 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
1539 return __and_v<is_nothrow_assignable<_Elements&, _UTypes>...>;
1544#if __cpp_lib_ranges_zip // >= C++23
1545 template<typename... _UTypes>
1546 static consteval bool
1547 __const_assignable()
1549 if constexpr (sizeof...(_UTypes) == sizeof...(_Elements))
1550 return __and_v<is_assignable<const _Elements&, _UTypes>...>;
1558 tuple& operator=(const tuple& __u) = delete;
1561 operator=(const tuple& __u)
1562 noexcept(__nothrow_assignable<const _Elements&...>())
1563 requires (__assignable<const _Elements&...>())
1565 this->_M_assign(__u);
1570 operator=(tuple&& __u)
1571 noexcept(__nothrow_assignable<_Elements...>())
1572 requires (__assignable<_Elements...>())
1574 this->_M_assign(std::move(__u));
1578 template<typename... _UTypes>
1579 requires (__assignable<const _UTypes&...>())
1581 operator=(const tuple<_UTypes...>& __u)
1582 noexcept(__nothrow_assignable<const _UTypes&...>())
1584 this->_M_assign(__u);
1588 template<typename... _UTypes>
1589 requires (__assignable<_UTypes...>())
1591 operator=(tuple<_UTypes...>&& __u)
1592 noexcept(__nothrow_assignable<_UTypes...>())
1594 this->_M_assign(std::move(__u));
1598#if __cpp_lib_ranges_zip // >= C++23
1599 constexpr const tuple&
1600 operator=(const tuple& __u) const
1601 requires (__const_assignable<const _Elements&...>())
1603 this->_M_assign(__u);
1607 constexpr const tuple&
1608 operator=(tuple&& __u) const
1609 requires (__const_assignable<_Elements...>())
1611 this->_M_assign(std::move(__u));
1615 template<typename... _UTypes>
1616 constexpr const tuple&
1617 operator=(const tuple<_UTypes...>& __u) const
1618 requires (__const_assignable<const _UTypes&...>())
1620 this->_M_assign(__u);
1624 template<typename... _UTypes>
1625 constexpr const tuple&
1626 operator=(tuple<_UTypes...>&& __u) const
1627 requires (__const_assignable<_UTypes...>())
1629 this->_M_assign(std::move(__u));
1634 template<typename _U1, typename _U2>
1635 requires (__assignable<const _U1&, const _U2&>())
1637 operator=(const pair<_U1, _U2>& __u)
1638 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1640 this->_M_head(*this) = __u.first;
1641 this->_M_tail(*this)._M_head(*this) = __u.second;
1645 template<typename _U1, typename _U2>
1646 requires (__assignable<_U1, _U2>())
1648 operator=(pair<_U1, _U2>&& __u)
1649 noexcept(__nothrow_assignable<_U1, _U2>())
1651 this->_M_head(*this) = std::forward<_U1>(__u.first);
1652 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__u.second);
1656#if __cpp_lib_ranges_zip // >= C++23
1657 template<typename _U1, typename _U2>
1658 requires (__const_assignable<const _U1&, const _U2>())
1659 constexpr const tuple&
1660 operator=(const pair<_U1, _U2>& __u) const
1662 this->_M_head(*this) = __u.first;
1663 this->_M_tail(*this)._M_head(*this) = __u.second;
1667 template<typename _U1, typename _U2>
1668 requires (__const_assignable<_U1, _U2>())
1669 constexpr const tuple&
1670 operator=(pair<_U1, _U2>&& __u) const
1672 this->_M_head(*this) = std::forward<_U1>(__u.first);
1673 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__u.second);
1678#if 0 && __cpp_lib_tuple_like // >= C++23
1679 template<__tuple_like _UTuple>
1681 operator=(_UTuple&& __u);
1683 template<__tuple_like _UTuple>
1685 operator=(_UTuple&& __u) const;
1690 _GLIBCXX20_CONSTEXPR
1692 operator=(__conditional_t<__assignable<const _Elements&...>(),
1694 const __nonesuch&> __in)
1695 noexcept(__nothrow_assignable<const _Elements&...>())
1697 this->_M_assign(__in);
1701 _GLIBCXX20_CONSTEXPR
1703 operator=(__conditional_t<__assignable<_Elements...>(),
1706 noexcept(__nothrow_assignable<_Elements...>())
1708 this->_M_assign(std::move(__in));
1712 template<typename... _UElements>
1713 _GLIBCXX20_CONSTEXPR
1714 __enable_if_t<__assignable<const _UElements&...>(), tuple&>
1715 operator=(const tuple<_UElements...>& __in)
1716 noexcept(__nothrow_assignable<const _UElements&...>())
1718 this->_M_assign(__in);
1722 template<typename... _UElements>
1723 _GLIBCXX20_CONSTEXPR
1724 __enable_if_t<__assignable<_UElements...>(), tuple&>
1725 operator=(tuple<_UElements...>&& __in)
1726 noexcept(__nothrow_assignable<_UElements...>())
1728 this->_M_assign(std::move(__in));
1734 _GLIBCXX20_CONSTEXPR
1737 noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
1738 { _Inherited::_M_swap(__in); }
1740#if __cpp_lib_ranges_zip // >= C++23
1741 // As an extension, we constrain the const swap member function in order
1742 // to continue accepting explicit instantiation of tuples whose elements
1743 // are not all const swappable. Without this constraint, such an
1744 // explicit instantiation would also instantiate the ill-formed body of
1745 // this function and yield a hard error. This constraint shouldn't
1746 // affect the behavior of valid programs.
1748 swap(const tuple& __in) const
1749 noexcept(__and_v<__is_nothrow_swappable<const _Elements>...>)
1750 requires (is_swappable_v<const _Elements> && ...)
1751 { _Inherited::_M_swap(__in); }
1755#if __cpp_deduction_guides >= 201606
1756 template<typename... _UTypes>
1757 tuple(_UTypes...) -> tuple<_UTypes...>;
1758 template<typename _T1, typename _T2>
1759 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
1760 template<typename _Alloc, typename... _UTypes>
1761 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
1762 template<typename _Alloc, typename _T1, typename _T2>
1763 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
1764 template<typename _Alloc, typename... _UTypes>
1765 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
1768 // Explicit specialization, zero-element tuple.
1773 _GLIBCXX20_CONSTEXPR
1774 void swap(tuple&) noexcept { /* no-op */ }
1775#if __cplusplus > 202002L
1776 constexpr void swap(const tuple&) const noexcept { /* no-op */ }
1778 // We need the default since we're going to define no-op
1779 // allocator constructors.
1781 // No-op allocator constructors.
1782 template<typename _Alloc>
1783 _GLIBCXX20_CONSTEXPR
1784 tuple(allocator_arg_t, const _Alloc&) noexcept { }
1785 template<typename _Alloc>
1786 _GLIBCXX20_CONSTEXPR
1787 tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
1790#if !(__cpp_concepts && __cpp_consteval && __cpp_conditional_explicit) // !C++20
1791 /// Partial specialization, 2-element tuple.
1792 /// Includes construction and assignment from a pair.
1793 template<typename _T1, typename _T2>
1794 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
1796 typedef _Tuple_impl<0, _T1, _T2> _Inherited;
1798 // Constraint for non-explicit default constructor
1799 template<bool _Dummy, typename _U1, typename _U2>
1800 using _ImplicitDefaultCtor = __enable_if_t<
1801 _TupleConstraints<_Dummy, _U1, _U2>::
1802 __is_implicitly_default_constructible(),
1805 // Constraint for explicit default constructor
1806 template<bool _Dummy, typename _U1, typename _U2>
1807 using _ExplicitDefaultCtor = __enable_if_t<
1808 _TupleConstraints<_Dummy, _U1, _U2>::
1809 __is_explicitly_default_constructible(),
1812 template<bool _Dummy>
1813 using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
1815 // Constraint for non-explicit constructors
1816 template<bool _Cond, typename _U1, typename _U2>
1817 using _ImplicitCtor = __enable_if_t<
1818 _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
1821 // Constraint for non-explicit constructors
1822 template<bool _Cond, typename _U1, typename _U2>
1823 using _ExplicitCtor = __enable_if_t<
1824 _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
1827 template<typename _U1, typename _U2>
1828 static constexpr bool __assignable()
1830 return __and_<is_assignable<_T1&, _U1>,
1831 is_assignable<_T2&, _U2>>::value;
1834 template<typename _U1, typename _U2>
1835 static constexpr bool __nothrow_assignable()
1837 return __and_<is_nothrow_assignable<_T1&, _U1>,
1838 is_nothrow_assignable<_T2&, _U2>>::value;
1841 template<typename _U1, typename _U2>
1842 static constexpr bool __nothrow_constructible()
1844 return __and_<is_nothrow_constructible<_T1, _U1>,
1845 is_nothrow_constructible<_T2, _U2>>::value;
1848 static constexpr bool __nothrow_default_constructible()
1850 return __and_<is_nothrow_default_constructible<_T1>,
1851 is_nothrow_default_constructible<_T2>>::value;
1854 template<typename _U1>
1855 static constexpr bool __is_alloc_arg()
1856 { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
1858 /// @cond undocumented
1859#undef __glibcxx_no_dangling_refs
1860 // Error if construction from _U1 and _U2 would create a dangling ref.
1861#if __has_builtin(__reference_constructs_from_temporary) \
1862 && defined _GLIBCXX_DEBUG
1863# define __glibcxx_no_dangling_refs(_U1, _U2) \
1864 static_assert(!__reference_constructs_from_temporary(_T1, _U1) \
1865 && !__reference_constructs_from_temporary(_T2, _U2), \
1866 "std::tuple constructor creates a dangling reference")
1868# define __glibcxx_no_dangling_refs(_U1, _U2)
1873 template<bool _Dummy = true,
1874 _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
1877 noexcept(__nothrow_default_constructible())
1880 template<bool _Dummy = true,
1881 _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>
1884 noexcept(__nothrow_default_constructible())
1887 template<bool _Dummy = true,
1888 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
1890 tuple(const _T1& __a1, const _T2& __a2)
1891 noexcept(__nothrow_constructible<const _T1&, const _T2&>())
1892 : _Inherited(__a1, __a2) { }
1894 template<bool _Dummy = true,
1895 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
1897 tuple(const _T1& __a1, const _T2& __a2)
1898 noexcept(__nothrow_constructible<const _T1&, const _T2&>())
1899 : _Inherited(__a1, __a2) { }
1901 template<typename _U1, typename _U2,
1902 _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>
1904 tuple(_U1&& __a1, _U2&& __a2)
1905 noexcept(__nothrow_constructible<_U1, _U2>())
1906 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2))
1907 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
1909 template<typename _U1, typename _U2,
1910 _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>
1912 tuple(_U1&& __a1, _U2&& __a2)
1913 noexcept(__nothrow_constructible<_U1, _U2>())
1914 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2))
1915 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
1917 constexpr tuple(const tuple&) = default;
1919 constexpr tuple(tuple&&) = default;
1921 template<typename _U1, typename _U2,
1922 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1924 tuple(const tuple<_U1, _U2>& __in)
1925 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1926 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1927 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
1929 template<typename _U1, typename _U2,
1930 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1932 tuple(const tuple<_U1, _U2>& __in)
1933 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1934 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1935 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
1937 template<typename _U1, typename _U2,
1938 _ImplicitCtor<true, _U1, _U2> = true>
1940 tuple(tuple<_U1, _U2>&& __in)
1941 noexcept(__nothrow_constructible<_U1, _U2>())
1942 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1943 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
1945 template<typename _U1, typename _U2,
1946 _ExplicitCtor<true, _U1, _U2> = false>
1948 tuple(tuple<_U1, _U2>&& __in)
1949 noexcept(__nothrow_constructible<_U1, _U2>())
1950 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1951 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
1953 template<typename _U1, typename _U2,
1954 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1956 tuple(const pair<_U1, _U2>& __in)
1957 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1958 : _Inherited(__in.first, __in.second)
1959 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
1961 template<typename _U1, typename _U2,
1962 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1964 tuple(const pair<_U1, _U2>& __in)
1965 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1966 : _Inherited(__in.first, __in.second)
1967 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
1969 template<typename _U1, typename _U2,
1970 _ImplicitCtor<true, _U1, _U2> = true>
1972 tuple(pair<_U1, _U2>&& __in)
1973 noexcept(__nothrow_constructible<_U1, _U2>())
1974 : _Inherited(std::forward<_U1>(__in.first),
1975 std::forward<_U2>(__in.second))
1976 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
1978 template<typename _U1, typename _U2,
1979 _ExplicitCtor<true, _U1, _U2> = false>
1981 tuple(pair<_U1, _U2>&& __in)
1982 noexcept(__nothrow_constructible<_U1, _U2>())
1983 : _Inherited(std::forward<_U1>(__in.first),
1984 std::forward<_U2>(__in.second))
1985 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
1987 // Allocator-extended constructors.
1989 template<typename _Alloc,
1990 _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>
1991 _GLIBCXX20_CONSTEXPR
1992 tuple(allocator_arg_t __tag, const _Alloc& __a)
1993 : _Inherited(__tag, __a) { }
1995 template<typename _Alloc, bool _Dummy = true,
1996 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
1997 _GLIBCXX20_CONSTEXPR
1998 tuple(allocator_arg_t __tag, const _Alloc& __a,
1999 const _T1& __a1, const _T2& __a2)
2000 : _Inherited(__tag, __a, __a1, __a2) { }
2002 template<typename _Alloc, bool _Dummy = true,
2003 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
2005 _GLIBCXX20_CONSTEXPR
2006 tuple(allocator_arg_t __tag, const _Alloc& __a,
2007 const _T1& __a1, const _T2& __a2)
2008 : _Inherited(__tag, __a, __a1, __a2) { }
2010 template<typename _Alloc, typename _U1, typename _U2,
2011 _ImplicitCtor<true, _U1, _U2> = true>
2012 _GLIBCXX20_CONSTEXPR
2013 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
2014 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
2015 std::forward<_U2>(__a2))
2016 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2018 template<typename _Alloc, typename _U1, typename _U2,
2019 _ExplicitCtor<true, _U1, _U2> = false>
2021 _GLIBCXX20_CONSTEXPR
2022 tuple(allocator_arg_t __tag, const _Alloc& __a,
2023 _U1&& __a1, _U2&& __a2)
2024 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
2025 std::forward<_U2>(__a2))
2026 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2028 template<typename _Alloc>
2029 _GLIBCXX20_CONSTEXPR
2030 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
2031 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
2033 template<typename _Alloc>
2034 _GLIBCXX20_CONSTEXPR
2035 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
2036 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
2038 template<typename _Alloc, typename _U1, typename _U2,
2039 _ImplicitCtor<true, const _U1&, const _U2&> = true>
2040 _GLIBCXX20_CONSTEXPR
2041 tuple(allocator_arg_t __tag, const _Alloc& __a,
2042 const tuple<_U1, _U2>& __in)
2043 : _Inherited(__tag, __a,
2044 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
2045 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
2047 template<typename _Alloc, typename _U1, typename _U2,
2048 _ExplicitCtor<true, const _U1&, const _U2&> = false>
2050 _GLIBCXX20_CONSTEXPR
2051 tuple(allocator_arg_t __tag, const _Alloc& __a,
2052 const tuple<_U1, _U2>& __in)
2053 : _Inherited(__tag, __a,
2054 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
2055 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
2057 template<typename _Alloc, typename _U1, typename _U2,
2058 _ImplicitCtor<true, _U1, _U2> = true>
2059 _GLIBCXX20_CONSTEXPR
2060 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
2061 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
2062 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2064 template<typename _Alloc, typename _U1, typename _U2,
2065 _ExplicitCtor<true, _U1, _U2> = false>
2067 _GLIBCXX20_CONSTEXPR
2068 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
2069 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
2070 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2072 template<typename _Alloc, typename _U1, typename _U2,
2073 _ImplicitCtor<true, const _U1&, const _U2&> = true>
2074 _GLIBCXX20_CONSTEXPR
2075 tuple(allocator_arg_t __tag, const _Alloc& __a,
2076 const pair<_U1, _U2>& __in)
2077 : _Inherited(__tag, __a, __in.first, __in.second)
2078 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
2080 template<typename _Alloc, typename _U1, typename _U2,
2081 _ExplicitCtor<true, const _U1&, const _U2&> = false>
2083 _GLIBCXX20_CONSTEXPR
2084 tuple(allocator_arg_t __tag, const _Alloc& __a,
2085 const pair<_U1, _U2>& __in)
2086 : _Inherited(__tag, __a, __in.first, __in.second)
2087 { __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
2089 template<typename _Alloc, typename _U1, typename _U2,
2090 _ImplicitCtor<true, _U1, _U2> = true>
2091 _GLIBCXX20_CONSTEXPR
2092 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
2093 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
2094 std::forward<_U2>(__in.second))
2095 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2097 template<typename _Alloc, typename _U1, typename _U2,
2098 _ExplicitCtor<true, _U1, _U2> = false>
2100 _GLIBCXX20_CONSTEXPR
2101 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
2102 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
2103 std::forward<_U2>(__in.second))
2104 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2106 // Tuple assignment.
2108 _GLIBCXX20_CONSTEXPR
2110 operator=(__conditional_t<__assignable<const _T1&, const _T2&>(),
2112 const __nonesuch&> __in)
2113 noexcept(__nothrow_assignable<const _T1&, const _T2&>())
2115 this->_M_assign(__in);
2119 _GLIBCXX20_CONSTEXPR
2121 operator=(__conditional_t<__assignable<_T1, _T2>(),
2124 noexcept(__nothrow_assignable<_T1, _T2>())
2126 this->_M_assign(std::move(__in));
2130 template<typename _U1, typename _U2>
2131 _GLIBCXX20_CONSTEXPR
2132 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
2133 operator=(const tuple<_U1, _U2>& __in)
2134 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
2136 this->_M_assign(__in);
2140 template<typename _U1, typename _U2>
2141 _GLIBCXX20_CONSTEXPR
2142 __enable_if_t<__assignable<_U1, _U2>(), tuple&>
2143 operator=(tuple<_U1, _U2>&& __in)
2144 noexcept(__nothrow_assignable<_U1, _U2>())
2146 this->_M_assign(std::move(__in));
2150 template<typename _U1, typename _U2>
2151 _GLIBCXX20_CONSTEXPR
2152 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
2153 operator=(const pair<_U1, _U2>& __in)
2154 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
2156 this->_M_head(*this) = __in.first;
2157 this->_M_tail(*this)._M_head(*this) = __in.second;
2161 template<typename _U1, typename _U2>
2162 _GLIBCXX20_CONSTEXPR
2163 __enable_if_t<__assignable<_U1, _U2>(), tuple&>
2164 operator=(pair<_U1, _U2>&& __in)
2165 noexcept(__nothrow_assignable<_U1, _U2>())
2167 this->_M_head(*this) = std::forward<_U1>(__in.first);
2168 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
2172 _GLIBCXX20_CONSTEXPR
2175 noexcept(__and_<__is_nothrow_swappable<_T1>,
2176 __is_nothrow_swappable<_T2>>::value)
2177 { _Inherited::_M_swap(__in); }
2179#endif // concepts && conditional_explicit
2181 /// class tuple_size
2182 template<typename... _Elements>
2183 struct tuple_size<tuple<_Elements...>>
2184 : public integral_constant<size_t, sizeof...(_Elements)> { };
2186#if __cplusplus >= 201703L
2187 template<typename... _Types>
2188 inline constexpr size_t tuple_size_v<tuple<_Types...>>
2189 = sizeof...(_Types);
2191 template<typename... _Types>
2192 inline constexpr size_t tuple_size_v<const tuple<_Types...>>
2193 = sizeof...(_Types);
2196 /// Trait to get the Ith element type from a tuple.
2197 template<size_t __i, typename... _Types>
2198 struct tuple_element<__i, tuple<_Types...>>
2200 static_assert(__i < sizeof...(_Types), "tuple index must be in range");
2202 using type = typename _Nth_type<__i, _Types...>::type;
2205 template<size_t __i, typename _Head, typename... _Tail>
2207 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
2208 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
2210 template<size_t __i, typename _Head, typename... _Tail>
2211 constexpr const _Head&
2212 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
2213 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
2215 // Deleted overload to improve diagnostics for invalid indices
2216 template<size_t __i, typename... _Types>
2217 __enable_if_t<(__i >= sizeof...(_Types))>
2218 __get_helper(const tuple<_Types...>&) = delete;
2220 /// Return a reference to the ith element of a tuple.
2221 template<size_t __i, typename... _Elements>
2222 constexpr __tuple_element_t<__i, tuple<_Elements...>>&
2223 get(tuple<_Elements...>& __t) noexcept
2224 { return std::__get_helper<__i>(__t); }
2226 /// Return a const reference to the ith element of a const tuple.
2227 template<size_t __i, typename... _Elements>
2228 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
2229 get(const tuple<_Elements...>& __t) noexcept
2230 { return std::__get_helper<__i>(__t); }
2232 /// Return an rvalue reference to the ith element of a tuple rvalue.
2233 template<size_t __i, typename... _Elements>
2234 constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
2235 get(tuple<_Elements...>&& __t) noexcept
2237 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
2238 return std::forward<__element_type>(std::__get_helper<__i>(__t));
2241 /// Return a const rvalue reference to the ith element of a const tuple rvalue.
2242 template<size_t __i, typename... _Elements>
2243 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
2244 get(const tuple<_Elements...>&& __t) noexcept
2246 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
2247 return std::forward<const __element_type>(std::__get_helper<__i>(__t));
2250 /// @cond undocumented
2251 // Deleted overload chosen for invalid indices.
2252 template<size_t __i, typename... _Elements>
2253 constexpr __enable_if_t<(__i >= sizeof...(_Elements))>
2254 get(const tuple<_Elements...>&) = delete;
2257#ifdef __cpp_lib_tuples_by_type // C++ >= 14
2258 /// Return a reference to the unique element of type _Tp of a tuple.
2259 template <typename _Tp, typename... _Types>
2261 get(tuple<_Types...>& __t) noexcept
2263 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
2264 static_assert(__idx < sizeof...(_Types),
2265 "the type T in std::get<T> must occur exactly once in the tuple");
2266 return std::__get_helper<__idx>(__t);
2269 /// Return a reference to the unique element of type _Tp of a tuple rvalue.
2270 template <typename _Tp, typename... _Types>
2272 get(tuple<_Types...>&& __t) noexcept
2274 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
2275 static_assert(__idx < sizeof...(_Types),
2276 "the type T in std::get<T> must occur exactly once in the tuple");
2277 return std::forward<_Tp>(std::__get_helper<__idx>(__t));
2280 /// Return a const reference to the unique element of type _Tp of a tuple.
2281 template <typename _Tp, typename... _Types>
2282 constexpr const _Tp&
2283 get(const tuple<_Types...>& __t) noexcept
2285 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
2286 static_assert(__idx < sizeof...(_Types),
2287 "the type T in std::get<T> must occur exactly once in the tuple");
2288 return std::__get_helper<__idx>(__t);
2291 /// Return a const reference to the unique element of type _Tp of
2292 /// a const tuple rvalue.
2293 template <typename _Tp, typename... _Types>
2294 constexpr const _Tp&&
2295 get(const tuple<_Types...>&& __t) noexcept
2297 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
2298 static_assert(__idx < sizeof...(_Types),
2299 "the type T in std::get<T> must occur exactly once in the tuple");
2300 return std::forward<const _Tp>(std::__get_helper<__idx>(__t));
2304 // This class performs the comparison operations on tuples
2305 template<typename _Tp, typename _Up, size_t __i, size_t __size>
2306 struct __tuple_compare
2308 static constexpr bool
2309 __eq(const _Tp& __t, const _Up& __u)
2311 return bool(std::get<__i>(__t) == std::get<__i>(__u))
2312 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
2315 static constexpr bool
2316 __less(const _Tp& __t, const _Up& __u)
2318 return bool(std::get<__i>(__t) < std::get<__i>(__u))
2319 || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
2320 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
2324 template<typename _Tp, typename _Up, size_t __size>
2325 struct __tuple_compare<_Tp, _Up, __size, __size>
2327 static constexpr bool
2328 __eq(const _Tp&, const _Up&) { return true; }
2330 static constexpr bool
2331 __less(const _Tp&, const _Up&) { return false; }
2334 template<typename... _TElements, typename... _UElements>
2336 operator==(const tuple<_TElements...>& __t,
2337 const tuple<_UElements...>& __u)
2339 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
2340 "tuple objects can only be compared if they have equal sizes.");
2341 using __compare = __tuple_compare<tuple<_TElements...>,
2342 tuple<_UElements...>,
2343 0, sizeof...(_TElements)>;
2344 return __compare::__eq(__t, __u);
2347#if __cpp_lib_three_way_comparison
2348 template<typename _Cat, typename _Tp, typename _Up>
2350 __tuple_cmp(const _Tp&, const _Up&, index_sequence<>)
2351 { return _Cat::equivalent; }
2353 template<typename _Cat, typename _Tp, typename _Up,
2354 size_t _Idx0, size_t... _Idxs>
2356 __tuple_cmp(const _Tp& __t, const _Up& __u,
2357 index_sequence<_Idx0, _Idxs...>)
2360 = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u));
2363 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>());
2366 template<typename... _Tps, typename... _Ups>
2368 common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
2369 operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
2372 = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
2373 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
2376 template<typename... _TElements, typename... _UElements>
2378 operator<(const tuple<_TElements...>& __t,
2379 const tuple<_UElements...>& __u)
2381 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
2382 "tuple objects can only be compared if they have equal sizes.");
2383 using __compare = __tuple_compare<tuple<_TElements...>,
2384 tuple<_UElements...>,
2385 0, sizeof...(_TElements)>;
2386 return __compare::__less(__t, __u);
2389 template<typename... _TElements, typename... _UElements>
2391 operator!=(const tuple<_TElements...>& __t,
2392 const tuple<_UElements...>& __u)
2393 { return !(__t == __u); }
2395 template<typename... _TElements, typename... _UElements>
2397 operator>(const tuple<_TElements...>& __t,
2398 const tuple<_UElements...>& __u)
2399 { return __u < __t; }
2401 template<typename... _TElements, typename... _UElements>
2403 operator<=(const tuple<_TElements...>& __t,
2404 const tuple<_UElements...>& __u)
2405 { return !(__u < __t); }
2407 template<typename... _TElements, typename... _UElements>
2409 operator>=(const tuple<_TElements...>& __t,
2410 const tuple<_UElements...>& __u)
2411 { return !(__t < __u); }
2412#endif // three_way_comparison
2415 /// Create a tuple containing copies of the arguments
2416 template<typename... _Elements>
2417 constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
2418 make_tuple(_Elements&&... __args)
2420 typedef tuple<typename __decay_and_strip<_Elements>::__type...>
2422 return __result_type(std::forward<_Elements>(__args)...);
2425 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2426 // 2275. Why is forward_as_tuple not constexpr?
2427 /// Create a tuple of lvalue or rvalue references to the arguments
2428 template<typename... _Elements>
2429 constexpr tuple<_Elements&&...>
2430 forward_as_tuple(_Elements&&... __args) noexcept
2431 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
2433 // Declarations of std::array and its std::get overloads, so that
2434 // std::tuple_cat can use them if <tuple> is included before <array>.
2436 template<typename _Tp, size_t _Nm> struct array;
2438 template<size_t _Int, typename _Tp, size_t _Nm>
2440 get(array<_Tp, _Nm>&) noexcept;
2442 template<size_t _Int, typename _Tp, size_t _Nm>
2444 get(array<_Tp, _Nm>&&) noexcept;
2446 template<size_t _Int, typename _Tp, size_t _Nm>
2447 constexpr const _Tp&
2448 get(const array<_Tp, _Nm>&) noexcept;
2450 template<size_t _Int, typename _Tp, size_t _Nm>
2451 constexpr const _Tp&&
2452 get(const array<_Tp, _Nm>&&) noexcept;
2454 /// @cond undocumented
2455 template<size_t, typename, typename, size_t>
2456 struct __make_tuple_impl;
2458 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
2459 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
2460 : __make_tuple_impl<_Idx + 1,
2461 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
2465 template<size_t _Nm, typename _Tuple, typename... _Tp>
2466 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
2468 typedef tuple<_Tp...> __type;
2471 template<typename _Tuple>
2472 struct __do_make_tuple
2473 : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value>
2476 // Returns the std::tuple equivalent of a tuple-like type.
2477 template<typename _Tuple>
2479 : public __do_make_tuple<__remove_cvref_t<_Tuple>>
2482 // Combines several std::tuple's into a single one.
2483 template<typename...>
2484 struct __combine_tuples;
2487 struct __combine_tuples<>
2489 typedef tuple<> __type;
2492 template<typename... _Ts>
2493 struct __combine_tuples<tuple<_Ts...>>
2495 typedef tuple<_Ts...> __type;
2498 template<typename... _T1s, typename... _T2s, typename... _Rem>
2499 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
2501 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
2502 _Rem...>::__type __type;
2505 // Computes the result type of tuple_cat given a set of tuple-like types.
2506 template<typename... _Tpls>
2507 struct __tuple_cat_result
2509 typedef typename __combine_tuples
2510 <typename __make_tuple<_Tpls>::__type...>::__type __type;
2513 // Helper to determine the index set for the first tuple-like
2514 // type of a given set.
2515 template<typename...>
2516 struct __make_1st_indices;
2519 struct __make_1st_indices<>
2521 typedef _Index_tuple<> __type;
2524 template<typename _Tp, typename... _Tpls>
2525 struct __make_1st_indices<_Tp, _Tpls...>
2527 typedef typename _Build_index_tuple<tuple_size<
2528 typename remove_reference<_Tp>::type>::value>::__type __type;
2531 // Performs the actual concatenation by step-wise expanding tuple-like
2532 // objects into the elements, which are finally forwarded into the
2534 template<typename _Ret, typename _Indices, typename... _Tpls>
2535 struct __tuple_concater;
2537 template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls>
2538 struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...>
2540 template<typename... _Us>
2541 static constexpr _Ret
2542 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
2544 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
2545 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
2546 return __next::_S_do(std::forward<_Tpls>(__tps)...,
2547 std::forward<_Us>(__us)...,
2548 std::get<_Is>(std::forward<_Tp>(__tp))...);
2552 template<typename _Ret>
2553 struct __tuple_concater<_Ret, _Index_tuple<>>
2555 template<typename... _Us>
2556 static constexpr _Ret
2557 _S_do(_Us&&... __us)
2559 return _Ret(std::forward<_Us>(__us)...);
2563 template<typename... _Tps>
2564 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
2568 /// Create a `tuple` containing all elements from multiple tuple-like objects
2569 template<typename... _Tpls, typename = typename
2570 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
2572 tuple_cat(_Tpls&&... __tpls)
2573 -> typename __tuple_cat_result<_Tpls...>::__type
2575 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
2576 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
2577 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
2578 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
2581 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2582 // 2301. Why is tie not constexpr?
2583 /// Return a tuple of lvalue references bound to the arguments
2584 template<typename... _Elements>
2585 constexpr tuple<_Elements&...>
2586 tie(_Elements&... __args) noexcept
2587 { return tuple<_Elements&...>(__args...); }
2589 /// Exchange the values of two tuples
2590 template<typename... _Elements>
2591 _GLIBCXX20_CONSTEXPR
2593#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
2594 // Constrained free swap overload, see p0185r1
2595 typename enable_if<__and_<__is_swappable<_Elements>...>::value
2600 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
2601 noexcept(noexcept(__x.swap(__y)))
2604#if __cpp_lib_ranges_zip // >= C++23
2605 template<typename... _Elements>
2606 requires (is_swappable_v<const _Elements> && ...)
2608 swap(const tuple<_Elements...>& __x, const tuple<_Elements...>& __y)
2609 noexcept(noexcept(__x.swap(__y)))
2613#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
2614 /// Exchange the values of two const tuples (if const elements can be swapped)
2615 template<typename... _Elements>
2616 _GLIBCXX20_CONSTEXPR
2617 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
2618 swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
2621 // A class (and instance) which can be used in 'tie' when an element
2622 // of a tuple is not required.
2623 // _GLIBCXX14_CONSTEXPR
2624 // 2933. PR for LWG 2773 could be clearer
2625 struct _Swallow_assign
2628 _GLIBCXX14_CONSTEXPR const _Swallow_assign&
2629 operator=(const _Tp&) const
2633 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2634 // 2773. Making std::ignore constexpr
2635 /** Used with `std::tie` to ignore an element of a tuple
2637 * When using `std::tie` to assign the elements of a tuple to variables,
2638 * unwanted elements can be ignored by using `std::ignore`. For example:
2642 * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3);
2645 * This assignment will perform `x=1; std::ignore=2; y=3;` which results
2646 * in the second element being ignored.
2650 _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
2652 /// Partial specialization for tuples
2653 template<typename... _Types, typename _Alloc>
2654 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
2656 // See stl_pair.h...
2657 /** "piecewise construction" using a tuple of arguments for each member.
2659 * @param __first Arguments for the first member of the pair.
2660 * @param __second Arguments for the second member of the pair.
2662 * The elements of each tuple will be used as the constructor arguments
2663 * for the data members of the pair.
2665 template<class _T1, class _T2>
2666 template<typename... _Args1, typename... _Args2>
2667 _GLIBCXX20_CONSTEXPR
2670 pair(piecewise_construct_t,
2671 tuple<_Args1...> __first, tuple<_Args2...> __second)
2672 : pair(__first, __second,
2673 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
2674 typename _Build_index_tuple<sizeof...(_Args2)>::__type())
2677 template<class _T1, class _T2>
2678 template<typename... _Args1, size_t... _Indexes1,
2679 typename... _Args2, size_t... _Indexes2>
2680 _GLIBCXX20_CONSTEXPR inline
2682 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
2683 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
2684 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
2685 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
2688#if defined(__cpp_lib_apply) || defined(__cpp_lib_make_from_tuple) // C++ >= 17
2689 // Unpack a std::tuple into a type trait and use its value.
2690 // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
2691 // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
2692 // Otherwise the result is false (because we don't know if std::get throws).
2693 template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
2694 inline constexpr bool __unpack_std_tuple = false;
2696 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
2697 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
2698 = _Trait<_Tp, _Up...>::value;
2700 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
2701 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
2702 = _Trait<_Tp, _Up&...>::value;
2704 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
2705 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
2706 = _Trait<_Tp, const _Up...>::value;
2708 template<template<typename...> class _Trait, typename _Tp, typename... _Up>
2709 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
2710 = _Trait<_Tp, const _Up&...>::value;
2713#ifdef __cpp_lib_apply // C++ >= 17
2714 template <typename _Fn, typename _Tuple, size_t... _Idx>
2715 constexpr decltype(auto)
2716 __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
2718 return std::__invoke(std::forward<_Fn>(__f),
2719 std::get<_Idx>(std::forward<_Tuple>(__t))...);
2722 template <typename _Fn, typename _Tuple>
2723 constexpr decltype(auto)
2724 apply(_Fn&& __f, _Tuple&& __t)
2725 noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
2728 = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
2729 return std::__apply_impl(std::forward<_Fn>(__f),
2730 std::forward<_Tuple>(__t),
2735#ifdef __cpp_lib_make_from_tuple // C++ >= 17
2736 template <typename _Tp, typename _Tuple, size_t... _Idx>
2738 __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
2739 { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
2741 template <typename _Tp, typename _Tuple>
2743 make_from_tuple(_Tuple&& __t)
2744 noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
2746 constexpr size_t __n = tuple_size_v<remove_reference_t<_Tuple>>;
2747#if __has_builtin(__reference_constructs_from_temporary)
2748 if constexpr (__n == 1)
2750 using _Elt = decltype(std::get<0>(std::declval<_Tuple>()));
2751 static_assert(!__reference_constructs_from_temporary(_Tp, _Elt));
2754 return __make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
2755 make_index_sequence<__n>{});
2759#if __cpp_lib_ranges_zip // >= C++23
2760 template<typename... _TTypes, typename... _UTypes,
2761 template<typename> class _TQual, template<typename> class _UQual>
2762 requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }
2763 struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual>
2764 { using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; };
2766 template<typename... _TTypes, typename... _UTypes>
2767 requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; }
2768 struct common_type<tuple<_TTypes...>, tuple<_UTypes...>>
2769 { using type = tuple<common_type_t<_TTypes, _UTypes>...>; };
2774#undef __glibcxx_no_dangling_refs
2776_GLIBCXX_END_NAMESPACE_VERSION
2781#endif // _GLIBCXX_TUPLE