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
15 // optional<T>& operator=(optional<U>&& rhs);
18 #include <type_traits>
22 #include "test_macros.h"
23 #include "archetypes.hpp"
29 static bool throw_now;
39 bool X::throw_now = false;
45 Y1& operator=(const Y1&) = delete;
51 Y2(const int&) = delete;
52 Y2& operator=(const int&) { return *this; }
56 class D : public B {};
60 struct AssignableFrom {
61 static int type_constructed;
62 static int type_assigned;
63 static int int_constructed;
64 static int int_assigned;
67 type_constructed = int_constructed = 0;
68 type_assigned = int_assigned = 0;
71 AssignableFrom() = default;
73 explicit AssignableFrom(T) { ++type_constructed; }
74 AssignableFrom& operator=(T) { ++type_assigned; return *this; }
76 AssignableFrom(int) { ++int_constructed; }
77 AssignableFrom& operator=(int) { ++int_assigned; return *this; }
79 AssignableFrom(AssignableFrom const&) = delete;
80 AssignableFrom& operator=(AssignableFrom const&) = delete;
83 template <class T> int AssignableFrom<T>::type_constructed = 0;
84 template <class T> int AssignableFrom<T>::type_assigned = 0;
85 template <class T> int AssignableFrom<T>::int_constructed = 0;
86 template <class T> int AssignableFrom<T>::int_assigned = 0;
88 void test_with_test_type() {
89 using T = TestTypes::TestType;
91 { // non-empty to empty
92 T::reset_constructors();
94 optional<int> other(42);
95 opt = std::move(other);
96 assert(T::alive == 1);
97 assert(T::constructed == 1);
98 assert(T::value_constructed == 1);
99 assert(T::assigned == 0);
100 assert(T::destroyed == 0);
101 assert(static_cast<bool>(other) == true);
102 assert(*other == 42);
103 assert(static_cast<bool>(opt) == true);
104 assert(*opt == T(42));
106 assert(T::alive == 0);
107 { // non-empty to non-empty
108 optional<T> opt(101);
109 optional<int> other(42);
110 T::reset_constructors();
111 opt = std::move(other);
112 assert(T::alive == 1);
113 assert(T::constructed == 0);
114 assert(T::assigned == 1);
115 assert(T::value_assigned == 1);
116 assert(T::destroyed == 0);
117 assert(static_cast<bool>(other) == true);
118 assert(*other == 42);
119 assert(static_cast<bool>(opt) == true);
120 assert(*opt == T(42));
122 assert(T::alive == 0);
123 { // empty to non-empty
124 optional<T> opt(101);
126 T::reset_constructors();
127 opt = std::move(other);
128 assert(T::alive == 0);
129 assert(T::constructed == 0);
130 assert(T::assigned == 0);
131 assert(T::destroyed == 1);
132 assert(static_cast<bool>(other) == false);
133 assert(static_cast<bool>(opt) == false);
135 assert(T::alive == 0);
139 T::reset_constructors();
140 opt = std::move(other);
141 assert(T::alive == 0);
142 assert(T::constructed == 0);
143 assert(T::assigned == 0);
144 assert(T::destroyed == 0);
145 assert(static_cast<bool>(other) == false);
146 assert(static_cast<bool>(opt) == false);
148 assert(T::alive == 0);
152 void test_ambigious_assign() {
153 using OptInt = std::optional<int>;
155 using T = AssignableFrom<OptInt&&>;
161 assert(T::type_constructed == 1);
162 assert(T::type_assigned == 0);
163 assert(T::int_constructed == 0);
164 assert(T::int_assigned == 0);
167 using Opt = std::optional<T>;
168 static_assert(!std::is_assignable<Opt&, const OptInt&&>::value, "");
169 static_assert(!std::is_assignable<Opt&, const OptInt&>::value, "");
170 static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
174 using T = AssignableFrom<OptInt const&&>;
180 assert(T::type_constructed == 1);
181 assert(T::type_assigned == 0);
182 assert(T::int_constructed == 0);
183 assert(T::int_assigned == 0);
190 assert(T::type_constructed == 1);
191 assert(T::type_assigned == 0);
192 assert(T::int_constructed == 0);
193 assert(T::int_assigned == 0);
196 using Opt = std::optional<T>;
197 static_assert(std::is_assignable<Opt&, OptInt&&>::value, "");
198 static_assert(!std::is_assignable<Opt&, const OptInt&>::value, "");
199 static_assert(!std::is_assignable<Opt&, OptInt&>::value, "");
207 test_with_test_type();
208 test_ambigious_assign();
211 optional<short> opt2;
212 opt = std::move(opt2);
213 assert(static_cast<bool>(opt2) == false);
214 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
218 optional<short> opt2(short{2});
219 opt = std::move(opt2);
220 assert(static_cast<bool>(opt2) == true);
222 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
223 assert(*opt == *opt2);
226 optional<int> opt(3);
227 optional<short> opt2;
228 opt = std::move(opt2);
229 assert(static_cast<bool>(opt2) == false);
230 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
233 optional<int> opt(3);
234 optional<short> opt2(short{2});
235 opt = std::move(opt2);
236 assert(static_cast<bool>(opt2) == true);
238 assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
239 assert(*opt == *opt2);
242 optional<std::unique_ptr<B>> opt;
243 optional<std::unique_ptr<D>> other(new D());
244 opt = std::move(other);
245 assert(static_cast<bool>(opt) == true);
246 assert(static_cast<bool>(other) == true);
247 assert(opt->get() != nullptr);
248 assert(other->get() == nullptr);
250 #ifndef TEST_HAS_NO_EXCEPTIONS
253 optional<int> opt2(42);
254 assert(static_cast<bool>(opt2) == true);
258 opt = std::move(opt2);
264 assert(static_cast<bool>(opt) == false);