• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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