1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // UNSUPPORTED: c++98, c++03, c++11
11 // <optional>
12
13 // optional<T>& operator=(optional<T>&& rhs)
14 // noexcept(is_nothrow_move_assignable<T>::value &&
15 // is_nothrow_move_constructible<T>::value);
16
17 #include <experimental/optional>
18 #include <type_traits>
19 #include <cassert>
20
21 #include "test_macros.h"
22
23 using std::experimental::optional;
24
25 struct AllowConstAssign {
AllowConstAssignAllowConstAssign26 AllowConstAssign(AllowConstAssign const&) {}
operator =AllowConstAssign27 AllowConstAssign const& operator=(AllowConstAssign const&) const {
28 return *this;
29 }
30 };
31
32 struct X
33 {
34 static bool throw_now;
35
36 X() = default;
XX37 X(X&&)
38 {
39 if (throw_now)
40 TEST_THROW(6);
41 }
operator =X42 X& operator=(X&&) noexcept
43 {
44 return *this;
45 }
46 };
47
48 bool X::throw_now = false;
49
50 struct Y {};
51
main()52 int main()
53 {
54 {
55 static_assert(std::is_nothrow_move_assignable<optional<int>>::value, "");
56 optional<int> opt;
57 constexpr optional<int> opt2;
58 opt = std::move(opt2);
59 static_assert(static_cast<bool>(opt2) == false, "");
60 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
61 }
62 {
63 optional<int> opt;
64 constexpr optional<int> opt2(2);
65 opt = std::move(opt2);
66 static_assert(static_cast<bool>(opt2) == true, "");
67 static_assert(*opt2 == 2, "");
68 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
69 assert(*opt == *opt2);
70 }
71 {
72 optional<int> opt(3);
73 constexpr optional<int> opt2;
74 opt = std::move(opt2);
75 static_assert(static_cast<bool>(opt2) == false, "");
76 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
77 }
78 {
79 optional<int> opt(3);
80 constexpr optional<int> opt2(2);
81 opt = std::move(opt2);
82 static_assert(static_cast<bool>(opt2) == true, "");
83 static_assert(*opt2 == 2, "");
84 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
85 assert(*opt == *opt2);
86 }
87 {
88 optional<const AllowConstAssign> opt;
89 optional<const AllowConstAssign> opt2;
90 opt = std::move(opt2);
91 }
92 #ifndef TEST_HAS_NO_EXCEPTIONS
93 {
94 static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
95 optional<X> opt;
96 optional<X> opt2(X{});
97 assert(static_cast<bool>(opt2) == true);
98 try
99 {
100 X::throw_now = true;
101 opt = std::move(opt2);
102 assert(false);
103 }
104 catch (int i)
105 {
106 assert(i == 6);
107 assert(static_cast<bool>(opt) == false);
108 }
109 }
110 #endif
111 {
112 static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, "");
113 }
114 }
115