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