Skip to content

Commit 91bb309

Browse files
committed
Add a optional<T&> copy and move test
1 parent 242e5eb commit 91bb309

File tree

3 files changed

+78
-34
lines changed

3 files changed

+78
-34
lines changed

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ constexpr bool test_all() {
8787
}
8888

8989
constexpr bool test() {
90+
static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value));
9091
test_all<int, short>();
9192
test_all<X, int>();
9293
test_all<Y, int>();
@@ -126,6 +127,5 @@ int main(int, char**) {
126127
test_throwing();
127128
}
128129

129-
static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value));
130130
return 0;
131131
}

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,26 @@ void test_ref(InitArgs&&... args) {
6565
assert(&(*lhs) == &(*rhs));
6666
}
6767

68-
// TODO: Add constexpr tests
69-
void test_reference_extension() {
7068
#if TEST_STD_VER >= 26
69+
struct X {
70+
int copy_count = 0;
71+
72+
constexpr X() {}
73+
constexpr X(const X&) { copy_count++; }
74+
};
75+
76+
constexpr void test_ref() {
77+
{
78+
X x{};
79+
std::optional<X&> o1(x);
80+
std::optional<X&> o2(o1);
81+
assert(o1.has_value() && o2.has_value());
82+
assert(x.copy_count == 0);
83+
assert(&*o1 == &*o2);
84+
}
85+
}
86+
87+
void test_reference_extension() {
7188
using T = TestTypes::TestType;
7289
T::reset();
7390
{
@@ -103,13 +120,15 @@ void test_reference_extension() {
103120
static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value);
104121
}
105122
# endif
106-
#endif
107123
}
124+
#endif
108125

109126
constexpr bool test() {
110127
test<int>();
111128
test<int>(3);
112129
test<const int>(42);
130+
test<TrivialTestTypes::TestType>();
131+
test<TrivialTestTypes::TestType>(42);
113132

114133
// FIXME: Why is this in ctor copy.pass.cpp?
115134
{
@@ -129,34 +148,19 @@ constexpr bool test() {
129148
}
130149
}
131150

132-
{
133-
using T = TrivialTestTypes::TestType;
134-
test<T>();
135-
test<T>(42);
136-
}
151+
#if TEST_STD_VER >= 26
152+
test_ref();
137153

138154
// TODO: Enable once P3068R6 is implemented
139-
#if TEST_STD_VER >= 26 && 0
155+
# if 0
140156
test_throwing_ctor();
157+
# endif
141158
#endif
142159

143160
return true;
144161
}
145162

146-
int main(int, char**) {
147-
test();
148-
static_assert(test());
149-
150-
{
151-
test_throwing_ctor();
152-
}
153-
154-
#if TEST_STD_VER >= 26
155-
{
156-
test_reference_extension();
157-
}
158-
#endif
159-
163+
void test_rt() {
160164
{ // FIXME: Shouldn't this be able to pass in a constexpr context since C++17?
161165
using T = ConstexprTestTypes::TestType;
162166
test<T>();
@@ -189,6 +193,25 @@ int main(int, char**) {
189193
}
190194

191195
TestTypes::TestType::reset();
196+
}
197+
198+
int main(int, char**) {
199+
test();
200+
static_assert(test());
201+
202+
{
203+
test_rt();
204+
}
205+
206+
{
207+
test_throwing_ctor();
208+
}
209+
210+
#if TEST_STD_VER >= 26
211+
{
212+
test_reference_extension();
213+
}
214+
#endif
192215

193216
return 0;
194217
}

libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,33 @@ TEST_CONSTEXPR_CXX26 void test_throwing_ctor() {
5959
template <class T, class... InitArgs>
6060
void test_ref(InitArgs&&... args) {
6161
optional<T> rhs(std::forward<InitArgs>(args)...);
62-
bool rhs_engaged = static_cast<bool>(rhs);
63-
optional<T> lhs = std::move(rhs);
64-
assert(static_cast<bool>(lhs) == rhs_engaged);
65-
if (rhs_engaged)
66-
assert(&(*lhs) == &(*rhs));
62+
optional<T> lhs(std::move(rhs));
63+
64+
assert(lhs.has_value() == rhs.has_value());
65+
assert(rhs.has_value() ? &*lhs == &*rhs : true);
6766
}
6867

69-
// TODO: Add constexpr tests
70-
void test_reference_extension() {
68+
struct F {
69+
int move_count = 0;
70+
71+
constexpr F() {}
72+
constexpr F(F&&) { move_count++; }
73+
};
74+
7175
#if TEST_STD_VER >= 26
76+
77+
constexpr void test_ref() {
78+
{ // Test that moving from an optional<T&> doesn't also move the object it's referencing
79+
F f{};
80+
std::optional<F&> o1(f);
81+
std::optional<F&> o2(std::move(o1));
82+
assert(f.move_count == 0);
83+
assert(o1.has_value() && o2.has_value());
84+
assert(&*o1 == &*o2);
85+
}
86+
}
87+
88+
void test_reference_extension() {
7289
using T = TestTypes::TestType;
7390
T::reset();
7491
{
@@ -129,8 +146,8 @@ void test_reference_extension() {
129146
static_assert(!std::is_copy_constructible_v<std::optional<T const&&>>);
130147
}
131148
# endif
132-
#endif
133149
}
150+
#endif
134151

135152
constexpr bool test() {
136153
test<int>();
@@ -143,6 +160,10 @@ constexpr bool test() {
143160
test<T>(42);
144161
}
145162

163+
#if TEST_STD_VER >= 26
164+
test_ref();
165+
#endif
166+
146167
#if TEST_STD_VER >= 26 && 0
147168
{
148169
test_throwing_ctor();
@@ -152,7 +173,7 @@ constexpr bool test() {
152173
return true;
153174
}
154175

155-
bool rt_test() {
176+
bool test_rt() {
156177
{
157178
using T = TestTypes::TestType;
158179
T::reset();
@@ -213,7 +234,7 @@ int main(int, char**) {
213234
static_assert(test());
214235

215236
{
216-
rt_test();
237+
test_rt();
217238
}
218239

219240
{

0 commit comments

Comments
 (0)