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