1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
13 // template <class T> void swap(optional<T>& x, optional<T>& y)
14 // noexcept(noexcept(x.swap(y)));
17 #include <type_traits>
20 #include "test_macros.h"
21 #include "archetypes.hpp"
29 static unsigned dtor_called;
32 X& operator=(X&&) = default;
35 friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
38 unsigned X::dtor_called = 0;
44 static unsigned dtor_called;
49 friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
50 friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
53 unsigned Y::dtor_called = 0;
60 Z(Z&&) { TEST_THROW(7);}
62 friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
63 friend void swap(Z&, Z&) { TEST_THROW(6);}
68 NonSwappable(NonSwappable const&) = delete;
70 void swap(NonSwappable&, NonSwappable&) = delete;
72 void test_swap_sfinae() {
75 using T = TestTypes::TestType;
76 static_assert(std::is_swappable_v<optional<T>>, "");
79 using T = TestTypes::MoveOnly;
80 static_assert(std::is_swappable_v<optional<T>>, "");
83 using T = TestTypes::Copyable;
84 static_assert(std::is_swappable_v<optional<T>>, "");
87 using T = TestTypes::NoCtors;
88 static_assert(!std::is_swappable_v<optional<T>>, "");
91 using T = NonSwappable;
92 static_assert(!std::is_swappable_v<optional<T>>, "");
95 // Even thought CopyOnly has deleted move operations, those operations
96 // cause optional<CopyOnly> to have implicitly deleted move operations
97 // that decay into copies.
98 using T = TestTypes::CopyOnly;
99 using Opt = optional<T>;
102 T::reset_constructors();
104 assert(L->value == 42);
105 assert(R->value == 101);
106 assert(T::copy_constructed == 1);
107 assert(T::constructed == T::copy_constructed);
108 assert(T::assigned == 2);
109 assert(T::assigned == T::copy_assigned);
119 static_assert(noexcept(swap(opt1, opt2)) == true, "");
120 assert(static_cast<bool>(opt1) == false);
121 assert(static_cast<bool>(opt2) == false);
123 assert(static_cast<bool>(opt1) == false);
124 assert(static_cast<bool>(opt2) == false);
127 optional<int> opt1(1);
129 static_assert(noexcept(swap(opt1, opt2)) == true, "");
130 assert(static_cast<bool>(opt1) == true);
132 assert(static_cast<bool>(opt2) == false);
134 assert(static_cast<bool>(opt1) == false);
135 assert(static_cast<bool>(opt2) == true);
140 optional<int> opt2(2);
141 static_assert(noexcept(swap(opt1, opt2)) == true, "");
142 assert(static_cast<bool>(opt1) == false);
143 assert(static_cast<bool>(opt2) == true);
146 assert(static_cast<bool>(opt1) == true);
148 assert(static_cast<bool>(opt2) == false);
151 optional<int> opt1(1);
152 optional<int> opt2(2);
153 static_assert(noexcept(swap(opt1, opt2)) == true, "");
154 assert(static_cast<bool>(opt1) == true);
156 assert(static_cast<bool>(opt2) == true);
159 assert(static_cast<bool>(opt1) == true);
161 assert(static_cast<bool>(opt2) == true);
167 static_assert(noexcept(swap(opt1, opt2)) == true, "");
168 assert(static_cast<bool>(opt1) == false);
169 assert(static_cast<bool>(opt2) == false);
171 assert(static_cast<bool>(opt1) == false);
172 assert(static_cast<bool>(opt2) == false);
173 assert(X::dtor_called == 0);
178 static_assert(noexcept(swap(opt1, opt2)) == true, "");
179 assert(static_cast<bool>(opt1) == true);
181 assert(static_cast<bool>(opt2) == false);
184 assert(X::dtor_called == 1);
185 assert(static_cast<bool>(opt1) == false);
186 assert(static_cast<bool>(opt2) == true);
192 static_assert(noexcept(swap(opt1, opt2)) == true, "");
193 assert(static_cast<bool>(opt1) == false);
194 assert(static_cast<bool>(opt2) == true);
198 assert(X::dtor_called == 1);
199 assert(static_cast<bool>(opt1) == true);
201 assert(static_cast<bool>(opt2) == false);
206 static_assert(noexcept(swap(opt1, opt2)) == true, "");
207 assert(static_cast<bool>(opt1) == true);
209 assert(static_cast<bool>(opt2) == true);
213 assert(X::dtor_called == 1); // from inside std::swap
214 assert(static_cast<bool>(opt1) == true);
216 assert(static_cast<bool>(opt2) == true);
222 static_assert(noexcept(swap(opt1, opt2)) == false, "");
223 assert(static_cast<bool>(opt1) == false);
224 assert(static_cast<bool>(opt2) == false);
226 assert(static_cast<bool>(opt1) == false);
227 assert(static_cast<bool>(opt2) == false);
228 assert(Y::dtor_called == 0);
233 static_assert(noexcept(swap(opt1, opt2)) == false, "");
234 assert(static_cast<bool>(opt1) == true);
236 assert(static_cast<bool>(opt2) == false);
239 assert(Y::dtor_called == 1);
240 assert(static_cast<bool>(opt1) == false);
241 assert(static_cast<bool>(opt2) == true);
247 static_assert(noexcept(swap(opt1, opt2)) == false, "");
248 assert(static_cast<bool>(opt1) == false);
249 assert(static_cast<bool>(opt2) == true);
253 assert(Y::dtor_called == 1);
254 assert(static_cast<bool>(opt1) == true);
256 assert(static_cast<bool>(opt2) == false);
261 static_assert(noexcept(swap(opt1, opt2)) == false, "");
262 assert(static_cast<bool>(opt1) == true);
264 assert(static_cast<bool>(opt2) == true);
268 assert(Y::dtor_called == 0);
269 assert(static_cast<bool>(opt1) == true);
271 assert(static_cast<bool>(opt2) == true);
277 static_assert(noexcept(swap(opt1, opt2)) == false, "");
278 assert(static_cast<bool>(opt1) == false);
279 assert(static_cast<bool>(opt2) == false);
281 assert(static_cast<bool>(opt1) == false);
282 assert(static_cast<bool>(opt2) == false);
284 #ifndef TEST_HAS_NO_EXCEPTIONS
289 static_assert(noexcept(swap(opt1, opt2)) == false, "");
290 assert(static_cast<bool>(opt1) == true);
292 assert(static_cast<bool>(opt2) == false);
302 assert(static_cast<bool>(opt1) == true);
304 assert(static_cast<bool>(opt2) == false);
310 static_assert(noexcept(swap(opt1, opt2)) == false, "");
311 assert(static_cast<bool>(opt1) == false);
312 assert(static_cast<bool>(opt2) == true);
323 assert(static_cast<bool>(opt1) == false);
324 assert(static_cast<bool>(opt2) == true);
332 static_assert(noexcept(swap(opt1, opt2)) == false, "");
333 assert(static_cast<bool>(opt1) == true);
335 assert(static_cast<bool>(opt2) == true);
346 assert(static_cast<bool>(opt1) == true);
348 assert(static_cast<bool>(opt2) == true);
351 #endif // TEST_HAS_NO_EXCEPTIONS