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 // optional<T>& operator=(optional<T>&& rhs) 14 // noexcept(is_nothrow_move_assignable<T>::value && 15 // is_nothrow_move_constructible<T>::value); 16 17 #include <experimental/optional> 18 #include <type_traits> 19 #include <cassert> 20 21 #include "test_macros.h" 22 23 using std::experimental::optional; 24 25 struct AllowConstAssign { 26 AllowConstAssign(AllowConstAssign const&) {} 27 AllowConstAssign const& operator=(AllowConstAssign const&) const { 28 return *this; 29 } 30 }; 31 32 struct X 33 { 34 static bool throw_now; 35 36 X() = default; 37 X(X&&) 38 { 39 if (throw_now) 40 TEST_THROW(6); 41 } 42 X& operator=(X&&) noexcept 43 { 44 return *this; 45 } 46 }; 47 48 bool X::throw_now = false; 49 50 struct Y {}; 51 52 int main() 53 { 54 { 55 static_assert(std::is_nothrow_move_assignable<optional<int>>::value, ""); 56 optional<int> opt; 57 constexpr optional<int> opt2; 58 opt = std::move(opt2); 59 static_assert(static_cast<bool>(opt2) == false, ""); 60 assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); 61 } 62 { 63 optional<int> opt; 64 constexpr optional<int> opt2(2); 65 opt = std::move(opt2); 66 static_assert(static_cast<bool>(opt2) == true, ""); 67 static_assert(*opt2 == 2, ""); 68 assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); 69 assert(*opt == *opt2); 70 } 71 { 72 optional<int> opt(3); 73 constexpr optional<int> opt2; 74 opt = std::move(opt2); 75 static_assert(static_cast<bool>(opt2) == false, ""); 76 assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); 77 } 78 { 79 optional<int> opt(3); 80 constexpr optional<int> opt2(2); 81 opt = std::move(opt2); 82 static_assert(static_cast<bool>(opt2) == true, ""); 83 static_assert(*opt2 == 2, ""); 84 assert(static_cast<bool>(opt) == static_cast<bool>(opt2)); 85 assert(*opt == *opt2); 86 } 87 { 88 optional<const AllowConstAssign> opt; 89 optional<const AllowConstAssign> opt2; 90 opt = std::move(opt2); 91 } 92 #ifndef TEST_HAS_NO_EXCEPTIONS 93 { 94 static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, ""); 95 optional<X> opt; 96 optional<X> opt2(X{}); 97 assert(static_cast<bool>(opt2) == true); 98 try 99 { 100 X::throw_now = true; 101 opt = std::move(opt2); 102 assert(false); 103 } 104 catch (int i) 105 { 106 assert(i == 6); 107 assert(static_cast<bool>(opt) == false); 108 } 109 } 110 #endif 111 { 112 static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, ""); 113 } 114 } 115