blob: bec0f09a3e9a54c443f152f866c2ea75f6c695f2 [file] [log] [blame]
Eric Fiselier35ce4852016-10-12 07:46:20 +00001//===----------------------------------------------------------------------===//
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// UNSUPPORTED: c++98, c++03, c++11, c++14
11// <optional>
12
Louis Dionne134a8482019-01-10 20:06:11 +000013// optional<T>& operator=(const optional<T>& rhs); // constexpr in C++20
Eric Fiselier35ce4852016-10-12 07:46:20 +000014
15#include <optional>
16#include <type_traits>
17#include <cassert>
18
19#include "test_macros.h"
20#include "archetypes.hpp"
21
22using std::optional;
23
24struct X
25{
26 static bool throw_now;
27
28 X() = default;
29 X(const X&)
30 {
31 if (throw_now)
32 TEST_THROW(6);
33 }
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()
53{
54 {
55 using O = optional<int>;
Louis Dionne134a8482019-01-10 20:06:11 +000056#if TEST_STD_VER > 17
Eric Fiselier35ce4852016-10-12 07:46:20 +000057 LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
58 LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
Louis Dionne134a8482019-01-10 20:06:11 +000059#endif
Eric Fiselier35ce4852016-10-12 07:46:20 +000060 assert(assign_empty(O{42}));
61 assert(assign_value(O{42}));
62 }
63 {
64 using O = optional<TrivialTestTypes::TestType>;
Louis Dionne134a8482019-01-10 20:06:11 +000065#if TEST_STD_VER > 17
Eric Fiselier35ce4852016-10-12 07:46:20 +000066 LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
67 LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
Louis Dionne134a8482019-01-10 20:06:11 +000068#endif
Eric Fiselier35ce4852016-10-12 07:46:20 +000069 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}