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