1 //===----------------------------------------------------------------------===//
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
13 // constexpr optional(const optional<T>& rhs);
14
15 #include <optional>
16 #include <type_traits>
17 #include <cassert>
18
19 #include "test_macros.h"
20 #include "archetypes.hpp"
21
22 using std::optional;
23
24 template <class T, class ...InitArgs>
test(InitArgs &&...args)25 void test(InitArgs&&... args)
26 {
27 const optional<T> rhs(std::forward<InitArgs>(args)...);
28 bool rhs_engaged = static_cast<bool>(rhs);
29 optional<T> lhs = rhs;
30 assert(static_cast<bool>(lhs) == rhs_engaged);
31 if (rhs_engaged)
32 assert(*lhs == *rhs);
33 }
34
35 template <class T, class ...InitArgs>
constexpr_test(InitArgs &&...args)36 constexpr bool constexpr_test(InitArgs&&... args)
37 {
38 static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
39 const optional<T> rhs(std::forward<InitArgs>(args)...);
40 optional<T> lhs = rhs;
41 return (lhs.has_value() == rhs.has_value()) &&
42 (lhs.has_value() ? *lhs == *rhs : true);
43 }
44
test_throwing_ctor()45 void test_throwing_ctor() {
46 #ifndef TEST_HAS_NO_EXCEPTIONS
47 struct Z {
48 Z() : count(0) {}
49 Z(Z const& o) : count(o.count + 1)
50 { if (count == 2) throw 6; }
51 int count;
52 };
53 const Z z;
54 const optional<Z> rhs(z);
55 try
56 {
57 optional<Z> lhs(rhs);
58 assert(false);
59 }
60 catch (int i)
61 {
62 assert(i == 6);
63 }
64 #endif
65 }
66
67 template <class T, class ...InitArgs>
test_ref(InitArgs &&...args)68 void test_ref(InitArgs&&... args)
69 {
70 const optional<T> rhs(std::forward<InitArgs>(args)...);
71 bool rhs_engaged = static_cast<bool>(rhs);
72 optional<T> lhs = rhs;
73 assert(static_cast<bool>(lhs) == rhs_engaged);
74 if (rhs_engaged)
75 assert(&(*lhs) == &(*rhs));
76 }
77
78
test_reference_extension()79 void test_reference_extension()
80 {
81 #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
82 using T = TestTypes::TestType;
83 T::reset();
84 {
85 T t;
86 T::reset_constructors();
87 test_ref<T&>();
88 test_ref<T&>(t);
89 assert(T::alive == 1);
90 assert(T::constructed == 0);
91 assert(T::assigned == 0);
92 assert(T::destroyed == 0);
93 }
94 assert(T::destroyed == 1);
95 assert(T::alive == 0);
96 {
97 T t;
98 const T& ct = t;
99 T::reset_constructors();
100 test_ref<T const&>();
101 test_ref<T const&>(t);
102 test_ref<T const&>(ct);
103 assert(T::alive == 1);
104 assert(T::constructed == 0);
105 assert(T::assigned == 0);
106 assert(T::destroyed == 0);
107 }
108 assert(T::alive == 0);
109 assert(T::destroyed == 1);
110 {
111 static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
112 static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
113 }
114 #endif
115 }
116
main()117 int main()
118 {
119 test<int>();
120 test<int>(3);
121 static_assert(constexpr_test<int>(), "" );
122 static_assert(constexpr_test<int>(3), "" );
123
124 {
125 const optional<const int> o(42);
126 optional<const int> o2(o);
127 assert(*o2 == 42);
128 }
129 {
130 using T = TestTypes::TestType;
131 T::reset();
132 const optional<T> rhs;
133 assert(T::alive == 0);
134 const optional<T> lhs(rhs);
135 assert(lhs.has_value() == false);
136 assert(T::alive == 0);
137 }
138 TestTypes::TestType::reset();
139 {
140 using T = TestTypes::TestType;
141 T::reset();
142 const optional<T> rhs(42);
143 assert(T::alive == 1);
144 assert(T::value_constructed == 1);
145 assert(T::copy_constructed == 0);
146 const optional<T> lhs(rhs);
147 assert(lhs.has_value());
148 assert(T::copy_constructed == 1);
149 assert(T::alive == 2);
150 }
151 TestTypes::TestType::reset();
152 {
153 using namespace ConstexprTestTypes;
154 test<TestType>();
155 test<TestType>(42);
156 }
157 {
158 using namespace TrivialTestTypes;
159 test<TestType>();
160 test<TestType>(42);
161 }
162 {
163 test_throwing_ctor();
164 }
165 {
166 test_reference_extension();
167 }
168 {
169 constexpr std::optional<int> o1{4};
170 constexpr std::optional<int> o2 = o1;
171 static_assert( *o2 == 4, "" );
172 }
173 }
174