1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// { dg-do run { target c++23 } }
#include <expected>
#include <testsuite_hooks.h>
struct NonTrivial
{
constexpr NonTrivial(int i) : i(i) { }
constexpr NonTrivial(const NonTrivial& x) noexcept(false): i(x.i) { }
constexpr ~NonTrivial() { }
int i;
constexpr bool operator==(const NonTrivial&) const = default;
};
constexpr bool
test_swap_obj()
{
std::expected<int, int> e1(1), e2(2);
std::expected<int, int> e3(std::unexpect, 3), e4(std::unexpect, 4);
swap(e1, e2);
VERIFY( e1.value() == 2 );
VERIFY( e2.value() == 1 );
swap(e1, e3);
VERIFY( ! e1.has_value() );
VERIFY( e1.error() == 3 );
VERIFY( e3.value() == 2 );
swap(e1, e3);
VERIFY( ! e3.has_value() );
VERIFY( e1.value() == 2 );
VERIFY( e3.error() == 3 );
swap(e3, e4);
VERIFY( ! e3.has_value() );
VERIFY( ! e4.has_value() );
VERIFY( e3.error() == 4 );
VERIFY( e4.error() == 3 );
std::expected<int, NonTrivial> e5(1), e6(2);
std::expected<int, NonTrivial> e7(std::unexpect, 3), e8(std::unexpect, 4);
swap(e5, e6);
VERIFY( e5.value() == 2 );
VERIFY( e6.value() == 1 );
swap(e5, e7);
VERIFY( ! e5.has_value() );
VERIFY( e5.error() == 3 );
VERIFY( e7.value() == 2 );
swap(e5, e7);
VERIFY( ! e7.has_value() );
VERIFY( e5.value() == 2 );
VERIFY( e7.error() == 3 );
swap(e7, e8);
VERIFY( ! e7.has_value() );
VERIFY( ! e8.has_value() );
VERIFY( e7.error() == 4 );
VERIFY( e8.error() == 3 );
std::expected<NonTrivial, int> e9(1), e10(2);
std::expected<NonTrivial, int> e11(std::unexpect, 3), e12(std::unexpect, 4);
swap(e9, e10);
VERIFY( e9.value() == 2 );
VERIFY( e10.value() == 1 );
swap(e9, e11);
VERIFY( ! e9.has_value() );
VERIFY( e9.error() == 3 );
VERIFY( e11.value() == 2 );
swap(e9, e11);
VERIFY( ! e11.has_value() );
VERIFY( e9.value() == 2 );
VERIFY( e11.error() == 3 );
swap(e11, e12);
VERIFY( ! e11.has_value() );
VERIFY( ! e12.has_value() );
VERIFY( e11.error() == 4 );
VERIFY( e12.error() == 3 );
return true;
}
constexpr bool
test_swap_void()
{
std::expected<void, int> v1, v2;
std::expected<void, int> v3(std::unexpect, 3), v4(std::unexpect, 4);
swap(v1, v2);
VERIFY( v1.has_value() );
VERIFY( v2.has_value() );
swap(v1, v3);
VERIFY( ! v1.has_value() );
VERIFY( v1.error() == 3 );
VERIFY( v3.has_value() );
swap(v1, v3);
VERIFY( ! v3.has_value() );
VERIFY( v1.has_value() );
VERIFY( v3.error() == 3 );
swap(v3, v4);
VERIFY( ! v3.has_value() );
VERIFY( ! v4.has_value() );
VERIFY( v3.error() == 4 );
VERIFY( v4.error() == 3 );
std::expected<void, NonTrivial> v5, v6;
std::expected<void, NonTrivial> v7(std::unexpect, 3), v8(std::unexpect, 4);
swap(v5, v6);
VERIFY( v5.has_value() );
VERIFY( v6.has_value() );
swap(v5, v7);
VERIFY( ! v5.has_value() );
VERIFY( v5.error() == 3 );
VERIFY( v7.has_value() );
swap(v5, v7);
VERIFY( ! v7.has_value() );
VERIFY( v5.has_value() );
VERIFY( v7.error() == 3 );
swap(v7, v8);
VERIFY( ! v7.has_value() );
VERIFY( ! v8.has_value() );
VERIFY( v7.error() == 4 );
VERIFY( v8.error() == 3 );
return true;
}
static_assert( std::is_swappable_v<std::expected<int, int>> );
static_assert( std::is_swappable_v<std::expected<void, int>> );
struct A { A& operator=(A&&) = delete; };
static_assert( ! std::is_swappable_v<std::expected<A, int>> );
static_assert( ! std::is_swappable_v<std::expected<int, A>> );
static_assert( ! std::is_swappable_v<std::expected<void, A>> );
int main()
{
static_assert( test_swap_obj() );
test_swap_obj();
static_assert( test_swap_void() );
test_swap_void();
}
|