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++98, c++03, c++11, c++14 10 // <optional> 11 12 // optional<T>& operator=(const optional<T>& rhs); // constexpr in C++20 13 14 #include <optional> 15 #include <type_traits> 16 #include <cassert> 17 18 #include "test_macros.h" 19 #include "archetypes.hpp" 20 21 using std::optional; 22 23 struct X 24 { 25 static bool throw_now; 26 27 X() = default; 28 X(const X&) 29 { 30 if (throw_now) 31 TEST_THROW(6); 32 } 33 }; 34 35 bool X::throw_now = false; 36 37 template <class Tp> 38 constexpr bool assign_empty(optional<Tp>&& lhs) { 39 const optional<Tp> rhs; 40 lhs = rhs; 41 return !lhs.has_value() && !rhs.has_value(); 42 } 43 44 template <class Tp> 45 constexpr bool assign_value(optional<Tp>&& lhs) { 46 const optional<Tp> rhs(101); 47 lhs = rhs; 48 return lhs.has_value() && rhs.has_value() && *lhs == *rhs; 49 } 50 51 int main(int, char**) 52 { 53 { 54 using O = optional<int>; 55 #if TEST_STD_VER > 17 56 LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); 57 LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); 58 #endif 59 assert(assign_empty(O{42})); 60 assert(assign_value(O{42})); 61 } 62 { 63 using O = optional<TrivialTestTypes::TestType>; 64 #if TEST_STD_VER > 17 65 LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); 66 LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); 67 #endif 68 assert(assign_empty(O{42})); 69 assert(assign_value(O{42})); 70 } 71 { 72 using O = optional<TestTypes::TestType>; 73 assert(assign_empty(O{42})); 74 assert(assign_value(O{42})); 75 } 76 { 77 using T = TestTypes::TestType; 78 T::reset(); 79 optional<T> opt(3); 80 const optional<T> opt2; 81 assert(T::alive == 1); 82 opt = opt2; 83 assert(T::alive == 0); 84 assert(!opt2.has_value()); 85 assert(!opt.has_value()); 86 } 87 #ifndef TEST_HAS_NO_EXCEPTIONS 88 { 89 optional<X> opt; 90 optional<X> opt2(X{}); 91 assert(static_cast<bool>(opt2) == true); 92 try 93 { 94 X::throw_now = true; 95 opt = opt2; 96 assert(false); 97 } 98 catch (int i) 99 { 100 assert(i == 6); 101 assert(static_cast<bool>(opt) == false); 102 } 103 } 104 #endif 105 106 return 0; 107 } 108