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