29 #ifndef _GLIBCXX_TUPLE
30 #define _GLIBCXX_TUPLE 1
32 #ifdef _GLIBCXX_SYSHDR
33 #pragma GCC system_header
36 #if __cplusplus < 201103L
41 #include <bits/uses_allocator.h>
44 #if __cplusplus > 201703L
49 #define __glibcxx_want_constexpr_tuple
50 #define __glibcxx_want_tuple_element_t
51 #define __glibcxx_want_tuples_by_type
52 #define __glibcxx_want_apply
53 #define __glibcxx_want_make_from_tuple
54 #define __glibcxx_want_ranges_zip
55 #define __glibcxx_want_tuple_like
56 #define __glibcxx_want_constrained_equality
59 namespace std _GLIBCXX_VISIBILITY(default)
61 _GLIBCXX_BEGIN_NAMESPACE_VERSION
68 template<
typename... _Elements>
72 template<
typename _Tp>
73 struct __is_empty_non_tuple :
is_empty<_Tp> { };
76 template<
typename _El0,
typename... _El>
80 template<
typename _Tp>
81 using __empty_not_final
83 __is_empty_non_tuple<_Tp>>;
85 template<
size_t _Idx,
typename _Head,
86 bool = __empty_not_final<_Head>::value>
89 #if __has_cpp_attribute(__no_unique_address__)
90 template<
size_t _Idx,
typename _Head>
91 struct _Head_base<_Idx, _Head, true>
93 constexpr _Head_base()
96 constexpr _Head_base(
const _Head& __h)
97 : _M_head_impl(__h) { }
99 constexpr _Head_base(
const _Head_base&) =
default;
100 constexpr _Head_base(_Head_base&&) =
default;
102 template<
typename _UHead>
103 constexpr _Head_base(_UHead&& __h)
107 _Head_base(allocator_arg_t, __uses_alloc0)
110 template<
typename _Alloc>
112 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
113 : _M_head_impl(allocator_arg, *__a._M_a) { }
115 template<
typename _Alloc>
117 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
118 : _M_head_impl(*__a._M_a) { }
120 template<
typename _UHead>
122 _Head_base(__uses_alloc0, _UHead&& __uhead)
123 : _M_head_impl(
std::
forward<_UHead>(__uhead)) { }
125 template<
typename _Alloc,
typename _UHead>
127 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
128 : _M_head_impl(allocator_arg, *__a._M_a,
std::
forward<_UHead>(__uhead))
131 template<
typename _Alloc,
typename _UHead>
133 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
134 : _M_head_impl(
std::
forward<_UHead>(__uhead), *__a._M_a) { }
136 static constexpr _Head&
137 _M_head(_Head_base& __b) noexcept {
return __b._M_head_impl; }
139 static constexpr
const _Head&
140 _M_head(
const _Head_base& __b) noexcept {
return __b._M_head_impl; }
142 [[__no_unique_address__]] _Head _M_head_impl;
145 template<
size_t _Idx,
typename _Head>
146 struct _Head_base<_Idx, _Head, true>
149 constexpr _Head_base()
152 constexpr _Head_base(
const _Head& __h)
155 constexpr _Head_base(
const _Head_base&) =
default;
156 constexpr _Head_base(_Head_base&&) =
default;
158 template<
typename _UHead>
159 constexpr _Head_base(_UHead&& __h)
163 _Head_base(allocator_arg_t, __uses_alloc0)
166 template<
typename _Alloc>
168 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
169 : _Head(allocator_arg, *__a._M_a) { }
171 template<
typename _Alloc>
173 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
174 : _Head(*__a._M_a) { }
176 template<
typename _UHead>
178 _Head_base(__uses_alloc0, _UHead&& __uhead)
181 template<
typename _Alloc,
typename _UHead>
183 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
184 : _Head(allocator_arg, *__a._M_a,
std::
forward<_UHead>(__uhead)) { }
186 template<
typename _Alloc,
typename _UHead>
188 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
189 : _Head(
std::
forward<_UHead>(__uhead), *__a._M_a) { }
191 static constexpr _Head&
192 _M_head(_Head_base& __b) noexcept {
return __b; }
194 static constexpr
const _Head&
195 _M_head(
const _Head_base& __b) noexcept {
return __b; }
199 template<
size_t _Idx,
typename _Head>
200 struct _Head_base<_Idx, _Head, false>
202 constexpr _Head_base()
205 constexpr _Head_base(
const _Head& __h)
206 : _M_head_impl(__h) { }
208 constexpr _Head_base(
const _Head_base&) =
default;
209 constexpr _Head_base(_Head_base&&) =
default;
211 template<
typename _UHead>
212 constexpr _Head_base(_UHead&& __h)
216 _Head_base(allocator_arg_t, __uses_alloc0)
219 template<
typename _Alloc>
221 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
222 : _M_head_impl(allocator_arg, *__a._M_a) { }
224 template<
typename _Alloc>
226 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
227 : _M_head_impl(*__a._M_a) { }
229 template<
typename _UHead>
231 _Head_base(__uses_alloc0, _UHead&& __uhead)
232 : _M_head_impl(
std::
forward<_UHead>(__uhead)) { }
234 template<
typename _Alloc,
typename _UHead>
236 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
237 : _M_head_impl(allocator_arg, *__a._M_a,
std::
forward<_UHead>(__uhead))
240 template<
typename _Alloc,
typename _UHead>
242 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
243 : _M_head_impl(
std::
forward<_UHead>(__uhead), *__a._M_a) { }
245 static constexpr _Head&
246 _M_head(_Head_base& __b) noexcept {
return __b._M_head_impl; }
248 static constexpr
const _Head&
249 _M_head(
const _Head_base& __b) noexcept {
return __b._M_head_impl; }
254 #if __cpp_lib_tuple_like // >= C++23
255 struct __tuple_like_tag_t {
explicit __tuple_like_tag_t() =
default; };
259 template<
typename _Cat,
typename _Tp,
typename _Up,
typename _IndexSeq>
261 __tuple_cmp(
const _Tp& __t,
const _Up& __u, _IndexSeq);
272 template<
size_t _Idx,
typename... _Elements>
280 template<
size_t _Idx,
typename _Head,
typename... _Tail>
281 struct _Tuple_impl<_Idx, _Head, _Tail...>
282 :
public _Tuple_impl<_Idx + 1, _Tail...>,
283 private _Head_base<_Idx, _Head>
285 template<size_t,
typename...>
friend struct _Tuple_impl;
287 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
288 typedef _Head_base<_Idx, _Head> _Base;
290 static constexpr _Head&
291 _M_head(_Tuple_impl& __t) noexcept {
return _Base::_M_head(__t); }
293 static constexpr
const _Head&
294 _M_head(
const _Tuple_impl& __t) noexcept {
return _Base::_M_head(__t); }
296 static constexpr _Inherited&
297 _M_tail(_Tuple_impl& __t) noexcept {
return __t; }
299 static constexpr
const _Inherited&
300 _M_tail(
const _Tuple_impl& __t) noexcept {
return __t; }
302 constexpr _Tuple_impl()
303 : _Inherited(), _Base() { }
306 _Tuple_impl(
const _Head& __head,
const _Tail&... __tail)
307 : _Inherited(__tail...), _Base(__head)
310 template<
typename _UHead,
typename... _UTail,
311 typename = __enable_if_t<
sizeof...(_Tail) ==
sizeof...(_UTail)>>
313 _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
314 : _Inherited(
std::
forward<_UTail>(__tail)...),
318 constexpr _Tuple_impl(
const _Tuple_impl&) =
default;
322 _Tuple_impl& operator=(
const _Tuple_impl&) =
delete;
324 _Tuple_impl(_Tuple_impl&&) =
default;
326 template<
typename... _UElements>
328 _Tuple_impl(
const _Tuple_impl<_Idx, _UElements...>& __in)
329 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
330 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
333 template<
typename _UHead,
typename... _UTails>
335 _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
337 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
339 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
342 #if __cpp_lib_ranges_zip // >= C++23
343 template<
typename... _UElements>
345 _Tuple_impl(_Tuple_impl<_Idx, _UElements...>& __in)
346 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
347 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
350 template<
typename _UHead,
typename... _UTails>
352 _Tuple_impl(
const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
354 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
356 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
360 #if __cpp_lib_tuple_like // >= C++23
361 template<
typename _UTuple,
size_t... _Is>
363 _Tuple_impl(__tuple_like_tag_t, _UTuple&& __u, index_sequence<_Is...>)
368 template<
typename _Alloc>
370 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a)
371 : _Inherited(__tag, __a),
372 _Base(__tag, __use_alloc<_Head>(__a))
375 template<
typename _Alloc>
377 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a,
378 const _Head& __head,
const _Tail&... __tail)
379 : _Inherited(__tag, __a, __tail...),
380 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head)
383 template<
typename _Alloc,
typename _UHead,
typename... _UTail,
384 typename = __enable_if_t<
sizeof...(_Tail) ==
sizeof...(_UTail)>>
386 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a,
387 _UHead&& __head, _UTail&&... __tail)
388 : _Inherited(__tag, __a,
std::
forward<_UTail>(__tail)...),
389 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
393 template<
typename _Alloc>
395 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a,
396 const _Tuple_impl& __in)
397 : _Inherited(__tag, __a, _M_tail(__in)),
398 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in))
401 template<
typename _Alloc>
403 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a,
405 : _Inherited(__tag, __a,
std::
move(_M_tail(__in))),
406 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
410 template<
typename _Alloc,
typename _UHead,
typename... _UTails>
412 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a,
413 const _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
414 : _Inherited(__tag, __a,
415 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
416 _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
417 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
420 template<
typename _Alloc,
typename _UHead,
typename... _UTails>
422 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a,
423 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
424 : _Inherited(__tag, __a,
std::
move
425 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
426 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
428 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
431 #if __cpp_lib_ranges_zip // >= C++23
432 template<
typename _Alloc,
typename _UHead,
typename... _UTails>
434 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a,
435 _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
436 : _Inherited(__tag, __a,
437 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
438 _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
439 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
442 template<
typename _Alloc,
typename _UHead,
typename... _UTails>
444 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a,
445 const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
446 : _Inherited(__tag, __a,
std::
move
447 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
448 _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
450 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
454 #if __cpp_lib_tuple_like // >= C++23
455 template<
typename _Alloc,
typename _UTuple,
size_t... _Is>
457 _Tuple_impl(__tuple_like_tag_t, allocator_arg_t __tag,
const _Alloc& __a,
458 _UTuple&& __u, index_sequence<_Is...>)
459 : _Tuple_impl(__tag, __a,
std::get<_Is>(
std::
forward<_UTuple>(__u))...)
463 template<
typename... _UElements>
466 _M_assign(
const _Tuple_impl<_Idx, _UElements...>& __in)
468 _M_head(*
this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
469 _M_tail(*this)._M_assign(
470 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
473 template<
typename _UHead,
typename... _UTails>
476 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
478 _M_head(*
this) = std::forward<_UHead>
479 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
480 _M_tail(*this)._M_assign(
481 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
484 #if __cpp_lib_ranges_zip // >= C++23
485 template<
typename... _UElements>
487 _M_assign(
const _Tuple_impl<_Idx, _UElements...>& __in)
const
489 _M_head(*
this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
490 _M_tail(*this)._M_assign(
491 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
494 template<
typename _UHead,
typename... _UTails>
496 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
const
498 _M_head(*
this) = std::forward<_UHead>
499 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
500 _M_tail(*this)._M_assign(
501 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
505 #if __cpp_lib_tuple_like // >= C++23
506 template<
typename _UTuple>
508 _M_assign(__tuple_like_tag_t __tag, _UTuple&& __u)
510 _M_head(*
this) = std::get<_Idx>(std::forward<_UTuple>(__u));
511 _M_tail(*this)._M_assign(__tag, std::forward<_UTuple>(__u));
514 template<
typename _UTuple>
516 _M_assign(__tuple_like_tag_t __tag, _UTuple&& __u)
const
518 _M_head(*
this) = std::get<_Idx>(std::forward<_UTuple>(__u));
519 _M_tail(*this)._M_assign(__tag, std::forward<_UTuple>(__u));
526 _M_swap(_Tuple_impl& __in)
529 swap(_M_head(*
this), _M_head(__in));
530 _Inherited::_M_swap(_M_tail(__in));
533 #if __cpp_lib_ranges_zip // >= C++23
535 _M_swap(
const _Tuple_impl& __in)
const
538 swap(_M_head(*
this), _M_head(__in));
539 _Inherited::_M_swap(_M_tail(__in));
545 template<
size_t _Idx,
typename _Head>
546 struct _Tuple_impl<_Idx, _Head>
547 :
private _Head_base<_Idx, _Head>
549 template<size_t,
typename...>
friend struct _Tuple_impl;
551 typedef _Head_base<_Idx, _Head> _Base;
553 static constexpr _Head&
554 _M_head(_Tuple_impl& __t) noexcept {
return _Base::_M_head(__t); }
556 static constexpr
const _Head&
557 _M_head(
const _Tuple_impl& __t) noexcept {
return _Base::_M_head(__t); }
564 _Tuple_impl(
const _Head& __head)
568 template<
typename _UHead>
570 _Tuple_impl(_UHead&& __head)
574 constexpr _Tuple_impl(
const _Tuple_impl&) =
default;
578 _Tuple_impl& operator=(
const _Tuple_impl&) =
delete;
580 #if _GLIBCXX_INLINE_VERSION
581 _Tuple_impl(_Tuple_impl&&) =
default;
584 _Tuple_impl(_Tuple_impl&& __in)
585 noexcept(is_nothrow_move_constructible<_Head>::value)
586 : _Base(static_cast<_Base&&>(__in))
590 template<
typename _UHead>
592 _Tuple_impl(
const _Tuple_impl<_Idx, _UHead>& __in)
593 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
596 template<
typename _UHead>
598 _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
599 : _Base(
std::
forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
602 #if __cpp_lib_ranges_zip // >= C++23
603 template<
typename _UHead>
605 _Tuple_impl(_Tuple_impl<_Idx, _UHead>& __in)
606 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
609 template<
typename _UHead>
611 _Tuple_impl(
const _Tuple_impl<_Idx, _UHead>&& __in)
612 : _Base(
std::
forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
616 #if __cpp_lib_tuple_like // >= C++23
617 template<
typename _UTuple>
619 _Tuple_impl(__tuple_like_tag_t, _UTuple&& __u, index_sequence<0>)
624 template<
typename _Alloc>
626 _Tuple_impl(allocator_arg_t __tag,
const _Alloc& __a)
627 : _Base(__tag, __use_alloc<_Head>(__a))
630 template<
typename _Alloc>
632 _Tuple_impl(allocator_arg_t,
const _Alloc& __a,
634 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head)
637 template<
typename _Alloc,
typename _UHead>
639 _Tuple_impl(allocator_arg_t,
const _Alloc& __a,
641 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
645 template<
typename _Alloc>
647 _Tuple_impl(allocator_arg_t,
const _Alloc& __a,
648 const _Tuple_impl& __in)
649 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in))
652 template<
typename _Alloc>
654 _Tuple_impl(allocator_arg_t,
const _Alloc& __a,
656 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
660 template<
typename _Alloc,
typename _UHead>
662 _Tuple_impl(allocator_arg_t,
const _Alloc& __a,
663 const _Tuple_impl<_Idx, _UHead>& __in)
664 : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
665 _Tuple_impl<_Idx, _UHead>::_M_head(__in))
668 template<
typename _Alloc,
typename _UHead>
670 _Tuple_impl(allocator_arg_t,
const _Alloc& __a,
671 _Tuple_impl<_Idx, _UHead>&& __in)
672 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
673 std::
forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
676 #if __cpp_lib_ranges_zip // >= C++23
677 template<
typename _Alloc,
typename _UHead>
679 _Tuple_impl(allocator_arg_t,
const _Alloc& __a,
680 _Tuple_impl<_Idx, _UHead>& __in)
681 : _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
682 _Tuple_impl<_Idx, _UHead>::_M_head(__in))
685 template<
typename _Alloc,
typename _UHead>
687 _Tuple_impl(allocator_arg_t,
const _Alloc& __a,
688 const _Tuple_impl<_Idx, _UHead>&& __in)
689 : _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
690 std::
forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
694 #if __cpp_lib_tuple_like // >= C++23
695 template<
typename _Alloc,
typename _UTuple>
697 _Tuple_impl(__tuple_like_tag_t, allocator_arg_t __tag,
const _Alloc& __a,
698 _UTuple&& __u, index_sequence<0>)
699 : _Tuple_impl(__tag, __a,
std::get<0>(
std::
forward<_UTuple>(__u)))
703 template<
typename _UHead>
706 _M_assign(
const _Tuple_impl<_Idx, _UHead>& __in)
708 _M_head(*
this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
711 template<
typename _UHead>
714 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
717 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
720 #if __cpp_lib_ranges_zip // >= C++23
721 template<
typename _UHead>
723 _M_assign(
const _Tuple_impl<_Idx, _UHead>& __in)
const
725 _M_head(*
this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
728 template<
typename _UHead>
730 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
const
733 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
737 #if __cpp_lib_tuple_like // >= C++23
738 template<
typename _UTuple>
740 _M_assign(__tuple_like_tag_t, _UTuple&& __u)
741 { _M_head(*
this) = std::get<_Idx>(std::forward<_UTuple>(__u)); }
743 template<
typename _UTuple>
745 _M_assign(__tuple_like_tag_t, _UTuple&& __u)
const
746 { _M_head(*
this) = std::get<_Idx>(std::forward<_UTuple>(__u)); }
752 _M_swap(_Tuple_impl& __in)
755 swap(_M_head(*
this), _M_head(__in));
758 #if __cpp_lib_ranges_zip // >= C++23
760 _M_swap(
const _Tuple_impl& __in)
const
763 swap(_M_head(*
this), _M_head(__in));
770 template<bool,
typename... _Types>
771 struct _TupleConstraints
773 template<
typename... _UTypes>
774 using __constructible = __and_<is_constructible<_Types, _UTypes>...>;
776 template<
typename... _UTypes>
777 using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
782 template<
typename... _UTypes>
783 static constexpr
bool __is_implicitly_constructible()
785 return __and_<__constructible<_UTypes...>,
786 __convertible<_UTypes...>
793 template<
typename... _UTypes>
794 static constexpr
bool __is_explicitly_constructible()
796 return __and_<__constructible<_UTypes...>,
797 __not_<__convertible<_UTypes...>>
801 static constexpr
bool __is_implicitly_default_constructible()
803 return __and_<std::__is_implicitly_default_constructible<_Types>...
807 static constexpr
bool __is_explicitly_default_constructible()
809 return __and_<is_default_constructible<_Types>...,
811 std::__is_implicitly_default_constructible<_Types>...>
818 template<
typename... _Types>
819 struct _TupleConstraints<false, _Types...>
821 template<
typename... _UTypes>
822 static constexpr
bool __is_implicitly_constructible()
825 template<
typename... _UTypes>
826 static constexpr
bool __is_explicitly_constructible()
832 template<
typename... _Elements>
833 class tuple :
public _Tuple_impl<0, _Elements...>
835 using _Inherited = _Tuple_impl<0, _Elements...>;
837 #if __cpp_concepts && __cpp_consteval && __cpp_conditional_explicit // >= C++20
838 template<
typename... _UTypes>
839 static consteval
bool
842 if constexpr (
sizeof...(_UTypes) ==
sizeof...(_Elements))
843 return __and_v<is_constructible<_Elements, _UTypes>...>;
848 template<
typename... _UTypes>
849 static consteval
bool
850 __nothrow_constructible()
852 if constexpr (
sizeof...(_UTypes) ==
sizeof...(_Elements))
853 return __and_v<is_nothrow_constructible<_Elements, _UTypes>...>;
858 template<
typename... _UTypes>
859 static consteval
bool
862 if constexpr (
sizeof...(_UTypes) ==
sizeof...(_Elements))
863 return __and_v<is_convertible<_UTypes, _Elements>...>;
870 template<
typename... _UTypes>
871 static consteval
bool
872 __disambiguating_constraint()
874 if constexpr (
sizeof...(_Elements) !=
sizeof...(_UTypes))
876 else if constexpr (
sizeof...(_Elements) == 1)
878 using _U0 =
typename _Nth_type<0, _UTypes...>::type;
879 return !is_same_v<remove_cvref_t<_U0>, tuple>;
881 else if constexpr (
sizeof...(_Elements) < 4)
883 using _U0 =
typename _Nth_type<0, _UTypes...>::type;
884 if constexpr (!is_same_v<remove_cvref_t<_U0>, allocator_arg_t>)
888 using _T0 =
typename _Nth_type<0, _Elements...>::type;
889 return is_same_v<remove_cvref_t<_T0>, allocator_arg_t>;
898 template<
typename _Tuple>
899 static consteval
bool
902 if constexpr (
sizeof...(_Elements) != 1)
904 else if constexpr (is_same_v<remove_cvref_t<_Tuple>, tuple>)
908 using _Tp =
typename _Nth_type<0, _Elements...>::type;
909 if constexpr (is_convertible_v<_Tuple, _Tp>)
911 else if constexpr (is_constructible_v<_Tp, _Tuple>)
917 template<
typename... _Up>
918 static consteval
bool
921 #if __has_builtin(__reference_constructs_from_temporary)
922 return (__reference_constructs_from_temporary(_Elements, _Up&&)
929 #if __cpp_lib_tuple_like // >= C++23
932 template<
typename _UTuple>
933 static consteval
bool
934 __dangles_from_tuple_like()
937 return __dangles<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
941 template<
typename _UTuple>
942 static consteval
bool
943 __constructible_from_tuple_like()
946 return __constructible<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
950 template<
typename _UTuple>
951 static consteval
bool
952 __convertible_from_tuple_like()
955 return __convertible<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
962 explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...))
964 noexcept((is_nothrow_default_constructible_v<_Elements> && ...))
965 requires (is_default_constructible_v<_Elements> && ...)
970 template<
typename =
void>
971 constexpr
explicit(!__convertible<
const _Elements&...>())
972 tuple(const type_identity_t<_Elements>&... __elements)
973 noexcept(__nothrow_constructible<const _Elements&...>())
974 requires (__constructible<const _Elements&...>())
975 : _Inherited(__elements...)
978 template<
typename... _UTypes>
979 requires (__disambiguating_constraint<_UTypes...>())
980 && (__constructible<_UTypes...>())
981 && (!__dangles<_UTypes...>())
982 constexpr
explicit(!__convertible<_UTypes...>())
983 tuple(_UTypes&&... __u)
984 noexcept(__nothrow_constructible<_UTypes...>())
988 template<
typename... _UTypes>
989 requires (__disambiguating_constraint<_UTypes...>())
990 && (__constructible<_UTypes...>())
991 && (__dangles<_UTypes...>())
992 tuple(_UTypes&&...) =
delete;
994 constexpr tuple(
const tuple&) =
default;
996 constexpr tuple(tuple&&) =
default;
998 template<
typename... _UTypes>
999 requires (__constructible<const _UTypes&...>())
1000 && (!__use_other_ctor<
const tuple<_UTypes...>&>())
1001 && (!__dangles<
const _UTypes&...>())
1002 constexpr
explicit(!__convertible<
const _UTypes&...>())
1003 tuple(const tuple<_UTypes...>& __u)
1004 noexcept(__nothrow_constructible<const _UTypes&...>())
1005 : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&>(__u))
1008 template<
typename... _UTypes>
1009 requires (__constructible<const _UTypes&...>())
1010 && (!__use_other_ctor<
const tuple<_UTypes...>&>())
1011 && (__dangles<
const _UTypes&...>())
1012 tuple(
const tuple<_UTypes...>&) =
delete;
1014 template<
typename... _UTypes>
1015 requires (__constructible<_UTypes...>())
1016 && (!__use_other_ctor<tuple<_UTypes...>>())
1017 && (!__dangles<_UTypes...>())
1018 constexpr
explicit(!__convertible<_UTypes...>())
1019 tuple(tuple<_UTypes...>&& __u)
1020 noexcept(__nothrow_constructible<_UTypes...>())
1021 : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&&>(__u))
1024 template<
typename... _UTypes>
1025 requires (__constructible<_UTypes...>())
1026 && (!__use_other_ctor<tuple<_UTypes...>>())
1027 && (__dangles<_UTypes...>())
1028 tuple(tuple<_UTypes...>&&) =
delete;
1030 #if __cpp_lib_ranges_zip // >= C++23
1031 template<
typename... _UTypes>
1032 requires (__constructible<_UTypes&...>())
1033 && (!__use_other_ctor<tuple<_UTypes...>&>())
1034 && (!__dangles<_UTypes&...>())
1035 constexpr
explicit(!__convertible<_UTypes&...>())
1036 tuple(tuple<_UTypes...>& __u)
1037 noexcept(__nothrow_constructible<_UTypes&...>())
1038 : _Inherited(static_cast<_Tuple_impl<0, _UTypes...>&>(__u))
1041 template<
typename... _UTypes>
1042 requires (__constructible<_UTypes&...>())
1043 && (!__use_other_ctor<tuple<_UTypes...>&>())
1044 && (__dangles<_UTypes&...>())
1045 tuple(tuple<_UTypes...>&) =
delete;
1047 template<
typename... _UTypes>
1048 requires (__constructible<const _UTypes...>())
1049 && (!__use_other_ctor<
const tuple<_UTypes...>>())
1050 && (!__dangles<
const _UTypes...>())
1051 constexpr
explicit(!__convertible<
const _UTypes...>())
1052 tuple(const tuple<_UTypes...>&& __u)
1053 noexcept(__nothrow_constructible<const _UTypes...>())
1054 : _Inherited(static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u))
1057 template<
typename... _UTypes>
1058 requires (__constructible<const _UTypes...>())
1059 && (!__use_other_ctor<
const tuple<_UTypes...>>())
1060 && (__dangles<
const _UTypes...>())
1061 tuple(
const tuple<_UTypes...>&&) =
delete;
1064 template<
typename _U1,
typename _U2>
1065 requires (
sizeof...(_Elements) == 2)
1066 && (__constructible<const _U1&, const _U2&>())
1067 && (!__dangles<const _U1&, const _U2&>())
1068 constexpr
explicit(!__convertible<const _U1&, const _U2&>())
1069 tuple(
const pair<_U1, _U2>& __u)
1070 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1071 : _Inherited(__u.first, __u.second)
1074 template<
typename _U1,
typename _U2>
1075 requires (
sizeof...(_Elements) == 2)
1076 && (__constructible<const _U1&, const _U2&>())
1077 && (__dangles<const _U1&, const _U2&>())
1078 tuple(
const pair<_U1, _U2>&) =
delete;
1080 template<
typename _U1,
typename _U2>
1081 requires (
sizeof...(_Elements) == 2)
1082 && (__constructible<_U1, _U2>())
1083 && (!__dangles<_U1, _U2>())
1084 constexpr
explicit(!__convertible<_U1, _U2>())
1085 tuple(pair<_U1, _U2>&& __u)
1086 noexcept(__nothrow_constructible<_U1, _U2>())
1091 template<
typename _U1,
typename _U2>
1092 requires (
sizeof...(_Elements) == 2)
1093 && (__constructible<_U1, _U2>())
1094 && (__dangles<_U1, _U2>())
1095 tuple(pair<_U1, _U2>&&) =
delete;
1097 #if __cpp_lib_ranges_zip // >= C++23
1098 template<
typename _U1,
typename _U2>
1099 requires (
sizeof...(_Elements) == 2)
1100 && (__constructible<_U1&, _U2&>())
1101 && (!__dangles<_U1&, _U2&>())
1102 constexpr
explicit(!__convertible<_U1&, _U2&>())
1103 tuple(pair<_U1, _U2>& __u)
1104 noexcept(__nothrow_constructible<_U1&, _U2&>())
1105 : _Inherited(__u.first, __u.second)
1108 template<
typename _U1,
typename _U2>
1109 requires (
sizeof...(_Elements) == 2)
1110 && (__constructible<_U1&, _U2&>())
1111 && (__dangles<_U1&, _U2&>())
1112 tuple(pair<_U1, _U2>&) =
delete;
1114 template<
typename _U1,
typename _U2>
1115 requires (
sizeof...(_Elements) == 2)
1116 && (__constructible<const _U1, const _U2>())
1117 && (!__dangles<const _U1, const _U2>())
1118 constexpr
explicit(!__convertible<const _U1, const _U2>())
1119 tuple(
const pair<_U1, _U2>&& __u)
1120 noexcept(__nothrow_constructible<const _U1, const _U2>())
1121 : _Inherited(
std::
forward<const _U1>(__u.first),
1125 template<
typename _U1,
typename _U2>
1126 requires (
sizeof...(_Elements) == 2)
1127 && (__constructible<const _U1, const _U2>())
1128 && (__dangles<const _U1, const _U2>())
1129 tuple(
const pair<_U1, _U2>&&) =
delete;
1132 #if __cpp_lib_tuple_like // >= C++23
1133 template<__eligible_tuple_like<tuple> _UTuple>
1134 requires (__constructible_from_tuple_like<_UTuple>())
1135 && (!__use_other_ctor<_UTuple>())
1136 && (!__dangles_from_tuple_like<_UTuple>())
1137 constexpr
explicit(!__convertible_from_tuple_like<_UTuple>())
1138 tuple(_UTuple&& __u)
1139 : _Inherited(__tuple_like_tag_t{},
1140 std::forward<_UTuple>(__u),
1144 template<__eligible_tuple_like<tuple> _UTuple>
1145 requires (__constructible_from_tuple_like<_UTuple>())
1146 && (!__use_other_ctor<_UTuple>())
1147 && (__dangles_from_tuple_like<_UTuple>())
1148 tuple(_UTuple&&) =
delete;
1153 template<
typename _Alloc>
1155 explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...))
1156 tuple(allocator_arg_t __tag,
const _Alloc& __a)
1157 requires (is_default_constructible_v<_Elements> && ...)
1158 : _Inherited(__tag, __a)
1161 template<
typename _Alloc>
1162 constexpr
explicit(!__convertible<
const _Elements&...>())
1163 tuple(allocator_arg_t __tag, const _Alloc& __a,
1164 const type_identity_t<_Elements>&... __elements)
1165 requires (__constructible<const _Elements&...>())
1166 : _Inherited(__tag, __a, __elements...)
1169 template<
typename _Alloc,
typename... _UTypes>
1170 requires (__disambiguating_constraint<_UTypes...>())
1171 && (__constructible<_UTypes...>())
1172 && (!__dangles<_UTypes...>())
1173 constexpr
explicit(!__convertible<_UTypes...>())
1174 tuple(allocator_arg_t __tag, const _Alloc& __a, _UTypes&&... __u)
1175 : _Inherited(__tag, __a,
std::
forward<_UTypes>(__u)...)
1178 template<
typename _Alloc,
typename... _UTypes>
1179 requires (__disambiguating_constraint<_UTypes...>())
1180 && (__constructible<_UTypes...>())
1181 && (__dangles<_UTypes...>())
1182 tuple(allocator_arg_t,
const _Alloc&, _UTypes&&...) =
delete;
1184 template<
typename _Alloc>
1186 tuple(allocator_arg_t __tag,
const _Alloc& __a,
const tuple& __u)
1187 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__u))
1190 template<
typename _Alloc>
1191 requires (__constructible<_Elements...>())
1193 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __u)
1194 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__u))
1197 template<
typename _Alloc,
typename... _UTypes>
1198 requires (__constructible<const _UTypes&...>())
1199 && (!__use_other_ctor<
const tuple<_UTypes...>&>())
1200 && (!__dangles<
const _UTypes&...>())
1201 constexpr
explicit(!__convertible<
const _UTypes&...>())
1202 tuple(allocator_arg_t __tag, const _Alloc& __a,
1203 const tuple<_UTypes...>& __u)
1204 : _Inherited(__tag, __a,
1205 static_cast<const _Tuple_impl<0, _UTypes...>&>(__u))
1208 template<
typename _Alloc,
typename... _UTypes>
1209 requires (__constructible<const _UTypes&...>())
1210 && (!__use_other_ctor<
const tuple<_UTypes...>&>())
1211 && (__dangles<
const _UTypes&...>())
1212 tuple(allocator_arg_t,
const _Alloc&,
const tuple<_UTypes...>&) =
delete;
1214 template<
typename _Alloc,
typename... _UTypes>
1215 requires (__constructible<_UTypes...>())
1216 && (!__use_other_ctor<tuple<_UTypes...>>())
1217 && (!__dangles<_UTypes...>())
1218 constexpr
explicit(!__use_other_ctor<tuple<_UTypes...>>())
1219 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UTypes...>&& __u)
1220 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&&>(__u))
1223 template<
typename _Alloc,
typename... _UTypes>
1224 requires (__constructible<_UTypes...>())
1225 && (!__use_other_ctor<tuple<_UTypes...>>())
1226 && (__dangles<_UTypes...>())
1227 tuple(allocator_arg_t,
const _Alloc&, tuple<_UTypes...>&&) =
delete;
1229 #if __cpp_lib_ranges_zip // >= C++23
1230 template<
typename _Alloc,
typename... _UTypes>
1231 requires (__constructible<_UTypes&...>())
1232 && (!__use_other_ctor<tuple<_UTypes...>&>())
1233 && (!__dangles<_UTypes&...>())
1234 constexpr
explicit(!__convertible<_UTypes&...>())
1235 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UTypes...>& __u)
1236 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UTypes...>&>(__u))
1239 template<
typename _Alloc,
typename... _UTypes>
1240 requires (__constructible<_UTypes&...>())
1241 && (!__use_other_ctor<tuple<_UTypes...>&>())
1242 && (__dangles<_UTypes&...>())
1243 tuple(allocator_arg_t,
const _Alloc&, tuple<_UTypes...>&) =
delete;
1245 template<
typename _Alloc,
typename... _UTypes>
1246 requires (__constructible<const _UTypes...>())
1247 && (!__use_other_ctor<
const tuple<_UTypes...>>())
1248 && (!__dangles<
const _UTypes...>())
1249 constexpr
explicit(!__convertible<
const _UTypes...>())
1250 tuple(allocator_arg_t __tag, const _Alloc& __a,
1251 const tuple<_UTypes...>&& __u)
1252 : _Inherited(__tag, __a,
1253 static_cast<const _Tuple_impl<0, _UTypes...>&&>(__u))
1256 template<
typename _Alloc,
typename... _UTypes>
1257 requires (__constructible<const _UTypes...>())
1258 && (!__use_other_ctor<
const tuple<_UTypes...>>())
1259 && (__dangles<
const _UTypes...>())
1260 tuple(allocator_arg_t,
const _Alloc&,
const tuple<_UTypes...>&&) =
delete;
1263 template<
typename _Alloc,
typename _U1,
typename _U2>
1264 requires (
sizeof...(_Elements) == 2)
1265 && (__constructible<const _U1&, const _U2&>())
1266 && (!__dangles<const _U1&, const _U2&>())
1267 constexpr
explicit(!__convertible<const _U1&, const _U2&>())
1268 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1269 const pair<_U1, _U2>& __u)
1270 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1271 : _Inherited(__tag, __a, __u.first, __u.second)
1274 template<
typename _Alloc,
typename _U1,
typename _U2>
1275 requires (
sizeof...(_Elements) == 2)
1276 && (__constructible<const _U1&, const _U2&>())
1277 && (__dangles<const _U1&, const _U2&>())
1278 tuple(allocator_arg_t,
const _Alloc&,
const pair<_U1, _U2>&) =
delete;
1280 template<
typename _Alloc,
typename _U1,
typename _U2>
1281 requires (
sizeof...(_Elements) == 2)
1282 && (__constructible<_U1, _U2>())
1283 && (!__dangles<_U1, _U2>())
1284 constexpr
explicit(!__convertible<_U1, _U2>())
1285 tuple(allocator_arg_t __tag,
const _Alloc& __a, pair<_U1, _U2>&& __u)
1286 noexcept(__nothrow_constructible<_U1, _U2>())
1287 : _Inherited(__tag, __a,
std::
move(__u.first),
std::
move(__u.second))
1290 template<
typename _Alloc,
typename _U1,
typename _U2>
1291 requires (
sizeof...(_Elements) == 2)
1292 && (__constructible<_U1, _U2>())
1293 && (__dangles<_U1, _U2>())
1294 tuple(allocator_arg_t,
const _Alloc&, pair<_U1, _U2>&&) =
delete;
1296 #if __cpp_lib_ranges_zip // >= C++23
1297 template<
typename _Alloc,
typename _U1,
typename _U2>
1298 requires (
sizeof...(_Elements) == 2)
1299 && (__constructible<_U1&, _U2&>())
1300 && (!__dangles<_U1&, _U2&>())
1301 constexpr
explicit(!__convertible<_U1&, _U2&>())
1302 tuple(allocator_arg_t __tag,
const _Alloc& __a, pair<_U1, _U2>& __u)
1303 noexcept(__nothrow_constructible<_U1&, _U2&>())
1304 : _Inherited(__tag, __a, __u.first, __u.second)
1307 template<
typename _Alloc,
typename _U1,
typename _U2>
1308 requires (
sizeof...(_Elements) == 2)
1309 && (__constructible<_U1&, _U2&>())
1310 && (__dangles<_U1&, _U2&>())
1311 tuple(allocator_arg_t,
const _Alloc&, pair<_U1, _U2>&) =
delete;
1313 template<
typename _Alloc,
typename _U1,
typename _U2>
1314 requires (
sizeof...(_Elements) == 2)
1315 && (__constructible<const _U1, const _U2>())
1316 && (!__dangles<const _U1, const _U2>())
1317 constexpr
explicit(!__convertible<const _U1, const _U2>())
1318 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1319 const pair<_U1, _U2>&& __u)
1320 noexcept(__nothrow_constructible<const _U1, const _U2>())
1321 : _Inherited(__tag, __a,
std::
move(__u.first),
std::
move(__u.second))
1324 template<
typename _Alloc,
typename _U1,
typename _U2>
1325 requires (
sizeof...(_Elements) == 2)
1326 && (__constructible<const _U1, const _U2>())
1327 && (__dangles<const _U1, const _U2>())
1328 tuple(allocator_arg_t,
const _Alloc&,
const pair<_U1, _U2>&&) =
delete;
1331 #if __cpp_lib_tuple_like // >= C++23
1332 template<
typename _Alloc, __eligible_tuple_like<tuple> _UTuple>
1333 requires (__constructible_from_tuple_like<_UTuple>())
1334 && (!__use_other_ctor<_UTuple>())
1335 && (!__dangles_from_tuple_like<_UTuple>())
1336 constexpr
explicit(!__convertible_from_tuple_like<_UTuple>())
1337 tuple(allocator_arg_t __tag,
const _Alloc& __a, _UTuple&& __u)
1338 : _Inherited(__tuple_like_tag_t{},
1339 __tag, __a, std::forward<_UTuple>(__u),
1343 template<
typename _Alloc, __eligible_tuple_like<tuple> _UTuple>
1344 requires (__constructible_from_tuple_like<_UTuple>())
1345 && (!__use_other_ctor<_UTuple>())
1346 && (__dangles_from_tuple_like<_UTuple>())
1347 tuple(allocator_arg_t,
const _Alloc&, _UTuple&&) =
delete;
1350 #else // !(concepts && conditional_explicit)
1352 template<
bool _Cond>
1353 using _TCC = _TupleConstraints<_Cond, _Elements...>;
1356 template<
bool _Dummy>
1357 using _ImplicitDefaultCtor = __enable_if_t<
1358 _TCC<_Dummy>::__is_implicitly_default_constructible(),
1362 template<
bool _Dummy>
1363 using _ExplicitDefaultCtor = __enable_if_t<
1364 _TCC<_Dummy>::__is_explicitly_default_constructible(),
1368 template<
bool _Cond,
typename... _Args>
1369 using _ImplicitCtor = __enable_if_t<
1370 _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
1374 template<
bool _Cond,
typename... _Args>
1375 using _ExplicitCtor = __enable_if_t<
1376 _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
1380 template<
typename... _UElements>
1381 static constexpr
bool __nothrow_constructible()
1384 __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;
1388 template<
typename _Up>
1389 static constexpr
bool __valid_args()
1391 return sizeof...(_Elements) == 1
1392 && !is_same<tuple, __remove_cvref_t<_Up>>::value;
1396 template<
typename,
typename,
typename... _Tail>
1397 static constexpr
bool __valid_args()
1398 {
return (
sizeof...(_Tail) + 2) ==
sizeof...(_Elements); }
1409 template<
typename _Tuple,
typename = tuple,
1410 typename = __remove_cvref_t<_Tuple>>
1411 struct _UseOtherCtor
1416 template<
typename _Tuple,
typename _Tp,
typename _Up>
1417 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
1418 : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>::type
1422 template<
typename _Tuple,
typename _Tp>
1423 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>
1430 template<
typename _Tuple>
1431 static constexpr
bool __use_other_ctor()
1432 {
return _UseOtherCtor<_Tuple>::value; }
1435 #undef __glibcxx_no_dangling_refs
1436 #if __has_builtin(__reference_constructs_from_temporary) \
1437 && defined _GLIBCXX_DEBUG
1439 # if __cpp_fold_expressions
1440 # define __glibcxx_dangling_refs(U) \
1441 (__reference_constructs_from_temporary(_Elements, U) || ...)
1443 # define __glibcxx_dangling_refs(U) \
1444 __or_<__bool_constant<__reference_constructs_from_temporary(_Elements, U) \
1447 # define __glibcxx_no_dangling_refs(U) \
1448 static_assert(!__glibcxx_dangling_refs(U), \
1449 "std::tuple constructor creates a dangling reference")
1451 # define __glibcxx_no_dangling_refs(U)
1456 template<
typename _Dummy = void,
1457 _ImplicitDefaultCtor<is_void<_Dummy>::value> =
true>
1460 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
1463 template<
typename _Dummy = void,
1464 _ExplicitDefaultCtor<is_void<_Dummy>::value> =
false>
1467 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
1470 template<
bool _NotEmpty = (
sizeof...(_Elements) >= 1),
1471 _ImplicitCtor<_NotEmpty,
const _Elements&...> =
true>
1473 tuple(
const __type_identity_t<_Elements>&... __elements)
1474 noexcept(__nothrow_constructible<const _Elements&...>())
1475 : _Inherited(__elements...) { }
1477 template<
bool _NotEmpty = (
sizeof...(_Elements) >= 1),
1478 _ExplicitCtor<_NotEmpty,
const _Elements&...> =
false>
1480 tuple(
const __type_identity_t<_Elements>&... __elements)
1481 noexcept(__nothrow_constructible<const _Elements&...>())
1482 : _Inherited(__elements...) { }
1484 template<
typename... _UElements,
1485 bool _Valid = __valid_args<_UElements...>(),
1486 _ImplicitCtor<_Valid, _UElements...> =
true>
1488 tuple(_UElements&&... __elements)
1489 noexcept(__nothrow_constructible<_UElements...>())
1490 : _Inherited(
std::
forward<_UElements>(__elements)...)
1491 { __glibcxx_no_dangling_refs(_UElements&&); }
1493 template<
typename... _UElements,
1494 bool _Valid = __valid_args<_UElements...>(),
1495 _ExplicitCtor<_Valid, _UElements...> =
false>
1497 tuple(_UElements&&... __elements)
1498 noexcept(__nothrow_constructible<_UElements...>())
1499 : _Inherited(
std::
forward<_UElements>(__elements)...)
1500 { __glibcxx_no_dangling_refs(_UElements&&); }
1502 constexpr tuple(
const tuple&) =
default;
1504 constexpr tuple(tuple&&) =
default;
1506 template<
typename... _UElements,
1507 bool _Valid = (
sizeof...(_Elements) ==
sizeof...(_UElements))
1508 && !__use_other_ctor<
const tuple<_UElements...>&>(),
1509 _ImplicitCtor<_Valid,
const _UElements&...> =
true>
1511 tuple(
const tuple<_UElements...>& __in)
1512 noexcept(__nothrow_constructible<const _UElements&...>())
1513 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
1514 { __glibcxx_no_dangling_refs(
const _UElements&); }
1516 template<
typename... _UElements,
1517 bool _Valid = (
sizeof...(_Elements) ==
sizeof...(_UElements))
1518 && !__use_other_ctor<
const tuple<_UElements...>&>(),
1519 _ExplicitCtor<_Valid,
const _UElements&...> =
false>
1521 tuple(
const tuple<_UElements...>& __in)
1522 noexcept(__nothrow_constructible<const _UElements&...>())
1523 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
1524 { __glibcxx_no_dangling_refs(
const _UElements&); }
1526 template<
typename... _UElements,
1527 bool _Valid = (
sizeof...(_Elements) ==
sizeof...(_UElements))
1528 && !__use_other_ctor<tuple<_UElements...>&&>(),
1529 _ImplicitCtor<_Valid, _UElements...> =
true>
1531 tuple(tuple<_UElements...>&& __in)
1532 noexcept(__nothrow_constructible<_UElements...>())
1533 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
1534 { __glibcxx_no_dangling_refs(_UElements&&); }
1536 template<
typename... _UElements,
1537 bool _Valid = (
sizeof...(_Elements) ==
sizeof...(_UElements))
1538 && !__use_other_ctor<tuple<_UElements...>&&>(),
1539 _ExplicitCtor<_Valid, _UElements...> =
false>
1541 tuple(tuple<_UElements...>&& __in)
1542 noexcept(__nothrow_constructible<_UElements...>())
1543 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
1544 { __glibcxx_no_dangling_refs(_UElements&&); }
1548 template<
typename _Alloc,
1549 _ImplicitDefaultCtor<is_object<_Alloc>::value> =
true>
1550 _GLIBCXX20_CONSTEXPR
1551 tuple(allocator_arg_t __tag,
const _Alloc& __a)
1552 : _Inherited(__tag, __a) { }
1554 template<
typename _Alloc,
1555 _ExplicitDefaultCtor<is_object<_Alloc>::value> =
false>
1556 _GLIBCXX20_CONSTEXPR
1558 tuple(allocator_arg_t __tag,
const _Alloc& __a)
1559 : _Inherited(__tag, __a) { }
1561 template<
typename _Alloc,
bool _NotEmpty = (
sizeof...(_Elements) >= 1),
1562 _ImplicitCtor<_NotEmpty,
const _Elements&...> =
true>
1563 _GLIBCXX20_CONSTEXPR
1564 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1565 const __type_identity_t<_Elements>&... __elements)
1566 : _Inherited(__tag, __a, __elements...) { }
1568 template<
typename _Alloc,
bool _NotEmpty = (
sizeof...(_Elements) >= 1),
1569 _ExplicitCtor<_NotEmpty,
const _Elements&...> =
false>
1570 _GLIBCXX20_CONSTEXPR
1572 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1573 const __type_identity_t<_Elements>&... __elements)
1574 : _Inherited(__tag, __a, __elements...) { }
1576 template<
typename _Alloc,
typename... _UElements,
1577 bool _Valid = __valid_args<_UElements...>(),
1578 _ImplicitCtor<_Valid, _UElements...> =
true>
1579 _GLIBCXX20_CONSTEXPR
1580 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1581 _UElements&&... __elements)
1582 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
1583 { __glibcxx_no_dangling_refs(_UElements&&); }
1585 template<
typename _Alloc,
typename... _UElements,
1586 bool _Valid = __valid_args<_UElements...>(),
1587 _ExplicitCtor<_Valid, _UElements...> =
false>
1588 _GLIBCXX20_CONSTEXPR
1590 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1591 _UElements&&... __elements)
1592 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
1593 { __glibcxx_no_dangling_refs(_UElements&&); }
1595 template<
typename _Alloc>
1596 _GLIBCXX20_CONSTEXPR
1597 tuple(allocator_arg_t __tag,
const _Alloc& __a,
const tuple& __in)
1598 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1600 template<
typename _Alloc>
1601 _GLIBCXX20_CONSTEXPR
1602 tuple(allocator_arg_t __tag,
const _Alloc& __a, tuple&& __in)
1603 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1605 template<
typename _Alloc,
typename... _UElements,
1606 bool _Valid = (
sizeof...(_Elements) ==
sizeof...(_UElements))
1607 && !__use_other_ctor<
const tuple<_UElements...>&>(),
1608 _ImplicitCtor<_Valid,
const _UElements&...> =
true>
1609 _GLIBCXX20_CONSTEXPR
1610 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1611 const tuple<_UElements...>& __in)
1612 : _Inherited(__tag, __a,
1613 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
1614 { __glibcxx_no_dangling_refs(
const _UElements&); }
1616 template<
typename _Alloc,
typename... _UElements,
1617 bool _Valid = (
sizeof...(_Elements) ==
sizeof...(_UElements))
1618 && !__use_other_ctor<
const tuple<_UElements...>&>(),
1619 _ExplicitCtor<_Valid,
const _UElements&...> =
false>
1620 _GLIBCXX20_CONSTEXPR
1622 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1623 const tuple<_UElements...>& __in)
1624 : _Inherited(__tag, __a,
1625 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
1626 { __glibcxx_no_dangling_refs(
const _UElements&); }
1628 template<
typename _Alloc,
typename... _UElements,
1629 bool _Valid = (
sizeof...(_Elements) ==
sizeof...(_UElements))
1630 && !__use_other_ctor<tuple<_UElements...>&&>(),
1631 _ImplicitCtor<_Valid, _UElements...> =
true>
1632 _GLIBCXX20_CONSTEXPR
1633 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1634 tuple<_UElements...>&& __in)
1635 : _Inherited(__tag, __a,
1636 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
1637 { __glibcxx_no_dangling_refs(_UElements&&); }
1639 template<
typename _Alloc,
typename... _UElements,
1640 bool _Valid = (
sizeof...(_Elements) ==
sizeof...(_UElements))
1641 && !__use_other_ctor<tuple<_UElements...>&&>(),
1642 _ExplicitCtor<_Valid, _UElements...> =
false>
1643 _GLIBCXX20_CONSTEXPR
1645 tuple(allocator_arg_t __tag,
const _Alloc& __a,
1646 tuple<_UElements...>&& __in)
1647 : _Inherited(__tag, __a,
1648 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
1649 { __glibcxx_no_dangling_refs(_UElements&&); }
1650 #endif // concepts && conditional_explicit
1654 #if __cpp_concepts && __cpp_consteval // >= C++20
1656 template<
typename... _UTypes>
1657 static consteval
bool
1660 if constexpr (
sizeof...(_UTypes) ==
sizeof...(_Elements))
1661 return __and_v<is_assignable<_Elements&, _UTypes>...>;
1666 template<
typename... _UTypes>
1667 static consteval
bool
1668 __nothrow_assignable()
1670 if constexpr (
sizeof...(_UTypes) ==
sizeof...(_Elements))
1671 return __and_v<is_nothrow_assignable<_Elements&, _UTypes>...>;
1676 #if __cpp_lib_ranges_zip // >= C++23
1677 template<
typename... _UTypes>
1678 static consteval
bool
1679 __const_assignable()
1681 if constexpr (
sizeof...(_UTypes) ==
sizeof...(_Elements))
1682 return __and_v<is_assignable<const _Elements&, _UTypes>...>;
1688 #if __cpp_lib_tuple_like // >= C++23
1689 template<
typename _UTuple>
1690 static consteval
bool
1691 __assignable_from_tuple_like()
1694 return __assignable<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
1698 template<
typename _UTuple>
1699 static consteval
bool
1700 __const_assignable_from_tuple_like()
1703 return __const_assignable<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
1710 tuple& operator=(
const tuple& __u) =
delete;
1713 operator=(
const tuple& __u)
1714 noexcept(__nothrow_assignable<const _Elements&...>())
1715 requires (__assignable<const _Elements&...>())
1717 this->_M_assign(__u);
1722 operator=(tuple&& __u)
1723 noexcept(__nothrow_assignable<_Elements...>())
1724 requires (__assignable<_Elements...>())
1730 template<
typename... _UTypes>
1731 requires (__assignable<const _UTypes&...>())
1733 operator=(const tuple<_UTypes...>& __u)
1734 noexcept(__nothrow_assignable<const _UTypes&...>())
1736 this->_M_assign(__u);
1740 template<
typename... _UTypes>
1741 requires (__assignable<_UTypes...>())
1743 operator=(tuple<_UTypes...>&& __u)
1744 noexcept(__nothrow_assignable<_UTypes...>())
1750 #if __cpp_lib_ranges_zip // >= C++23
1751 constexpr
const tuple&
1752 operator=(
const tuple& __u)
const
1753 requires (__const_assignable<const _Elements&...>())
1755 this->_M_assign(__u);
1759 constexpr
const tuple&
1760 operator=(tuple&& __u)
const
1761 requires (__const_assignable<_Elements...>())
1767 template<
typename... _UTypes>
1768 constexpr
const tuple&
1769 operator=(
const tuple<_UTypes...>& __u)
const
1770 requires (__const_assignable<const _UTypes&...>())
1772 this->_M_assign(__u);
1776 template<
typename... _UTypes>
1777 constexpr
const tuple&
1778 operator=(tuple<_UTypes...>&& __u)
const
1779 requires (__const_assignable<_UTypes...>())
1786 template<
typename _U1,
typename _U2>
1787 requires (__assignable<const _U1&, const _U2&>())
1789 operator=(const pair<_U1, _U2>& __u)
1790 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1792 this->_M_head(*
this) = __u.first;
1793 this->_M_tail(*this)._M_head(*
this) = __u.second;
1797 template<
typename _U1,
typename _U2>
1798 requires (__assignable<_U1, _U2>())
1800 operator=(pair<_U1, _U2>&& __u)
1801 noexcept(__nothrow_assignable<_U1, _U2>())
1803 this->_M_head(*
this) = std::forward<_U1>(__u.first);
1804 this->_M_tail(*this)._M_head(*
this) = std::forward<_U2>(__u.second);
1808 #if __cpp_lib_ranges_zip // >= C++23
1809 template<
typename _U1,
typename _U2>
1810 requires (__const_assignable<const _U1&, const _U2>())
1811 constexpr const tuple&
1812 operator=(const pair<_U1, _U2>& __u)
const
1814 this->_M_head(*
this) = __u.first;
1815 this->_M_tail(*this)._M_head(*
this) = __u.second;
1819 template<
typename _U1,
typename _U2>
1820 requires (__const_assignable<_U1, _U2>())
1821 constexpr const tuple&
1822 operator=(pair<_U1, _U2>&& __u)
const
1824 this->_M_head(*
this) = std::forward<_U1>(__u.first);
1825 this->_M_tail(*this)._M_head(*
this) = std::forward<_U2>(__u.second);
1830 #if __cpp_lib_tuple_like // >= C++23
1831 template<__eligible_tuple_like<tuple> _UTuple>
1832 requires (__assignable_from_tuple_like<_UTuple>())
1834 operator=(_UTuple&& __u)
1836 this->_M_assign(__tuple_like_tag_t{}, std::forward<_UTuple>(__u));
1840 template<__eligible_tuple_like<tuple> _UTuple>
1841 requires (__const_assignable_from_tuple_like<_UTuple>())
1842 constexpr const tuple&
1843 operator=(_UTuple&& __u)
const
1845 this->_M_assign(__tuple_like_tag_t{}, std::forward<_UTuple>(__u));
1849 template<__tuple_like _UTuple>
1850 requires (!__is_tuple_v<_UTuple>)
1851 friend constexpr
bool
1852 operator== [[nodiscard]] (
const tuple& __t,
const _UTuple& __u)
1854 static_assert(
sizeof...(_Elements) == tuple_size_v<_UTuple>,
1855 "tuple objects can only be compared if they have equal sizes.");
1857 return (
bool(std::get<_Is>(__t) == std::get<_Is>(__u))
1862 template<__tuple_like _UTuple,
1863 typename = make_index_sequence<tuple_size_v<_UTuple>>>
1864 struct __tuple_like_common_comparison_category;
1866 template<__tuple_like _UTuple,
size_t... _Is>
1868 {
typename void_t<__detail::__synth3way_t<_Elements, tuple_element_t<_Is, _UTuple>>...>; }
1869 struct __tuple_like_common_comparison_category<_UTuple,
index_sequence<_Is...>>
1871 using type = common_comparison_category_t
1872 <__detail::__synth3way_t<_Elements, tuple_element_t<_Is, _UTuple>>...>;
1875 template<__tuple_like _UTuple>
1876 requires (!__is_tuple_v<_UTuple>)
1877 friend constexpr
typename __tuple_like_common_comparison_category<_UTuple>::type
1878 operator<=>(
const tuple& __t,
const _UTuple& __u)
1880 using _Cat =
typename __tuple_like_common_comparison_category<_UTuple>::type;
1881 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Elements...>());
1885 #else // ! (concepts && consteval)
1888 template<
typename... _UElements>
1890 __enable_if_t<
sizeof...(_UElements) ==
sizeof...(_Elements),
bool>
1892 {
return __and_<is_assignable<_Elements&, _UElements>...>::value; }
1895 template<
typename... _UElements>
1896 static constexpr
bool __nothrow_assignable()
1899 __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
1904 _GLIBCXX20_CONSTEXPR
1906 operator=(__conditional_t<__assignable<const _Elements&...>(),
1908 const __nonesuch&> __in)
1909 noexcept(__nothrow_assignable<const _Elements&...>())
1911 this->_M_assign(__in);
1915 _GLIBCXX20_CONSTEXPR
1917 operator=(__conditional_t<__assignable<_Elements...>(),
1920 noexcept(__nothrow_assignable<_Elements...>())
1926 template<
typename... _UElements>
1927 _GLIBCXX20_CONSTEXPR
1928 __enable_if_t<__assignable<
const _UElements&...>(), tuple&>
1929 operator=(
const tuple<_UElements...>& __in)
1930 noexcept(__nothrow_assignable<const _UElements&...>())
1932 this->_M_assign(__in);
1936 template<
typename... _UElements>
1937 _GLIBCXX20_CONSTEXPR
1938 __enable_if_t<__assignable<_UElements...>(), tuple&>
1939 operator=(tuple<_UElements...>&& __in)
1940 noexcept(__nothrow_assignable<_UElements...>())
1945 #endif // concepts && consteval
1948 _GLIBCXX20_CONSTEXPR
1951 noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
1952 { _Inherited::_M_swap(__in); }
1954 #if __cpp_lib_ranges_zip // >= C++23
1962 swap(
const tuple& __in)
const
1963 noexcept(__and_v<__is_nothrow_swappable<const _Elements>...>)
1964 requires (is_swappable_v<const _Elements> && ...)
1965 { _Inherited::_M_swap(__in); }
1969 #if __cpp_deduction_guides >= 201606
1970 template<
typename... _UTypes>
1971 tuple(_UTypes...) -> tuple<_UTypes...>;
1972 template<
typename _T1,
typename _T2>
1973 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
1974 template<
typename _Alloc,
typename... _UTypes>
1975 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
1976 template<
typename _Alloc,
typename _T1,
typename _T2>
1977 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
1978 template<
typename _Alloc,
typename... _UTypes>
1979 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
1992 tuple(
const tuple&) =
default;
1993 tuple& operator=(
const tuple&) =
default;
1995 _GLIBCXX20_CONSTEXPR
1996 void swap(tuple&) noexcept { }
1998 #if __cpp_lib_ranges_zip // >= C++23
1999 template<same_as<tuple> _Tuple = tuple>
2000 constexpr
const tuple&
2001 operator=(
const _Tuple&)
const noexcept
2004 constexpr
void swap(
const tuple&)
const noexcept
2009 template<
typename _Alloc>
2010 _GLIBCXX20_CONSTEXPR
2011 tuple(allocator_arg_t,
const _Alloc&) noexcept { }
2012 template<
typename _Alloc>
2013 _GLIBCXX20_CONSTEXPR
2014 tuple(allocator_arg_t,
const _Alloc&,
const tuple&) noexcept { }
2016 #if __cpp_lib_tuple_like // >= C++23
2017 template<__tuple_like _UTuple>
2018 requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>)
2019 && (!is_same_v<remove_cvref_t<_UTuple>, allocator_arg_t>)
2020 && (tuple_size_v<remove_cvref_t<_UTuple>> == 0)
2022 tuple(_UTuple&&) noexcept { }
2024 template<
typename _Alloc, __tuple_like _UTuple>
2025 requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>)
2026 && (tuple_size_v<remove_cvref_t<_UTuple>> == 0)
2028 tuple(allocator_arg_t,
const _Alloc&, _UTuple&&) noexcept { }
2030 template<__tuple_like _UTuple>
2031 requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>)
2032 && (tuple_size_v<remove_cvref_t<_UTuple>> == 0)
2034 operator=(_UTuple&&) noexcept
2037 template<__tuple_like _UTuple>
2038 requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>)
2039 && (tuple_size_v<remove_cvref_t<_UTuple>> == 0)
2040 constexpr
const tuple&
2041 operator=(_UTuple&&)
const noexcept
2044 template<__tuple_like _UTuple>
2045 requires (!__is_tuple_v<_UTuple>) && (tuple_size_v<_UTuple> == 0)
2047 friend constexpr
bool
2048 operator==(
const tuple&,
const _UTuple&) noexcept
2051 template<__tuple_like _UTuple>
2052 requires (!__is_tuple_v<_UTuple>) && (tuple_size_v<_UTuple> == 0)
2053 friend constexpr strong_ordering
2054 operator<=>(
const tuple&,
const _UTuple&) noexcept
2055 {
return strong_ordering::equal; }
2059 #if !(__cpp_concepts && __cpp_consteval && __cpp_conditional_explicit) // !C++20
2062 template<
typename _T1,
typename _T2>
2063 class tuple<_T1, _T2> :
public _Tuple_impl<0, _T1, _T2>
2065 typedef _Tuple_impl<0, _T1, _T2> _Inherited;
2068 template<
bool _Dummy,
typename _U1,
typename _U2>
2069 using _ImplicitDefaultCtor = __enable_if_t<
2070 _TupleConstraints<_Dummy, _U1, _U2>::
2071 __is_implicitly_default_constructible(),
2075 template<
bool _Dummy,
typename _U1,
typename _U2>
2076 using _ExplicitDefaultCtor = __enable_if_t<
2077 _TupleConstraints<_Dummy, _U1, _U2>::
2078 __is_explicitly_default_constructible(),
2081 template<
bool _Dummy>
2082 using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
2085 template<
bool _Cond,
typename _U1,
typename _U2>
2086 using _ImplicitCtor = __enable_if_t<
2087 _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
2091 template<
bool _Cond,
typename _U1,
typename _U2>
2092 using _ExplicitCtor = __enable_if_t<
2093 _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
2096 template<
typename _U1,
typename _U2>
2097 static constexpr
bool __assignable()
2099 return __and_<is_assignable<_T1&, _U1>,
2103 template<
typename _U1,
typename _U2>
2104 static constexpr
bool __nothrow_assignable()
2106 return __and_<is_nothrow_assignable<_T1&, _U1>,
2110 template<
typename _U1,
typename _U2>
2111 static constexpr
bool __nothrow_constructible()
2113 return __and_<is_nothrow_constructible<_T1, _U1>,
2117 static constexpr
bool __nothrow_default_constructible()
2119 return __and_<is_nothrow_default_constructible<_T1>,
2123 template<
typename _U1>
2124 static constexpr
bool __is_alloc_arg()
2128 #undef __glibcxx_no_dangling_refs
2130 #if __has_builtin(__reference_constructs_from_temporary) \
2131 && defined _GLIBCXX_DEBUG
2132 # define __glibcxx_no_dangling_refs(_U1, _U2) \
2133 static_assert(!__reference_constructs_from_temporary(_T1, _U1) \
2134 && !__reference_constructs_from_temporary(_T2, _U2), \
2135 "std::tuple constructor creates a dangling reference")
2137 # define __glibcxx_no_dangling_refs(_U1, _U2)
2142 template<
bool _Dummy =
true,
2143 _ImplicitDefaultCtor<_Dummy, _T1, _T2> =
true>
2146 noexcept(__nothrow_default_constructible())
2149 template<
bool _Dummy =
true,
2150 _ExplicitDefaultCtor<_Dummy, _T1, _T2> =
false>
2153 noexcept(__nothrow_default_constructible())
2156 template<
bool _Dummy =
true,
2157 _ImplicitCtor<_Dummy, const _T1&, const _T2&> =
true>
2159 tuple(
const _T1& __a1,
const _T2& __a2)
2160 noexcept(__nothrow_constructible<const _T1&, const _T2&>())
2161 : _Inherited(__a1, __a2) { }
2163 template<
bool _Dummy =
true,
2164 _ExplicitCtor<_Dummy, const _T1&, const _T2&> =
false>
2166 tuple(
const _T1& __a1,
const _T2& __a2)
2167 noexcept(__nothrow_constructible<const _T1&, const _T2&>())
2168 : _Inherited(__a1, __a2) { }
2170 template<
typename _U1,
typename _U2,
2171 _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> =
true>
2173 tuple(_U1&& __a1, _U2&& __a2)
2174 noexcept(__nothrow_constructible<_U1, _U2>())
2175 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2))
2176 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2178 template<
typename _U1,
typename _U2,
2179 _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> =
false>
2181 tuple(_U1&& __a1, _U2&& __a2)
2182 noexcept(__nothrow_constructible<_U1, _U2>())
2183 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2))
2184 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2190 template<
typename _U1,
typename _U2,
2191 _ImplicitCtor<true, const _U1&, const _U2&> =
true>
2194 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
2195 : _Inherited(
static_cast<const _Tuple_impl<0, _U1, _U2>&
>(__in))
2196 { __glibcxx_no_dangling_refs(
const _U1&,
const _U2&); }
2198 template<
typename _U1,
typename _U2,
2199 _ExplicitCtor<true, const _U1&, const _U2&> =
false>
2202 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
2203 : _Inherited(
static_cast<const _Tuple_impl<0, _U1, _U2>&
>(__in))
2204 { __glibcxx_no_dangling_refs(
const _U1&,
const _U2&); }
2206 template<
typename _U1,
typename _U2,
2207 _ImplicitCtor<true, _U1, _U2> =
true>
2210 noexcept(__nothrow_constructible<_U1, _U2>())
2211 : _Inherited(
static_cast<_Tuple_impl<0, _U1, _U2>&&
>(__in))
2212 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2214 template<
typename _U1,
typename _U2,
2215 _ExplicitCtor<true, _U1, _U2> =
false>
2218 noexcept(__nothrow_constructible<_U1, _U2>())
2219 : _Inherited(
static_cast<_Tuple_impl<0, _U1, _U2>&&
>(__in))
2220 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2222 template<
typename _U1,
typename _U2,
2223 _ImplicitCtor<true, const _U1&, const _U2&> =
true>
2226 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
2228 { __glibcxx_no_dangling_refs(
const _U1&,
const _U2&); }
2230 template<
typename _U1,
typename _U2,
2231 _ExplicitCtor<true, const _U1&, const _U2&> =
false>
2234 noexcept(__nothrow_constructible<const _U1&, const _U2&>())
2236 { __glibcxx_no_dangling_refs(
const _U1&,
const _U2&); }
2238 template<
typename _U1,
typename _U2,
2239 _ImplicitCtor<true, _U1, _U2> =
true>
2242 noexcept(__nothrow_constructible<_U1, _U2>())
2243 : _Inherited(std::forward<_U1>(__in.
first),
2244 std::forward<_U2>(__in.
second))
2245 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2247 template<
typename _U1,
typename _U2,
2248 _ExplicitCtor<true, _U1, _U2> =
false>
2251 noexcept(__nothrow_constructible<_U1, _U2>())
2252 : _Inherited(std::forward<_U1>(__in.
first),
2253 std::forward<_U2>(__in.
second))
2254 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2258 template<
typename _Alloc,
2259 _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> =
true>
2260 _GLIBCXX20_CONSTEXPR
2261 tuple(allocator_arg_t __tag,
const _Alloc& __a)
2262 : _Inherited(__tag, __a) { }
2264 template<
typename _Alloc,
2265 _ExplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> =
false>
2266 _GLIBCXX20_CONSTEXPR
2268 tuple(allocator_arg_t __tag,
const _Alloc& __a)
2269 : _Inherited(__tag, __a) { }
2271 template<
typename _Alloc,
bool _Dummy =
true,
2272 _ImplicitCtor<_Dummy, const _T1&, const _T2&> =
true>
2273 _GLIBCXX20_CONSTEXPR
2274 tuple(allocator_arg_t __tag,
const _Alloc& __a,
2275 const _T1& __a1,
const _T2& __a2)
2276 : _Inherited(__tag, __a, __a1, __a2) { }
2278 template<
typename _Alloc,
bool _Dummy =
true,
2279 _ExplicitCtor<_Dummy, const _T1&, const _T2&> =
false>
2281 _GLIBCXX20_CONSTEXPR
2282 tuple(allocator_arg_t __tag,
const _Alloc& __a,
2283 const _T1& __a1,
const _T2& __a2)
2284 : _Inherited(__tag, __a, __a1, __a2) { }
2286 template<
typename _Alloc,
typename _U1,
typename _U2,
2287 _ImplicitCtor<true, _U1, _U2> =
true>
2288 _GLIBCXX20_CONSTEXPR
2289 tuple(allocator_arg_t __tag,
const _Alloc& __a, _U1&& __a1, _U2&& __a2)
2290 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
2291 std::forward<_U2>(__a2))
2292 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2294 template<
typename _Alloc,
typename _U1,
typename _U2,
2295 _ExplicitCtor<true, _U1, _U2> =
false>
2297 _GLIBCXX20_CONSTEXPR
2298 tuple(allocator_arg_t __tag,
const _Alloc& __a,
2299 _U1&& __a1, _U2&& __a2)
2300 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
2301 std::forward<_U2>(__a2))
2302 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2304 template<
typename _Alloc>
2305 _GLIBCXX20_CONSTEXPR
2306 tuple(allocator_arg_t __tag,
const _Alloc& __a,
const tuple& __in)
2307 : _Inherited(__tag, __a,
static_cast<const _Inherited&
>(__in)) { }
2309 template<
typename _Alloc>
2310 _GLIBCXX20_CONSTEXPR
2311 tuple(allocator_arg_t __tag,
const _Alloc& __a,
tuple&& __in)
2312 : _Inherited(__tag, __a,
static_cast<_Inherited&&
>(__in)) { }
2314 template<
typename _Alloc,
typename _U1,
typename _U2,
2315 _ImplicitCtor<true, const _U1&, const _U2&> =
true>
2316 _GLIBCXX20_CONSTEXPR
2317 tuple(allocator_arg_t __tag,
const _Alloc& __a,
2319 : _Inherited(__tag, __a,
2320 static_cast<const _Tuple_impl<0, _U1, _U2>&
>(__in))
2321 { __glibcxx_no_dangling_refs(
const _U1&,
const _U2&); }
2323 template<
typename _Alloc,
typename _U1,
typename _U2,
2324 _ExplicitCtor<true, const _U1&, const _U2&> =
false>
2326 _GLIBCXX20_CONSTEXPR
2327 tuple(allocator_arg_t __tag,
const _Alloc& __a,
2329 : _Inherited(__tag, __a,
2330 static_cast<const _Tuple_impl<0, _U1, _U2>&
>(__in))
2331 { __glibcxx_no_dangling_refs(
const _U1&,
const _U2&); }
2333 template<
typename _Alloc,
typename _U1,
typename _U2,
2334 _ImplicitCtor<true, _U1, _U2> =
true>
2335 _GLIBCXX20_CONSTEXPR
2337 : _Inherited(__tag, __a,
static_cast<_Tuple_impl<0, _U1, _U2>&&
>(__in))
2338 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2340 template<
typename _Alloc,
typename _U1,
typename _U2,
2341 _ExplicitCtor<true, _U1, _U2> =
false>
2343 _GLIBCXX20_CONSTEXPR
2345 : _Inherited(__tag, __a,
static_cast<_Tuple_impl<0, _U1, _U2>&&
>(__in))
2346 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2348 template<
typename _Alloc,
typename _U1,
typename _U2,
2349 _ImplicitCtor<true, const _U1&, const _U2&> =
true>
2350 _GLIBCXX20_CONSTEXPR
2351 tuple(allocator_arg_t __tag,
const _Alloc& __a,
2354 { __glibcxx_no_dangling_refs(
const _U1&,
const _U2&); }
2356 template<
typename _Alloc,
typename _U1,
typename _U2,
2357 _ExplicitCtor<true, const _U1&, const _U2&> =
false>
2359 _GLIBCXX20_CONSTEXPR
2360 tuple(allocator_arg_t __tag,
const _Alloc& __a,
2363 { __glibcxx_no_dangling_refs(
const _U1&,
const _U2&); }
2365 template<
typename _Alloc,
typename _U1,
typename _U2,
2366 _ImplicitCtor<true, _U1, _U2> =
true>
2367 _GLIBCXX20_CONSTEXPR
2369 : _Inherited(__tag, __a, std::forward<_U1>(__in.
first),
2370 std::forward<_U2>(__in.
second))
2371 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2373 template<
typename _Alloc,
typename _U1,
typename _U2,
2374 _ExplicitCtor<true, _U1, _U2> =
false>
2376 _GLIBCXX20_CONSTEXPR
2378 : _Inherited(__tag, __a, std::forward<_U1>(__in.
first),
2379 std::forward<_U2>(__in.
second))
2380 { __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
2384 _GLIBCXX20_CONSTEXPR
2386 operator=(__conditional_t<__assignable<const _T1&, const _T2&>(),
2388 const __nonesuch&> __in)
2389 noexcept(__nothrow_assignable<const _T1&, const _T2&>())
2391 this->_M_assign(__in);
2395 _GLIBCXX20_CONSTEXPR
2397 operator=(__conditional_t<__assignable<_T1, _T2>(),
2400 noexcept(__nothrow_assignable<_T1, _T2>())
2406 template<
typename _U1,
typename _U2>
2407 _GLIBCXX20_CONSTEXPR
2408 __enable_if_t<__assignable<const _U1&, const _U2&>(),
tuple&>
2410 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
2412 this->_M_assign(__in);
2416 template<
typename _U1,
typename _U2>
2417 _GLIBCXX20_CONSTEXPR
2418 __enable_if_t<__assignable<_U1, _U2>(),
tuple&>
2420 noexcept(__nothrow_assignable<_U1, _U2>())
2426 template<
typename _U1,
typename _U2>
2427 _GLIBCXX20_CONSTEXPR
2428 __enable_if_t<__assignable<const _U1&, const _U2&>(),
tuple&>
2430 noexcept(__nothrow_assignable<const _U1&, const _U2&>())
2432 this->_M_head(*
this) = __in.
first;
2433 this->_M_tail(*this)._M_head(*
this) = __in.
second;
2437 template<
typename _U1,
typename _U2>
2438 _GLIBCXX20_CONSTEXPR
2439 __enable_if_t<__assignable<_U1, _U2>(),
tuple&>
2441 noexcept(__nothrow_assignable<_U1, _U2>())
2443 this->_M_head(*
this) = std::forward<_U1>(__in.
first);
2444 this->_M_tail(*this)._M_head(*
this) = std::forward<_U2>(__in.
second);
2448 _GLIBCXX20_CONSTEXPR
2451 noexcept(__and_<__is_nothrow_swappable<_T1>,
2452 __is_nothrow_swappable<_T2>>::value)
2453 { _Inherited::_M_swap(__in); }
2455 #endif // concepts && conditional_explicit
2458 template<
typename... _Elements>
2462 #if __cplusplus >= 201703L
2463 template<
typename... _Types>
2464 inline constexpr
size_t tuple_size_v<
tuple<_Types...>>
2465 =
sizeof...(_Types);
2467 template<
typename... _Types>
2468 inline constexpr
size_t tuple_size_v<
const tuple<_Types...>>
2469 =
sizeof...(_Types);
2473 template<
size_t __i,
typename... _Types>
2476 static_assert(__i <
sizeof...(_Types),
"tuple index must be in range");
2478 using type =
typename _Nth_type<__i, _Types...>::type;
2481 template<
size_t __i,
typename _Head,
typename... _Tail>
2483 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
2484 {
return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
2486 template<
size_t __i,
typename _Head,
typename... _Tail>
2487 constexpr
const _Head&
2488 __get_helper(
const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
2489 {
return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
2492 template<
size_t __i,
typename... _Types>
2493 __enable_if_t<(__i >=
sizeof...(_Types))>
2494 __get_helper(
const tuple<_Types...>&) =
delete;
2497 template<
size_t __i,
typename... _Elements>
2498 constexpr __tuple_element_t<__i, tuple<_Elements...>>&
2500 {
return std::__get_helper<__i>(__t); }
2503 template<
size_t __i,
typename... _Elements>
2504 constexpr
const __tuple_element_t<__i, tuple<_Elements...>>&
2506 {
return std::__get_helper<__i>(__t); }
2509 template<
size_t __i,
typename... _Elements>
2510 constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
2513 typedef __tuple_element_t<__i,
tuple<_Elements...>> __element_type;
2514 return std::forward<__element_type>(std::__get_helper<__i>(__t));
2518 template<
size_t __i,
typename... _Elements>
2519 constexpr
const __tuple_element_t<__i, tuple<_Elements...>>&&
2522 typedef __tuple_element_t<__i,
tuple<_Elements...>> __element_type;
2523 return std::forward<const __element_type>(std::__get_helper<__i>(__t));
2528 template<
size_t __i,
typename... _Elements>
2529 constexpr __enable_if_t<(__i >=
sizeof...(_Elements))>
2530 get(
const tuple<_Elements...>&) =
delete;
2533 #ifdef __cpp_lib_tuples_by_type // C++ >= 14
2535 template <
typename _Tp,
typename... _Types>
2537 get(tuple<_Types...>& __t) noexcept
2539 constexpr
size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
2540 static_assert(__idx <
sizeof...(_Types),
2541 "the type T in std::get<T> must occur exactly once in the tuple");
2542 return std::__get_helper<__idx>(__t);
2546 template <
typename _Tp,
typename... _Types>
2548 get(tuple<_Types...>&& __t) noexcept
2550 constexpr
size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
2551 static_assert(__idx <
sizeof...(_Types),
2552 "the type T in std::get<T> must occur exactly once in the tuple");
2553 return std::forward<_Tp>(std::__get_helper<__idx>(__t));
2557 template <
typename _Tp,
typename... _Types>
2558 constexpr
const _Tp&
2559 get(
const tuple<_Types...>& __t) noexcept
2561 constexpr
size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
2562 static_assert(__idx <
sizeof...(_Types),
2563 "the type T in std::get<T> must occur exactly once in the tuple");
2564 return std::__get_helper<__idx>(__t);
2569 template <
typename _Tp,
typename... _Types>
2570 constexpr
const _Tp&&
2571 get(
const tuple<_Types...>&& __t) noexcept
2573 constexpr
size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
2574 static_assert(__idx <
sizeof...(_Types),
2575 "the type T in std::get<T> must occur exactly once in the tuple");
2576 return std::forward<const _Tp>(std::__get_helper<__idx>(__t));
2580 #if __cpp_lib_three_way_comparison
2581 template<
typename... _Tps,
typename... _Ups>
2582 requires (
sizeof...(_Tps) ==
sizeof...(_Ups))
2583 && (requires (
const _Tps& __t,
const _Ups& __u) {
2584 { __t == __u } -> __detail::__boolean_testable;
2587 operator== [[nodiscard]] (
const tuple<_Tps...>& __t,
2588 const tuple<_Ups...>& __u)
2592 return (
bool(std::get<_Inds>(__t) == std::get<_Inds>(__u)) && ...);
2596 template<
typename _Cat,
typename _Tp,
typename _Up,
typename _IndexSeq>
2599 __tuple_cmp(
const _Tp& __t,
const _Up& __u, _IndexSeq __indices)
2601 _Cat __c = _Cat::equivalent;
2605 auto __cmp = [&]<
size_t _Ind>(integral_constant<size_t, _Ind>) {
2606 __c = __detail::__synth3way(std::get<_Ind>(__t), std::get<_Ind>(__u));
2612 (void)(__cmp(integral_constant<size_t, _Inds>{}) && ...);
2618 template<
typename... _Tps,
typename... _Ups>
2619 requires (
sizeof...(_Tps) ==
sizeof...(_Ups))
2620 && (requires {
typename __detail::__synth3way_t<_Tps, _Ups>; } && ...)
2622 common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
2623 operator<=> [[nodiscard]] (
const tuple<_Tps...>& __t,
2624 const tuple<_Ups...>& __u)
2627 = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
2628 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
2633 template<
typename _Tp,
typename _Up,
size_t __i,
size_t __size>
2634 struct __tuple_compare
2636 static constexpr
bool
2637 __eq(
const _Tp& __t,
const _Up& __u)
2639 return bool(std::get<__i>(__t) == std::get<__i>(__u))
2640 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
2643 static constexpr
bool
2644 __less(
const _Tp& __t,
const _Up& __u)
2646 return bool(std::get<__i>(__t) < std::get<__i>(__u))
2647 || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
2648 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
2652 template<
typename _Tp,
typename _Up,
size_t __size>
2653 struct __tuple_compare<_Tp, _Up, __size, __size>
2655 static constexpr
bool
2656 __eq(
const _Tp&,
const _Up&) {
return true; }
2658 static constexpr
bool
2659 __less(
const _Tp&,
const _Up&) {
return false; }
2662 template<
typename... _TElements,
typename... _UElements>
2665 operator==(
const tuple<_TElements...>& __t,
2666 const tuple<_UElements...>& __u)
2668 static_assert(
sizeof...(_TElements) ==
sizeof...(_UElements),
2669 "tuple objects can only be compared if they have equal sizes.");
2670 using __compare = __tuple_compare<tuple<_TElements...>,
2671 tuple<_UElements...>,
2672 0,
sizeof...(_TElements)>;
2673 return __compare::__eq(__t, __u);
2676 template<
typename... _TElements,
typename... _UElements>
2679 operator<(
const tuple<_TElements...>& __t,
2680 const tuple<_UElements...>& __u)
2682 static_assert(
sizeof...(_TElements) ==
sizeof...(_UElements),
2683 "tuple objects can only be compared if they have equal sizes.");
2684 using __compare = __tuple_compare<tuple<_TElements...>,
2685 tuple<_UElements...>,
2686 0,
sizeof...(_TElements)>;
2687 return __compare::__less(__t, __u);
2690 template<
typename... _TElements,
typename... _UElements>
2693 operator!=(
const tuple<_TElements...>& __t,
2694 const tuple<_UElements...>& __u)
2695 {
return !(__t == __u); }
2697 template<
typename... _TElements,
typename... _UElements>
2700 operator>(
const tuple<_TElements...>& __t,
2701 const tuple<_UElements...>& __u)
2702 {
return __u < __t; }
2704 template<
typename... _TElements,
typename... _UElements>
2708 const tuple<_UElements...>& __u)
2709 {
return !(__u < __t); }
2711 template<
typename... _TElements,
typename... _UElements>
2715 const tuple<_UElements...>& __u)
2716 {
return !(__t < __u); }
2717 #endif // three_way_comparison
2721 template<
typename... _Elements>
2727 return __result_type(std::forward<_Elements>(__args)...);
2733 template<
typename... _Elements>
2734 constexpr
tuple<_Elements&&...>
2736 {
return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
2739 template<
typename _Tuple,
typename _Idx_tuple>
2740 struct __do_make_tuple;
2742 template<
typename _Tuple,
size_t... _Idx>
2743 struct __do_make_tuple<_Tuple, _Index_tuple<_Idx...>>
2745 using __type = tuple<__tuple_element_t<_Idx, _Tuple>...>;
2749 template<
typename _Tuple,
2750 typename _Tup = __remove_cvref_t<_Tuple>,
2751 typename _Indices = _Build_index_tuple<tuple_size<_Tup>::value>>
2753 : __do_make_tuple<_Tup, typename _Indices::__type>
2757 template<
typename...>
2758 struct __combine_tuples;
2761 struct __combine_tuples<>
2763 using __type = tuple<>;
2766 template<
typename... _Ts>
2767 struct __combine_tuples<tuple<_Ts...>>
2769 using __type = tuple<_Ts...>;
2772 template<
typename... _T1s,
typename... _T2s>
2773 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>>
2775 using __type = tuple<_T1s..., _T2s...>;
2778 template<
typename... _T1s,
typename... _T2s,
typename... _T3s,
2780 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, tuple<_T3s...>,
2783 using _First = tuple<_T1s..., _T2s..., _T3s...>;
2784 using _Second =
typename __combine_tuples<_Rem...>::__type;
2785 using __type =
typename __combine_tuples<_First, _Second>::__type;
2789 template<
typename... _Tpls>
2790 struct __tuple_cat_result
2792 typedef typename __combine_tuples
2793 <
typename __make_tuple<_Tpls>::__type...>::__type __type;
2798 template<
typename...>
2799 struct __make_1st_indices;
2802 struct __make_1st_indices<>
2804 typedef _Index_tuple<> __type;
2807 template<
typename _Tp,
typename... _Tpls>
2808 struct __make_1st_indices<_Tp, _Tpls...>
2810 typedef typename _Build_index_tuple<tuple_size<
2811 typename remove_reference<_Tp>::type>::value>::__type __type;
2817 template<
typename _Ret,
typename _Indices,
typename... _Tpls>
2818 struct __tuple_concater;
2820 template<
typename _Ret,
size_t... _Is,
typename _Tp,
typename... _Tpls>
2821 struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...>
2823 template<
typename... _Us>
2824 static constexpr _Ret
2825 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
2827 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
2828 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
2829 return __next::_S_do(std::forward<_Tpls>(__tps)...,
2830 std::forward<_Us>(__us)...,
2831 std::get<_Is>(std::forward<_Tp>(__tp))...);
2835 template<
typename _Ret>
2836 struct __tuple_concater<_Ret, _Index_tuple<>>
2838 template<
typename... _Us>
2839 static constexpr _Ret
2840 _S_do(_Us&&... __us)
2842 return _Ret(std::forward<_Us>(__us)...);
2846 template<
typename... _Tps>
2847 struct __is_tuple_like_impl<tuple<_Tps...>> :
true_type
2852 #if __cpp_lib_tuple_like // >= C++23
2853 template<__tuple_like... _Tpls>
2855 template<
typename... _Tpls,
typename =
typename
2856 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
2860 ->
typename __tuple_cat_result<_Tpls...>::__type
2862 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
2863 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
2864 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
2865 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
2871 template<
typename... _Elements>
2872 constexpr
tuple<_Elements&...>
2873 tie(_Elements&... __args) noexcept
2874 {
return tuple<_Elements&...>(__args...); }
2877 template<
typename... _Elements>
2878 _GLIBCXX20_CONSTEXPR
2880 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
2882 typename enable_if<__and_<__is_swappable<_Elements>...>::value
2888 noexcept(noexcept(__x.swap(__y)))
2891 #if __cpp_lib_ranges_zip // >= C++23
2893 template<
typename... _Elements>
2894 requires (is_swappable_v<const _Elements> && ...)
2896 swap(const tuple<_Elements...>& __x, const tuple<_Elements...>& __y)
2897 noexcept(noexcept(__x.swap(__y)))
2901 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
2904 template<
typename... _Elements>
2905 _GLIBCXX20_CONSTEXPR
2906 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
2907 swap(tuple<_Elements...>&, tuple<_Elements...>&) =
delete;
2911 template<
typename... _Types,
typename _Alloc>
2923 template<
class _T1,
class _T2>
2924 template<
typename... _Args1,
typename... _Args2>
2925 _GLIBCXX20_CONSTEXPR
2930 :
pair(__first, __second,
2931 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
2932 typename _Build_index_tuple<sizeof...(_Args2)>::__type())
2935 template<
class _T1,
class _T2>
2936 template<
typename... _Args1,
size_t... _Indexes1,
2937 typename... _Args2,
size_t... _Indexes2>
2938 _GLIBCXX20_CONSTEXPR
inline
2941 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
2946 #if defined(__cpp_lib_apply) || defined(__cpp_lib_make_from_tuple) // C++ >= 17
2951 template<
template<
typename...>
class _Trait,
typename _Tp,
typename _Tuple>
2952 inline constexpr
bool __unpack_std_tuple =
false;
2954 template<
template<
typename...>
class _Trait,
typename _Tp,
typename... _Up>
2955 inline constexpr
bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
2956 = _Trait<_Tp, _Up...>::value;
2958 template<
template<
typename...>
class _Trait,
typename _Tp,
typename... _Up>
2959 inline constexpr
bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
2960 = _Trait<_Tp, _Up&...>::value;
2962 template<
template<
typename...>
class _Trait,
typename _Tp,
typename... _Up>
2963 inline constexpr
bool __unpack_std_tuple<_Trait, _Tp,
const tuple<_Up...>>
2964 = _Trait<_Tp,
const _Up...>::value;
2966 template<
template<
typename...>
class _Trait,
typename _Tp,
typename... _Up>
2967 inline constexpr
bool __unpack_std_tuple<_Trait, _Tp,
const tuple<_Up...>&>
2968 = _Trait<_Tp,
const _Up&...>::value;
2971 #ifdef __cpp_lib_apply // C++ >= 17
2972 template <
typename _Fn,
typename _Tuple,
size_t... _Idx>
2973 constexpr decltype(
auto)
2977 std::get<_Idx>(std::forward<_Tuple>(__t))...);
2980 #if __cpp_lib_tuple_like // >= C++23
2981 template <
typename _Fn, __tuple_like _Tuple>
2983 template <
typename _Fn,
typename _Tuple>
2985 constexpr decltype(
auto)
2986 apply(_Fn&& __f, _Tuple&& __t)
2987 noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
2990 = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
2991 return std::__apply_impl(std::forward<_Fn>(__f),
2992 std::forward<_Tuple>(__t),
2997 #ifdef __cpp_lib_make_from_tuple // C++ >= 17
2998 template <
typename _Tp,
typename _Tuple,
typename _Seq
2999 = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>>
3000 constexpr
bool __can_make_from_tuple =
false;
3004 template <
typename _Tp,
typename _Tuple,
size_t... _Idx>
3005 constexpr
bool __can_make_from_tuple<_Tp, _Tuple,
index_sequence<_Idx...>>
3006 = is_constructible_v<_Tp,
3007 decltype(std::get<_Idx>(std::declval<_Tuple>()))...>;
3009 template <
typename _Tp,
typename _Tuple,
size_t... _Idx>
3011 __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
3013 static_assert(__can_make_from_tuple<_Tp, _Tuple, index_sequence<_Idx...>>);
3014 return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...);
3017 #if __cpp_lib_tuple_like // >= C++23
3018 template <
typename _Tp, __tuple_like _Tuple>
3020 template <
typename _Tp,
typename _Tuple>
3023 make_from_tuple(_Tuple&& __t)
3024 noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
3025 #ifdef __cpp_concepts // >= C++20
3027 requires __can_make_from_tuple<_Tp, _Tuple>
3029 -> __enable_if_t<__can_make_from_tuple<_Tp, _Tuple>, _Tp>
3032 constexpr
size_t __n = tuple_size_v<remove_reference_t<_Tuple>>;
3033 #if __has_builtin(__reference_constructs_from_temporary)
3034 if constexpr (__n == 1)
3036 using _Elt = decltype(std::get<0>(std::declval<_Tuple>()));
3037 static_assert(!__reference_constructs_from_temporary(_Tp, _Elt));
3040 return __make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
3041 make_index_sequence<__n>{});
3045 #if __cpp_lib_tuple_like // >= C++23
3046 template<__tuple_like _TTuple, __tuple_like _UTuple,
3047 template<
typename>
class _TQual,
template<
typename>
class _UQual,
3048 typename = make_index_sequence<tuple_size_v<_TTuple>>>
3049 struct __tuple_like_common_reference;
3051 template<__tuple_like _TTuple, __tuple_like _UTuple,
3052 template<
typename>
class _TQual,
template<
typename>
class _UQual,
3055 {
typename tuple<common_reference_t<_TQual<tuple_element_t<_Is, _TTuple>>,
3056 _UQual<tuple_element_t<_Is, _UTuple>>>...>; }
3057 struct __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual,
index_sequence<_Is...>>
3059 using type = tuple<common_reference_t<_TQual<tuple_element_t<_Is, _TTuple>>,
3060 _UQual<tuple_element_t<_Is, _UTuple>>>...>;
3063 template<__tuple_like _TTuple, __tuple_like _UTuple,
3064 template<
typename>
class _TQual,
template<
typename>
class _UQual>
3065 requires (__is_tuple_v<_TTuple> || __is_tuple_v<_UTuple>)
3066 && is_same_v<_TTuple, decay_t<_TTuple>>
3067 && is_same_v<_UTuple, decay_t<_UTuple>>
3068 && (tuple_size_v<_TTuple> == tuple_size_v<_UTuple>)
3069 && requires {
typename __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual>::type; }
3070 struct basic_common_reference<_TTuple, _UTuple, _TQual, _UQual>
3072 using type =
typename __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual>::type;
3075 template<__tuple_like _TTuple, __tuple_like _UTuple,
3076 typename = make_index_sequence<tuple_size_v<_TTuple>>>
3077 struct __tuple_like_common_type;
3079 template<__tuple_like _TTuple, __tuple_like _UTuple,
size_t... _Is>
3081 {
typename tuple<common_type_t<tuple_element_t<_Is, _TTuple>,
3082 tuple_element_t<_Is, _UTuple>>...>; }
3083 struct __tuple_like_common_type<_TTuple, _UTuple,
index_sequence<_Is...>>
3085 using type = tuple<common_type_t<tuple_element_t<_Is, _TTuple>,
3086 tuple_element_t<_Is, _UTuple>>...>;
3089 template<__tuple_like _TTuple, __tuple_like _UTuple>
3090 requires (__is_tuple_v<_TTuple> || __is_tuple_v<_UTuple>)
3091 && is_same_v<_TTuple, decay_t<_TTuple>>
3092 && is_same_v<_UTuple, decay_t<_UTuple>>
3093 && (tuple_size_v<_TTuple> == tuple_size_v<_UTuple>)
3094 && requires {
typename __tuple_like_common_type<_TTuple, _UTuple>::type; }
3095 struct common_type<_TTuple, _UTuple>
3097 using type =
typename __tuple_like_common_type<_TTuple, _UTuple>::type;
3103 #undef __glibcxx_no_dangling_refs
3105 _GLIBCXX_END_NAMESPACE_VERSION
3110 #endif // _GLIBCXX_TUPLE