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