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 // template <class T> void swap(optional<T>& x, optional<T>& y)
14 // noexcept(noexcept(x.swap(y)));
15
16 #include <experimental/optional>
17 #include <type_traits>
18 #include <cassert>
19
20 #include "test_macros.h"
21
22 using std::experimental::optional;
23
24 class X
25 {
26 int i_;
27 public:
28 static unsigned dtor_called;
X(int i)29 X(int i) : i_(i) {}
30 X(X&& x) = default;
31 X& operator=(X&&) = default;
~X()32 ~X() {++dtor_called;}
33
operator ==(const X & x,const X & y)34 friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
35 };
36
37 unsigned X::dtor_called = 0;
38
39 class Y
40 {
41 int i_;
42 public:
43 static unsigned dtor_called;
Y(int i)44 Y(int i) : i_(i) {}
45 Y(Y&&) = default;
~Y()46 ~Y() {++dtor_called;}
47
operator ==(const Y & x,const Y & y)48 friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
swap(Y & x,Y & y)49 friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
50 };
51
52 unsigned Y::dtor_called = 0;
53
54 class Z
55 {
56 int i_;
57 public:
Z(int i)58 Z(int i) : i_(i) {}
Z(Z &&)59 Z(Z&&) {TEST_THROW(7);}
60
operator ==(const Z & x,const Z & y)61 friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
swap(Z &,Z &)62 friend void swap(Z&, Z&) {TEST_THROW(6);}
63 };
64
main()65 int main()
66 {
67 {
68 optional<int> opt1;
69 optional<int> opt2;
70 static_assert(noexcept(swap(opt1, opt2)) == true, "");
71 assert(static_cast<bool>(opt1) == false);
72 assert(static_cast<bool>(opt2) == false);
73 swap(opt1, opt2);
74 assert(static_cast<bool>(opt1) == false);
75 assert(static_cast<bool>(opt2) == false);
76 }
77 {
78 optional<int> opt1(1);
79 optional<int> opt2;
80 static_assert(noexcept(swap(opt1, opt2)) == true, "");
81 assert(static_cast<bool>(opt1) == true);
82 assert(*opt1 == 1);
83 assert(static_cast<bool>(opt2) == false);
84 swap(opt1, opt2);
85 assert(static_cast<bool>(opt1) == false);
86 assert(static_cast<bool>(opt2) == true);
87 assert(*opt2 == 1);
88 }
89 {
90 optional<int> opt1;
91 optional<int> opt2(2);
92 static_assert(noexcept(swap(opt1, opt2)) == true, "");
93 assert(static_cast<bool>(opt1) == false);
94 assert(static_cast<bool>(opt2) == true);
95 assert(*opt2 == 2);
96 swap(opt1, opt2);
97 assert(static_cast<bool>(opt1) == true);
98 assert(*opt1 == 2);
99 assert(static_cast<bool>(opt2) == false);
100 }
101 {
102 optional<int> opt1(1);
103 optional<int> opt2(2);
104 static_assert(noexcept(swap(opt1, opt2)) == true, "");
105 assert(static_cast<bool>(opt1) == true);
106 assert(*opt1 == 1);
107 assert(static_cast<bool>(opt2) == true);
108 assert(*opt2 == 2);
109 swap(opt1, opt2);
110 assert(static_cast<bool>(opt1) == true);
111 assert(*opt1 == 2);
112 assert(static_cast<bool>(opt2) == true);
113 assert(*opt2 == 1);
114 }
115 {
116 optional<X> opt1;
117 optional<X> opt2;
118 static_assert(noexcept(swap(opt1, opt2)) == true, "");
119 assert(static_cast<bool>(opt1) == false);
120 assert(static_cast<bool>(opt2) == false);
121 swap(opt1, opt2);
122 assert(static_cast<bool>(opt1) == false);
123 assert(static_cast<bool>(opt2) == false);
124 assert(X::dtor_called == 0);
125 }
126 {
127 optional<X> opt1(1);
128 optional<X> opt2;
129 static_assert(noexcept(swap(opt1, opt2)) == true, "");
130 assert(static_cast<bool>(opt1) == true);
131 assert(*opt1 == 1);
132 assert(static_cast<bool>(opt2) == false);
133 X::dtor_called = 0;
134 swap(opt1, opt2);
135 assert(X::dtor_called == 1);
136 assert(static_cast<bool>(opt1) == false);
137 assert(static_cast<bool>(opt2) == true);
138 assert(*opt2 == 1);
139 }
140 {
141 optional<X> opt1;
142 optional<X> opt2(2);
143 static_assert(noexcept(swap(opt1, opt2)) == true, "");
144 assert(static_cast<bool>(opt1) == false);
145 assert(static_cast<bool>(opt2) == true);
146 assert(*opt2 == 2);
147 X::dtor_called = 0;
148 swap(opt1, opt2);
149 assert(X::dtor_called == 1);
150 assert(static_cast<bool>(opt1) == true);
151 assert(*opt1 == 2);
152 assert(static_cast<bool>(opt2) == false);
153 }
154 {
155 optional<X> opt1(1);
156 optional<X> opt2(2);
157 static_assert(noexcept(swap(opt1, opt2)) == true, "");
158 assert(static_cast<bool>(opt1) == true);
159 assert(*opt1 == 1);
160 assert(static_cast<bool>(opt2) == true);
161 assert(*opt2 == 2);
162 X::dtor_called = 0;
163 swap(opt1, opt2);
164 assert(X::dtor_called == 1); // from inside std::swap
165 assert(static_cast<bool>(opt1) == true);
166 assert(*opt1 == 2);
167 assert(static_cast<bool>(opt2) == true);
168 assert(*opt2 == 1);
169 }
170 {
171 optional<Y> opt1;
172 optional<Y> opt2;
173 static_assert(noexcept(swap(opt1, opt2)) == false, "");
174 assert(static_cast<bool>(opt1) == false);
175 assert(static_cast<bool>(opt2) == false);
176 swap(opt1, opt2);
177 assert(static_cast<bool>(opt1) == false);
178 assert(static_cast<bool>(opt2) == false);
179 assert(Y::dtor_called == 0);
180 }
181 {
182 optional<Y> opt1(1);
183 optional<Y> opt2;
184 static_assert(noexcept(swap(opt1, opt2)) == false, "");
185 assert(static_cast<bool>(opt1) == true);
186 assert(*opt1 == 1);
187 assert(static_cast<bool>(opt2) == false);
188 Y::dtor_called = 0;
189 swap(opt1, opt2);
190 assert(Y::dtor_called == 1);
191 assert(static_cast<bool>(opt1) == false);
192 assert(static_cast<bool>(opt2) == true);
193 assert(*opt2 == 1);
194 }
195 {
196 optional<Y> opt1;
197 optional<Y> opt2(2);
198 static_assert(noexcept(swap(opt1, opt2)) == false, "");
199 assert(static_cast<bool>(opt1) == false);
200 assert(static_cast<bool>(opt2) == true);
201 assert(*opt2 == 2);
202 Y::dtor_called = 0;
203 swap(opt1, opt2);
204 assert(Y::dtor_called == 1);
205 assert(static_cast<bool>(opt1) == true);
206 assert(*opt1 == 2);
207 assert(static_cast<bool>(opt2) == false);
208 }
209 {
210 optional<Y> opt1(1);
211 optional<Y> opt2(2);
212 static_assert(noexcept(swap(opt1, opt2)) == false, "");
213 assert(static_cast<bool>(opt1) == true);
214 assert(*opt1 == 1);
215 assert(static_cast<bool>(opt2) == true);
216 assert(*opt2 == 2);
217 Y::dtor_called = 0;
218 swap(opt1, opt2);
219 assert(Y::dtor_called == 0);
220 assert(static_cast<bool>(opt1) == true);
221 assert(*opt1 == 2);
222 assert(static_cast<bool>(opt2) == true);
223 assert(*opt2 == 1);
224 }
225 {
226 optional<Z> opt1;
227 optional<Z> opt2;
228 static_assert(noexcept(swap(opt1, opt2)) == false, "");
229 assert(static_cast<bool>(opt1) == false);
230 assert(static_cast<bool>(opt2) == false);
231 swap(opt1, opt2);
232 assert(static_cast<bool>(opt1) == false);
233 assert(static_cast<bool>(opt2) == false);
234 }
235 #ifndef TEST_HAS_NO_EXCEPTIONS
236 {
237 optional<Z> opt1;
238 opt1.emplace(1);
239 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 optional<Z> opt1;
259 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 optional<Z> opt1;
280 opt1.emplace(1);
281 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 // TEST_HAS_NO_EXCEPTIONS
303 }
304