1a9e65961SEric Fiselier //===----------------------------------------------------------------------===// 2a9e65961SEric Fiselier // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a9e65961SEric Fiselier // 7a9e65961SEric Fiselier //===----------------------------------------------------------------------===// 8a9e65961SEric Fiselier 9*31cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14 10a9e65961SEric Fiselier // <optional> 11a9e65961SEric Fiselier 121d5f6a81SLouis Dionne // optional<T>& operator=(const optional<T>& rhs); // constexpr in C++20 13a9e65961SEric Fiselier 14a9e65961SEric Fiselier #include <optional> 15a9e65961SEric Fiselier #include <type_traits> 16a9e65961SEric Fiselier #include <cassert> 17a9e65961SEric Fiselier 18a9e65961SEric Fiselier #include "test_macros.h" 19cc89063bSNico Weber #include "archetypes.h" 20a9e65961SEric Fiselier 21a9e65961SEric Fiselier using std::optional; 22a9e65961SEric Fiselier 23a9e65961SEric Fiselier struct X 24a9e65961SEric Fiselier { 25a9e65961SEric Fiselier static bool throw_now; 26a9e65961SEric Fiselier 27a9e65961SEric Fiselier X() = default; XX28a9e65961SEric Fiselier X(const X&) 29a9e65961SEric Fiselier { 30a9e65961SEric Fiselier if (throw_now) 31a9e65961SEric Fiselier TEST_THROW(6); 32a9e65961SEric Fiselier } 33f97936faSEric Fiselier X& operator=(X const&) = default; 34a9e65961SEric Fiselier }; 35a9e65961SEric Fiselier 36a9e65961SEric Fiselier bool X::throw_now = false; 37a9e65961SEric Fiselier 38a9e65961SEric Fiselier template <class Tp> assign_empty(optional<Tp> && lhs)39a9e65961SEric Fiselierconstexpr bool assign_empty(optional<Tp>&& lhs) { 40a9e65961SEric Fiselier const optional<Tp> rhs; 41a9e65961SEric Fiselier lhs = rhs; 42a9e65961SEric Fiselier return !lhs.has_value() && !rhs.has_value(); 43a9e65961SEric Fiselier } 44a9e65961SEric Fiselier 45a9e65961SEric Fiselier template <class Tp> assign_value(optional<Tp> && lhs)46a9e65961SEric Fiselierconstexpr bool assign_value(optional<Tp>&& lhs) { 47a9e65961SEric Fiselier const optional<Tp> rhs(101); 48a9e65961SEric Fiselier lhs = rhs; 49a9e65961SEric Fiselier return lhs.has_value() && rhs.has_value() && *lhs == *rhs; 50a9e65961SEric Fiselier } 51a9e65961SEric Fiselier main(int,char **)522df59c50SJF Bastienint main(int, char**) 53a9e65961SEric Fiselier { 54a9e65961SEric Fiselier { 55a9e65961SEric Fiselier using O = optional<int>; 561d5f6a81SLouis Dionne #if TEST_STD_VER > 17 57a9e65961SEric Fiselier LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); 58a9e65961SEric Fiselier LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); 591d5f6a81SLouis Dionne #endif 60a9e65961SEric Fiselier assert(assign_empty(O{42})); 61a9e65961SEric Fiselier assert(assign_value(O{42})); 62a9e65961SEric Fiselier } 63a9e65961SEric Fiselier { 64a9e65961SEric Fiselier using O = optional<TrivialTestTypes::TestType>; 651d5f6a81SLouis Dionne #if TEST_STD_VER > 17 66a9e65961SEric Fiselier LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); 67a9e65961SEric Fiselier LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); 681d5f6a81SLouis Dionne #endif 69a9e65961SEric Fiselier assert(assign_empty(O{42})); 70a9e65961SEric Fiselier assert(assign_value(O{42})); 71a9e65961SEric Fiselier } 72a9e65961SEric Fiselier { 73a9e65961SEric Fiselier using O = optional<TestTypes::TestType>; 74a9e65961SEric Fiselier assert(assign_empty(O{42})); 75a9e65961SEric Fiselier assert(assign_value(O{42})); 76a9e65961SEric Fiselier } 77a9e65961SEric Fiselier { 78a9e65961SEric Fiselier using T = TestTypes::TestType; 79a9e65961SEric Fiselier T::reset(); 80a9e65961SEric Fiselier optional<T> opt(3); 81a9e65961SEric Fiselier const optional<T> opt2; 82a9e65961SEric Fiselier assert(T::alive == 1); 83a9e65961SEric Fiselier opt = opt2; 84a9e65961SEric Fiselier assert(T::alive == 0); 85a9e65961SEric Fiselier assert(!opt2.has_value()); 86a9e65961SEric Fiselier assert(!opt.has_value()); 87a9e65961SEric Fiselier } 88a9e65961SEric Fiselier #ifndef TEST_HAS_NO_EXCEPTIONS 89a9e65961SEric Fiselier { 90a9e65961SEric Fiselier optional<X> opt; 91a9e65961SEric Fiselier optional<X> opt2(X{}); 92a9e65961SEric Fiselier assert(static_cast<bool>(opt2) == true); 93a9e65961SEric Fiselier try 94a9e65961SEric Fiselier { 95a9e65961SEric Fiselier X::throw_now = true; 96a9e65961SEric Fiselier opt = opt2; 97a9e65961SEric Fiselier assert(false); 98a9e65961SEric Fiselier } 99a9e65961SEric Fiselier catch (int i) 100a9e65961SEric Fiselier { 101a9e65961SEric Fiselier assert(i == 6); 102a9e65961SEric Fiselier assert(static_cast<bool>(opt) == false); 103a9e65961SEric Fiselier } 104a9e65961SEric Fiselier } 105a9e65961SEric Fiselier #endif 1062df59c50SJF Bastien 1072df59c50SJF Bastien return 0; 108a9e65961SEric Fiselier } 109