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