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