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
14 // optional<T>& operator=(const optional<U>& rhs);
17 #include <type_traits>
20 #include "test_macros.h"
21 #include "archetypes.h"
27 static bool throw_now
;
37 bool X::throw_now
= false;
43 Y1
& operator=(const Y1
&) = delete;
49 Y2(const int&) = delete;
50 Y2
& operator=(const int&) { return *this; }
54 struct AssignableFrom
{
55 static int type_constructed
;
56 static int type_assigned
;
57 static int int_constructed
;
58 static int int_assigned
;
61 type_constructed
= int_constructed
= 0;
62 type_assigned
= int_assigned
= 0;
65 AssignableFrom() = default;
67 explicit AssignableFrom(T
) { ++type_constructed
; }
68 AssignableFrom
& operator=(T
) { ++type_assigned
; return *this; }
70 AssignableFrom(int) { ++int_constructed
; }
71 AssignableFrom
& operator=(int) { ++int_assigned
; return *this; }
73 AssignableFrom(AssignableFrom
const&) = delete;
74 AssignableFrom
& operator=(AssignableFrom
const&) = delete;
77 template <class T
> int AssignableFrom
<T
>::type_constructed
= 0;
78 template <class T
> int AssignableFrom
<T
>::type_assigned
= 0;
79 template <class T
> int AssignableFrom
<T
>::int_constructed
= 0;
80 template <class T
> int AssignableFrom
<T
>::int_assigned
= 0;
83 void test_with_test_type() {
84 using T
= TestTypes::TestType
;
86 { // non-empty to empty
87 T::reset_constructors();
89 const optional
<int> other(42);
91 assert(T::alive
== 1);
92 assert(T::constructed
== 1);
93 assert(T::value_constructed
== 1);
94 assert(T::assigned
== 0);
95 assert(T::destroyed
== 0);
96 assert(static_cast<bool>(other
) == true);
98 assert(static_cast<bool>(opt
) == true);
99 assert(*opt
== T(42));
101 assert(T::alive
== 0);
102 { // non-empty to non-empty
103 optional
<T
> opt(101);
104 const optional
<int> other(42);
105 T::reset_constructors();
107 assert(T::alive
== 1);
108 assert(T::constructed
== 0);
109 assert(T::assigned
== 1);
110 assert(T::value_assigned
== 1);
111 assert(T::destroyed
== 0);
112 assert(static_cast<bool>(other
) == true);
113 assert(*other
== 42);
114 assert(static_cast<bool>(opt
) == true);
115 assert(*opt
== T(42));
117 assert(T::alive
== 0);
118 { // empty to non-empty
119 optional
<T
> opt(101);
120 const optional
<int> other
;
121 T::reset_constructors();
123 assert(T::alive
== 0);
124 assert(T::constructed
== 0);
125 assert(T::assigned
== 0);
126 assert(T::destroyed
== 1);
127 assert(static_cast<bool>(other
) == false);
128 assert(static_cast<bool>(opt
) == false);
130 assert(T::alive
== 0);
133 const optional
<int> other
;
134 T::reset_constructors();
136 assert(T::alive
== 0);
137 assert(T::constructed
== 0);
138 assert(T::assigned
== 0);
139 assert(T::destroyed
== 0);
140 assert(static_cast<bool>(other
) == false);
141 assert(static_cast<bool>(opt
) == false);
143 assert(T::alive
== 0);
146 void test_ambiguous_assign() {
147 using OptInt
= std::optional
<int>;
149 using T
= AssignableFrom
<OptInt
const&>;
155 assert(T::type_constructed
== 1);
156 assert(T::type_assigned
== 0);
157 assert(T::int_constructed
== 0);
158 assert(T::int_assigned
== 0);
162 std::optional
<T
> t(42);
164 assert(T::type_constructed
== 0);
165 assert(T::type_assigned
== 1);
166 assert(T::int_constructed
== 1);
167 assert(T::int_assigned
== 0);
171 std::optional
<T
> t(42);
173 assert(T::type_constructed
== 0);
174 assert(T::type_assigned
== 1);
175 assert(T::int_constructed
== 1);
176 assert(T::int_assigned
== 0);
180 using T
= AssignableFrom
<OptInt
&>;
186 assert(T::type_constructed
== 1);
187 assert(T::type_assigned
== 0);
188 assert(T::int_constructed
== 0);
189 assert(T::int_assigned
== 0);
192 using Opt
= std::optional
<T
>;
193 static_assert(!std::is_assignable_v
<Opt
&, OptInt
const&>, "");
199 int main(int, char**)
201 test_with_test_type();
202 test_ambiguous_assign();
205 constexpr optional
<short> opt2
;
207 static_assert(static_cast<bool>(opt2
) == false, "");
208 assert(static_cast<bool>(opt
) == static_cast<bool>(opt2
));
212 constexpr optional
<short> opt2(short{2});
214 static_assert(static_cast<bool>(opt2
) == true, "");
215 static_assert(*opt2
== 2, "");
216 assert(static_cast<bool>(opt
) == static_cast<bool>(opt2
));
217 assert(*opt
== *opt2
);
220 optional
<int> opt(3);
221 constexpr optional
<short> opt2
;
223 static_assert(static_cast<bool>(opt2
) == false, "");
224 assert(static_cast<bool>(opt
) == static_cast<bool>(opt2
));
227 optional
<int> opt(3);
228 constexpr optional
<short> opt2(short{2});
230 static_assert(static_cast<bool>(opt2
) == true, "");
231 static_assert(*opt2
== 2, "");
232 assert(static_cast<bool>(opt
) == static_cast<bool>(opt2
));
233 assert(*opt
== *opt2
);
235 #ifndef TEST_HAS_NO_EXCEPTIONS
238 optional
<int> opt2(42);
239 assert(static_cast<bool>(opt2
) == true);
249 assert(static_cast<bool>(opt
) == false);