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
11 // XFAIL: availability-bad_optional_access-missing && !no-exceptions
15 // constexpr optional(optional<T>&& rhs);
18 #include <type_traits>
21 #include "test_macros.h"
22 #include "archetypes.h"
26 template <class T
, class ...InitArgs
>
27 void test(InitArgs
&&... args
)
29 const optional
<T
> orig(std::forward
<InitArgs
>(args
)...);
30 optional
<T
> rhs(orig
);
31 bool rhs_engaged
= static_cast<bool>(rhs
);
32 optional
<T
> lhs
= std::move(rhs
);
33 assert(static_cast<bool>(lhs
) == rhs_engaged
);
35 assert(*lhs
== *orig
);
38 template <class T
, class ...InitArgs
>
39 constexpr bool constexpr_test(InitArgs
&&... args
)
41 static_assert( std::is_trivially_copy_constructible_v
<T
>, ""); // requirement
42 const optional
<T
> orig(std::forward
<InitArgs
>(args
)...);
43 optional
<T
> rhs(orig
);
44 optional
<T
> lhs
= std::move(rhs
);
45 return (lhs
.has_value() == orig
.has_value()) &&
46 (lhs
.has_value() ? *lhs
== *orig
: true);
49 void test_throwing_ctor() {
50 #ifndef TEST_HAS_NO_EXCEPTIONS
53 Z(Z
&& o
) : count(o
.count
+ 1)
54 { if (count
== 2) throw 6; }
58 optional
<Z
> rhs(std::move(z
));
61 optional
<Z
> lhs(std::move(rhs
));
72 template <class T
, class ...InitArgs
>
73 void test_ref(InitArgs
&&... args
)
75 optional
<T
> rhs(std::forward
<InitArgs
>(args
)...);
76 bool rhs_engaged
= static_cast<bool>(rhs
);
77 optional
<T
> lhs
= std::move(rhs
);
78 assert(static_cast<bool>(lhs
) == rhs_engaged
);
80 assert(&(*lhs
) == &(*rhs
));
83 void test_reference_extension()
85 #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
86 using T
= TestTypes::TestType
;
90 T::reset_constructors();
93 assert(T::alive
== 1);
94 assert(T::constructed
== 0);
95 assert(T::assigned
== 0);
96 assert(T::destroyed
== 0);
98 assert(T::destroyed
== 1);
99 assert(T::alive
== 0);
103 T::reset_constructors();
104 test_ref
<T
const&>();
105 test_ref
<T
const&>(t
);
106 test_ref
<T
const&>(ct
);
107 assert(T::alive
== 1);
108 assert(T::constructed
== 0);
109 assert(T::assigned
== 0);
110 assert(T::destroyed
== 0);
112 assert(T::alive
== 0);
113 assert(T::destroyed
== 1);
116 T::reset_constructors();
118 test_ref
<T
&&>(std::move(t
));
119 assert(T::alive
== 1);
120 assert(T::constructed
== 0);
121 assert(T::assigned
== 0);
122 assert(T::destroyed
== 0);
124 assert(T::alive
== 0);
125 assert(T::destroyed
== 1);
129 T::reset_constructors();
130 test_ref
<T
const&&>();
131 test_ref
<T
const&&>(std::move(t
));
132 test_ref
<T
const&&>(std::move(ct
));
133 assert(T::alive
== 1);
134 assert(T::constructed
== 0);
135 assert(T::assigned
== 0);
136 assert(T::destroyed
== 0);
138 assert(T::alive
== 0);
139 assert(T::destroyed
== 1);
141 static_assert(!std::is_copy_constructible
<std::optional
<T
&&>>::value
, "");
142 static_assert(!std::is_copy_constructible
<std::optional
<T
const&&>>::value
, "");
148 int main(int, char**)
152 static_assert(constexpr_test
<int>(), "" );
153 static_assert(constexpr_test
<int>(3), "" );
156 optional
<const int> o(42);
157 optional
<const int> o2(std::move(o
));
161 using T
= TestTypes::TestType
;
164 assert(T::alive
== 0);
165 const optional
<T
> lhs(std::move(rhs
));
166 assert(lhs
.has_value() == false);
167 assert(rhs
.has_value() == false);
168 assert(T::alive
== 0);
170 TestTypes::TestType::reset();
172 using T
= TestTypes::TestType
;
175 assert(T::alive
== 1);
176 assert(T::value_constructed
== 1);
177 assert(T::move_constructed
== 0);
178 const optional
<T
> lhs(std::move(rhs
));
179 assert(lhs
.has_value());
180 assert(rhs
.has_value());
181 assert(lhs
.value().value
== 42);
182 assert(rhs
.value().value
== -1);
183 assert(T::move_constructed
== 1);
184 assert(T::alive
== 2);
186 TestTypes::TestType::reset();
188 using namespace ConstexprTestTypes
;
193 using namespace TrivialTestTypes
;
198 test_throwing_ctor();
202 ThrowsMove() noexcept(false) {}
203 ThrowsMove(ThrowsMove
const&) noexcept(false) {}
204 ThrowsMove(ThrowsMove
&&) noexcept(false) {}
206 static_assert(!std::is_nothrow_move_constructible
<optional
<ThrowsMove
>>::value
, "");
208 NoThrowMove() noexcept(false) {}
209 NoThrowMove(NoThrowMove
const&) noexcept(false) {}
210 NoThrowMove(NoThrowMove
&&) noexcept(true) {}
212 static_assert(std::is_nothrow_move_constructible
<optional
<NoThrowMove
>>::value
, "");
215 test_reference_extension();
218 constexpr std::optional
<int> o1
{4};
219 constexpr std::optional
<int> o2
= std::move(o1
);
220 static_assert( *o2
== 4, "" );