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