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