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