1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
12 // constexpr optional<T>& operator=(optional<T>&& rhs)
13 // noexcept(is_nothrow_move_assignable<T>::value &&
14 // is_nothrow_move_constructible<T>::value);
18 #include <type_traits>
21 #include "test_macros.h"
22 #include "archetypes.h"
28 static bool throw_now
;
46 ~X() { assert(alive
> 0); --alive
; }
51 bool X::throw_now
= false;
56 constexpr bool assign_empty(optional
<Tp
>&& lhs
) {
59 return !lhs
.has_value() && !rhs
.has_value();
63 constexpr bool assign_value(optional
<Tp
>&& lhs
) {
64 optional
<Tp
> rhs(101);
66 return lhs
.has_value() && rhs
.has_value() && *lhs
== Tp
{101};
72 static_assert(std::is_nothrow_move_assignable
<optional
<int>>::value
, "");
74 constexpr optional
<int> opt2
;
75 opt
= std::move(opt2
);
76 static_assert(static_cast<bool>(opt2
) == false, "");
77 assert(static_cast<bool>(opt
) == static_cast<bool>(opt2
));
81 constexpr optional
<int> opt2(2);
82 opt
= std::move(opt2
);
83 static_assert(static_cast<bool>(opt2
) == true, "");
84 static_assert(*opt2
== 2, "");
85 assert(static_cast<bool>(opt
) == static_cast<bool>(opt2
));
86 assert(*opt
== *opt2
);
90 constexpr optional
<int> opt2
;
91 opt
= std::move(opt2
);
92 static_assert(static_cast<bool>(opt2
) == false, "");
93 assert(static_cast<bool>(opt
) == static_cast<bool>(opt2
));
96 using T
= TestTypes::TestType
;
100 assert(T::alive
== 1);
101 opt
= std::move(opt2
);
102 assert(T::alive
== 0);
103 assert(static_cast<bool>(opt2
) == false);
104 assert(static_cast<bool>(opt
) == static_cast<bool>(opt2
));
107 optional
<int> opt(3);
108 constexpr optional
<int> opt2(2);
109 opt
= std::move(opt2
);
110 static_assert(static_cast<bool>(opt2
) == true, "");
111 static_assert(*opt2
== 2, "");
112 assert(static_cast<bool>(opt
) == static_cast<bool>(opt2
));
113 assert(*opt
== *opt2
);
116 using O
= optional
<int>;
117 static_assert(assign_empty(O
{42}));
118 static_assert(assign_value(O
{42}));
119 assert(assign_empty(O
{42}));
120 assert(assign_value(O
{42}));
123 using O
= optional
<TrivialTestTypes::TestType
>;
124 static_assert(assign_empty(O
{42}));
125 static_assert(assign_value(O
{42}));
126 assert(assign_empty(O
{42}));
127 assert(assign_value(O
{42}));
129 #ifndef TEST_HAS_NO_EXCEPTIONS
131 static_assert(!std::is_nothrow_move_assignable
<optional
<X
>>::value
, "");
133 X::throw_now
= false;
135 optional
<X
> opt2(X
{});
136 assert(X::alive
== 1);
137 assert(static_cast<bool>(opt2
) == true);
141 opt
= std::move(opt2
);
147 assert(static_cast<bool>(opt
) == false);
149 assert(X::alive
== 1);
151 assert(X::alive
== 0);
153 static_assert(!std::is_nothrow_move_assignable
<optional
<X
>>::value
, "");
154 X::throw_now
= false;
155 optional
<X
> opt(X
{});
156 optional
<X
> opt2(X
{});
157 assert(X::alive
== 2);
158 assert(static_cast<bool>(opt2
) == true);
162 opt
= std::move(opt2
);
168 assert(static_cast<bool>(opt
) == true);
170 assert(X::alive
== 2);
172 assert(X::alive
== 0);
173 #endif // TEST_HAS_NO_EXCEPTIONS
175 static_assert(std::is_nothrow_move_assignable
<optional
<Y
>>::value
, "");
179 ThrowsMove() noexcept
{}
180 ThrowsMove(ThrowsMove
const&) noexcept
{}
181 ThrowsMove(ThrowsMove
&&) noexcept(false) {}
182 ThrowsMove
& operator=(ThrowsMove
const&) noexcept
{ return *this; }
183 ThrowsMove
& operator=(ThrowsMove
&&) noexcept
{ return *this; }
185 static_assert(!std::is_nothrow_move_assignable
<optional
<ThrowsMove
>>::value
, "");
186 struct ThrowsMoveAssign
{
187 ThrowsMoveAssign() noexcept
{}
188 ThrowsMoveAssign(ThrowsMoveAssign
const&) noexcept
{}
189 ThrowsMoveAssign(ThrowsMoveAssign
&&) noexcept
{}
190 ThrowsMoveAssign
& operator=(ThrowsMoveAssign
const&) noexcept
{ return *this; }
191 ThrowsMoveAssign
& operator=(ThrowsMoveAssign
&&) noexcept(false) { return *this; }
193 static_assert(!std::is_nothrow_move_assignable
<optional
<ThrowsMoveAssign
>>::value
, "");
195 NoThrowMove() noexcept(false) {}
196 NoThrowMove(NoThrowMove
const&) noexcept(false) {}
197 NoThrowMove(NoThrowMove
&&) noexcept
{}
198 NoThrowMove
& operator=(NoThrowMove
const&) noexcept
{ return *this; }
199 NoThrowMove
& operator=(NoThrowMove
&&) noexcept
{ return *this; }
201 static_assert(std::is_nothrow_move_assignable
<optional
<NoThrowMove
>>::value
, "");