105 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410// <optional>11 12// constexpr optional<T>& operator=(const optional<T>& rhs);13 14#include <optional>15#include <type_traits>16#include <cassert>17 18#include "test_macros.h"19#include "archetypes.h"20 21using std::optional;22 23struct X24{25 static bool throw_now;26 27 X() = default;28 X(const X&)29 {30 if (throw_now)31 TEST_THROW(6);32 }33 X& operator=(X const&) = default;34};35 36bool X::throw_now = false;37 38template <class Tp>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 45template <class Tp>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 52int main(int, char**)53{54 {55 using O = optional<int>;56 static_assert(assign_empty(O{42}));57 static_assert(assign_value(O{42}));58 assert(assign_empty(O{42}));59 assert(assign_value(O{42}));60 }61 {62 using O = optional<TrivialTestTypes::TestType>;63 static_assert(assign_empty(O{42}));64 static_assert(assign_value(O{42}));65 assert(assign_empty(O{42}));66 assert(assign_value(O{42}));67 }68 {69 using O = optional<TestTypes::TestType>;70 assert(assign_empty(O{42}));71 assert(assign_value(O{42}));72 }73 {74 using T = TestTypes::TestType;75 T::reset();76 optional<T> opt(3);77 const optional<T> opt2;78 assert(T::alive == 1);79 opt = opt2;80 assert(T::alive == 0);81 assert(!opt2.has_value());82 assert(!opt.has_value());83 }84#ifndef TEST_HAS_NO_EXCEPTIONS85 {86 optional<X> opt;87 optional<X> opt2(X{});88 assert(static_cast<bool>(opt2) == true);89 try90 {91 X::throw_now = true;92 opt = opt2;93 assert(false);94 }95 catch (int i)96 {97 assert(i == 6);98 assert(static_cast<bool>(opt) == false);99 }100 }101#endif102 103 return 0;104}105