@@ -219,8 +219,16 @@ public:
219
219
constexpr tuple(_Tag, const _Alloc&) noexcept /* strengthened */ {}
220
220
221
221
constexpr tuple& operator=(const tuple&) = default;
222
+ #if _HAS_CXX23
223
+ constexpr const tuple& operator=(const tuple&) const {
224
+ return *this;
225
+ }
226
+ #endif // _HAS_CXX23
222
227
223
228
_CONSTEXPR20 void swap(tuple&) noexcept {}
229
+ #if _HAS_CXX23
230
+ constexpr void swap(const tuple&) const noexcept {}
231
+ #endif // _HAS_CXX23
224
232
225
233
constexpr bool _Equals(const tuple&) const noexcept {
226
234
return true;
@@ -349,6 +357,15 @@ public:
349
357
tuple(const tuple&) = default;
350
358
tuple(tuple&&) = default;
351
359
360
+ #if _HAS_CXX23
361
+ template <class... _Other, enable_if_t<conjunction_v<_STD _Tuple_constructible_val<tuple, _Other&...>,
362
+ _STD _Tuple_convert_val<tuple, tuple<_Other...>&, _Other...>>,
363
+ int> = 0>
364
+ constexpr explicit(_Tuple_conditional_explicit_v<tuple, _Other&...>)
365
+ tuple(tuple<_Other...>& _Right) noexcept(_Tuple_nothrow_constructible_v<tuple, _Other&...>) // strengthened
366
+ : tuple(_Unpack_tuple_t{}, _Right) {}
367
+ #endif // _HAS_CXX23
368
+
352
369
#if _HAS_CONDITIONAL_EXPLICIT
353
370
template <class... _Other, enable_if_t<conjunction_v<_STD _Tuple_constructible_val<tuple, const _Other&...>,
354
371
_STD _Tuple_convert_val<tuple, const tuple<_Other...>&, _Other...>>,
@@ -396,6 +413,24 @@ public:
396
413
: tuple(_Unpack_tuple_t{}, _STD move(_Right)) {}
397
414
#endif // ^^^ !_HAS_CONDITIONAL_EXPLICIT ^^^
398
415
416
+ #if _HAS_CXX23
417
+ template <class... _Other, enable_if_t<conjunction_v<_STD _Tuple_constructible_val<tuple, const _Other...>,
418
+ _STD _Tuple_convert_val<tuple, const tuple<_Other...>, _Other...>>,
419
+ int> = 0>
420
+ constexpr explicit(_Tuple_conditional_explicit_v<tuple, const _Other...>)
421
+ tuple(const tuple<_Other...>&& _Right) noexcept(
422
+ _Tuple_nothrow_constructible_v<tuple, const _Other...>) // strengthened
423
+ : tuple(_Unpack_tuple_t{}, _STD move(_Right)) {}
424
+ #endif // _HAS_CXX23
425
+
426
+ #if _HAS_CXX23
427
+ template <class _First, class _Second, enable_if_t<_Tuple_constructible_v<tuple, _First&, _Second&>, int> = 0>
428
+ constexpr explicit(_Tuple_conditional_explicit_v<tuple, _First&, _Second&>)
429
+ tuple(pair<_First, _Second>& _Right) noexcept(
430
+ _Tuple_nothrow_constructible_v<tuple, _First&, _Second&>) // strengthened
431
+ : tuple(_Unpack_tuple_t{}, _Right) {}
432
+ #endif // _HAS_CXX23
433
+
399
434
#if _HAS_CONDITIONAL_EXPLICIT
400
435
template <class _First, class _Second,
401
436
enable_if_t<_Tuple_constructible_v<tuple, const _First&, const _Second&>, int> = 0>
@@ -434,6 +469,15 @@ public:
434
469
: tuple(_Unpack_tuple_t{}, _STD move(_Right)) {}
435
470
#endif // ^^^ !_HAS_CONDITIONAL_EXPLICIT ^^^
436
471
472
+ #if _HAS_CXX23
473
+ template <class _First, class _Second,
474
+ enable_if_t<_Tuple_constructible_v<tuple, const _First, const _Second>, int> = 0>
475
+ constexpr explicit(_Tuple_conditional_explicit_v<tuple, const _First, const _Second>)
476
+ tuple(const pair<_First, _Second>&& _Right) noexcept(
477
+ _Tuple_nothrow_constructible_v<tuple, const _First, const _Second>) // strengthened
478
+ : tuple(_Unpack_tuple_t{}, _STD move(_Right)) {}
479
+ #endif // _HAS_CXX23
480
+
437
481
#if _HAS_CONDITIONAL_EXPLICIT
438
482
template <class _Alloc, class _This2 = _This,
439
483
enable_if_t<conjunction_v<_STD is_default_constructible<_This2>, _STD is_default_constructible<_Rest>...>,
@@ -510,6 +554,16 @@ public:
510
554
_CONSTEXPR20 tuple(allocator_arg_t, const _Alloc& _Al, tuple&& _Right)
511
555
: tuple(_Alloc_unpack_tuple_t{}, _Al, _STD move(_Right)) {}
512
556
557
+ #if _HAS_CXX23
558
+ template <class _Alloc, class... _Other,
559
+ enable_if_t<conjunction_v<_STD _Tuple_constructible_val<tuple, _Other&...>,
560
+ _STD _Tuple_convert_val<tuple, tuple<_Other...>&, _Other...>>,
561
+ int> = 0>
562
+ constexpr explicit(_Tuple_conditional_explicit_v<tuple, _Other&...>)
563
+ tuple(allocator_arg_t, const _Alloc& _Al, tuple<_Other...>& _Right)
564
+ : tuple(_Alloc_unpack_tuple_t{}, _Al, _Right) {}
565
+ #endif // _HAS_CXX23
566
+
513
567
#if _HAS_CONDITIONAL_EXPLICIT
514
568
template <class _Alloc, class... _Other,
515
569
enable_if_t<conjunction_v<_STD _Tuple_constructible_val<tuple, const _Other&...>,
@@ -558,6 +612,24 @@ public:
558
612
: tuple(_Alloc_unpack_tuple_t{}, _Al, _STD move(_Right)) {}
559
613
#endif // ^^^ !_HAS_CONDITIONAL_EXPLICIT ^^^
560
614
615
+ #if _HAS_CXX23
616
+ template <class _Alloc, class... _Other,
617
+ enable_if_t<conjunction_v<_STD _Tuple_constructible_val<tuple, const _Other...>,
618
+ _STD _Tuple_convert_val<tuple, const tuple<_Other...>, _Other...>>,
619
+ int> = 0>
620
+ constexpr explicit(_Tuple_conditional_explicit_v<tuple, const _Other...>)
621
+ tuple(allocator_arg_t, const _Alloc& _Al, const tuple<_Other...>&& _Right)
622
+ : tuple(_Alloc_unpack_tuple_t{}, _Al, _STD move(_Right)) {}
623
+ #endif // _HAS_CXX23
624
+
625
+ #if _HAS_CXX23
626
+ template <class _Alloc, class _First, class _Second,
627
+ enable_if_t<_Tuple_constructible_v<tuple, _First&, _Second&>, int> = 0>
628
+ constexpr explicit(_Tuple_conditional_explicit_v<tuple, _First&, _Second&>)
629
+ tuple(allocator_arg_t, const _Alloc& _Al, pair<_First, _Second>& _Right)
630
+ : tuple(_Alloc_unpack_tuple_t{}, _Al, _Right) {}
631
+ #endif // _HAS_CXX23
632
+
561
633
#if _HAS_CONDITIONAL_EXPLICIT
562
634
template <class _Alloc, class _First, class _Second,
563
635
enable_if_t<_Tuple_constructible_v<tuple, const _First&, const _Second&>, int> = 0>
@@ -594,6 +666,14 @@ public:
594
666
: tuple(_Alloc_unpack_tuple_t{}, _Al, _STD move(_Right)) {}
595
667
#endif // ^^^ !_HAS_CONDITIONAL_EXPLICIT ^^^
596
668
669
+ #if _HAS_CXX23
670
+ template <class _Alloc, class _First, class _Second,
671
+ enable_if_t<_Tuple_constructible_v<tuple, const _First, const _Second>, int> = 0>
672
+ constexpr explicit(_Tuple_conditional_explicit_v<tuple, const _First, const _Second>)
673
+ tuple(allocator_arg_t, const _Alloc& _Al, const pair<_First, _Second>&& _Right)
674
+ : tuple(_Alloc_unpack_tuple_t{}, _Al, _STD move(_Right)) {}
675
+ #endif // _HAS_CXX23
676
+
597
677
tuple& operator=(const volatile tuple&) = delete;
598
678
599
679
template <class _Myself = tuple, class _This2 = _This,
@@ -607,6 +687,20 @@ public:
607
687
return *this;
608
688
}
609
689
690
+ #if _HAS_CXX23
691
+ template <class _Myself = tuple, class _This2 = _This,
692
+ enable_if_t<conjunction_v<_STD _Is_copy_assignable_no_precondition_check<const _This2>,
693
+ _STD _Is_copy_assignable_no_precondition_check<const _Rest>...>,
694
+ int> = 0>
695
+ constexpr const tuple& operator=(_Identity_t<const _Myself&> _Right) const
696
+ noexcept(conjunction_v<is_nothrow_copy_assignable<const _This2>,
697
+ is_nothrow_copy_assignable<const _Rest>...>) /* strengthened */ {
698
+ _Myfirst._Val = _Right._Myfirst._Val;
699
+ _Get_rest() = _Right._Get_rest();
700
+ return *this;
701
+ }
702
+ #endif // _HAS_CXX23
703
+
610
704
template <class _Myself = tuple, class _This2 = _This,
611
705
enable_if_t<conjunction_v<_STD _Is_move_assignable_no_precondition_check<_This2>,
612
706
_STD _Is_move_assignable_no_precondition_check<_Rest>...>,
@@ -618,6 +712,20 @@ public:
618
712
return *this;
619
713
}
620
714
715
+ #if _HAS_CXX23
716
+ template <class _Myself = tuple, class _This2 = _This,
717
+ enable_if_t<conjunction_v<_STD _Is_assignable_no_precondition_check<const _This2&, _This2>,
718
+ _STD _Is_assignable_no_precondition_check<const _Rest&, _Rest>...>,
719
+ int> = 0>
720
+ constexpr const tuple& operator=(_Identity_t<_Myself&&> _Right) const
721
+ noexcept(conjunction_v<is_nothrow_assignable<const _This2&, _This2>,
722
+ is_nothrow_assignable<const _Rest&, _Rest>...>) /* strengthened */ {
723
+ _Myfirst._Val = _STD forward<_This>(_Right._Myfirst._Val);
724
+ _Get_rest() = _STD forward<_Mybase>(_Right._Get_rest());
725
+ return *this;
726
+ }
727
+ #endif // _HAS_CXX23
728
+
621
729
template <class... _Other, enable_if_t<conjunction_v<_STD negation<_STD is_same<tuple, _STD tuple<_Other...>>>,
622
730
_STD _Tuple_assignable_val<tuple, const _Other&...>>,
623
731
int> = 0>
@@ -628,6 +736,18 @@ public:
628
736
return *this;
629
737
}
630
738
739
+ #if _HAS_CXX23
740
+ template <class... _Other, enable_if_t<conjunction_v<_STD negation<_STD is_same<tuple, _STD tuple<_Other...>>>,
741
+ _STD _Tuple_assignable_val<const tuple, const _Other&...>>,
742
+ int> = 0>
743
+ constexpr const tuple& operator=(const tuple<_Other...>& _Right) const
744
+ noexcept(_Tuple_nothrow_assignable_v<const tuple, const _Other&...>) /* strengthened */ {
745
+ _Myfirst._Val = _Right._Myfirst._Val;
746
+ _Get_rest() = _Right._Get_rest();
747
+ return *this;
748
+ }
749
+ #endif // _HAS_CXX23
750
+
631
751
template <class... _Other, enable_if_t<conjunction_v<_STD negation<_STD is_same<tuple, _STD tuple<_Other...>>>,
632
752
_STD _Tuple_assignable_val<tuple, _Other...>>,
633
753
int> = 0>
@@ -638,6 +758,18 @@ public:
638
758
return *this;
639
759
}
640
760
761
+ #if _HAS_CXX23
762
+ template <class... _Other, enable_if_t<conjunction_v<_STD negation<_STD is_same<tuple, _STD tuple<_Other...>>>,
763
+ _STD _Tuple_assignable_val<const tuple, _Other...>>,
764
+ int> = 0>
765
+ constexpr const tuple& operator=(tuple<_Other...>&& _Right) const
766
+ noexcept(_Tuple_nothrow_assignable_v<const tuple, _Other...>) /* strengthened */ {
767
+ _Myfirst._Val = _STD forward<typename tuple<_Other...>::_This_type>(_Right._Myfirst._Val);
768
+ _Get_rest() = _STD forward<typename tuple<_Other...>::_Mybase>(_Right._Get_rest());
769
+ return *this;
770
+ }
771
+ #endif // _HAS_CXX23
772
+
641
773
template <class _First, class _Second,
642
774
enable_if_t<_Tuple_assignable_v<tuple, const _First&, const _Second&>, int> = 0>
643
775
_CONSTEXPR20 tuple& operator=(const pair<_First, _Second>& _Right) noexcept(
@@ -647,6 +779,17 @@ public:
647
779
return *this;
648
780
}
649
781
782
+ #if _HAS_CXX23
783
+ template <class _First, class _Second,
784
+ enable_if_t<_Tuple_assignable_v<const tuple, const _First&, const _Second&>, int> = 0>
785
+ constexpr const tuple& operator=(const pair<_First, _Second>& _Right) const
786
+ noexcept(_Tuple_nothrow_assignable_v<const tuple, const _First&, const _Second&>) /* strengthened */ {
787
+ _Myfirst._Val = _Right.first;
788
+ _Get_rest()._Myfirst._Val = _Right.second;
789
+ return *this;
790
+ }
791
+ #endif // _HAS_CXX23
792
+
650
793
template <class _First, class _Second, enable_if_t<_Tuple_assignable_v<tuple, _First, _Second>, int> = 0>
651
794
_CONSTEXPR20 tuple& operator=(pair<_First, _Second>&& _Right) noexcept(
652
795
_Tuple_nothrow_assignable_v<tuple, _First, _Second>) /* strengthened */ {
@@ -655,12 +798,30 @@ public:
655
798
return *this;
656
799
}
657
800
801
+ #if _HAS_CXX23
802
+ template <class _First, class _Second, enable_if_t<_Tuple_assignable_v<const tuple, _First, _Second>, int> = 0>
803
+ constexpr const tuple& operator=(pair<_First, _Second>&& _Right) const
804
+ noexcept(_Tuple_nothrow_assignable_v<const tuple, _First, _Second>) /* strengthened */ {
805
+ _Myfirst._Val = _STD forward<_First>(_Right.first);
806
+ _Get_rest()._Myfirst._Val = _STD forward<_Second>(_Right.second);
807
+ return *this;
808
+ }
809
+ #endif // _HAS_CXX23
810
+
658
811
_CONSTEXPR20 void swap(tuple& _Right) noexcept(
659
812
conjunction_v<_Is_nothrow_swappable<_This>, _Is_nothrow_swappable<_Rest>...>) {
660
813
_Swap_adl(_Myfirst._Val, _Right._Myfirst._Val);
661
814
_Mybase::swap(_Right._Get_rest());
662
815
}
663
816
817
+ #if _HAS_CXX23
818
+ constexpr void swap(const tuple& _Right) const
819
+ noexcept(conjunction_v<_Is_nothrow_swappable<const _This>, _Is_nothrow_swappable<const _Rest>...>) {
820
+ _Swap_adl(_Myfirst._Val, _Right._Myfirst._Val);
821
+ _Mybase::swap(_Right._Get_rest());
822
+ }
823
+ #endif // _HAS_CXX23
824
+
664
825
constexpr _Mybase& _Get_rest() noexcept { // get reference to rest of elements
665
826
return *this;
666
827
}
@@ -787,6 +948,14 @@ _CONSTEXPR20 void swap(tuple<_Types...>& _Left, tuple<_Types...>& _Right) noexce
787
948
return _Left.swap(_Right);
788
949
}
789
950
951
+ #if _HAS_CXX23
952
+ template <class... _Types, enable_if_t<conjunction_v<_STD _Is_swappable<const _Types>...>, int> = 0>
953
+ constexpr void swap(const tuple<_Types...>& _Left, const tuple<_Types...>& _Right) noexcept(
954
+ noexcept(_Left.swap(_Right))) {
955
+ return _Left.swap(_Right);
956
+ }
957
+ #endif // _HAS_CXX23
958
+
790
959
template <class _Ty, class _Tuple>
791
960
struct _Tuple_element {}; // backstop _Tuple_element definition
792
961
@@ -1003,6 +1172,24 @@ _NODISCARD constexpr _Ty make_from_tuple(_Tuple&& _Tpl) { // construct _Ty from
1003
1172
template <class... _Types, class _Alloc>
1004
1173
struct uses_allocator<tuple<_Types...>, _Alloc> : true_type {}; // true_type if container allocator enabled
1005
1174
1175
+ #if _HAS_CXX23
1176
+ template <class... _TTypes, class... _UTypes, template <class> class _TQual, template <class> class _UQual>
1177
+ requires requires {
1178
+ typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>;
1179
+ }
1180
+ struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> {
1181
+ using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>;
1182
+ };
1183
+
1184
+ template <class... _TTypes, class... _UTypes>
1185
+ requires requires {
1186
+ typename tuple<common_type_t<_TTypes, _UTypes>...>;
1187
+ }
1188
+ struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> {
1189
+ using type = tuple<common_type_t<_TTypes, _UTypes>...>;
1190
+ };
1191
+ #endif // _HAS_CXX23
1192
+
1006
1193
#if _HAS_TR1_NAMESPACE
1007
1194
namespace _DEPRECATE_TR1_NAMESPACE tr1 {
1008
1195
using _STD get;
0 commit comments