blob: d98dd40ec6bfffab1cd521817e541d65ff97ea1a [file] [log] [blame]
Howard Hinnant01afa5c2013-09-02 20:30:37 +00001//===----------------------------------------------------------------------===//
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// <optional>
11
12// template <class T> void swap(optional<T>& x, optional<T>& y)
13// noexcept(noexcept(x.swap(y)));
14
15#include <optional>
16#include <type_traits>
17#include <cassert>
18
19#if _LIBCPP_STD_VER > 11
20
21class X
22{
23 int i_;
24public:
25 static unsigned dtor_called;
26 X(int i) : i_(i) {}
27 X(X&& x) = default;
28 X& operator=(X&&) = default;
29 ~X() {++dtor_called;}
30
31 friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
32};
33
34unsigned X::dtor_called = 0;
35
36class Y
37{
38 int i_;
39public:
40 static unsigned dtor_called;
41 Y(int i) : i_(i) {}
42 Y(Y&&) = default;
43 ~Y() {++dtor_called;}
44
45 friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
46 friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
47};
48
49unsigned Y::dtor_called = 0;
50
51class Z
52{
53 int i_;
54public:
55 Z(int i) : i_(i) {}
56 Z(Z&&) {throw 7;}
57
58 friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
59 friend void swap(Z& x, Z& y) {throw 6;}
60};
61
62
63#endif // _LIBCPP_STD_VER > 11
64
65int main()
66{
67#if _LIBCPP_STD_VER > 11
68 {
69 std::optional<int> opt1;
70 std::optional<int> opt2;
71 static_assert(noexcept(swap(opt1, opt2)) == true, "");
72 assert(static_cast<bool>(opt1) == false);
73 assert(static_cast<bool>(opt2) == false);
74 swap(opt1, opt2);
75 assert(static_cast<bool>(opt1) == false);
76 assert(static_cast<bool>(opt2) == false);
77 }
78 {
79 std::optional<int> opt1(1);
80 std::optional<int> opt2;
81 static_assert(noexcept(swap(opt1, opt2)) == true, "");
82 assert(static_cast<bool>(opt1) == true);
83 assert(*opt1 == 1);
84 assert(static_cast<bool>(opt2) == false);
85 swap(opt1, opt2);
86 assert(static_cast<bool>(opt1) == false);
87 assert(static_cast<bool>(opt2) == true);
88 assert(*opt2 == 1);
89 }
90 {
91 std::optional<int> opt1;
92 std::optional<int> opt2(2);
93 static_assert(noexcept(swap(opt1, opt2)) == true, "");
94 assert(static_cast<bool>(opt1) == false);
95 assert(static_cast<bool>(opt2) == true);
96 assert(*opt2 == 2);
97 swap(opt1, opt2);
98 assert(static_cast<bool>(opt1) == true);
99 assert(*opt1 == 2);
100 assert(static_cast<bool>(opt2) == false);
101 }
102 {
103 std::optional<int> opt1(1);
104 std::optional<int> opt2(2);
105 static_assert(noexcept(swap(opt1, opt2)) == true, "");
106 assert(static_cast<bool>(opt1) == true);
107 assert(*opt1 == 1);
108 assert(static_cast<bool>(opt2) == true);
109 assert(*opt2 == 2);
110 swap(opt1, opt2);
111 assert(static_cast<bool>(opt1) == true);
112 assert(*opt1 == 2);
113 assert(static_cast<bool>(opt2) == true);
114 assert(*opt2 == 1);
115 }
116 {
117 std::optional<X> opt1;
118 std::optional<X> opt2;
119 static_assert(noexcept(swap(opt1, opt2)) == true, "");
120 assert(static_cast<bool>(opt1) == false);
121 assert(static_cast<bool>(opt2) == false);
122 swap(opt1, opt2);
123 assert(static_cast<bool>(opt1) == false);
124 assert(static_cast<bool>(opt2) == false);
125 assert(X::dtor_called == 0);
126 }
127 {
128 std::optional<X> opt1(1);
129 std::optional<X> opt2;
130 static_assert(noexcept(swap(opt1, opt2)) == true, "");
131 assert(static_cast<bool>(opt1) == true);
132 assert(*opt1 == 1);
133 assert(static_cast<bool>(opt2) == false);
134 X::dtor_called = 0;
135 swap(opt1, opt2);
136 assert(X::dtor_called == 1);
137 assert(static_cast<bool>(opt1) == false);
138 assert(static_cast<bool>(opt2) == true);
139 assert(*opt2 == 1);
140 }
141 {
142 std::optional<X> opt1;
143 std::optional<X> opt2(2);
144 static_assert(noexcept(swap(opt1, opt2)) == true, "");
145 assert(static_cast<bool>(opt1) == false);
146 assert(static_cast<bool>(opt2) == true);
147 assert(*opt2 == 2);
148 X::dtor_called = 0;
149 swap(opt1, opt2);
150 assert(X::dtor_called == 1);
151 assert(static_cast<bool>(opt1) == true);
152 assert(*opt1 == 2);
153 assert(static_cast<bool>(opt2) == false);
154 }
155 {
156 std::optional<X> opt1(1);
157 std::optional<X> opt2(2);
158 static_assert(noexcept(swap(opt1, opt2)) == true, "");
159 assert(static_cast<bool>(opt1) == true);
160 assert(*opt1 == 1);
161 assert(static_cast<bool>(opt2) == true);
162 assert(*opt2 == 2);
163 X::dtor_called = 0;
164 swap(opt1, opt2);
165 assert(X::dtor_called == 1); // from inside std::swap
166 assert(static_cast<bool>(opt1) == true);
167 assert(*opt1 == 2);
168 assert(static_cast<bool>(opt2) == true);
169 assert(*opt2 == 1);
170 }
171 {
172 std::optional<Y> opt1;
173 std::optional<Y> opt2;
174 static_assert(noexcept(swap(opt1, opt2)) == false, "");
175 assert(static_cast<bool>(opt1) == false);
176 assert(static_cast<bool>(opt2) == false);
177 swap(opt1, opt2);
178 assert(static_cast<bool>(opt1) == false);
179 assert(static_cast<bool>(opt2) == false);
180 assert(Y::dtor_called == 0);
181 }
182 {
183 std::optional<Y> opt1(1);
184 std::optional<Y> opt2;
185 static_assert(noexcept(swap(opt1, opt2)) == false, "");
186 assert(static_cast<bool>(opt1) == true);
187 assert(*opt1 == 1);
188 assert(static_cast<bool>(opt2) == false);
189 Y::dtor_called = 0;
190 swap(opt1, opt2);
191 assert(Y::dtor_called == 1);
192 assert(static_cast<bool>(opt1) == false);
193 assert(static_cast<bool>(opt2) == true);
194 assert(*opt2 == 1);
195 }
196 {
197 std::optional<Y> opt1;
198 std::optional<Y> opt2(2);
199 static_assert(noexcept(swap(opt1, opt2)) == false, "");
200 assert(static_cast<bool>(opt1) == false);
201 assert(static_cast<bool>(opt2) == true);
202 assert(*opt2 == 2);
203 Y::dtor_called = 0;
204 swap(opt1, opt2);
205 assert(Y::dtor_called == 1);
206 assert(static_cast<bool>(opt1) == true);
207 assert(*opt1 == 2);
208 assert(static_cast<bool>(opt2) == false);
209 }
210 {
211 std::optional<Y> opt1(1);
212 std::optional<Y> opt2(2);
213 static_assert(noexcept(swap(opt1, opt2)) == false, "");
214 assert(static_cast<bool>(opt1) == true);
215 assert(*opt1 == 1);
216 assert(static_cast<bool>(opt2) == true);
217 assert(*opt2 == 2);
218 Y::dtor_called = 0;
219 swap(opt1, opt2);
220 assert(Y::dtor_called == 0);
221 assert(static_cast<bool>(opt1) == true);
222 assert(*opt1 == 2);
223 assert(static_cast<bool>(opt2) == true);
224 assert(*opt2 == 1);
225 }
226 {
227 std::optional<Z> opt1;
228 std::optional<Z> opt2;
229 static_assert(noexcept(swap(opt1, opt2)) == false, "");
230 assert(static_cast<bool>(opt1) == false);
231 assert(static_cast<bool>(opt2) == false);
232 swap(opt1, opt2);
233 assert(static_cast<bool>(opt1) == false);
234 assert(static_cast<bool>(opt2) == false);
235 }
236 {
237 std::optional<Z> opt1;
238 opt1.emplace(1);
239 std::optional<Z> opt2;
240 static_assert(noexcept(swap(opt1, opt2)) == false, "");
241 assert(static_cast<bool>(opt1) == true);
242 assert(*opt1 == 1);
243 assert(static_cast<bool>(opt2) == false);
244 try
245 {
246 swap(opt1, opt2);
247 assert(false);
248 }
249 catch (int i)
250 {
251 assert(i == 7);
252 }
253 assert(static_cast<bool>(opt1) == true);
254 assert(*opt1 == 1);
255 assert(static_cast<bool>(opt2) == false);
256 }
257 {
258 std::optional<Z> opt1;
259 std::optional<Z> opt2;
260 opt2.emplace(2);
261 static_assert(noexcept(swap(opt1, opt2)) == false, "");
262 assert(static_cast<bool>(opt1) == false);
263 assert(static_cast<bool>(opt2) == true);
264 assert(*opt2 == 2);
265 try
266 {
267 swap(opt1, opt2);
268 assert(false);
269 }
270 catch (int i)
271 {
272 assert(i == 7);
273 }
274 assert(static_cast<bool>(opt1) == false);
275 assert(static_cast<bool>(opt2) == true);
276 assert(*opt2 == 2);
277 }
278 {
279 std::optional<Z> opt1;
280 opt1.emplace(1);
281 std::optional<Z> opt2;
282 opt2.emplace(2);
283 static_assert(noexcept(swap(opt1, opt2)) == false, "");
284 assert(static_cast<bool>(opt1) == true);
285 assert(*opt1 == 1);
286 assert(static_cast<bool>(opt2) == true);
287 assert(*opt2 == 2);
288 try
289 {
290 swap(opt1, opt2);
291 assert(false);
292 }
293 catch (int i)
294 {
295 assert(i == 6);
296 }
297 assert(static_cast<bool>(opt1) == true);
298 assert(*opt1 == 1);
299 assert(static_cast<bool>(opt2) == true);
300 assert(*opt2 == 2);
301 }
302#endif // _LIBCPP_STD_VER > 11
303}