// Verify P2321R2 "zip" enhancements to std::pair. // { dg-do run { target c++23 } } #include #include using std::pair; struct A { }; constexpr bool test01() { struct B { bool v; constexpr B(A&) : v(true) { } }; // template // constexpr explicit(false) pair(pair&); pair p2a0; pair p2b0 = p2a0; VERIFY( std::get<0>(p2b0).v ); pair p2a1; pair p2b1 = p2a1; VERIFY( std::get<1>(p2b1).v ); return true; } constexpr bool test02() { struct B { bool v; explicit constexpr B(A&) : v(true) { } }; // template // constexpr explicit(true) pair(pair&); static_assert(!std::is_convertible_v&, pair>); static_assert(!std::is_convertible_v&, pair>); pair p2a0; pair p2b0(p2a0); VERIFY( std::get<0>(p2b0).v ); pair p2a1; pair p2b1(p2a1); VERIFY( std::get<1>(p2b1).v ); return true; } constexpr bool test03() { struct B { bool v; constexpr B(const A&&) : v(true) { } }; // template // constexpr explicit(false) pair(const pair&&); const pair p2a0; pair p2b0 = std::move(p2a0); VERIFY( std::get<0>(p2b0).v ); const pair p2a1; pair p2b1 = std::move(p2a1); VERIFY( std::get<1>(p2b1).v ); return true; } constexpr bool test04() { struct B { bool v; explicit constexpr B(const A&&) : v(true) { } }; // template // constexpr explicit(true) pair(const pair&&); static_assert(!std::is_convertible_v&&, pair>); static_assert(!std::is_convertible_v&&, pair>); const pair p2a0; pair p2b0(std::move(p2a0)); VERIFY( std::get<0>(p2b0).v ); const pair p2a1; pair p2b1(std::move(p2a1)); VERIFY( std::get<1>(p2b1).v ); return true; } constexpr bool test05() { struct B { mutable bool v; constexpr const B& operator=(const A&) const { v = true; return *this; } }; // template // constexpr const pair& operator=(const pair&) const; const pair p2a; const pair p2b; p2b = p2a; return true; } constexpr bool test06() { struct B { mutable bool v; constexpr const B& operator=(A&&) const { v = true; return *this; } }; // template // constexpr const pair& operator=(pair&&) const; pair p2a; const pair p2b; p2b = std::move(p2a); return true; } constexpr bool test07() { struct B { mutable bool v; constexpr const B& operator=(const B&) const { v = true; return *this; } }; // constexpr const pair& operator=(const pair&) const; const pair t2a; const pair t2b; t2b = t2a; VERIFY( std::get<0>(t2b).v ); VERIFY( std::get<1>(t2b).v ); return true; } constexpr bool test08() { struct B { mutable bool v; constexpr const B& operator=(B&&) const { v = true; return *this; } }; // constexpr const pair& operator=(pair&&) const; pair t2a; const pair t2b; t2b = std::move(t2a); VERIFY( std::get<0>(t2b).v ); VERIFY( std::get<1>(t2b).v ); return true; } struct S { mutable int v = 0; friend constexpr void swap(S&& x, S&& y) = delete; friend constexpr void swap(const S& x, const S& y) { ++x.v; ++y.v; } }; constexpr bool test09() { const pair t2, u2; std::swap(t2, u2); VERIFY( std::get<0>(t2).v == 1 ); VERIFY( std::get<0>(u2).v == 1 ); VERIFY( std::get<1>(t2).v == 1 ); VERIFY( std::get<1>(u2).v == 1 ); static_assert(!std::is_swappable_v&>); static_assert(!std::is_swappable_v&>); return true; } int main() { static_assert(test01()); static_assert(test02()); static_assert(test03()); static_assert(test04()); // FIXME: G++ doesn't support reading mutable members during constexpr (PR c++/92505). test05(); test06(); test07(); test08(); test09(); }