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, c++14 11// <optional> 12 13// void swap(optional&) 14// noexcept(is_nothrow_move_constructible<T>::value && 15// is_nothrow_swappable<T>::value) 16 17#include <optional> 18#include <type_traits> 19#include <cassert> 20 21#include "test_macros.h" 22#include "archetypes.hpp" 23 24using std::optional; 25 26class X 27{ 28 int i_; 29public: 30 static unsigned dtor_called; 31 X(int i) : i_(i) {} 32 X(X&& x) = default; 33 X& operator=(X&&) = default; 34 ~X() {++dtor_called;} 35 36 friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;} 37}; 38 39unsigned X::dtor_called = 0; 40 41class Y 42{ 43 int i_; 44public: 45 static unsigned dtor_called; 46 Y(int i) : i_(i) {} 47 Y(Y&&) = default; 48 ~Y() {++dtor_called;} 49 50 friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;} 51 friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);} 52}; 53 54unsigned Y::dtor_called = 0; 55 56class Z 57{ 58 int i_; 59public: 60 Z(int i) : i_(i) {} 61 Z(Z&&) {TEST_THROW(7);} 62 63 friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;} 64 friend void swap(Z&, Z&) {TEST_THROW(6);} 65}; 66 67 68int main() 69{ 70 { 71 optional<int> opt1; 72 optional<int> opt2; 73 static_assert(noexcept(opt1.swap(opt2)) == true, ""); 74 assert(static_cast<bool>(opt1) == false); 75 assert(static_cast<bool>(opt2) == false); 76 opt1.swap(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(opt1.swap(opt2)) == true, ""); 84 assert(static_cast<bool>(opt1) == true); 85 assert(*opt1 == 1); 86 assert(static_cast<bool>(opt2) == false); 87 opt1.swap(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(opt1.swap(opt2)) == true, ""); 96 assert(static_cast<bool>(opt1) == false); 97 assert(static_cast<bool>(opt2) == true); 98 assert(*opt2 == 2); 99 opt1.swap(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(opt1.swap(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 opt1.swap(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(opt1.swap(opt2)) == true, ""); 122 assert(static_cast<bool>(opt1) == false); 123 assert(static_cast<bool>(opt2) == false); 124 opt1.swap(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(opt1.swap(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 opt1.swap(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(opt1.swap(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 opt1.swap(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(opt1.swap(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 opt1.swap(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(opt1.swap(opt2)) == false, ""); 177 assert(static_cast<bool>(opt1) == false); 178 assert(static_cast<bool>(opt2) == false); 179 opt1.swap(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(opt1.swap(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 opt1.swap(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(opt1.swap(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 opt1.swap(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(opt1.swap(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 opt1.swap(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(opt1.swap(opt2)) == false, ""); 232 assert(static_cast<bool>(opt1) == false); 233 assert(static_cast<bool>(opt2) == false); 234 opt1.swap(opt2); 235 assert(static_cast<bool>(opt1) == false); 236 assert(static_cast<bool>(opt2) == false); 237 } 238#ifndef TEST_HAS_NO_EXCEPTIONS 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 306} 307