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