[libcxx-commits] [libcxx] [libc++] Refactor `optional` constructor tests (PR #169203)
William Tran-Viet via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Nov 23 00:03:52 PST 2025
https://github.com/smallp-o-p created https://github.com/llvm/llvm-project/pull/169203
- Reformat, and refactor as much as possible `std::optional<T>` to be simpler and more similar to the pattern newer tests have.
- This consequently should increase `constexpr` test coverage by some amount.
- The intent of the tests should not have been changed, meaning they should be testing the same things as they did before this PR.
- This PR also unlocks runtime constructor tests for `std::optional<T&>` that were missed in the original `optional<T&>` PR.
>From 85d6c5b2d591f1989ec3d98d05f39f9c7d97328b Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sat, 22 Nov 2025 22:22:39 -0500
Subject: [PATCH 01/22] Default
---
.../optional.object.ctor/default.pass.cpp | 105 +++++++++---------
1 file changed, 52 insertions(+), 53 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp
index 61a365edb64ea..540863b2b19c4 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/default.pass.cpp
@@ -6,77 +6,76 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// constexpr optional() noexcept;
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
-using std::optional;
+template <class T>
+constexpr void test() {
+ static_assert(std::is_nothrow_default_constructible_v<std::optional<T>>);
+ static_assert(std::is_trivially_destructible_v<T> == std::is_trivially_destructible_v<std::optional<T>>);
-template <class Opt>
-void
-test_constexpr()
-{
- static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
- static_assert(std::is_trivially_destructible<Opt>::value, "");
- static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
+ if constexpr (!std::is_lvalue_reference_v<T>) {
+ static_assert(
+ std::is_trivially_destructible_v<T> == std::is_trivially_destructible_v<typename std::optional<T>::value_type>);
+ }
- constexpr Opt opt;
- static_assert(static_cast<bool>(opt) == false, "");
+ {
+ std::optional<T> opt;
+ assert(static_cast<bool>(opt) == false);
+ }
+ {
+ const std::optional<T> opt;
+ assert(static_cast<bool>(opt) == false);
+ }
- struct test_constexpr_ctor
- : public Opt
- {
- constexpr test_constexpr_ctor() {}
- };
+ struct test_constexpr_ctor : public std::optional<T> {
+ constexpr test_constexpr_ctor() {}
+ };
}
-template <class Opt>
-void
-test()
-{
- static_assert(std::is_nothrow_default_constructible<Opt>::value, "");
- static_assert(!std::is_trivially_destructible<Opt>::value, "");
- static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
- {
- Opt opt;
- assert(static_cast<bool>(opt) == false);
- }
- {
- const Opt opt;
- assert(static_cast<bool>(opt) == false);
- }
-
- struct test_constexpr_ctor
- : public Opt
- {
- constexpr test_constexpr_ctor() {}
- };
+TEST_CONSTEXPR_CXX23 void non_literal_test() {
+ test<NonLiteralTypes::NoCtors>();
+ test<NonLiteralTypes::NoCtors>();
}
-int main(int, char**)
-{
- test_constexpr<optional<int>>();
- test_constexpr<optional<int*>>();
- test_constexpr<optional<ImplicitTypes::NoCtors>>();
- test_constexpr<optional<NonTrivialTypes::NoCtors>>();
- test_constexpr<optional<NonConstexprTypes::NoCtors>>();
- test<optional<NonLiteralTypes::NoCtors>>();
- // EXTENSIONS
-#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
- test_constexpr<optional<int&>>();
- test_constexpr<optional<const int&>>();
- test_constexpr<optional<int&>>();
- test_constexpr<optional<NonLiteralTypes::NoCtors&>>();
- test_constexpr<optional<NonLiteralTypes::NoCtors&&>>();
+constexpr bool test() {
+ test<int>();
+ test<int*>();
+ test<ImplicitTypes::NoCtors>();
+ test<NonTrivialTypes::NoCtors>();
+ test<NonConstexprTypes::NoCtors>();
+#if TEST_STD_VER >= 23
+ non_literal_test();
+#endif
+#if TEST_STD_VER >= 26
+ test<int&>();
+ test<const int&>();
+ test<int&>();
+ test<NonLiteralTypes::NoCtors&>();
+// TODO: optional<T&&> is not allowed.
+# if 0
+ test<NonLiteralTypes::NoCtors&&>();
+# endif
#endif
+ return true;
+}
+
+int main(int, char**) {
+ assert(test());
+ static_assert(test());
+
+ {
+ non_literal_test();
+ }
return 0;
}
>From 7f700effefd5d66647074d76c071ef2873d334c4 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sat, 22 Nov 2025 23:11:39 -0500
Subject: [PATCH 02/22] optional<U> and friends
---
.../const_optional_U.pass.cpp | 139 ++++++++++--------
.../explicit_const_optional_U.pass.cpp | 132 +++++++++--------
.../explicit_optional_U.pass.cpp | 115 ++++++++-------
3 files changed, 208 insertions(+), 178 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp
index 9505238e6e5e2..ab424a6509183 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_optional_U.pass.cpp
@@ -6,80 +6,75 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class U>
// optional(const optional<U>& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
using std::optional;
template <class T, class U>
-TEST_CONSTEXPR_CXX20 void
-test(const optional<U>& rhs, bool is_going_to_throw = false)
-{
- bool rhs_engaged = static_cast<bool>(rhs);
+TEST_CONSTEXPR_CXX20 void test(const optional<U>& rhs, bool is_going_to_throw = false) {
+ bool rhs_engaged = static_cast<bool>(rhs);
#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- optional<T> lhs = rhs;
- assert(is_going_to_throw == false);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == *rhs);
- }
- catch (int i)
- {
- assert(i == 6);
- }
-#else
- if (is_going_to_throw) return;
+ try {
optional<T> lhs = rhs;
+ assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
if (rhs_engaged)
- assert(*lhs == *rhs);
+ assert(*lhs == *rhs);
+ } catch (int i) {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw)
+ return;
+ optional<T> lhs = rhs;
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *rhs);
#endif
}
-class X
-{
- int i_;
+class X {
+ int i_;
+
public:
- constexpr X(int i) : i_(i) {}
- constexpr X(const X& x) : i_(x.i_) {}
- TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;}
- friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+ constexpr X(int i) : i_(i) {}
+ constexpr X(const X& x) : i_(x.i_) {}
+ TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; }
+ friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; }
};
-class Y
-{
- int i_;
+class Y {
+ int i_;
+
public:
- constexpr Y(int i) : i_(i) {}
+ constexpr Y(int i) : i_(i) {}
- friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
+ friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_; }
};
int count = 0;
-class Z
-{
- int i_;
+class Z {
+ int i_;
+
public:
- Z(int i) : i_(i) {TEST_THROW(6);}
+ constexpr Z(int i) : i_(i) { TEST_THROW(6); }
- friend bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
+ friend bool operator==(const Z& x, const Z& y) { return x.i_ == y.i_; }
};
-template<class T, class U>
-constexpr bool test_all()
-{
+template <class T, class U>
+constexpr bool test_all() {
{
optional<U> rhs;
test<T>(rhs);
@@ -91,30 +86,46 @@ constexpr bool test_all()
return true;
}
-int main(int, char**)
-{
- test_all<int, short>();
- test_all<X, int>();
- test_all<Y, int>();
-#if TEST_STD_VER > 17
- static_assert(test_all<int, short>());
- static_assert(test_all<X, int>());
- static_assert(test_all<Y, int>());
+constexpr bool test() {
+ test_all<int, short>();
+ test_all<X, int>();
+ test_all<Y, int>();
+
+// TODO: Enable once P3068R6 is implemented
+#if TEST_STD_VER >= 26 && 0
+ test_throwing();
#endif
- {
- typedef Z T;
- typedef int U;
- optional<U> rhs;
- test<T>(rhs);
- }
- {
- typedef Z T;
- typedef int U;
- optional<U> rhs(U{3});
- test<T>(rhs, true);
- }
-
- static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value), "");
+ return true;
+}
+
+TEST_CONSTEXPR_CXX26 bool test_throwing() {
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs(U{3});
+ test<T>(rhs, true);
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 20
+ static_assert(test());
+#endif
+
+ {
+ test_throwing();
+ }
+
+ static_assert(!(std::is_constructible<optional<X>, const optional<Y>&>::value));
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp
index d8594bc03b132..fa9a96c39b8fa 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_const_optional_U.pass.cpp
@@ -6,81 +6,76 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRED: std-at-least-c++17
// <optional>
// template <class U>
// explicit optional(const optional<U>& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
using std::optional;
template <class T, class U>
-TEST_CONSTEXPR_CXX20 void
-test(const optional<U>& rhs, bool is_going_to_throw = false)
-{
- static_assert(!(std::is_convertible<const optional<U>&, optional<T>>::value), "");
- bool rhs_engaged = static_cast<bool>(rhs);
+TEST_CONSTEXPR_CXX20 void test(const optional<U>& rhs, bool is_going_to_throw = false) {
+ static_assert(!(std::is_convertible<const optional<U>&, optional<T>>::value));
+ bool rhs_engaged = static_cast<bool>(rhs);
#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- optional<T> lhs(rhs);
- assert(is_going_to_throw == false);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == T(*rhs));
- }
- catch (int i)
- {
- assert(i == 6);
- }
-#else
- if (is_going_to_throw) return;
+ try {
optional<T> lhs(rhs);
+ assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
if (rhs_engaged)
- assert(*lhs == T(*rhs));
+ assert(*lhs == T(*rhs));
+ } catch (int i) {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw)
+ return;
+ optional<T> lhs(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == T(*rhs));
#endif
}
-class X
-{
- int i_;
+class X {
+ int i_;
+
public:
- constexpr explicit X(int i) : i_(i) {}
- constexpr X(const X& x) : i_(x.i_) {}
- TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;}
- friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+ constexpr explicit X(int i) : i_(i) {}
+ constexpr X(const X& x) : i_(x.i_) {}
+ TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; }
+ friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; }
};
-class Y
-{
- int i_;
+class Y {
+ int i_;
+
public:
- constexpr explicit Y(int i) : i_(i) {}
+ constexpr explicit Y(int i) : i_(i) {}
- friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
+ friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_; }
};
int count = 0;
-class Z
-{
- int i_;
+class Z {
+ int i_;
+
public:
- explicit Z(int i) : i_(i) {TEST_THROW(6);}
+ constexpr explicit Z(int i) : i_(i) { TEST_THROW(6); }
- friend bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
+ friend constexpr bool operator==(const Z& x, const Z& y) { return x.i_ == y.i_; }
};
-template<class T, class U>
-constexpr bool test_all()
-{
+template <class T, class U>
+constexpr bool test_all() {
{
optional<U> rhs;
test<T>(rhs);
@@ -92,27 +87,42 @@ constexpr bool test_all()
return true;
}
+TEST_CONSTEXPR_CXX26 bool test_throwing() {
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs;
+ test<T>(rhs);
+ }
+ {
+ typedef Z T;
+ typedef int U;
+ optional<U> rhs(3);
+ test<T>(rhs, true);
+ }
+
+ return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test() {
+ test_all<X, int>();
+ test_all<Y, int>();
-int main(int, char**)
-{
- test_all<X, int>();
- test_all<Y, int>();
-#if TEST_STD_VER > 17
- static_assert(test_all<X, int>());
- static_assert(test_all<Y, int>());
+// TODO: Enable once P3068R6 is implemented
+#if TEST_STD_VER >= 26 && 0
+ test_throwing();
#endif
- {
- typedef Z T;
- typedef int U;
- optional<U> rhs;
- test<T>(rhs);
- }
- {
- typedef Z T;
- typedef int U;
- optional<U> rhs(3);
- test<T>(rhs, true);
- }
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 20
+ static_assert(test());
+#endif
+ {
+ test_throwing();
+ }
return 0;
}
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp
index 708370a47b616..f89ba1319a9ed 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/explicit_optional_U.pass.cpp
@@ -6,89 +6,98 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class U>
// explicit optional(optional<U>&& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
using std::optional;
template <class T, class U>
-TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false)
-{
- static_assert(!(std::is_convertible<optional<U>&&, optional<T>>::value), "");
- bool rhs_engaged = static_cast<bool>(rhs);
+TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false) {
+ static_assert(!(std::is_convertible<optional<U>&&, optional<T>>::value));
+ bool rhs_engaged = static_cast<bool>(rhs);
#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- optional<T> lhs(std::move(rhs));
- assert(is_going_to_throw == false);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- }
- catch (int i)
- {
- assert(i == 6);
- }
-#else
- if (is_going_to_throw) return;
+ try {
optional<T> lhs(std::move(rhs));
+ assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
+ } catch (int i) {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw)
+ return;
+ optional<T> lhs(std::move(rhs));
+ assert(static_cast<bool>(lhs) == rhs_engaged);
#endif
}
-class X
-{
- int i_;
+class X {
+ int i_;
+
public:
- constexpr explicit X(int i) : i_(i) {}
- constexpr X(X&& x) : i_(x.i_) { x.i_ = 0; }
- TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;}
- friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+ constexpr explicit X(int i) : i_(i) {}
+ constexpr X(X&& x) : i_(x.i_) { x.i_ = 0; }
+ TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; }
+ friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; }
};
int count = 0;
-class Z
-{
+class Z {
public:
- explicit Z(int) { TEST_THROW(6); }
+ explicit Z(int) { TEST_THROW(6); }
};
-TEST_CONSTEXPR_CXX20 bool test()
-{
- {
- optional<int> rhs;
- test<X>(std::move(rhs));
- }
- {
- optional<int> rhs(3);
- test<X>(std::move(rhs));
- }
-
- return true;
+TEST_CONSTEXPR_CXX26 bool test_throwing() {
+ {
+ optional<int> rhs;
+ test<Z>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<Z>(std::move(rhs), true);
+ }
+
+ return true;
+}
+
+TEST_CONSTEXPR_CXX20 bool test() {
+ {
+ optional<int> rhs;
+ test<X>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<X>(std::move(rhs));
+ }
+
+ {
+// TODO: Enable once P3068R6 is implemented
+#if TEST_STD_VER >= 26 && 0
+ test_throwing();
+#endif
+ }
+
+ return true;
}
-int main(int, char**)
-{
-#if TEST_STD_VER > 17
- static_assert(test());
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 20
+ static_assert(test());
#endif
- test();
- {
- optional<int> rhs;
- test<Z>(std::move(rhs));
- }
- {
- optional<int> rhs(3);
- test<Z>(std::move(rhs), true);
- }
+ {
+ test_throwing();
+ }
return 0;
}
>From 562e3c6959cafb79f7ebbe7a3857d988a23e2433 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sat, 22 Nov 2025 23:15:14 -0500
Subject: [PATCH 03/22] Format optional(nullopt_t)
---
.../optional.object.ctor/nullopt_t.pass.cpp | 70 ++++++++-----------
1 file changed, 30 insertions(+), 40 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
index 36a60f29da854..f0bc422d292a9 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
@@ -11,66 +11,56 @@
// constexpr optional(nullopt_t) noexcept;
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "archetypes.h"
-
#include "test_macros.h"
-using std::optional;
-using std::nullopt_t;
using std::nullopt;
+using std::nullopt_t;
+using std::optional;
template <class Opt>
-void
-test_constexpr()
-{
- static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
- static_assert(std::is_trivially_destructible<Opt>::value, "");
- static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
+void test_constexpr() {
+ static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
+ static_assert(std::is_trivially_destructible<Opt>::value, "");
+ static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
- constexpr Opt opt(nullopt);
- static_assert(static_cast<bool>(opt) == false, "");
+ constexpr Opt opt(nullopt);
+ static_assert(static_cast<bool>(opt) == false, "");
- struct test_constexpr_ctor
- : public Opt
- {
- constexpr test_constexpr_ctor() {}
- };
+ struct test_constexpr_ctor : public Opt {
+ constexpr test_constexpr_ctor() {}
+ };
}
template <class Opt>
-void
-test()
-{
- static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
- static_assert(!std::is_trivially_destructible<Opt>::value, "");
- static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
- {
+void test() {
+ static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
+ static_assert(!std::is_trivially_destructible<Opt>::value, "");
+ static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
+ {
Opt opt(nullopt);
assert(static_cast<bool>(opt) == false);
- }
- {
+ }
+ {
const Opt opt(nullopt);
assert(static_cast<bool>(opt) == false);
- }
- struct test_constexpr_ctor
- : public Opt
- {
- constexpr test_constexpr_ctor() {}
- };
+ }
+ struct test_constexpr_ctor : public Opt {
+ constexpr test_constexpr_ctor() {}
+ };
}
-int main(int, char**)
-{
- test_constexpr<optional<int>>();
- test_constexpr<optional<int*>>();
- test_constexpr<optional<ImplicitTypes::NoCtors>>();
- test_constexpr<optional<NonTrivialTypes::NoCtors>>();
- test_constexpr<optional<NonConstexprTypes::NoCtors>>();
- test<optional<NonLiteralTypes::NoCtors>>();
+int main(int, char**) {
+ test_constexpr<optional<int>>();
+ test_constexpr<optional<int*>>();
+ test_constexpr<optional<ImplicitTypes::NoCtors>>();
+ test_constexpr<optional<NonTrivialTypes::NoCtors>>();
+ test_constexpr<optional<NonConstexprTypes::NoCtors>>();
+ test<optional<NonLiteralTypes::NoCtors>>();
return 0;
}
>From c74225786c2a2e5a0edd5fb1501863bff1457a78 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sat, 22 Nov 2025 23:21:48 -0500
Subject: [PATCH 04/22] nullopt_t
---
.../optional.object.ctor/nullopt_t.pass.cpp | 77 ++++++++++---------
1 file changed, 42 insertions(+), 35 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
index f0bc422d292a9..05ad8db2b6a6c 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/nullopt_t.pass.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// constexpr optional(nullopt_t) noexcept;
@@ -18,49 +18,56 @@
#include "archetypes.h"
#include "test_macros.h"
-using std::nullopt;
-using std::nullopt_t;
-using std::optional;
+template <class T>
+constexpr void test() {
+ static_assert(std::is_nothrow_constructible_v<std::optional<T>, std::nullopt_t&>);
+ static_assert(std::is_trivially_destructible_v<T> == std::is_trivially_destructible_v<std::optional<T>>);
+ static_assert(
+ std::is_trivially_destructible_v<T> == std::is_trivially_destructible_v<typename std::optional<T>::value_type>);
-template <class Opt>
-void test_constexpr() {
- static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
- static_assert(std::is_trivially_destructible<Opt>::value, "");
- static_assert(std::is_trivially_destructible<typename Opt::value_type>::value, "");
+ constexpr std::optional<T> opt(std::nullopt);
+ assert(!static_cast<bool>(opt));
- constexpr Opt opt(nullopt);
- static_assert(static_cast<bool>(opt) == false, "");
-
- struct test_constexpr_ctor : public Opt {
+ struct test_constexpr_ctor : public std::optional<T> {
constexpr test_constexpr_ctor() {}
};
}
-template <class Opt>
-void test() {
- static_assert(std::is_nothrow_constructible<Opt, nullopt_t&>::value, "");
- static_assert(!std::is_trivially_destructible<Opt>::value, "");
- static_assert(!std::is_trivially_destructible<typename Opt::value_type>::value, "");
- {
- Opt opt(nullopt);
- assert(static_cast<bool>(opt) == false);
- }
- {
- const Opt opt(nullopt);
- assert(static_cast<bool>(opt) == false);
- }
- struct test_constexpr_ctor : public Opt {
- constexpr test_constexpr_ctor() {}
- };
+template <class T>
+TEST_CONSTEXPR_CXX23 void rt_test() {
+ static_assert(std::is_nothrow_constructible_v<std::optional<T>, std::nullopt_t&>);
+ static_assert(std::is_trivially_destructible_v<T> == std::is_trivially_destructible_v<std::optional<T>>);
+ static_assert(
+ std::is_trivially_destructible_v<T> == std::is_trivially_destructible_v<typename std::optional<T>::value_type>);
+
+ const std::optional<T> opt(std::nullopt);
+ assert(!static_cast<bool>(opt));
+}
+
+TEST_CONSTEXPR_CXX23 bool test_non_literal() {
+ rt_test<NonLiteralTypes::NoCtors>();
+ return true;
+}
+
+constexpr bool test() {
+ test<int>();
+ test<int*>();
+ test<ImplicitTypes::NoCtors>();
+ test<NonTrivialTypes::NoCtors>();
+ test<NonConstexprTypes::NoCtors>();
+#if TEST_STD_VER >= 23
+ test_non_literal();
+#endif
+ return true;
}
int main(int, char**) {
- test_constexpr<optional<int>>();
- test_constexpr<optional<int*>>();
- test_constexpr<optional<ImplicitTypes::NoCtors>>();
- test_constexpr<optional<NonTrivialTypes::NoCtors>>();
- test_constexpr<optional<NonConstexprTypes::NoCtors>>();
- test<optional<NonLiteralTypes::NoCtors>>();
+ assert(test());
+ static_assert(test());
+
+ {
+ test_non_literal();
+ }
return 0;
}
>From 267271daf62e80e4b122804619e6c89070fdfc66 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sat, 22 Nov 2025 23:23:23 -0500
Subject: [PATCH 05/22] Format copy
---
.../optional.object.ctor/copy.pass.cpp | 272 +++++++++---------
1 file changed, 132 insertions(+), 140 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
index 54a424c4c347d..8006dbfdb3604 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
@@ -20,164 +20,156 @@
using std::optional;
-template <class T, class ...InitArgs>
-void test(InitArgs&&... args)
-{
- const optional<T> rhs(std::forward<InitArgs>(args)...);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = rhs;
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == *rhs);
+template <class T, class... InitArgs>
+void test(InitArgs&&... args) {
+ const optional<T> rhs(std::forward<InitArgs>(args)...);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = rhs;
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *rhs);
}
-template <class T, class ...InitArgs>
-constexpr bool constexpr_test(InitArgs&&... args)
-{
- static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
- const optional<T> rhs(std::forward<InitArgs>(args)...);
- optional<T> lhs = rhs;
- return (lhs.has_value() == rhs.has_value()) &&
- (lhs.has_value() ? *lhs == *rhs : true);
+template <class T, class... InitArgs>
+constexpr bool constexpr_test(InitArgs&&... args) {
+ static_assert(std::is_trivially_copy_constructible_v<T>, ""); // requirement
+ const optional<T> rhs(std::forward<InitArgs>(args)...);
+ optional<T> lhs = rhs;
+ return (lhs.has_value() == rhs.has_value()) && (lhs.has_value() ? *lhs == *rhs : true);
}
void test_throwing_ctor() {
#ifndef TEST_HAS_NO_EXCEPTIONS
- struct Z {
- Z() : count(0) {}
- Z(Z const& o) : count(o.count + 1)
- { if (count == 2) throw 6; }
- int count;
- };
- const Z z;
- const optional<Z> rhs(z);
- try
- {
- optional<Z> lhs(rhs);
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
+ struct Z {
+ Z() : count(0) {}
+ Z(Z const& o) : count(o.count + 1) {
+ if (count == 2)
+ throw 6;
}
+ int count;
+ };
+ const Z z;
+ const optional<Z> rhs(z);
+ try {
+ optional<Z> lhs(rhs);
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
+ }
#endif
}
-template <class T, class ...InitArgs>
-void test_ref(InitArgs&&... args)
-{
- const optional<T> rhs(std::forward<InitArgs>(args)...);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = rhs;
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(&(*lhs) == &(*rhs));
+template <class T, class... InitArgs>
+void test_ref(InitArgs&&... args) {
+ const optional<T> rhs(std::forward<InitArgs>(args)...);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = rhs;
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(&(*lhs) == &(*rhs));
}
-
-void test_reference_extension()
-{
+void test_reference_extension() {
#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
- using T = TestTypes::TestType;
- T::reset();
- {
- T t;
- T::reset_constructors();
- test_ref<T&>();
- test_ref<T&>(t);
- assert(T::alive == 1);
- assert(T::constructed == 0);
- assert(T::assigned == 0);
- assert(T::destroyed == 0);
- }
- assert(T::destroyed == 1);
- assert(T::alive == 0);
- {
- T t;
- const T& ct = t;
- T::reset_constructors();
- test_ref<T const&>();
- test_ref<T const&>(t);
- test_ref<T const&>(ct);
- assert(T::alive == 1);
- assert(T::constructed == 0);
- assert(T::assigned == 0);
- assert(T::destroyed == 0);
- }
- assert(T::alive == 0);
- assert(T::destroyed == 1);
- {
- static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
- static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
- }
+ using T = TestTypes::TestType;
+ T::reset();
+ {
+ T t;
+ T::reset_constructors();
+ test_ref<T&>();
+ test_ref<T&>(t);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::destroyed == 1);
+ assert(T::alive == 0);
+ {
+ T t;
+ const T& ct = t;
+ T::reset_constructors();
+ test_ref<T const&>();
+ test_ref<T const&>(t);
+ test_ref<T const&>(ct);
+ assert(T::alive == 1);
+ assert(T::constructed == 0);
+ assert(T::assigned == 0);
+ assert(T::destroyed == 0);
+ }
+ assert(T::alive == 0);
+ assert(T::destroyed == 1);
+ {
+ static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
+ static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
+ }
#endif
}
-int main(int, char**)
-{
- test<int>();
- test<int>(3);
- static_assert(constexpr_test<int>(), "" );
- static_assert(constexpr_test<int>(3), "" );
+int main(int, char**) {
+ test<int>();
+ test<int>(3);
+ static_assert(constexpr_test<int>(), "");
+ static_assert(constexpr_test<int>(3), "");
- {
- const optional<const int> o(42);
- optional<const int> o2(o);
- assert(*o2 == 42);
- }
- {
- using T = TestTypes::TestType;
- T::reset();
- const optional<T> rhs;
- assert(T::alive == 0);
- const optional<T> lhs(rhs);
- assert(lhs.has_value() == false);
- assert(T::alive == 0);
- }
- TestTypes::TestType::reset();
- {
- using T = TestTypes::TestType;
- T::reset();
- const optional<T> rhs(42);
- assert(T::alive == 1);
- assert(T::value_constructed == 1);
- assert(T::copy_constructed == 0);
- const optional<T> lhs(rhs);
- assert(lhs.has_value());
- assert(T::copy_constructed == 1);
- assert(T::alive == 2);
- }
- TestTypes::TestType::reset();
- {
- using namespace ConstexprTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- using namespace TrivialTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- test_throwing_ctor();
- }
- {
- test_reference_extension();
- }
- {
- constexpr std::optional<int> o1{4};
- constexpr std::optional<int> o2 = o1;
- static_assert( *o2 == 4, "" );
- }
+ {
+ const optional<const int> o(42);
+ optional<const int> o2(o);
+ assert(*o2 == 42);
+ }
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ const optional<T> rhs;
+ assert(T::alive == 0);
+ const optional<T> lhs(rhs);
+ assert(lhs.has_value() == false);
+ assert(T::alive == 0);
+ }
+ TestTypes::TestType::reset();
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ const optional<T> rhs(42);
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::copy_constructed == 0);
+ const optional<T> lhs(rhs);
+ assert(lhs.has_value());
+ assert(T::copy_constructed == 1);
+ assert(T::alive == 2);
+ }
+ TestTypes::TestType::reset();
+ {
+ using namespace ConstexprTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ using namespace TrivialTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ test_throwing_ctor();
+ }
+ {
+ test_reference_extension();
+ }
+ {
+ constexpr std::optional<int> o1{4};
+ constexpr std::optional<int> o2 = o1;
+ static_assert(*o2 == 4, "");
+ }
- // LWG3836 https://wg21.link/LWG3836
- // std::optional<bool> conversion constructor optional(const optional<U>&)
- // should take precedence over optional(U&&) with operator bool
- {
- std::optional<bool> o1(false);
- std::optional<bool> o2(o1);
- assert(!o2.value());
- }
+ // LWG3836 https://wg21.link/LWG3836
+ // std::optional<bool> conversion constructor optional(const optional<U>&)
+ // should take precedence over optional(U&&) with operator bool
+ {
+ std::optional<bool> o1(false);
+ std::optional<bool> o2(o1);
+ assert(!o2.value());
+ }
return 0;
}
>From cd6d9f180c1dcd4624895be700d2ca50a6eaa94d Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sat, 22 Nov 2025 23:49:47 -0500
Subject: [PATCH 06/22] Copy
---
.../optional.object.ctor/copy.pass.cpp | 131 ++++++++++--------
1 file changed, 75 insertions(+), 56 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
index 8006dbfdb3604..bd4741154e6d8 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/copy.pass.cpp
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// constexpr optional(const optional<T>& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
@@ -21,24 +21,18 @@
using std::optional;
template <class T, class... InitArgs>
-void test(InitArgs&&... args) {
- const optional<T> rhs(std::forward<InitArgs>(args)...);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = rhs;
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == *rhs);
-}
+constexpr bool test(InitArgs&&... args) {
+ static_assert(std::is_trivially_copy_constructible_v<T> ==
+ std::is_trivially_copy_constructible_v<std::optional<T>>); // requirement
+ const optional<T> lhs(std::forward<InitArgs>(args)...);
+ optional<T> rhs(lhs);
+ assert(lhs.has_value() == rhs.has_value());
+ assert(lhs.has_value() ? *lhs == *rhs : true);
-template <class T, class... InitArgs>
-constexpr bool constexpr_test(InitArgs&&... args) {
- static_assert(std::is_trivially_copy_constructible_v<T>, ""); // requirement
- const optional<T> rhs(std::forward<InitArgs>(args)...);
- optional<T> lhs = rhs;
- return (lhs.has_value() == rhs.has_value()) && (lhs.has_value() ? *lhs == *rhs : true);
+ return true;
}
-void test_throwing_ctor() {
+TEST_CONSTEXPR_CXX26 bool test_throwing_ctor() {
#ifndef TEST_HAS_NO_EXCEPTIONS
struct Z {
Z() : count(0) {}
@@ -57,6 +51,8 @@ void test_throwing_ctor() {
assert(i == 6);
}
#endif
+
+ return true;
}
template <class T, class... InitArgs>
@@ -69,8 +65,9 @@ void test_ref(InitArgs&&... args) {
assert(&(*lhs) == &(*rhs));
}
+// TODO: Add constexpr tests
void test_reference_extension() {
-#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
+#if TEST_STD_VER >= 26
using T = TestTypes::TestType;
T::reset();
{
@@ -99,24 +96,73 @@ void test_reference_extension() {
}
assert(T::alive == 0);
assert(T::destroyed == 1);
+
+# if 0 // FIXME: optional<T&&> is not allowed.
{
- static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
- static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
+ static_assert(!std::is_copy_constructible<std::optional<T&&>>::value);
+ static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value);
}
+# endif
#endif
}
-int main(int, char**) {
+constexpr bool test() {
test<int>();
test<int>(3);
- static_assert(constexpr_test<int>(), "");
- static_assert(constexpr_test<int>(3), "");
+ test<const int>(42);
+
+ // FIXME: Why is this in ctor copy.pass.cpp?
+ {
+ constexpr std::optional<int> o1{4};
+ constexpr std::optional<int> o2 = o1;
+ static_assert(*o2 == 4, "");
+ }
+
+ {
+ // LWG3836 https://wg21.link/LWG3836
+ // std::optional<bool> conversion constructor optional(const optional<U>&)
+ // should take precedence over optional(U&&) with operator bool
+ {
+ std::optional<bool> o1(false);
+ std::optional<bool> o2(o1);
+ assert(!o2.value());
+ }
+ }
+
+ {
+ using T = TrivialTestTypes::TestType;
+ test<T>();
+ test<T>(42);
+ }
+
+ // TODO: Enable once P3068R6 is implemented
+#if TEST_STD_VER >= 26 && 0
+ test_throwing_ctor();
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ {
+ test_throwing_ctor();
+ }
+#if TEST_STD_VER >= 26
{
- const optional<const int> o(42);
- optional<const int> o2(o);
- assert(*o2 == 42);
+ test_reference_extension();
+ }
+#endif
+
+ { // FIXME: Shouldn't this be able to pass in a constexpr context since C++17?
+ using T = ConstexprTestTypes::TestType;
+ test<T>();
+ test<T>(42);
}
+
{
using T = TestTypes::TestType;
T::reset();
@@ -126,7 +172,9 @@ int main(int, char**) {
assert(lhs.has_value() == false);
assert(T::alive == 0);
}
+
TestTypes::TestType::reset();
+
{
using T = TestTypes::TestType;
T::reset();
@@ -139,37 +187,8 @@ int main(int, char**) {
assert(T::copy_constructed == 1);
assert(T::alive == 2);
}
- TestTypes::TestType::reset();
- {
- using namespace ConstexprTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- using namespace TrivialTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- test_throwing_ctor();
- }
- {
- test_reference_extension();
- }
- {
- constexpr std::optional<int> o1{4};
- constexpr std::optional<int> o2 = o1;
- static_assert(*o2 == 4, "");
- }
- // LWG3836 https://wg21.link/LWG3836
- // std::optional<bool> conversion constructor optional(const optional<U>&)
- // should take precedence over optional(U&&) with operator bool
- {
- std::optional<bool> o1(false);
- std::optional<bool> o2(o1);
- assert(!o2.value());
- }
+ TestTypes::TestType::reset();
return 0;
}
>From d8b2c9eb733cadbd9f98bf1b4361039bc99da08a Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 00:11:46 -0500
Subject: [PATCH 07/22] Format move.pass
---
.../optional.object.ctor/move.pass.cpp | 229 +++++++++---------
1 file changed, 111 insertions(+), 118 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
index f59fc3b82ad7f..faaf711054eea 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
@@ -6,76 +6,70 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// constexpr optional(optional<T>&& rhs);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
using std::optional;
-template <class T, class ...InitArgs>
-void test(InitArgs&&... args)
-{
- const optional<T> orig(std::forward<InitArgs>(args)...);
- optional<T> rhs(orig);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = std::move(rhs);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == *orig);
+template <class T, class... InitArgs>
+void test(InitArgs&&... args) {
+ const optional<T> orig(std::forward<InitArgs>(args)...);
+ optional<T> rhs(orig);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = std::move(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(*lhs == *orig);
}
-template <class T, class ...InitArgs>
-constexpr bool constexpr_test(InitArgs&&... args)
-{
- static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
- const optional<T> orig(std::forward<InitArgs>(args)...);
- optional<T> rhs(orig);
- optional<T> lhs = std::move(rhs);
- return (lhs.has_value() == orig.has_value()) &&
- (lhs.has_value() ? *lhs == *orig : true);
+template <class T, class... InitArgs>
+constexpr bool constexpr_test(InitArgs&&... args) {
+ static_assert(std::is_trivially_copy_constructible_v<T>, ""); // requirement
+ const optional<T> orig(std::forward<InitArgs>(args)...);
+ optional<T> rhs(orig);
+ optional<T> lhs = std::move(rhs);
+ return (lhs.has_value() == orig.has_value()) && (lhs.has_value() ? *lhs == *orig : true);
}
void test_throwing_ctor() {
#ifndef TEST_HAS_NO_EXCEPTIONS
- struct Z {
- Z() : count(0) {}
- Z(Z&& o) : count(o.count + 1)
- { if (count == 2) throw 6; }
- int count;
- };
- Z z;
- optional<Z> rhs(std::move(z));
- try
- {
- optional<Z> lhs(std::move(rhs));
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
+ struct Z {
+ Z() : count(0) {}
+ Z(Z&& o) : count(o.count + 1) {
+ if (count == 2)
+ throw 6;
}
+ int count;
+ };
+ Z z;
+ optional<Z> rhs(std::move(z));
+ try {
+ optional<Z> lhs(std::move(rhs));
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
+ }
#endif
}
-
-template <class T, class ...InitArgs>
-void test_ref(InitArgs&&... args)
-{
- optional<T> rhs(std::forward<InitArgs>(args)...);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = std::move(rhs);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(&(*lhs) == &(*rhs));
+template <class T, class... InitArgs>
+void test_ref(InitArgs&&... args) {
+ optional<T> rhs(std::forward<InitArgs>(args)...);
+ bool rhs_engaged = static_cast<bool>(rhs);
+ optional<T> lhs = std::move(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
+ if (rhs_engaged)
+ assert(&(*lhs) == &(*rhs));
}
void test_reference_extension() {
@@ -143,80 +137,79 @@ void test_reference_extension() {
#endif
}
-int main(int, char**)
-{
- test<int>();
- test<int>(3);
- static_assert(constexpr_test<int>(), "" );
- static_assert(constexpr_test<int>(3), "" );
+int main(int, char**) {
+ test<int>();
+ test<int>(3);
+ static_assert(constexpr_test<int>(), "");
+ static_assert(constexpr_test<int>(3), "");
- {
- optional<const int> o(42);
- optional<const int> o2(std::move(o));
- assert(*o2 == 42);
- }
- {
- using T = TestTypes::TestType;
- T::reset();
- optional<T> rhs;
- assert(T::alive == 0);
- const optional<T> lhs(std::move(rhs));
- assert(lhs.has_value() == false);
- assert(rhs.has_value() == false);
- assert(T::alive == 0);
- }
- TestTypes::TestType::reset();
- {
- using T = TestTypes::TestType;
- T::reset();
- optional<T> rhs(42);
- assert(T::alive == 1);
- assert(T::value_constructed == 1);
- assert(T::move_constructed == 0);
- const optional<T> lhs(std::move(rhs));
- assert(lhs.has_value());
- assert(rhs.has_value());
- assert(lhs.value().value == 42);
- assert(rhs.value().value == -1);
- assert(T::move_constructed == 1);
- assert(T::alive == 2);
- }
- TestTypes::TestType::reset();
- {
- using namespace ConstexprTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- using namespace TrivialTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- test_throwing_ctor();
- }
- {
- struct ThrowsMove {
- ThrowsMove() noexcept(false) {}
- ThrowsMove(ThrowsMove const&) noexcept(false) {}
- ThrowsMove(ThrowsMove &&) noexcept(false) {}
- };
- static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, "");
- struct NoThrowMove {
- NoThrowMove() noexcept(false) {}
- NoThrowMove(NoThrowMove const&) noexcept(false) {}
- NoThrowMove(NoThrowMove &&) noexcept(true) {}
- };
- static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, "");
- }
- {
- test_reference_extension();
- }
- {
+ {
+ optional<const int> o(42);
+ optional<const int> o2(std::move(o));
+ assert(*o2 == 42);
+ }
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ optional<T> rhs;
+ assert(T::alive == 0);
+ const optional<T> lhs(std::move(rhs));
+ assert(lhs.has_value() == false);
+ assert(rhs.has_value() == false);
+ assert(T::alive == 0);
+ }
+ TestTypes::TestType::reset();
+ {
+ using T = TestTypes::TestType;
+ T::reset();
+ optional<T> rhs(42);
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::move_constructed == 0);
+ const optional<T> lhs(std::move(rhs));
+ assert(lhs.has_value());
+ assert(rhs.has_value());
+ assert(lhs.value().value == 42);
+ assert(rhs.value().value == -1);
+ assert(T::move_constructed == 1);
+ assert(T::alive == 2);
+ }
+ TestTypes::TestType::reset();
+ {
+ using namespace ConstexprTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ using namespace TrivialTestTypes;
+ test<TestType>();
+ test<TestType>(42);
+ }
+ {
+ test_throwing_ctor();
+ }
+ {
+ struct ThrowsMove {
+ ThrowsMove() noexcept(false) {}
+ ThrowsMove(ThrowsMove const&) noexcept(false) {}
+ ThrowsMove(ThrowsMove&&) noexcept(false) {}
+ };
+ static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, "");
+ struct NoThrowMove {
+ NoThrowMove() noexcept(false) {}
+ NoThrowMove(NoThrowMove const&) noexcept(false) {}
+ NoThrowMove(NoThrowMove&&) noexcept(true) {}
+ };
+ static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, "");
+ }
+ {
+ test_reference_extension();
+ }
+ {
constexpr std::optional<int> o1{4};
constexpr std::optional<int> o2 = std::move(o1);
- static_assert( *o2 == 4, "" );
- }
+ static_assert(*o2 == 4, "");
+ }
return 0;
}
>From 74ae05ad5faaf547311be1653c99538a89b99789 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 00:23:17 -0500
Subject: [PATCH 08/22] Move
---
.../optional.object.ctor/move.pass.cpp | 83 +++++++++++--------
1 file changed, 48 insertions(+), 35 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
index faaf711054eea..34c851d31eb2c 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp
@@ -22,26 +22,20 @@
using std::optional;
template <class T, class... InitArgs>
-void test(InitArgs&&... args) {
+constexpr bool test(InitArgs&&... args) {
+ static_assert(std::is_trivially_move_constructible_v<T> == std::is_trivially_move_constructible_v<std::optional<T>>);
const optional<T> orig(std::forward<InitArgs>(args)...);
- optional<T> rhs(orig);
- bool rhs_engaged = static_cast<bool>(rhs);
- optional<T> lhs = std::move(rhs);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- if (rhs_engaged)
- assert(*lhs == *orig);
-}
-template <class T, class... InitArgs>
-constexpr bool constexpr_test(InitArgs&&... args) {
- static_assert(std::is_trivially_copy_constructible_v<T>, ""); // requirement
- const optional<T> orig(std::forward<InitArgs>(args)...);
- optional<T> rhs(orig);
- optional<T> lhs = std::move(rhs);
- return (lhs.has_value() == orig.has_value()) && (lhs.has_value() ? *lhs == *orig : true);
+ optional<T> lhs(orig);
+ optional<T> rhs(std::move(lhs));
+
+ assert(lhs.has_value() == rhs.has_value());
+ assert(lhs.has_value() ? *rhs == *orig : true);
+
+ return true;
}
-void test_throwing_ctor() {
+TEST_CONSTEXPR_CXX26 void test_throwing_ctor() {
#ifndef TEST_HAS_NO_EXCEPTIONS
struct Z {
Z() : count(0) {}
@@ -72,6 +66,7 @@ void test_ref(InitArgs&&... args) {
assert(&(*lhs) == &(*rhs));
}
+// TODO: Add constexpr tests
void test_reference_extension() {
#if TEST_STD_VER >= 26
using T = TestTypes::TestType;
@@ -137,17 +132,27 @@ void test_reference_extension() {
#endif
}
-int main(int, char**) {
+constexpr bool test() {
test<int>();
test<int>(3);
- static_assert(constexpr_test<int>(), "");
- static_assert(constexpr_test<int>(3), "");
+ test<const int>(42);
+
+ {
+ using T = TrivialTestTypes::TestType;
+ test<T>();
+ test<T>(42);
+ }
+#if TEST_STD_VER >= 26 && 0
{
- optional<const int> o(42);
- optional<const int> o2(std::move(o));
- assert(*o2 == 42);
+ test_throwing_ctor();
}
+#endif
+
+ return true;
+}
+
+bool rt_test() {
{
using T = TestTypes::TestType;
T::reset();
@@ -158,7 +163,9 @@ int main(int, char**) {
assert(rhs.has_value() == false);
assert(T::alive == 0);
}
+
TestTypes::TestType::reset();
+
{
using T = TestTypes::TestType;
T::reset();
@@ -174,20 +181,15 @@ int main(int, char**) {
assert(T::move_constructed == 1);
assert(T::alive == 2);
}
+
TestTypes::TestType::reset();
- {
+
+ { // TODO: Why doesn't this pass in a C++17 constexpr context?
using namespace ConstexprTestTypes;
test<TestType>();
test<TestType>(42);
}
- {
- using namespace TrivialTestTypes;
- test<TestType>();
- test<TestType>(42);
- }
- {
- test_throwing_ctor();
- }
+
{
struct ThrowsMove {
ThrowsMove() noexcept(false) {}
@@ -202,13 +204,24 @@ int main(int, char**) {
};
static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, "");
}
+
+ return true;
+}
+
+int main(int, char**) {
+ assert(test());
+ static_assert(test());
+
{
- test_reference_extension();
+ rt_test();
+ }
+
+ {
+ test_throwing_ctor();
}
+
{
- constexpr std::optional<int> o1{4};
- constexpr std::optional<int> o2 = std::move(o1);
- static_assert(*o2 == 4, "");
+ test_reference_extension();
}
return 0;
>From c5b4bafbdebdf3b91923ce1c02826131b061d395 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 00:28:23 -0500
Subject: [PATCH 09/22] Format const_T
---
.../optional.object.ctor/const_T.pass.cpp | 183 ++++++++----------
1 file changed, 84 insertions(+), 99 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
index 91a2323eebbf4..eadcaba9e39f7 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
@@ -5,124 +5,109 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: c++03, c++11, c++14
+
+// REQUIRES: std-at-least-c++17
// <optional>
// constexpr optional(const T& v);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
using std::optional;
-int main(int, char**)
-{
- {
- typedef int T;
- constexpr T t(5);
- constexpr optional<T> opt(t);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 5, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
-
- }
- {
- typedef double T;
- constexpr T t(3);
- constexpr optional<T> opt(t);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
+int main(int, char**) {
+ {
+ typedef int T;
+ constexpr T t(5);
+ constexpr optional<T> opt(t);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 5, "");
- }
- {
- const int x = 42;
- optional<const int> o(x);
- assert(*o == x);
- }
- {
- typedef TestTypes::TestType T;
- T::reset();
- const T t(3);
- optional<T> opt = t;
- assert(T::alive == 2);
- assert(T::copy_constructed == 1);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef ExplicitTestTypes::TestType T;
- static_assert(!std::is_convertible<T const&, optional<T>>::value, "");
- T::reset();
- const T t(3);
- optional<T> opt(t);
- assert(T::alive == 2);
- assert(T::copy_constructed == 1);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef ConstexprTestTypes::TestType T;
- constexpr T t(3);
- constexpr optional<T> opt = {t};
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef double T;
+ constexpr T t(3);
+ constexpr optional<T> opt(t);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 3, "");
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef ExplicitConstexprTestTypes::TestType T;
- static_assert(!std::is_convertible<const T&, optional<T>>::value, "");
- constexpr T t(3);
- constexpr optional<T> opt(t);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ const int x = 42;
+ optional<const int> o(x);
+ assert(*o == x);
+ }
+ {
+ typedef TestTypes::TestType T;
+ T::reset();
+ const T t(3);
+ optional<T> opt = t;
+ assert(T::alive == 2);
+ assert(T::copy_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ExplicitTestTypes::TestType T;
+ static_assert(!std::is_convertible<T const&, optional<T>>::value, "");
+ T::reset();
+ const T t(3);
+ optional<T> opt(t);
+ assert(T::alive == 2);
+ assert(T::copy_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ConstexprTestTypes::TestType T;
+ constexpr T t(3);
+ constexpr optional<T> opt = {t};
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef ExplicitConstexprTestTypes::TestType T;
+ static_assert(!std::is_convertible<const T&, optional<T>>::value, "");
+ constexpr T t(3);
+ constexpr optional<T> opt(t);
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
- }
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- struct Z {
- Z(int) {}
- Z(const Z&) {throw 6;}
- };
- typedef Z T;
- try
- {
- const T t(3);
- optional<T> opt(t);
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
- }
+ {
+ struct Z {
+ Z(int) {}
+ Z(const Z&) { throw 6; }
+ };
+ typedef Z T;
+ try {
+ const T t(3);
+ optional<T> opt(t);
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
}
+ }
#endif
return 0;
>From 2203d54ce0944388e1787b8cc099008fd5af8ac5 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 00:33:49 -0500
Subject: [PATCH 10/22] const_T
---
.../optional.object.ctor/const_T.pass.cpp | 80 +++++++------------
1 file changed, 31 insertions(+), 49 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
index eadcaba9e39f7..735a362a7d4f9 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/const_T.pass.cpp
@@ -20,35 +20,38 @@
#include "archetypes.h"
using std::optional;
+template <typename T, typename... Args>
+constexpr void test_ctor(Args... args) {
+ const T t(args...);
+ const std::optional<T> opt(t);
+
+ assert(static_cast<bool>(opt));
+ assert(*opt == t);
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+}
+
+constexpr bool test() {
+ test_ctor<int>(5);
+ test_ctor<double>(3.0);
+ test_ctor<const int>(42);
+ test_ctor<ConstexprTestTypes::TestType>(3);
-int main(int, char**) {
- {
- typedef int T;
- constexpr T t(5);
- constexpr optional<T> opt(t);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 5, "");
-
- struct test_constexpr_ctor : public optional<T> {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef double T;
- constexpr T t(3);
- constexpr optional<T> opt(t);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 3, "");
-
- struct test_constexpr_ctor : public optional<T> {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
{
- const int x = 42;
- optional<const int> o(x);
- assert(*o == x);
+ using T = ExplicitConstexprTestTypes::TestType;
+ static_assert(!std::is_convertible_v<const T&, optional<T>>);
+ test_ctor<T>(3);
}
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
{
typedef TestTypes::TestType T;
T::reset();
@@ -59,6 +62,7 @@ int main(int, char**) {
assert(static_cast<bool>(opt) == true);
assert(opt.value().value == 3);
}
+
{
typedef ExplicitTestTypes::TestType T;
static_assert(!std::is_convertible<T const&, optional<T>>::value, "");
@@ -70,29 +74,7 @@ int main(int, char**) {
assert(static_cast<bool>(opt) == true);
assert(opt.value().value == 3);
}
- {
- typedef ConstexprTestTypes::TestType T;
- constexpr T t(3);
- constexpr optional<T> opt = {t};
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor : public optional<T> {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef ExplicitConstexprTestTypes::TestType T;
- static_assert(!std::is_convertible<const T&, optional<T>>::value, "");
- constexpr T t(3);
- constexpr optional<T> opt(t);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor : public optional<T> {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
+
#ifndef TEST_HAS_NO_EXCEPTIONS
{
struct Z {
>From 72616eaffa7c74414a2903ed026b3f5b00d65ae9 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 00:39:02 -0500
Subject: [PATCH 11/22] Format optional_U
---
.../optional.object.ctor/optional_U.pass.cpp | 101 ++++++++----------
1 file changed, 47 insertions(+), 54 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
index 14c400cdd1526..6ad9b254ec933 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRED: std-at-least-c++17
// <optional>
// template <class U>
@@ -23,75 +23,68 @@
using std::optional;
template <class T, class U>
-TEST_CONSTEXPR_CXX20 void
-test(optional<U>&& rhs, bool is_going_to_throw = false)
-{
- bool rhs_engaged = static_cast<bool>(rhs);
+TEST_CONSTEXPR_CXX20 void test(optional<U>&& rhs, bool is_going_to_throw = false) {
+ bool rhs_engaged = static_cast<bool>(rhs);
#ifndef TEST_HAS_NO_EXCEPTIONS
- try
- {
- optional<T> lhs = std::move(rhs);
- assert(is_going_to_throw == false);
- assert(static_cast<bool>(lhs) == rhs_engaged);
- }
- catch (int i)
- {
- assert(i == 6);
- }
-#else
- if (is_going_to_throw) return;
+ try {
optional<T> lhs = std::move(rhs);
+ assert(is_going_to_throw == false);
assert(static_cast<bool>(lhs) == rhs_engaged);
+ } catch (int i) {
+ assert(i == 6);
+ }
+#else
+ if (is_going_to_throw)
+ return;
+ optional<T> lhs = std::move(rhs);
+ assert(static_cast<bool>(lhs) == rhs_engaged);
#endif
}
-class X
-{
- int i_;
+class X {
+ int i_;
+
public:
- TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {}
- TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {}
- TEST_CONSTEXPR_CXX20 ~X() {i_ = 0;}
- friend constexpr bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
+ TEST_CONSTEXPR_CXX20 X(int i) : i_(i) {}
+ TEST_CONSTEXPR_CXX20 X(X&& x) : i_(std::exchange(x.i_, 0)) {}
+ TEST_CONSTEXPR_CXX20 ~X() { i_ = 0; }
+ friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_; }
};
-struct Z
-{
- Z(int) { TEST_THROW(6); }
+struct Z {
+ Z(int) { TEST_THROW(6); }
};
-template<class T, class U>
-TEST_CONSTEXPR_CXX20 bool test_all()
-{
- {
- optional<T> rhs;
- test<U>(std::move(rhs));
- }
- {
- optional<T> rhs(short{3});
- test<U>(std::move(rhs));
- }
- return true;
+template <class T, class U>
+TEST_CONSTEXPR_CXX20 bool test_all() {
+ {
+ optional<T> rhs;
+ test<U>(std::move(rhs));
+ }
+ {
+ optional<T> rhs(short{3});
+ test<U>(std::move(rhs));
+ }
+ return true;
}
-int main(int, char**)
-{
- test_all<short, int>();
- test_all<int, X>();
+int main(int, char**) {
+ test_all<short, int>();
+ test_all<int, X>();
#if TEST_STD_VER > 17
- static_assert(test_all<short, int>());
- static_assert(test_all<int, X>());
+ static_assert(test_all<short, int>());
+ static_assert(test_all<int, X>());
#endif
- {
- optional<int> rhs;
- test<Z>(std::move(rhs));
- }
- {
- optional<int> rhs(3);
- test<Z>(std::move(rhs), true);
- }
+ {
+ optional<int> rhs;
+ test<Z>(std::move(rhs));
+ }
+ {
+ optional<int> rhs(3);
+ test<Z>(std::move(rhs), true);
+ }
- static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");
+ static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");
return 0;
}
>From e527a0edbd21e215aa2eac649c196ba27ee96f92 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 00:43:59 -0500
Subject: [PATCH 12/22] optional_U
---
.../optional.object.ctor/optional_U.pass.cpp | 29 ++++++++++++++-----
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
index 6ad9b254ec933..79c2e0d7b2738 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/optional_U.pass.cpp
@@ -68,13 +68,7 @@ TEST_CONSTEXPR_CXX20 bool test_all() {
return true;
}
-int main(int, char**) {
- test_all<short, int>();
- test_all<int, X>();
-#if TEST_STD_VER > 17
- static_assert(test_all<short, int>());
- static_assert(test_all<int, X>());
-#endif
+TEST_CONSTEXPR_CXX26 void test_throw() {
{
optional<int> rhs;
test<Z>(std::move(rhs));
@@ -85,6 +79,27 @@ int main(int, char**) {
}
static_assert(!(std::is_constructible<optional<X>, optional<Z>>::value), "");
+}
+
+TEST_CONSTEXPR_CXX20 bool test() {
+ test_all<short, int>();
+ test_all<int, X>();
+
+#if TEST_STD_VER >= 26 && 0
+ test_throw();
+#endif
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 20
+ static_assert(test());
+#endif
+
+ {
+ test_throw();
+ }
return 0;
}
>From 259b8f94b47e46d7f7ef6e948da9c9a2fe9ad1dd Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 00:45:40 -0500
Subject: [PATCH 13/22] Format ctor.verify
---
.../optional.object.ctor/ctor.verify.cpp | 41 +++++++++++--------
1 file changed, 25 insertions(+), 16 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp
index c5281783d4350..0f459ed44414b 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/ctor.verify.cpp
@@ -6,23 +6,24 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// T shall be an object type other than cv in_place_t or cv nullopt_t
// and shall satisfy the Cpp17Destructible requirements.
// Note: array types do not satisfy the Cpp17Destructible requirements.
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
-struct NonDestructible { ~NonDestructible() = delete; };
+struct NonDestructible {
+ ~NonDestructible() = delete;
+};
-int main(int, char**)
-{
+int main(int, char**) {
{
#if TEST_STD_VER >= 26
std::optional<int&&>
@@ -38,18 +39,26 @@ int main(int, char**)
}
{
- std::optional< std::in_place_t> o1; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
- std::optional<const std::in_place_t> o2; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
- std::optional< volatile std::in_place_t> o3; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
- std::optional<const volatile std::in_place_t> o4; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
+ std::optional< std::in_place_t>
+ o1; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
+ std::optional<const std::in_place_t>
+ o2; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
+ std::optional< volatile std::in_place_t>
+ o3; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
+ std::optional<const volatile std::in_place_t>
+ o4; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}}
}
- {
- std::optional< std::nullopt_t> o1; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
- std::optional<const std::nullopt_t> o2; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
- std::optional< volatile std::nullopt_t> o3; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
- std::optional<const volatile std::nullopt_t> o4; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
- }
+ {
+ std::optional< std::nullopt_t>
+ o1; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
+ std::optional<const std::nullopt_t>
+ o2; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
+ std::optional< volatile std::nullopt_t>
+ o3; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
+ std::optional<const volatile std::nullopt_t>
+ o4; // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
+ }
- return 0;
+ return 0;
}
>From 9f57c4c6006c80535e1d8885b36a8324b919966a Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 00:58:27 -0500
Subject: [PATCH 14/22] Deduct
---
.../optional.object.ctor/deduct.pass.cpp | 82 ++++++++++---------
1 file changed, 42 insertions(+), 40 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
index 9bfde5abaa9ac..1d7707a6d3f05 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp
@@ -6,73 +6,75 @@
//
//===----------------------------------------------------------------------===//
+// REQUIRES: std-at-least-c++17
+
// <optional>
-// UNSUPPORTED: c++03, c++11, c++14
// template<class T>
// optional(T) -> optional<T>;
-#include <optional>
#include <cassert>
+#include <optional>
#include "test_macros.h"
-struct A {};
+struct A {
+ friend constexpr bool operator==(const A&, const A&) { return true; }
+};
-int main(int, char**)
-{
-// Test the explicit deduction guides
- {
-// optional(T)
- std::optional opt(5);
- ASSERT_SAME_TYPE(decltype(opt), std::optional<int>);
- assert(static_cast<bool>(opt));
- assert(*opt == 5);
- }
+template <typename T>
+constexpr void test_deduct(T arg) {
+ std::optional opt(arg);
- {
-// optional(T)
- std::optional opt(A{});
- ASSERT_SAME_TYPE(decltype(opt), std::optional<A>);
- assert(static_cast<bool>(opt));
- }
+ ASSERT_SAME_TYPE(decltype(opt), std::optional<T>);
+ assert(static_cast<bool>(opt));
+ assert(*opt == arg);
+}
- {
-// optional(const T&);
+constexpr bool test() {
+ // optional(T)
+ test_deduct<int>(5);
+ test_deduct<A>(A{});
+
+ {
+ // optional(const T&);
const int& source = 5;
- std::optional opt(source);
- ASSERT_SAME_TYPE(decltype(opt), std::optional<int>);
- assert(static_cast<bool>(opt));
- assert(*opt == 5);
- }
+ test_deduct<int>(source);
+ }
- {
-// optional(T*);
+ {
+ // optional(T*);
const int* source = nullptr;
- std::optional opt(source);
- ASSERT_SAME_TYPE(decltype(opt), std::optional<const int*>);
- assert(static_cast<bool>(opt));
- assert(*opt == nullptr);
- }
+ test_deduct<const int*>(source);
+ }
- {
-// optional(T[]);
+ {
+ // optional(T[]);
int source[] = {1, 2, 3};
std::optional opt(source);
+
ASSERT_SAME_TYPE(decltype(opt), std::optional<int*>);
assert(static_cast<bool>(opt));
assert((*opt)[0] == 1);
- }
+ }
-// Test the implicit deduction guides
- {
-// optional(optional);
+ // Test the implicit deduction guides
+ {
+ // optional(optional);
std::optional<char> source('A');
std::optional opt(source);
+
ASSERT_SAME_TYPE(decltype(opt), std::optional<char>);
assert(static_cast<bool>(opt) == static_cast<bool>(source));
assert(*opt == *source);
- }
+ }
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
>From b23a4b1770947458d449e22ab724f731a26ed937 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 01:01:11 -0500
Subject: [PATCH 15/22] Format deduct.verify
---
.../optional.object.ctor/deduct.verify.cpp | 32 +++++++++----------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp
index 364f9b2e955f0..4bde0778595e3 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp
@@ -6,32 +6,32 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIREd: std-at-least-c++17
// <optional>
// template<class T>
// optional(T) -> optional<T>;
-#include <optional>
#include <cassert>
+#include <optional>
struct A {};
-int main(int, char**)
-{
-// Test the explicit deduction guides
-
-// Test the implicit deduction guides
- {
-// optional()
- std::optional opt; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}optional'}}
- }
-
- {
-// optional(nullopt_t)
- std::optional opt(std::nullopt); // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
- }
+int main(int, char**) {
+ // Test the implicit deduction guides
+ {
+ // optional()
+ std::optional
+ opt; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}optional'}}
+ }
+
+ {
+ // optional(nullopt_t)
+ std::optional opt(
+ std::
+ nullopt); // expected-error-re at optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}}
+ }
return 0;
}
>From ec46f297cee44386376730a502650daa3241c87e Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 01:12:29 -0500
Subject: [PATCH 16/22] Format empty_in_place_t_does_not_clobber
---
.../empty_in_place_t_does_not_clobber.pass.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp
index 594aac770bc82..9f883b4973bf0 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/empty_in_place_t_does_not_clobber.pass.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// constexpr optional(in_place_t);
@@ -15,9 +15,9 @@
// in_place_t constructor with no arguments when the Clang is trying to check
// copy constructor.
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
@@ -32,7 +32,7 @@ struct Wrapped {
};
int main(int, char**) {
- static_assert(std::is_default_constructible<Wrapped::Inner>::value, "");
+ static_assert(std::is_default_constructible<Wrapped::Inner>::value);
Wrapped w;
w.inner.emplace();
assert(w.inner.has_value());
>From cde8298dfc0a5763b0b7589b04674022218d0e76 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 01:14:06 -0500
Subject: [PATCH 17/22] Format initializer_list
---
.../initializer_list.pass.cpp | 142 ++++++++----------
1 file changed, 65 insertions(+), 77 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp
index 6c42df9e1e097..852f90af6b558 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/initializer_list.pass.cpp
@@ -6,112 +6,100 @@
//
//===----------------------------------------------------------------------===//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// <optional>
// template <class U, class... Args>
// constexpr
// explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
+#include <cassert>
+#include <memory>
#include <optional>
#include <type_traits>
-#include <memory>
#include <vector>
-#include <cassert>
#include "test_macros.h"
-using std::optional;
-using std::in_place_t;
using std::in_place;
+using std::in_place_t;
+using std::optional;
+
+class X {
+ int i_;
+ int j_ = 0;
-class X
-{
- int i_;
- int j_ = 0;
public:
- X() : i_(0) {}
- X(int i) : i_(i) {}
- X(int i, int j) : i_(i), j_(j) {}
+ X() : i_(0) {}
+ X(int i) : i_(i) {}
+ X(int i, int j) : i_(i), j_(j) {}
- ~X() {}
+ ~X() {}
- friend bool operator==(const X& x, const X& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
+ friend bool operator==(const X& x, const X& y) { return x.i_ == y.i_ && x.j_ == y.j_; }
};
-class Y
-{
- int i_;
- int j_ = 0;
+class Y {
+ int i_;
+ int j_ = 0;
+
public:
- constexpr Y() : i_(0) {}
- constexpr Y(int i) : i_(i) {}
- constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
+ constexpr Y() : i_(0) {}
+ constexpr Y(int i) : i_(i) {}
+ constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
- friend constexpr bool operator==(const Y& x, const Y& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
+ friend constexpr bool operator==(const Y& x, const Y& y) { return x.i_ == y.i_ && x.j_ == y.j_; }
};
-class Z
-{
- int i_;
- int j_ = 0;
+class Z {
+ int i_;
+ int j_ = 0;
+
public:
- Z() : i_(0) {}
- Z(int i) : i_(i) {}
- Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
- {TEST_THROW(6);}
+ Z() : i_(0) {}
+ Z(int i) : i_(i) {}
+ Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) { TEST_THROW(6); }
- friend bool operator==(const Z& x, const Z& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
+ friend bool operator==(const Z& x, const Z& y) { return x.i_ == y.i_ && x.j_ == y.j_; }
};
-int main(int, char**)
-{
- {
- static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, "");
- static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, "");
- }
- {
- optional<std::vector<int>> opt(in_place, {3, 1});
- assert(static_cast<bool>(opt) == true);
- assert((*opt == std::vector<int>{3, 1}));
- assert(opt->size() == 2);
- }
- {
- optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>());
- assert(static_cast<bool>(opt) == true);
- assert((*opt == std::vector<int>{3, 1}));
- assert(opt->size() == 2);
- }
- {
- static_assert(std::is_constructible<optional<Y>, std::initializer_list<int>&>::value, "");
- constexpr optional<Y> opt(in_place, {3, 1});
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == Y{3, 1}, "");
-
- struct test_constexpr_ctor
- : public optional<Y>
- {
- constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i)
- : optional<Y>(in_place, i) {}
- };
-
- }
+int main(int, char**) {
+ {
+ static_assert(!std::is_constructible<X, std::initializer_list<int>&>::value, "");
+ static_assert(!std::is_constructible<optional<X>, std::initializer_list<int>&>::value, "");
+ }
+ {
+ optional<std::vector<int>> opt(in_place, {3, 1});
+ assert(static_cast<bool>(opt) == true);
+ assert((*opt == std::vector<int>{3, 1}));
+ assert(opt->size() == 2);
+ }
+ {
+ optional<std::vector<int>> opt(in_place, {3, 1}, std::allocator<int>());
+ assert(static_cast<bool>(opt) == true);
+ assert((*opt == std::vector<int>{3, 1}));
+ assert(opt->size() == 2);
+ }
+ {
+ static_assert(std::is_constructible<optional<Y>, std::initializer_list<int>&>::value, "");
+ constexpr optional<Y> opt(in_place, {3, 1});
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == Y{3, 1}, "");
+
+ struct test_constexpr_ctor : public optional<Y> {
+ constexpr test_constexpr_ctor(in_place_t, std::initializer_list<int> i) : optional<Y>(in_place, i) {}
+ };
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, "");
- try
- {
- optional<Z> opt(in_place, {3, 1});
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
- }
+ {
+ static_assert(std::is_constructible<optional<Z>, std::initializer_list<int>&>::value, "");
+ try {
+ optional<Z> opt(in_place, {3, 1});
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
}
+ }
#endif
return 0;
>From 41a716e5f8ff6913ebca654016aec9ed2b709917 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 01:23:35 -0500
Subject: [PATCH 18/22] in_place_t
---
.../optional.object.ctor/in_place_t.pass.cpp | 165 ++++++------------
1 file changed, 53 insertions(+), 112 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp
index 65276c5a01976..ae3d76eff4a42 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/in_place_t.pass.cpp
@@ -6,144 +6,85 @@
//
//===----------------------------------------------------------------------===//
//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRED: std-at-least-c++17
// <optional>
// template <class... Args>
// constexpr explicit optional(in_place_t, Args&&... args);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
+#include <utility>
#include "test_macros.h"
-using std::optional;
-using std::in_place_t;
using std::in_place;
+using std::in_place_t;
+using std::optional;
-class X
-{
- int i_;
- int j_ = 0;
-public:
- X() : i_(0) {}
- X(int i) : i_(i) {}
- X(int i, int j) : i_(i), j_(j) {}
-
- ~X() {}
-
- friend bool operator==(const X& x, const X& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
-};
+class X {
+ int i_;
+ int j_ = 0;
-class Y
-{
- int i_;
- int j_ = 0;
public:
- constexpr Y() : i_(0) {}
- constexpr Y(int i) : i_(i) {}
- constexpr Y(int i, int j) : i_(i), j_(j) {}
+ constexpr X() : i_(0) {}
+ constexpr X(int i) : i_(i) {}
+ constexpr X(int i, int j) : i_(i), j_(j) {}
- friend constexpr bool operator==(const Y& x, const Y& y)
- {return x.i_ == y.i_ && x.j_ == y.j_;}
+ ~X() = default;
+
+ friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_ && x.j_ == y.j_; }
};
-class Z
-{
+class Z {
public:
- Z(int) {TEST_THROW(6);}
+ Z(int) { TEST_THROW(6); }
};
+template <typename T, typename... Args>
+constexpr void test_inplace(Args... args) {
+ optional<T> opt(in_place, args...);
+ assert(bool(opt));
+ assert(*opt == T(args...));
-int main(int, char**)
-{
- {
- constexpr optional<int> opt(in_place, 5);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 5, "");
-
- struct test_constexpr_ctor
- : public optional<int>
- {
- constexpr test_constexpr_ctor(in_place_t, int i)
- : optional<int>(in_place, i) {}
- };
-
- }
- {
- optional<const int> opt(in_place, 5);
- assert(*opt == 5);
- }
- {
- const optional<X> opt(in_place);
- assert(static_cast<bool>(opt) == true);
- assert(*opt == X());
- }
- {
- const optional<X> opt(in_place, 5);
- assert(static_cast<bool>(opt) == true);
- assert(*opt == X(5));
- }
- {
- const optional<X> opt(in_place, 5, 4);
- assert(static_cast<bool>(opt) == true);
- assert(*opt == X(5, 4));
- }
- {
- constexpr optional<Y> opt(in_place);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == Y(), "");
-
- struct test_constexpr_ctor
- : public optional<Y>
- {
- constexpr test_constexpr_ctor(in_place_t)
- : optional<Y>(in_place) {}
- };
-
- }
- {
- constexpr optional<Y> opt(in_place, 5);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == Y(5), "");
-
- struct test_constexpr_ctor
- : public optional<Y>
- {
- constexpr test_constexpr_ctor(in_place_t, int i)
- : optional<Y>(in_place, i) {}
- };
-
- }
- {
- constexpr optional<Y> opt(in_place, 5, 4);
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == Y(5, 4), "");
-
- struct test_constexpr_ctor
- : public optional<Y>
- {
- constexpr test_constexpr_ctor(in_place_t, int i, int j)
- : optional<Y>(in_place, i, j) {}
- };
+ struct test_constexpr_ctor : public optional<int> {
+ constexpr test_constexpr_ctor(in_place_t, int i) : optional<int>(in_place, i) {}
+ };
+}
- }
+TEST_CONSTEXPR_CXX26 void test_throwing() {
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- try
- {
- const optional<Z> opt(in_place, 1);
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
- }
+ {
+ try {
+ const optional<Z> opt(in_place, 1);
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
}
+ }
#endif
+}
+
+constexpr bool test() {
+ test_inplace<int>(5);
+ test_inplace<const int>(5);
+ test_inplace<X>();
+ test_inplace<X>(5);
+ test_inplace<X>(5, 4);
+#if TEST_STD_VER >= 26 && 0
+ test_throwing();
+#endif
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+ {
+ test_throwing();
+ }
return 0;
}
>From db19ac0d910b14561fa47f30a186c54d4d648aaf Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 01:36:28 -0500
Subject: [PATCH 19/22] Format rvalue_T
---
.../optional.object.ctor/rvalue_T.pass.cpp | 219 ++++++++----------
1 file changed, 100 insertions(+), 119 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
index 12425955f5a86..4120974ae76ee 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
@@ -6,143 +6,124 @@
//
//===----------------------------------------------------------------------===//
//
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRED: std-at-least-c++17
// <optional>
// constexpr optional(T&& v);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
#include "test_macros.h"
#include "archetypes.h"
-
using std::optional;
-
-class Z
-{
+class Z {
public:
- Z(int) {}
- Z(Z&&) {TEST_THROW(6);}
+ Z(int) {}
+ Z(Z&&) { TEST_THROW(6); }
};
-
-int main(int, char**)
-{
- {
- typedef int T;
- constexpr optional<T> opt(T(5));
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 5, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(T&&) {}
- };
- }
- {
- typedef double T;
- constexpr optional<T> opt(T(3));
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(T&&) {}
- };
- }
- {
- const int x = 42;
- optional<const int> o(std::move(x));
- assert(*o == 42);
- }
- {
- typedef TestTypes::TestType T;
- T::reset();
- optional<T> opt = T{3};
- assert(T::alive == 1);
- assert(T::move_constructed == 1);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef ExplicitTestTypes::TestType T;
- static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
- T::reset();
- optional<T> opt(T{3});
- assert(T::alive == 1);
- assert(T::move_constructed == 1);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef TestTypes::TestType T;
- T::reset();
- optional<T> opt = {3};
- assert(T::alive == 1);
- assert(T::value_constructed == 1);
- assert(T::copy_constructed == 0);
- assert(T::move_constructed == 0);
- assert(static_cast<bool>(opt) == true);
- assert(opt.value().value == 3);
- }
- {
- typedef ConstexprTestTypes::TestType T;
- constexpr optional<T> opt = {T(3)};
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef ConstexprTestTypes::TestType T;
- constexpr optional<T> opt = {3};
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef ExplicitConstexprTestTypes::TestType T;
- static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
- constexpr optional<T> opt(T{3});
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor
- : public optional<T>
- {
- constexpr test_constexpr_ctor(T&&) {}
- };
-
- }
+int main(int, char**) {
+ {
+ typedef int T;
+ constexpr optional<T> opt(T(5));
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 5, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(T&&) {}
+ };
+ }
+ {
+ typedef double T;
+ constexpr optional<T> opt(T(3));
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(*opt == 3, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(T&&) {}
+ };
+ }
+ {
+ const int x = 42;
+ optional<const int> o(std::move(x));
+ assert(*o == 42);
+ }
+ {
+ typedef TestTypes::TestType T;
+ T::reset();
+ optional<T> opt = T{3};
+ assert(T::alive == 1);
+ assert(T::move_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ExplicitTestTypes::TestType T;
+ static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
+ T::reset();
+ optional<T> opt(T{3});
+ assert(T::alive == 1);
+ assert(T::move_constructed == 1);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef TestTypes::TestType T;
+ T::reset();
+ optional<T> opt = {3};
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::copy_constructed == 0);
+ assert(T::move_constructed == 0);
+ assert(static_cast<bool>(opt) == true);
+ assert(opt.value().value == 3);
+ }
+ {
+ typedef ConstexprTestTypes::TestType T;
+ constexpr optional<T> opt = {T(3)};
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef ConstexprTestTypes::TestType T;
+ constexpr optional<T> opt = {3};
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+ }
+ {
+ typedef ExplicitConstexprTestTypes::TestType T;
+ static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
+ constexpr optional<T> opt(T{3});
+ static_assert(static_cast<bool>(opt) == true, "");
+ static_assert(opt.value().value == 3, "");
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(T&&) {}
+ };
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- try
- {
- Z z(3);
- optional<Z> opt(std::move(z));
- assert(false);
- }
- catch (int i)
- {
- assert(i == 6);
- }
+ {
+ try {
+ Z z(3);
+ optional<Z> opt(std::move(z));
+ assert(false);
+ } catch (int i) {
+ assert(i == 6);
}
+ }
#endif
return 0;
>From 3d253e21c2bffb8f2dbd26500baac11f940b4d94 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 01:59:54 -0500
Subject: [PATCH 20/22] rvalue_T
---
.../optional.object.ctor/rvalue_T.pass.cpp | 116 ++++++++++--------
1 file changed, 63 insertions(+), 53 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
index 4120974ae76ee..6d56e938cfb38 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/rvalue_T.pass.cpp
@@ -5,7 +5,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
+
// REQUIRED: std-at-least-c++17
// <optional>
@@ -27,32 +27,27 @@ class Z {
Z(Z&&) { TEST_THROW(6); }
};
-int main(int, char**) {
+template <typename T, typename U>
+constexpr void test_rvalueT(U arg) {
{
- typedef int T;
- constexpr optional<T> opt(T(5));
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 5, "");
-
- struct test_constexpr_ctor : public optional<T> {
- constexpr test_constexpr_ctor(T&&) {}
- };
- }
- {
- typedef double T;
- constexpr optional<T> opt(T(3));
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(*opt == 3, "");
-
- struct test_constexpr_ctor : public optional<T> {
- constexpr test_constexpr_ctor(T&&) {}
- };
+ const optional<T> opt(arg);
+ assert(bool(opt));
+ assert(*opt == T(arg));
}
+
{
- const int x = 42;
- optional<const int> o(std::move(x));
- assert(*o == 42);
+ T t(arg);
+ optional<T> opt(std::move(t));
+ assert(*opt == T(arg));
}
+
+ struct test_constexpr_ctor : public optional<T> {
+ constexpr test_constexpr_ctor(T&&) {}
+ constexpr test_constexpr_ctor(const T&) {}
+ };
+}
+
+void test_rt() {
{
typedef TestTypes::TestType T;
T::reset();
@@ -83,37 +78,9 @@ int main(int, char**) {
assert(static_cast<bool>(opt) == true);
assert(opt.value().value == 3);
}
- {
- typedef ConstexprTestTypes::TestType T;
- constexpr optional<T> opt = {T(3)};
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor : public optional<T> {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef ConstexprTestTypes::TestType T;
- constexpr optional<T> opt = {3};
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
-
- struct test_constexpr_ctor : public optional<T> {
- constexpr test_constexpr_ctor(const T&) {}
- };
- }
- {
- typedef ExplicitConstexprTestTypes::TestType T;
- static_assert(!std::is_convertible<T&&, optional<T>>::value, "");
- constexpr optional<T> opt(T{3});
- static_assert(static_cast<bool>(opt) == true, "");
- static_assert(opt.value().value == 3, "");
+}
- struct test_constexpr_ctor : public optional<T> {
- constexpr test_constexpr_ctor(T&&) {}
- };
- }
+TEST_CONSTEXPR_CXX26 void test_throwing() {
#ifndef TEST_HAS_NO_EXCEPTIONS
{
try {
@@ -125,6 +92,49 @@ int main(int, char**) {
}
}
#endif
+}
+
+constexpr bool test() {
+ test_rvalueT<int>(5);
+ test_rvalueT<double>(3.0);
+ test_rvalueT<const int>(42);
+
+ {
+ using T = ConstexprTestTypes::TestType;
+ test_rvalueT<T>(T(3));
+ }
+
+ {
+ using T = ConstexprTestTypes::TestType;
+ test_rvalueT<T>(3);
+ }
+
+ {
+ using T = ExplicitConstexprTestTypes::TestType;
+ static_assert(!std::is_convertible<T&&, optional<T>>::value);
+ test_rvalueT<T>(T(3));
+ }
+#if TEST_STD_VER >= 26 && 0
+ {
+ test_throwing();
+ }
+
+#endif
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
+
+ {
+ test_rt();
+ }
+
+ {
+ test_throwing();
+ }
return 0;
}
>From bc5e3a4ca9060d458b3b154bb807f6d25da25d9c Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 02:05:46 -0500
Subject: [PATCH 21/22] Format U.pass
---
.../optional.object.ctor/U.pass.cpp | 192 +++++++++---------
1 file changed, 95 insertions(+), 97 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
index a90fecfd075fe..15b520bd15887 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
@@ -5,33 +5,36 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// UNSUPPORTED: c++03, c++11, c++14
+
+// REQUIRED: std-at-least-c++17
// <optional>
// template <class U>
-// constexpr EXPLICIT optional(U&& u);
+// constexpr explicit optional(U&& u);
+#include <cassert>
#include <optional>
#include <type_traits>
-#include <cassert>
-#include "test_macros.h"
#include "archetypes.h"
#include "test_convertible.h"
-
+#include "test_macros.h"
using std::optional;
-struct ImplicitThrow
-{
- constexpr ImplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
+struct ImplicitThrow {
+ constexpr ImplicitThrow(int x) {
+ if (x != -1)
+ TEST_THROW(6);
+ }
};
-struct ExplicitThrow
-{
- constexpr explicit ExplicitThrow(int x) { if (x != -1) TEST_THROW(6);}
+struct ExplicitThrow {
+ constexpr explicit ExplicitThrow(int x) {
+ if (x != -1)
+ TEST_THROW(6);
+ }
};
struct ImplicitAny {
@@ -39,56 +42,52 @@ struct ImplicitAny {
constexpr ImplicitAny(U&&) {}
};
-
template <class To, class From>
-constexpr bool implicit_conversion(optional<To>&& opt, const From& v)
-{
- using O = optional<To>;
- static_assert(test_convertible<O, From>(), "");
- static_assert(!test_convertible<O, void*>(), "");
- static_assert(!test_convertible<O, From, int>(), "");
- return opt && *opt == static_cast<To>(v);
+constexpr bool implicit_conversion(optional<To>&& opt, const From& v) {
+ using O = optional<To>;
+ static_assert(test_convertible<O, From>(), "");
+ static_assert(!test_convertible<O, void*>(), "");
+ static_assert(!test_convertible<O, From, int>(), "");
+ return opt && *opt == static_cast<To>(v);
}
template <class To, class Input, class Expect>
-constexpr bool explicit_conversion(Input&& in, const Expect& v)
-{
- using O = optional<To>;
- static_assert(std::is_constructible<O, Input>::value, "");
- static_assert(!std::is_convertible<Input, O>::value, "");
- static_assert(!std::is_constructible<O, void*>::value, "");
- static_assert(!std::is_constructible<O, Input, int>::value, "");
- optional<To> opt(std::forward<Input>(in));
- optional<To> opt2{std::forward<Input>(in)};
- return opt && *opt == static_cast<To>(v) && (opt2 && *opt2 == static_cast<To>(v));
+constexpr bool explicit_conversion(Input&& in, const Expect& v) {
+ using O = optional<To>;
+ static_assert(std::is_constructible<O, Input>::value, "");
+ static_assert(!std::is_convertible<Input, O>::value, "");
+ static_assert(!std::is_constructible<O, void*>::value, "");
+ static_assert(!std::is_constructible<O, Input, int>::value, "");
+ optional<To> opt(std::forward<Input>(in));
+ optional<To> opt2{std::forward<Input>(in)};
+ return opt && *opt == static_cast<To>(v) && (opt2 && *opt2 == static_cast<To>(v));
}
-void test_implicit()
-{
- {
- static_assert(implicit_conversion<long long>(42, 42), "");
- }
- {
- static_assert(implicit_conversion<long double>(3.14, 3.14), "");
- }
- {
- int x = 42;
- optional<void* const> o(&x);
- assert(*o == &x);
- }
- {
- using T = TrivialTestTypes::TestType;
- static_assert(implicit_conversion<T>(42, 42), "");
- }
- {
- using T = TestTypes::TestType;
- assert(implicit_conversion<T>(3, T(3)));
- }
- {
- using T = TestTypes::TestType;
- optional<T> opt({3});
- assert(opt && *opt == static_cast<T>(3));
- }
+void test_implicit() {
+ {
+ static_assert(implicit_conversion<long long>(42, 42), "");
+ }
+ {
+ static_assert(implicit_conversion<long double>(3.14, 3.14), "");
+ }
+ {
+ int x = 42;
+ optional<void* const> o(&x);
+ assert(*o == &x);
+ }
+ {
+ using T = TrivialTestTypes::TestType;
+ static_assert(implicit_conversion<T>(42, 42), "");
+ }
+ {
+ using T = TestTypes::TestType;
+ assert(implicit_conversion<T>(3, T(3)));
+ }
+ {
+ using T = TestTypes::TestType;
+ optional<T> opt({3});
+ assert(opt && *opt == static_cast<T>(3));
+ }
{
using O = optional<ImplicitAny>;
static_assert(!test_convertible<O, std::in_place_t>(), "");
@@ -96,64 +95,63 @@ void test_implicit()
static_assert(!test_convertible<O, const std::in_place_t&>(), "");
static_assert(!test_convertible<O, std::in_place_t&&>(), "");
static_assert(!test_convertible<O, const std::in_place_t&&>(), "");
-
}
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- try {
- using T = ImplicitThrow;
- optional<T> t = 42;
- assert(false);
- ((void)t);
- } catch (int) {
- }
+ {
+ try {
+ using T = ImplicitThrow;
+ optional<T> t = 42;
+ assert(false);
+ ((void)t);
+ } catch (int) {
}
+ }
#endif
}
void test_explicit() {
+ {
+ using T = ExplicitTrivialTestTypes::TestType;
+ static_assert(explicit_conversion<T>(42, 42), "");
+ }
+ {
+ using T = ExplicitConstexprTestTypes::TestType;
+ static_assert(explicit_conversion<T>(42, 42), "");
+ static_assert(!std::is_convertible<int, T>::value, "");
+ }
+ {
+ using T = ExplicitTestTypes::TestType;
+ T::reset();
{
- using T = ExplicitTrivialTestTypes::TestType;
- static_assert(explicit_conversion<T>(42, 42), "");
- }
- {
- using T = ExplicitConstexprTestTypes::TestType;
- static_assert(explicit_conversion<T>(42, 42), "");
- static_assert(!std::is_convertible<int, T>::value, "");
+ assert(explicit_conversion<T>(42, 42));
+ assert(T::alive == 0);
}
+ T::reset();
{
- using T = ExplicitTestTypes::TestType;
- T::reset();
- {
- assert(explicit_conversion<T>(42, 42));
- assert(T::alive == 0);
- }
- T::reset();
- {
- optional<T> t(42);
- assert(T::alive == 1);
- assert(T::value_constructed == 1);
- assert(T::move_constructed == 0);
- assert(T::copy_constructed == 0);
- assert(t.value().value == 42);
- }
- assert(T::alive == 0);
+ optional<T> t(42);
+ assert(T::alive == 1);
+ assert(T::value_constructed == 1);
+ assert(T::move_constructed == 0);
+ assert(T::copy_constructed == 0);
+ assert(t.value().value == 42);
}
+ assert(T::alive == 0);
+ }
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- try {
- using T = ExplicitThrow;
- optional<T> t(42);
- assert(false);
- } catch (int) {
- }
+ {
+ try {
+ using T = ExplicitThrow;
+ optional<T> t(42);
+ assert(false);
+ } catch (int) {
}
+ }
#endif
}
int main(int, char**) {
- test_implicit();
- test_explicit();
+ test_implicit();
+ test_explicit();
return 0;
}
>From 82d5ea9e3cef650173c505f0a458252728c1b515 Mon Sep 17 00:00:00 2001
From: William Tran-Viet <wtranviet at proton.me>
Date: Sun, 23 Nov 2025 02:19:27 -0500
Subject: [PATCH 22/22] U.pass
---
.../optional.object.ctor/U.pass.cpp | 151 +++++++++++-------
1 file changed, 95 insertions(+), 56 deletions(-)
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
index 15b520bd15887..d0093da688a0e 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/U.pass.cpp
@@ -45,80 +45,47 @@ struct ImplicitAny {
template <class To, class From>
constexpr bool implicit_conversion(optional<To>&& opt, const From& v) {
using O = optional<To>;
- static_assert(test_convertible<O, From>(), "");
- static_assert(!test_convertible<O, void*>(), "");
- static_assert(!test_convertible<O, From, int>(), "");
- return opt && *opt == static_cast<To>(v);
+ assert((test_convertible<O, From>()));
+ assert(!(test_convertible<O, void*>()));
+ assert(!(test_convertible<O, From, int>()));
+ assert(opt);
+ assert(*opt == static_cast<To>(v));
+
+ return true;
}
template <class To, class Input, class Expect>
constexpr bool explicit_conversion(Input&& in, const Expect& v) {
using O = optional<To>;
- static_assert(std::is_constructible<O, Input>::value, "");
- static_assert(!std::is_convertible<Input, O>::value, "");
- static_assert(!std::is_constructible<O, void*>::value, "");
- static_assert(!std::is_constructible<O, Input, int>::value, "");
+ assert((std::is_constructible<O, Input>::value));
+ assert(!(std::is_convertible<Input, O>::value));
+ assert(!(std::is_constructible<O, void*>::value));
+ assert(!(std::is_constructible<O, Input, int>::value));
+
optional<To> opt(std::forward<Input>(in));
optional<To> opt2{std::forward<Input>(in)};
- return opt && *opt == static_cast<To>(v) && (opt2 && *opt2 == static_cast<To>(v));
+ assert(opt);
+ assert(opt2);
+ assert(*opt == static_cast<To>(v));
+ assert(*opt2 == static_cast<To>(v));
+
+ return true;
}
void test_implicit() {
- {
- static_assert(implicit_conversion<long long>(42, 42), "");
- }
- {
- static_assert(implicit_conversion<long double>(3.14, 3.14), "");
- }
- {
- int x = 42;
- optional<void* const> o(&x);
- assert(*o == &x);
- }
- {
- using T = TrivialTestTypes::TestType;
- static_assert(implicit_conversion<T>(42, 42), "");
- }
- {
- using T = TestTypes::TestType;
- assert(implicit_conversion<T>(3, T(3)));
- }
{
using T = TestTypes::TestType;
optional<T> opt({3});
assert(opt && *opt == static_cast<T>(3));
}
+
{
- using O = optional<ImplicitAny>;
- static_assert(!test_convertible<O, std::in_place_t>(), "");
- static_assert(!test_convertible<O, std::in_place_t&>(), "");
- static_assert(!test_convertible<O, const std::in_place_t&>(), "");
- static_assert(!test_convertible<O, std::in_place_t&&>(), "");
- static_assert(!test_convertible<O, const std::in_place_t&&>(), "");
- }
-#ifndef TEST_HAS_NO_EXCEPTIONS
- {
- try {
- using T = ImplicitThrow;
- optional<T> t = 42;
- assert(false);
- ((void)t);
- } catch (int) {
- }
+ using T = TestTypes::TestType;
+ assert((implicit_conversion<T>(3, T(3))));
}
-#endif
}
void test_explicit() {
- {
- using T = ExplicitTrivialTestTypes::TestType;
- static_assert(explicit_conversion<T>(42, 42), "");
- }
- {
- using T = ExplicitConstexprTestTypes::TestType;
- static_assert(explicit_conversion<T>(42, 42), "");
- static_assert(!std::is_convertible<int, T>::value, "");
- }
{
using T = ExplicitTestTypes::TestType;
T::reset();
@@ -137,7 +104,20 @@ void test_explicit() {
}
assert(T::alive == 0);
}
+}
+
+TEST_CONSTEXPR_CXX26 void test_throwing() {
#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ try {
+ using T = ImplicitThrow;
+ optional<T> t = 42;
+ assert(false);
+ ((void)t);
+ } catch (int) {
+ }
+ }
+
{
try {
using T = ExplicitThrow;
@@ -149,9 +129,68 @@ void test_explicit() {
#endif
}
+constexpr bool test() {
+ {
+ assert((implicit_conversion<long long>(42, 42)));
+ }
+
+ {
+ assert((implicit_conversion<long double>(3.14, 3.14)));
+ }
+
+ {
+ int x = 42;
+ optional<void* const> o(&x);
+ assert(*o == &x);
+ }
+
+ {
+ using T = TrivialTestTypes::TestType;
+ assert((implicit_conversion<T>(42, 42)));
+ }
+
+ {
+ using O = optional<ImplicitAny>;
+ assert(!(test_convertible<O, std::in_place_t>()));
+ assert(!(test_convertible<O, std::in_place_t&>()));
+ assert(!(test_convertible<O, const std::in_place_t&>()));
+ assert(!(test_convertible<O, std::in_place_t&&>()));
+ assert(!(test_convertible<O, const std::in_place_t&&>()));
+ }
+
+ {
+ using T = ExplicitTrivialTestTypes::TestType;
+ assert((explicit_conversion<T>(42, 42)));
+ }
+
+ {
+ using T = ExplicitConstexprTestTypes::TestType;
+ assert(explicit_conversion<T>(42, 42));
+ assert(!(std::is_convertible<int, T>::value));
+ }
+
+#if TEST_STD_VER >= 26 && 0
+ test_throwing();
+#endif
+
+ return true;
+}
+
int main(int, char**) {
- test_implicit();
- test_explicit();
+ test();
+ static_assert(test());
+
+ {
+ test_implicit();
+ }
+
+ {
+ test_explicit();
+ }
+
+ {
+ test_throwing();
+ }
return 0;
}
More information about the libcxx-commits
mailing list