@@ -741,6 +741,89 @@ namespace msvc {
741
741
}
742
742
} // namespace gh2770
743
743
744
+ namespace gh4901 {
745
+ #if _HAS_CXX20
746
+ #define CONSTEXPR20 constexpr
747
+ #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
748
+ #define CONSTEXPR20 inline
749
+ #endif // ^^^ !_HAS_CXX20 ^^^
750
+ struct X {
751
+ CONSTEXPR20 ~X () {}
752
+ };
753
+
754
+ struct Y {
755
+ X _;
756
+ };
757
+
758
+ struct ZA {
759
+ std::variant<Y, int > z;
760
+ };
761
+
762
+ struct ZB {
763
+ std::variant<int , Y> z;
764
+ };
765
+
766
+ #if _HAS_CXX20
767
+ static_assert (ZA{0 }.z.index() == 1);
768
+ static_assert (ZA{Y{}}.z.index() == 0);
769
+ static_assert (ZB{0 }.z.index() == 0);
770
+ static_assert (ZB{Y{}}.z.index() == 1);
771
+ #endif // _HAS_CXX20
772
+
773
+ static_assert (std::is_nothrow_destructible_v<X>);
774
+ static_assert (std::is_nothrow_destructible_v<Y>);
775
+ static_assert (std::is_nothrow_destructible_v<std::variant<Y, int >>);
776
+ static_assert (std::is_nothrow_destructible_v<std::variant<int , Y>>);
777
+ static_assert (std::is_nothrow_destructible_v<ZA>);
778
+ static_assert (std::is_nothrow_destructible_v<ZB>);
779
+
780
+ // Verify that variant::~variant is noexcept even when an alternative has a potentially-throwing destructor,
781
+ // per N4988 [res.on.exception.handling]/3.
782
+ struct X2 {
783
+ CONSTEXPR20 ~X2 () noexcept (false ) {}
784
+ };
785
+
786
+ struct Y2 {
787
+ X2 _;
788
+ };
789
+
790
+ struct ZA2 {
791
+ std::variant<Y2, int > z;
792
+ };
793
+
794
+ struct ZB2 {
795
+ std::variant<int , Y2> z;
796
+ };
797
+
798
+ #if _HAS_CXX20
799
+ static_assert (ZA2{0 }.z.index() == 1);
800
+ static_assert (ZA2{Y2{}}.z.index() == 0);
801
+ static_assert (ZB2{0 }.z.index() == 0);
802
+ static_assert (ZB2{Y2{}}.z.index() == 1);
803
+ #endif // _HAS_CXX20
804
+
805
+ static_assert (!std::is_nothrow_destructible_v<X2>);
806
+ static_assert (!std::is_nothrow_destructible_v<Y2>);
807
+ static_assert (std::is_nothrow_destructible_v<std::variant<Y2, int >>);
808
+ static_assert (std::is_nothrow_destructible_v<std::variant<int , Y2>>);
809
+ static_assert (std::is_nothrow_destructible_v<ZA2>);
810
+ static_assert (std::is_nothrow_destructible_v<ZB2>);
811
+
812
+ struct ZC {
813
+ std::variant<Y, int , Y2> z;
814
+ };
815
+
816
+ #if _HAS_CXX20
817
+ static_assert (ZC{Y{}}.z.index() == 0);
818
+ static_assert (ZC{0 }.z.index() == 1);
819
+ static_assert (ZC{Y2{}}.z.index() == 2);
820
+ #endif // _HAS_CXX20
821
+
822
+ static_assert (std::is_nothrow_destructible_v<std::variant<Y, int , Y2>>);
823
+ static_assert (std::is_nothrow_destructible_v<ZC>);
824
+ #undef CONSTEXPR20
825
+ } // namespace gh4901
826
+
744
827
namespace assign_cv {
745
828
template <class T >
746
829
struct TypeIdentityImpl {
0 commit comments