// { dg-do compile { target c++20 } } // { dg-add-options no_pch } #include // P2231R1 Missing constexpr in std::optional and std::variant #ifndef __cpp_lib_variant #error "Feature test macro for variant is missing in " #elif __cpp_lib_variant < 202106L # error "Feature test macro for variant has wrong value for C++20 in " #endif #include constexpr bool test_assign() { std::variant v1(1); v1 = 2.5; VERIFY( std::get(v1) == 2.5 ); v1 = 99; VERIFY( std::get(v1) == 99 ); v1 = 999; VERIFY( std::get(v1) == 999 ); struct S // non-trivial special members { constexpr S(int i) : i(i) { } constexpr ~S() { } constexpr S(const S& s) : i(s.i) { } int i; }; std::variant v; v = S(123); VERIFY( std::get<1>(v).i == 123 ); const S s(456); v = s; VERIFY( std::get<1>(v).i == 456 ); v = 789; VERIFY( std::get<0>(v) == 789 ); return true; } static_assert( test_assign() ); constexpr bool test_emplace() { struct S // non-trivial special members { constexpr S(std::initializer_list l) : i(l.begin()[0]) { } constexpr S(std::initializer_list l, int n) : i(l.begin()[n]) { } constexpr ~S() { } constexpr S(const S& s) : i(s.i) { } int i; }; std::variant v(1); // template constexpr T& emplace(Args&&... args); v.emplace(2.0); VERIFY( std::get<1>(v) == 2.0 ); v.emplace(2.5); VERIFY( std::get<1>(v) == 2.5 ); v.emplace(2.5); VERIFY( std::get<0>(v) == 2 ); // template // constexpr T& emplace(initializer_list, Args&&... args); v.emplace({3, 2, 1}); VERIFY( std::get<2>(v).i == 3 ); v.emplace({3, 2, 1}, 1); VERIFY( std::get<2>(v).i == 2 ); // template // constexpr variant_alternative_t& emplace(Args&&... args); v.emplace<1>(3.0); VERIFY( std::get<1>(v) == 3.0 ); v.emplace<1>(0.5); VERIFY( std::get<1>(v) == 0.5 ); v.emplace<0>(1.5); VERIFY( std::get<0>(v) == 1 ); // template // constexpr variant_alternative_t& // emplace(initializer_list, Args&&... args); v.emplace<2>({7, 8, 9}); VERIFY( std::get<2>(v).i == 7 ); v.emplace<2>({13, 12, 11}, 1); VERIFY( std::get<2>(v).i == 12 ); return true; } static_assert( test_emplace() ); constexpr bool test_swap() { std::variant v1(1), v2(2.5); v1.swap(v2); VERIFY( std::get(v1) == 2.5 ); VERIFY( std::get(v2) == 1 ); swap(v1, v2); VERIFY( std::get(v1) == 1 ); VERIFY( std::get(v2) == 2.5 ); struct S { constexpr S(int i) : i(i) { } constexpr S(S&& s) : i(s.i) { } constexpr S& operator=(S&& s) { i = s.i; s.i = -1; return *this; } int i; }; std::variant v3(3), v4(S(4)); v3.swap(v4); VERIFY( std::get(v3).i == 4 ); VERIFY( std::get(v4) == 3 ); v3.swap(v4); VERIFY( std::get(v3) == 3 ); VERIFY( std::get(v4).i == 4 ); return true; } static_assert( test_swap() );