1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
13 // optional<T>& operator=(optional<T>&& rhs)
14 // noexcept(is_nothrow_move_assignable<T>::value &&
15 // is_nothrow_move_constructible<T>::value);
18 #include <type_traits>
21 #include "test_macros.h"
22 #include "archetypes.hpp"
28 static bool throw_now;
46 ~X() { assert(alive > 0); --alive; }
51 bool X::throw_now = false;
57 static_assert(std::is_nothrow_move_assignable<optional<int>>::value, "");
59 constexpr optional<int> opt2;
60 opt = std::move(opt2);
61 static_assert(static_cast<bool>(opt2) == false, "");
62 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
66 constexpr optional<int> opt2(2);
67 opt = std::move(opt2);
68 static_assert(static_cast<bool>(opt2) == true, "");
69 static_assert(*opt2 == 2, "");
70 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
71 assert(*opt == *opt2);
75 constexpr optional<int> opt2;
76 opt = std::move(opt2);
77 static_assert(static_cast<bool>(opt2) == false, "");
78 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
81 using T = TestTypes::TestType;
85 assert(T::alive == 1);
86 opt = std::move(opt2);
87 assert(T::alive == 0);
88 assert(static_cast<bool>(opt2) == false);
89 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
93 constexpr optional<int> opt2(2);
94 opt = std::move(opt2);
95 static_assert(static_cast<bool>(opt2) == true, "");
96 static_assert(*opt2 == 2, "");
97 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
98 assert(*opt == *opt2);
100 #ifndef TEST_HAS_NO_EXCEPTIONS
102 static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
104 X::throw_now = false;
106 optional<X> opt2(X{});
107 assert(X::alive == 1);
108 assert(static_cast<bool>(opt2) == true);
112 opt = std::move(opt2);
118 assert(static_cast<bool>(opt) == false);
120 assert(X::alive == 1);
122 assert(X::alive == 0);
124 static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
125 X::throw_now = false;
126 optional<X> opt(X{});
127 optional<X> opt2(X{});
128 assert(X::alive == 2);
129 assert(static_cast<bool>(opt2) == true);
133 opt = std::move(opt2);
139 assert(static_cast<bool>(opt) == true);
141 assert(X::alive == 2);
143 assert(X::alive == 0);
144 #endif // TEST_HAS_NO_EXCEPTIONS
146 static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, "");
150 ThrowsMove() noexcept {}
151 ThrowsMove(ThrowsMove const&) noexcept {}
152 ThrowsMove(ThrowsMove &&) noexcept(false) {}
153 ThrowsMove& operator=(ThrowsMove const&) noexcept { return *this; }
154 ThrowsMove& operator=(ThrowsMove &&) noexcept { return *this; }
156 static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMove>>::value, "");
157 struct ThrowsMoveAssign {
158 ThrowsMoveAssign() noexcept {}
159 ThrowsMoveAssign(ThrowsMoveAssign const&) noexcept {}
160 ThrowsMoveAssign(ThrowsMoveAssign &&) noexcept {}
161 ThrowsMoveAssign& operator=(ThrowsMoveAssign const&) noexcept { return *this; }
162 ThrowsMoveAssign& operator=(ThrowsMoveAssign &&) noexcept(false) { return *this; }
164 static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMoveAssign>>::value, "");
166 NoThrowMove() noexcept(false) {}
167 NoThrowMove(NoThrowMove const&) noexcept(false) {}
168 NoThrowMove(NoThrowMove &&) noexcept {}
169 NoThrowMove& operator=(NoThrowMove const&) noexcept { return *this; }
170 NoThrowMove& operator=(NoThrowMove&&) noexcept { return *this; }
172 static_assert(std::is_nothrow_move_assignable<optional<NoThrowMove>>::value, "");