1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14 10 // <optional> 11 12 // void swap(optional&) 13 // noexcept(is_nothrow_move_constructible<T>::value && 14 // is_nothrow_swappable<T>::value) 15 16 #include <optional> 17 #include <type_traits> 18 #include <cassert> 19 20 #include "test_macros.h" 21 #include "archetypes.h" 22 23 using std::optional; 24 25 class X 26 { 27 int i_; 28 public: 29 static unsigned dtor_called; 30 X(int i) : i_(i) {} 31 X(X&& x) = default; 32 X& operator=(X&&) = default; 33 ~X() {++dtor_called;} 34 35 friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} 36 }; 37 38 unsigned X::dtor_called = 0; 39 40 class Y 41 { 42 int i_; 43 public: 44 static unsigned dtor_called; 45 Y(int i) : i_(i) {} 46 Y(Y&&) = default; 47 ~Y() {++dtor_called;} 48 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_);} 51 }; 52 53 unsigned Y::dtor_called = 0; 54 55 class Z 56 { 57 int i_; 58 public: 59 Z(int i) : i_(i) {} 60 Z(Z&&) {TEST_THROW(7);} 61 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);} 64 }; 65 66 67 int main(int, char**) 68 { 69 { 70 optional<int> opt1; 71 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 optional<int> opt1(1); 81 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 optional<int> opt1; 93 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 optional<int> opt1(1); 105 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 optional<X> opt1; 119 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 optional<X> opt1(1); 130 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 optional<X> opt1; 144 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 optional<X> opt1(1); 158 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 optional<Y> opt1; 174 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 optional<Y> opt1(1); 185 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 optional<Y> opt1; 199 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 optional<Y> opt1(1); 213 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 optional<Z> opt1; 229 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 #ifndef TEST_HAS_NO_EXCEPTIONS 238 { 239 optional<Z> opt1; 240 opt1.emplace(1); 241 optional<Z> opt2; 242 static_assert(noexcept(opt1.swap(opt2)) == false, ""); 243 assert(static_cast<bool>(opt1) == true); 244 assert(*opt1 == 1); 245 assert(static_cast<bool>(opt2) == false); 246 try 247 { 248 opt1.swap(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(opt1.swap(opt2)) == false, ""); 264 assert(static_cast<bool>(opt1) == false); 265 assert(static_cast<bool>(opt2) == true); 266 assert(*opt2 == 2); 267 try 268 { 269 opt1.swap(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(opt1.swap(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 opt1.swap(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 305 306 return 0; 307 } 308