1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
12 // constexpr optional(const optional<T>& rhs);
15 #include <type_traits>
18 #include "test_macros.h"
19 #include "archetypes.h"
23 template <class T
, class ...InitArgs
>
24 void test(InitArgs
&&... args
)
26 const optional
<T
> rhs(std::forward
<InitArgs
>(args
)...);
27 bool rhs_engaged
= static_cast<bool>(rhs
);
28 optional
<T
> lhs
= rhs
;
29 assert(static_cast<bool>(lhs
) == rhs_engaged
);
34 template <class T
, class ...InitArgs
>
35 constexpr bool constexpr_test(InitArgs
&&... args
)
37 static_assert( std::is_trivially_copy_constructible_v
<T
>, ""); // requirement
38 const optional
<T
> rhs(std::forward
<InitArgs
>(args
)...);
39 optional
<T
> lhs
= rhs
;
40 return (lhs
.has_value() == rhs
.has_value()) &&
41 (lhs
.has_value() ? *lhs
== *rhs
: true);
44 void test_throwing_ctor() {
45 #ifndef TEST_HAS_NO_EXCEPTIONS
48 Z(Z
const& o
) : count(o
.count
+ 1)
49 { if (count
== 2) throw 6; }
53 const optional
<Z
> rhs(z
);
66 template <class T
, class ...InitArgs
>
67 void test_ref(InitArgs
&&... args
)
69 const optional
<T
> rhs(std::forward
<InitArgs
>(args
)...);
70 bool rhs_engaged
= static_cast<bool>(rhs
);
71 optional
<T
> lhs
= rhs
;
72 assert(static_cast<bool>(lhs
) == rhs_engaged
);
74 assert(&(*lhs
) == &(*rhs
));
78 void test_reference_extension()
80 #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
81 using T
= TestTypes::TestType
;
85 T::reset_constructors();
88 assert(T::alive
== 1);
89 assert(T::constructed
== 0);
90 assert(T::assigned
== 0);
91 assert(T::destroyed
== 0);
93 assert(T::destroyed
== 1);
94 assert(T::alive
== 0);
98 T::reset_constructors();
100 test_ref
<T
const&>(t
);
101 test_ref
<T
const&>(ct
);
102 assert(T::alive
== 1);
103 assert(T::constructed
== 0);
104 assert(T::assigned
== 0);
105 assert(T::destroyed
== 0);
107 assert(T::alive
== 0);
108 assert(T::destroyed
== 1);
110 static_assert(!std::is_copy_constructible
<std::optional
<T
&&>>::value
, "");
111 static_assert(!std::is_copy_constructible
<std::optional
<T
const&&>>::value
, "");
116 int main(int, char**)
120 static_assert(constexpr_test
<int>(), "" );
121 static_assert(constexpr_test
<int>(3), "" );
124 const optional
<const int> o(42);
125 optional
<const int> o2(o
);
129 using T
= TestTypes::TestType
;
131 const optional
<T
> rhs
;
132 assert(T::alive
== 0);
133 const optional
<T
> lhs(rhs
);
134 assert(lhs
.has_value() == false);
135 assert(T::alive
== 0);
137 TestTypes::TestType::reset();
139 using T
= TestTypes::TestType
;
141 const optional
<T
> rhs(42);
142 assert(T::alive
== 1);
143 assert(T::value_constructed
== 1);
144 assert(T::copy_constructed
== 0);
145 const optional
<T
> lhs(rhs
);
146 assert(lhs
.has_value());
147 assert(T::copy_constructed
== 1);
148 assert(T::alive
== 2);
150 TestTypes::TestType::reset();
152 using namespace ConstexprTestTypes
;
157 using namespace TrivialTestTypes
;
162 test_throwing_ctor();
165 test_reference_extension();
168 constexpr std::optional
<int> o1
{4};
169 constexpr std::optional
<int> o2
= o1
;
170 static_assert( *o2
== 4, "" );
173 // LWG3836 https://wg21.link/LWG3836
174 // std::optional<bool> conversion constructor optional(const optional<U>&)
175 // should take precedence over optional(U&&) with operator bool
177 std::optional
<bool> o1(false);
178 std::optional
<bool> o2(o1
);