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 // UNSUPPORTED: c++98, c++03, c++11 11 // <optional> 12 13 // template <class T> void swap(optional<T>& x, optional<T>& y) 14 // noexcept(noexcept(x.swap(y))); 15 16 #include <experimental/optional> 17 #include <type_traits> 18 #include <cassert> 19 20 #include "test_macros.h" 21 22 using std::experimental::optional; 23 24 class X 25 { 26 int i_; 27 public: 28 static unsigned dtor_called; 29 X(int i) : i_(i) {} 30 X(X&& x) = default; 31 X& operator=(X&&) = default; 32 ~X() {++dtor_called;} 33 34 friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} 35 }; 36 37 unsigned X::dtor_called = 0; 38 39 class Y 40 { 41 int i_; 42 public: 43 static unsigned dtor_called; 44 Y(int i) : i_(i) {} 45 Y(Y&&) = default; 46 ~Y() {++dtor_called;} 47 48 friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} 49 friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);} 50 }; 51 52 unsigned Y::dtor_called = 0; 53 54 class Z 55 { 56 int i_; 57 public: 58 Z(int i) : i_(i) {} 59 Z(Z&&) {TEST_THROW(7);} 60 61 friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} 62 friend void swap(Z&, Z&) {TEST_THROW(6);} 63 }; 64 65 int main() 66 { 67 { 68 optional<int> opt1; 69 optional<int> opt2; 70 static_assert(noexcept(swap(opt1, opt2)) == true, ""); 71 assert(static_cast<bool>(opt1) == false); 72 assert(static_cast<bool>(opt2) == false); 73 swap(opt1, opt2); 74 assert(static_cast<bool>(opt1) == false); 75 assert(static_cast<bool>(opt2) == false); 76 } 77 { 78 optional<int> opt1(1); 79 optional<int> opt2; 80 static_assert(noexcept(swap(opt1, opt2)) == true, ""); 81 assert(static_cast<bool>(opt1) == true); 82 assert(*opt1 == 1); 83 assert(static_cast<bool>(opt2) == false); 84 swap(opt1, opt2); 85 assert(static_cast<bool>(opt1) == false); 86 assert(static_cast<bool>(opt2) == true); 87 assert(*opt2 == 1); 88 } 89 { 90 optional<int> opt1; 91 optional<int> opt2(2); 92 static_assert(noexcept(swap(opt1, opt2)) == true, ""); 93 assert(static_cast<bool>(opt1) == false); 94 assert(static_cast<bool>(opt2) == true); 95 assert(*opt2 == 2); 96 swap(opt1, opt2); 97 assert(static_cast<bool>(opt1) == true); 98 assert(*opt1 == 2); 99 assert(static_cast<bool>(opt2) == false); 100 } 101 { 102 optional<int> opt1(1); 103 optional<int> opt2(2); 104 static_assert(noexcept(swap(opt1, opt2)) == true, ""); 105 assert(static_cast<bool>(opt1) == true); 106 assert(*opt1 == 1); 107 assert(static_cast<bool>(opt2) == true); 108 assert(*opt2 == 2); 109 swap(opt1, opt2); 110 assert(static_cast<bool>(opt1) == true); 111 assert(*opt1 == 2); 112 assert(static_cast<bool>(opt2) == true); 113 assert(*opt2 == 1); 114 } 115 { 116 optional<X> opt1; 117 optional<X> opt2; 118 static_assert(noexcept(swap(opt1, opt2)) == true, ""); 119 assert(static_cast<bool>(opt1) == false); 120 assert(static_cast<bool>(opt2) == false); 121 swap(opt1, opt2); 122 assert(static_cast<bool>(opt1) == false); 123 assert(static_cast<bool>(opt2) == false); 124 assert(X::dtor_called == 0); 125 } 126 { 127 optional<X> opt1(1); 128 optional<X> opt2; 129 static_assert(noexcept(swap(opt1, opt2)) == true, ""); 130 assert(static_cast<bool>(opt1) == true); 131 assert(*opt1 == 1); 132 assert(static_cast<bool>(opt2) == false); 133 X::dtor_called = 0; 134 swap(opt1, opt2); 135 assert(X::dtor_called == 1); 136 assert(static_cast<bool>(opt1) == false); 137 assert(static_cast<bool>(opt2) == true); 138 assert(*opt2 == 1); 139 } 140 { 141 optional<X> opt1; 142 optional<X> opt2(2); 143 static_assert(noexcept(swap(opt1, opt2)) == true, ""); 144 assert(static_cast<bool>(opt1) == false); 145 assert(static_cast<bool>(opt2) == true); 146 assert(*opt2 == 2); 147 X::dtor_called = 0; 148 swap(opt1, opt2); 149 assert(X::dtor_called == 1); 150 assert(static_cast<bool>(opt1) == true); 151 assert(*opt1 == 2); 152 assert(static_cast<bool>(opt2) == false); 153 } 154 { 155 optional<X> opt1(1); 156 optional<X> opt2(2); 157 static_assert(noexcept(swap(opt1, opt2)) == true, ""); 158 assert(static_cast<bool>(opt1) == true); 159 assert(*opt1 == 1); 160 assert(static_cast<bool>(opt2) == true); 161 assert(*opt2 == 2); 162 X::dtor_called = 0; 163 swap(opt1, opt2); 164 assert(X::dtor_called == 1); // from inside std::swap 165 assert(static_cast<bool>(opt1) == true); 166 assert(*opt1 == 2); 167 assert(static_cast<bool>(opt2) == true); 168 assert(*opt2 == 1); 169 } 170 { 171 optional<Y> opt1; 172 optional<Y> opt2; 173 static_assert(noexcept(swap(opt1, opt2)) == false, ""); 174 assert(static_cast<bool>(opt1) == false); 175 assert(static_cast<bool>(opt2) == false); 176 swap(opt1, opt2); 177 assert(static_cast<bool>(opt1) == false); 178 assert(static_cast<bool>(opt2) == false); 179 assert(Y::dtor_called == 0); 180 } 181 { 182 optional<Y> opt1(1); 183 optional<Y> opt2; 184 static_assert(noexcept(swap(opt1, opt2)) == false, ""); 185 assert(static_cast<bool>(opt1) == true); 186 assert(*opt1 == 1); 187 assert(static_cast<bool>(opt2) == false); 188 Y::dtor_called = 0; 189 swap(opt1, opt2); 190 assert(Y::dtor_called == 1); 191 assert(static_cast<bool>(opt1) == false); 192 assert(static_cast<bool>(opt2) == true); 193 assert(*opt2 == 1); 194 } 195 { 196 optional<Y> opt1; 197 optional<Y> opt2(2); 198 static_assert(noexcept(swap(opt1, opt2)) == false, ""); 199 assert(static_cast<bool>(opt1) == false); 200 assert(static_cast<bool>(opt2) == true); 201 assert(*opt2 == 2); 202 Y::dtor_called = 0; 203 swap(opt1, opt2); 204 assert(Y::dtor_called == 1); 205 assert(static_cast<bool>(opt1) == true); 206 assert(*opt1 == 2); 207 assert(static_cast<bool>(opt2) == false); 208 } 209 { 210 optional<Y> opt1(1); 211 optional<Y> opt2(2); 212 static_assert(noexcept(swap(opt1, opt2)) == false, ""); 213 assert(static_cast<bool>(opt1) == true); 214 assert(*opt1 == 1); 215 assert(static_cast<bool>(opt2) == true); 216 assert(*opt2 == 2); 217 Y::dtor_called = 0; 218 swap(opt1, opt2); 219 assert(Y::dtor_called == 0); 220 assert(static_cast<bool>(opt1) == true); 221 assert(*opt1 == 2); 222 assert(static_cast<bool>(opt2) == true); 223 assert(*opt2 == 1); 224 } 225 { 226 optional<Z> opt1; 227 optional<Z> opt2; 228 static_assert(noexcept(swap(opt1, opt2)) == false, ""); 229 assert(static_cast<bool>(opt1) == false); 230 assert(static_cast<bool>(opt2) == false); 231 swap(opt1, opt2); 232 assert(static_cast<bool>(opt1) == false); 233 assert(static_cast<bool>(opt2) == false); 234 } 235 #ifndef TEST_HAS_NO_EXCEPTIONS 236 { 237 optional<Z> opt1; 238 opt1.emplace(1); 239 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 optional<Z> opt1; 259 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 optional<Z> opt1; 280 opt1.emplace(1); 281 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 // TEST_HAS_NO_EXCEPTIONS 303 } 304