• 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 // 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