[analyzer][Z3] Restore the original timeout of 15s (#118291)
[llvm-project.git] / libcxx / test / std / utilities / expected / expected.void / assign / assign.move.pass.cpp
blobd96a70ccff67f87e8eb21c305789937fbfd5ffe3
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
11 // constexpr expected& operator=(expected&& rhs) noexcept(see below);
13 // Effects:
14 // - If this->has_value() && rhs.has_value() is true, no effects.
15 // - Otherwise, if this->has_value() is true, equivalent to:
16 // construct_at(addressof(unex), std::move(rhs.unex));
17 // has_val = false;
18 // - Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
19 // - Otherwise, equivalent to unex = std::move(rhs.error()).
21 // Returns: *this.
23 // Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>.
25 // This operator is defined as deleted unless is_move_constructible_v<E> is true and is_move_assignable_v<E> is true.
27 #include <cassert>
28 #include <concepts>
29 #include <expected>
30 #include <type_traits>
31 #include <utility>
33 #include "../../types.h"
34 #include "test_macros.h"
36 struct NotMoveConstructible {
37 NotMoveConstructible(NotMoveConstructible&&) = delete;
38 NotMoveConstructible& operator=(NotMoveConstructible&&) = default;
41 struct NotMoveAssignable {
42 NotMoveAssignable(NotMoveAssignable&&) = default;
43 NotMoveAssignable& operator=(NotMoveAssignable&&) = delete;
46 // Test constraints
47 static_assert(std::is_move_assignable_v<std::expected<void, int>>);
49 // !is_move_assignable_v<E>
50 static_assert(!std::is_move_assignable_v<std::expected<void, NotMoveAssignable>>);
52 // !is_move_constructible_v<E>
53 static_assert(!std::is_move_assignable_v<std::expected<void, NotMoveConstructible>>);
55 // Test noexcept
56 struct MoveCtorMayThrow {
57 MoveCtorMayThrow(MoveCtorMayThrow&&) noexcept(false) {}
58 MoveCtorMayThrow& operator=(MoveCtorMayThrow&&) noexcept = default;
61 struct MoveAssignMayThrow {
62 MoveAssignMayThrow(MoveAssignMayThrow&&) noexcept = default;
63 MoveAssignMayThrow& operator=(MoveAssignMayThrow&&) noexcept(false) { return *this; }
66 // Test noexcept
67 static_assert(std::is_nothrow_move_assignable_v<std::expected<void, int>>);
69 // !is_nothrow_move_assignable_v<E>
70 static_assert(!std::is_nothrow_move_assignable_v<std::expected<void, MoveAssignMayThrow>>);
72 // !is_nothrow_move_constructible_v<E>
73 static_assert(!std::is_nothrow_move_assignable_v<std::expected<void, MoveCtorMayThrow>>);
75 constexpr bool test() {
76 // If this->has_value() && rhs.has_value() is true, no effects.
78 std::expected<void, int> e1;
79 std::expected<void, int> e2;
80 decltype(auto) x = (e1 = std::move(e2));
81 static_assert(std::same_as<decltype(x), std::expected<void, int>&>);
82 assert(&x == &e1);
83 assert(e1.has_value());
86 // Otherwise, if this->has_value() is true, equivalent to:
87 // construct_at(addressof(unex), std::move(rhs.unex));
88 // has_val = false;
90 Traced::state state{};
91 std::expected<void, Traced> e1;
92 std::expected<void, Traced> e2(std::unexpect, state, 5);
93 decltype(auto) x = (e1 = std::move(e2));
94 static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
95 assert(&x == &e1);
96 assert(!e1.has_value());
97 assert(e1.error().data_ == 5);
99 assert(state.moveCtorCalled);
102 // Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
104 Traced::state state{};
105 std::expected<void, Traced> e1(std::unexpect, state, 5);
106 std::expected<void, Traced> e2;
107 decltype(auto) x = (e1 = std::move(e2));
108 static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
109 assert(&x == &e1);
110 assert(e1.has_value());
112 assert(state.dtorCalled);
115 // Otherwise, equivalent to unex = rhs.error().
117 Traced::state state{};
118 std::expected<void, Traced> e1(std::unexpect, state, 5);
119 std::expected<void, Traced> e2(std::unexpect, state, 10);
120 decltype(auto) x = (e1 = std::move(e2));
121 static_assert(std::same_as<decltype(x), std::expected<void, Traced>&>);
122 assert(&x == &e1);
123 assert(!e1.has_value());
124 assert(e1.error().data_ == 10);
126 assert(state.moveAssignCalled);
129 // CheckForInvalidWrites
132 CheckForInvalidWrites<true, true> e1;
133 CheckForInvalidWrites<true, true> e2(std::unexpect);
135 e1 = std::move(e2);
137 assert(e1.check());
138 assert(e2.check());
141 CheckForInvalidWrites<false, true> e1;
142 CheckForInvalidWrites<false, true> e2(std::unexpect);
144 e1 = std::move(e2);
146 assert(e1.check());
147 assert(e2.check());
151 return true;
154 void testException() {
155 #ifndef TEST_HAS_NO_EXCEPTIONS
156 std::expected<void, ThrowOnMoveConstruct> e1(std::in_place);
157 std::expected<void, ThrowOnMoveConstruct> e2(std::unexpect);
158 try {
159 e1 = std::move(e2);
160 assert(false);
161 } catch (Except) {
162 assert(e1.has_value());
164 #endif // TEST_HAS_NO_EXCEPTIONS
167 int main(int, char**) {
168 test();
169 static_assert(test());
170 testException();
171 return 0;