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