From aad59c30ff774e54c6d94dde37ce61bff0baf37a Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sat, 22 Nov 2025 22:22:39 -0500 Subject: [PATCH 01/17] Default --- .../optional.object.ctor/default.pass.cpp | 82 ++++++++++--------- 1 file changed, 45 insertions(+), 37 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 71d4d052da3b7..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,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// REQUIRES: std-at-least-c++17 // // constexpr optional() noexcept; @@ -18,56 +18,64 @@ #include "test_macros.h" #include "archetypes.h" -using std::optional; +template +constexpr void test() { + static_assert(std::is_nothrow_default_constructible_v>); + static_assert(std::is_trivially_destructible_v == std::is_trivially_destructible_v>); -template -void test_constexpr() { - static_assert(std::is_nothrow_default_constructible::value, ""); - static_assert(std::is_trivially_destructible::value, ""); - static_assert(std::is_trivially_destructible::value, ""); - - constexpr Opt opt; - static_assert(static_cast(opt) == false, ""); - - struct test_constexpr_ctor : public Opt { - constexpr test_constexpr_ctor() {} - }; -} + if constexpr (!std::is_lvalue_reference_v) { + static_assert( + std::is_trivially_destructible_v == std::is_trivially_destructible_v::value_type>); + } -template -void test() { - static_assert(std::is_nothrow_default_constructible::value, ""); - static_assert(!std::is_trivially_destructible::value, ""); - static_assert(!std::is_trivially_destructible::value, ""); { - Opt opt; + std::optional opt; assert(static_cast(opt) == false); } { - const Opt opt; + const std::optional opt; assert(static_cast(opt) == false); } - struct test_constexpr_ctor : public Opt { + struct test_constexpr_ctor : public std::optional { constexpr test_constexpr_ctor() {} }; } -int main(int, char**) { - test_constexpr>(); - test_constexpr>(); - test_constexpr>(); - test_constexpr>(); - test_constexpr>(); - test>(); - // EXTENSIONS -#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled. - test_constexpr>(); - test_constexpr>(); - test_constexpr>(); - test_constexpr>(); - test_constexpr>(); +TEST_CONSTEXPR_CXX23 void non_literal_test() { + test(); + test(); +} + +constexpr bool test() { + test(); + test(); + test(); + test(); + test(); +#if TEST_STD_VER >= 23 + non_literal_test(); +#endif +#if TEST_STD_VER >= 26 + test(); + test(); + test(); + test(); +// TODO: optional is not allowed. +# if 0 + test(); +# endif #endif + return true; +} + +int main(int, char**) { + assert(test()); + static_assert(test()); + + { + non_literal_test(); + } return 0; } From fc5d81154c79218f34c9c082413f9344af185c89 Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sat, 22 Nov 2025 23:11:39 -0500 Subject: [PATCH 02/17] optional and friends --- .../const_optional_U.pass.cpp | 33 ++++++++++++---- .../explicit_const_optional_U.pass.cpp | 39 +++++++++++++------ .../explicit_optional_U.pass.cpp | 35 ++++++++++++----- 3 files changed, 78 insertions(+), 29 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 70fd76ec6ed0b..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,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// REQUIRES: std-at-least-c++17 // // template @@ -68,7 +68,7 @@ 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_; } }; @@ -86,15 +86,20 @@ constexpr bool test_all() { return true; } -int main(int, char**) { +constexpr bool test() { test_all(); test_all(); test_all(); -#if TEST_STD_VER > 17 - static_assert(test_all()); - static_assert(test_all()); - static_assert(test_all()); + +// TODO: Enable once P3068R6 is implemented +#if TEST_STD_VER >= 26 && 0 + test_throwing(); #endif + + return true; +} + +TEST_CONSTEXPR_CXX26 bool test_throwing() { { typedef Z T; typedef int U; @@ -108,7 +113,19 @@ int main(int, char**) { test(rhs, true); } - static_assert(!(std::is_constructible, const optional&>::value), ""); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 20 + static_assert(test()); +#endif + + { + test_throwing(); + } + static_assert(!(std::is_constructible, const optional&>::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 1b9882fb25633..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,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// REQUIRED: std-at-least-c++17 // // template @@ -22,7 +22,7 @@ using std::optional; template TEST_CONSTEXPR_CXX20 void test(const optional& rhs, bool is_going_to_throw = false) { - static_assert(!(std::is_convertible&, optional>::value), ""); + static_assert(!(std::is_convertible&, optional>::value)); bool rhs_engaged = static_cast(rhs); #ifndef TEST_HAS_NO_EXCEPTIONS try { @@ -69,9 +69,9 @@ 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 @@ -87,13 +87,7 @@ constexpr bool test_all() { return true; } -int main(int, char**) { - test_all(); - test_all(); -#if TEST_STD_VER > 17 - static_assert(test_all()); - static_assert(test_all()); -#endif +TEST_CONSTEXPR_CXX26 bool test_throwing() { { typedef Z T; typedef int U; @@ -107,5 +101,28 @@ int main(int, char**) { test(rhs, true); } + return true; +} + +TEST_CONSTEXPR_CXX20 bool test() { + test_all(); + test_all(); + +// TODO: Enable once P3068R6 is implemented +#if TEST_STD_VER >= 26 && 0 + test_throwing(); +#endif + + 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 bddbd4ba93d5a..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,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// REQUIRES: std-at-least-c++17 // // template @@ -22,7 +22,7 @@ using std::optional; template TEST_CONSTEXPR_CXX20 void test(optional&& rhs, bool is_going_to_throw = false) { - static_assert(!(std::is_convertible&&, optional>::value), ""); + static_assert(!(std::is_convertible&&, optional>::value)); bool rhs_engaged = static_cast(rhs); #ifndef TEST_HAS_NO_EXCEPTIONS try { @@ -57,6 +57,19 @@ class Z { explicit Z(int) { TEST_THROW(6); } }; +TEST_CONSTEXPR_CXX26 bool test_throwing() { + { + optional rhs; + test(std::move(rhs)); + } + { + optional rhs(3); + test(std::move(rhs), true); + } + + return true; +} + TEST_CONSTEXPR_CXX20 bool test() { { optional rhs; @@ -67,21 +80,23 @@ TEST_CONSTEXPR_CXX20 bool test() { test(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 + test(); +#if TEST_STD_VER >= 20 static_assert(test()); #endif - test(); { - optional rhs; - test(std::move(rhs)); - } - { - optional rhs(3); - test(std::move(rhs), true); + test_throwing(); } return 0; From d4eaafc80925a7d67385939eb110065fddf119bf Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sat, 22 Nov 2025 23:21:48 -0500 Subject: [PATCH 03/17] 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 c1bdd81e5ed47..9e06b9b609a0a 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 // // constexpr optional(nullopt_t) noexcept; @@ -19,49 +19,56 @@ #include "test_macros.h" -using std::nullopt; -using std::nullopt_t; -using std::optional; +template +constexpr void test() { + static_assert(std::is_nothrow_constructible_v, std::nullopt_t&>); + static_assert(std::is_trivially_destructible_v == std::is_trivially_destructible_v>); + static_assert( + std::is_trivially_destructible_v == std::is_trivially_destructible_v::value_type>); -template -void test_constexpr() { - static_assert(std::is_nothrow_constructible::value, ""); - static_assert(std::is_trivially_destructible::value, ""); - static_assert(std::is_trivially_destructible::value, ""); + constexpr std::optional opt(std::nullopt); + assert(!static_cast(opt)); - constexpr Opt opt(nullopt); - static_assert(static_cast(opt) == false, ""); - - struct test_constexpr_ctor : public Opt { + struct test_constexpr_ctor : public std::optional { constexpr test_constexpr_ctor() {} }; } -template -void test() { - static_assert(std::is_nothrow_constructible::value, ""); - static_assert(!std::is_trivially_destructible::value, ""); - static_assert(!std::is_trivially_destructible::value, ""); - { - Opt opt(nullopt); - assert(static_cast(opt) == false); - } - { - const Opt opt(nullopt); - assert(static_cast(opt) == false); - } - struct test_constexpr_ctor : public Opt { - constexpr test_constexpr_ctor() {} - }; +template +TEST_CONSTEXPR_CXX23 void rt_test() { + static_assert(std::is_nothrow_constructible_v, std::nullopt_t&>); + static_assert(std::is_trivially_destructible_v == std::is_trivially_destructible_v>); + static_assert( + std::is_trivially_destructible_v == std::is_trivially_destructible_v::value_type>); + + const std::optional opt(std::nullopt); + assert(!static_cast(opt)); +} + +TEST_CONSTEXPR_CXX23 bool test_non_literal() { + rt_test(); + return true; +} + +constexpr bool test() { + test(); + test(); + test(); + test(); + test(); +#if TEST_STD_VER >= 23 + test_non_literal(); +#endif + return true; } int main(int, char**) { - test_constexpr>(); - test_constexpr>(); - test_constexpr>(); - test_constexpr>(); - test_constexpr>(); - test>(); + assert(test()); + static_assert(test()); + + { + test_non_literal(); + } return 0; } From 5edaf25ba8bf9c95803f44012d62e431cac13757 Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sat, 22 Nov 2025 23:49:47 -0500 Subject: [PATCH 04/17] Copy --- .../optional.object.ctor/copy.pass.cpp | 129 ++++++++++-------- 1 file changed, 74 insertions(+), 55 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 f61a22c23a04d..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,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14 +// REQUIRES: std-at-least-c++17 // // constexpr optional(const optional& rhs); @@ -21,24 +21,18 @@ using std::optional; template -void test(InitArgs&&... args) { - const optional rhs(std::forward(args)...); - bool rhs_engaged = static_cast(rhs); - optional lhs = rhs; - assert(static_cast(lhs) == rhs_engaged); - if (rhs_engaged) - assert(*lhs == *rhs); -} +constexpr bool test(InitArgs&&... args) { + static_assert(std::is_trivially_copy_constructible_v == + std::is_trivially_copy_constructible_v>); // requirement + const optional lhs(std::forward(args)...); + optional rhs(lhs); + assert(lhs.has_value() == rhs.has_value()); + assert(lhs.has_value() ? *lhs == *rhs : true); -template -constexpr bool constexpr_test(InitArgs&&... args) { - static_assert(std::is_trivially_copy_constructible_v, ""); // requirement - const optional rhs(std::forward(args)...); - optional 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 @@ -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 is not allowed. { - static_assert(!std::is_copy_constructible>::value, ""); - static_assert(!std::is_copy_constructible>::value, ""); + static_assert(!std::is_copy_constructible>::value); + static_assert(!std::is_copy_constructible>::value); } +# endif #endif } -int main(int, char**) { +constexpr bool test() { test(); test(3); - static_assert(constexpr_test(), ""); - static_assert(constexpr_test(3), ""); + test(42); + + // FIXME: Why is this in ctor copy.pass.cpp? + { + constexpr std::optional o1{4}; + constexpr std::optional o2 = o1; + static_assert(*o2 == 4, ""); + } + + { + // LWG3836 https://wg21.link/LWG3836 + // std::optional conversion constructor optional(const optional&) + // should take precedence over optional(U&&) with operator bool + { + std::optional o1(false); + std::optional o2(o1); + assert(!o2.value()); + } + } + + { + using T = TrivialTestTypes::TestType; + test(); + test(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()); { - const optional o(42); - optional o2(o); - assert(*o2 == 42); + test_throwing_ctor(); } + +#if TEST_STD_VER >= 26 + { + test_reference_extension(); + } +#endif + + { // FIXME: Shouldn't this be able to pass in a constexpr context since C++17? + using T = ConstexprTestTypes::TestType; + test(); + test(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(); - test(42); - } - { - using namespace TrivialTestTypes; - test(); - test(42); - } - { - test_throwing_ctor(); - } - { - test_reference_extension(); - } - { - constexpr std::optional o1{4}; - constexpr std::optional o2 = o1; - static_assert(*o2 == 4, ""); - } - // LWG3836 https://wg21.link/LWG3836 - // std::optional conversion constructor optional(const optional&) - // should take precedence over optional(U&&) with operator bool - { - std::optional o1(false); - std::optional o2(o1); - assert(!o2.value()); - } + TestTypes::TestType::reset(); return 0; } From e3e454eb14952114686677bc3fecdb84dde92919 Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sun, 23 Nov 2025 00:23:17 -0500 Subject: [PATCH 05/17] 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 583debcaac650..ba37fad3f1e2c 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 -void test(InitArgs&&... args) { +constexpr bool test(InitArgs&&... args) { + static_assert(std::is_trivially_move_constructible_v == std::is_trivially_move_constructible_v>); const optional orig(std::forward(args)...); - optional rhs(orig); - bool rhs_engaged = static_cast(rhs); - optional lhs = std::move(rhs); - assert(static_cast(lhs) == rhs_engaged); - if (rhs_engaged) - assert(*lhs == *orig); -} -template -constexpr bool constexpr_test(InitArgs&&... args) { - static_assert(std::is_trivially_copy_constructible_v, ""); // requirement - const optional orig(std::forward(args)...); - optional rhs(orig); - optional lhs = std::move(rhs); - return (lhs.has_value() == orig.has_value()) && (lhs.has_value() ? *lhs == *orig : true); + optional lhs(orig); + optional 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(); test(3); - static_assert(constexpr_test(), ""); - static_assert(constexpr_test(3), ""); + test(42); + + { + using T = TrivialTestTypes::TestType; + test(); + test(42); + } +#if TEST_STD_VER >= 26 && 0 { - optional o(42); - optional 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(); test(42); } - { - using namespace TrivialTestTypes; - test(); - test(42); - } - { - test_throwing_ctor(); - } + { struct ThrowsMove { ThrowsMove() noexcept(false) {} @@ -202,13 +204,24 @@ int main(int, char**) { }; static_assert(std::is_nothrow_move_constructible>::value, ""); } + + return true; +} + +int main(int, char**) { + assert(test()); + static_assert(test()); + { - test_reference_extension(); + rt_test(); + } + + { + test_throwing_ctor(); } + { - constexpr std::optional o1{4}; - constexpr std::optional o2 = std::move(o1); - static_assert(*o2 == 4, ""); + test_reference_extension(); } return 0; From c8ee1c4e0d8ac04fd9de9fabe21e943bba9ae14d Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sun, 23 Nov 2025 00:33:49 -0500 Subject: [PATCH 06/17] const_T --- .../optional.object.ctor/const_T.pass.cpp | 74 +++++++------------ 1 file changed, 28 insertions(+), 46 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 67d0fcfc18b86..61cfc056dadd6 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 +constexpr void test_ctor(Args... args) { + const T t(args...); + const std::optional opt(t); -int main(int, char**) { - { - typedef int T; - constexpr T t(5); - constexpr optional opt(t); - static_assert(static_cast(opt) == true, ""); - static_assert(*opt == 5, ""); + assert(static_cast(opt)); + assert(*opt == t); - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(const T&) {} - }; - } - { - typedef double T; - constexpr T t(3); - constexpr optional opt(t); - static_assert(static_cast(opt) == true, ""); - static_assert(*opt == 3, ""); + struct test_constexpr_ctor : public optional { + constexpr test_constexpr_ctor(const T&) {} + }; +} + +constexpr bool test() { + test_ctor(5); + test_ctor(3.0); + test_ctor(42); + test_ctor(3); - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(const T&) {} - }; - } { - const int x = 42; - optional o(x); - assert(*o == x); + using T = ExplicitConstexprTestTypes::TestType; + static_assert(!std::is_convertible_v>); + test_ctor(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(opt) == true); assert(opt.value().value == 3); } + { typedef ExplicitTestTypes::TestType T; static_assert(!std::is_convertible>::value, ""); @@ -70,29 +74,7 @@ int main(int, char**) { assert(static_cast(opt) == true); assert(opt.value().value == 3); } - { - typedef ConstexprTestTypes::TestType T; - constexpr T t(3); - constexpr optional opt = {t}; - static_assert(static_cast(opt) == true, ""); - static_assert(opt.value().value == 3, ""); - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(const T&) {} - }; - } - { - typedef ExplicitConstexprTestTypes::TestType T; - static_assert(!std::is_convertible>::value, ""); - constexpr T t(3); - constexpr optional opt(t); - static_assert(static_cast(opt) == true, ""); - static_assert(opt.value().value == 3, ""); - - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(const T&) {} - }; - } #ifndef TEST_HAS_NO_EXCEPTIONS { struct Z { From 0b8f6ee78b2382869798413d86edb4c1c35a8626 Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sun, 23 Nov 2025 00:43:59 -0500 Subject: [PATCH 07/17] 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 709b106c800a6..ff315de570a4d 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(); - test_all(); -#if TEST_STD_VER > 17 - static_assert(test_all()); - static_assert(test_all()); -#endif +TEST_CONSTEXPR_CXX26 void test_throw() { { optional rhs; test(std::move(rhs)); @@ -85,6 +79,27 @@ int main(int, char**) { } static_assert(!(std::is_constructible, optional>::value), ""); +} + +TEST_CONSTEXPR_CXX20 bool test() { + test_all(); + test_all(); + +#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 b626e1d8a80acf3c40e5b23ece6730b39031723c Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sun, 23 Nov 2025 00:58:27 -0500 Subject: [PATCH 08/17] Deduct --- .../optional.object.ctor/deduct.pass.cpp | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 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 bc1d26aa8bd18..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,8 +6,9 @@ // //===----------------------------------------------------------------------===// +// REQUIRES: std-at-least-c++17 + // -// UNSUPPORTED: c++03, c++11, c++14 // template // optional(T) -> optional; @@ -17,47 +18,41 @@ #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); - assert(static_cast(opt)); - assert(*opt == 5); - } +template +constexpr void test_deduct(T arg) { + std::optional opt(arg); - { - // optional(T) - std::optional opt(A{}); - ASSERT_SAME_TYPE(decltype(opt), std::optional); - assert(static_cast(opt)); - } + ASSERT_SAME_TYPE(decltype(opt), std::optional); + assert(static_cast(opt)); + assert(*opt == arg); +} + +constexpr bool test() { + // optional(T) + test_deduct(5); + test_deduct(A{}); { // optional(const T&); const int& source = 5; - std::optional opt(source); - ASSERT_SAME_TYPE(decltype(opt), std::optional); - assert(static_cast(opt)); - assert(*opt == 5); + test_deduct(source); } { // optional(T*); const int* source = nullptr; - std::optional opt(source); - ASSERT_SAME_TYPE(decltype(opt), std::optional); - assert(static_cast(opt)); - assert(*opt == nullptr); + test_deduct(source); } { // optional(T[]); int source[] = {1, 2, 3}; std::optional opt(source); + ASSERT_SAME_TYPE(decltype(opt), std::optional); assert(static_cast(opt)); assert((*opt)[0] == 1); @@ -68,10 +63,18 @@ int main(int, char**) { // optional(optional); std::optional source('A'); std::optional opt(source); + ASSERT_SAME_TYPE(decltype(opt), std::optional); assert(static_cast(opt) == static_cast(source)); assert(*opt == *source); } + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + return 0; } From cee7738080504e4f7ec5582ae9b0652c84fbe52e Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sun, 23 Nov 2025 01:23:35 -0500 Subject: [PATCH 09/17] in_place_t --- .../optional.object.ctor/in_place_t.pass.cpp | 109 ++++++------------ 1 file changed, 37 insertions(+), 72 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 902754418fbde..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,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// UNSUPPORTED: c++03, c++11, c++14 +// REQUIRED: std-at-least-c++17 // @@ -16,6 +16,7 @@ #include #include #include +#include #include "test_macros.h" @@ -28,25 +29,13 @@ class X { int j_ = 0; public: - X() : i_(0) {} - X(int i) : i_(i) {} - X(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) {} - ~X() {} + ~X() = default; - 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; - -public: - constexpr Y() : i_(0) {} - constexpr Y(int i) : i_(i) {} - constexpr Y(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_; } + friend constexpr bool operator==(const X& x, const X& y) { return x.i_ == y.i_ && x.j_ == y.j_; } }; class Z { @@ -54,62 +43,18 @@ class Z { Z(int) { TEST_THROW(6); } }; -int main(int, char**) { - { - constexpr optional opt(in_place, 5); - static_assert(static_cast(opt) == true, ""); - static_assert(*opt == 5, ""); +template +constexpr void test_inplace(Args... args) { + optional opt(in_place, args...); + assert(bool(opt)); + assert(*opt == T(args...)); - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(in_place_t, int i) : optional(in_place, i) {} - }; - } - { - optional opt(in_place, 5); - assert(*opt == 5); - } - { - const optional opt(in_place); - assert(static_cast(opt) == true); - assert(*opt == X()); - } - { - const optional opt(in_place, 5); - assert(static_cast(opt) == true); - assert(*opt == X(5)); - } - { - const optional opt(in_place, 5, 4); - assert(static_cast(opt) == true); - assert(*opt == X(5, 4)); - } - { - constexpr optional opt(in_place); - static_assert(static_cast(opt) == true, ""); - static_assert(*opt == Y(), ""); - - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(in_place_t) : optional(in_place) {} - }; - } - { - constexpr optional opt(in_place, 5); - static_assert(static_cast(opt) == true, ""); - static_assert(*opt == Y(5), ""); - - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(in_place_t, int i) : optional(in_place, i) {} - }; - } - { - constexpr optional opt(in_place, 5, 4); - static_assert(static_cast(opt) == true, ""); - static_assert(*opt == Y(5, 4), ""); + struct test_constexpr_ctor : public optional { + constexpr test_constexpr_ctor(in_place_t, int i) : optional(in_place, i) {} + }; +} - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(in_place_t, int i, int j) : optional(in_place, i, j) {} - }; - } +TEST_CONSTEXPR_CXX26 void test_throwing() { #ifndef TEST_HAS_NO_EXCEPTIONS { try { @@ -120,6 +65,26 @@ int main(int, char**) { } } #endif +} + +constexpr bool test() { + test_inplace(5); + test_inplace(5); + test_inplace(); + test_inplace(5); + test_inplace(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 5f575023551d7d2bcdb86f7ddb190e81208d7889 Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sun, 23 Nov 2025 01:59:54 -0500 Subject: [PATCH 10/17] rvalue_T --- .../optional.object.ctor/rvalue_T.pass.cpp | 114 ++++++++++-------- 1 file changed, 62 insertions(+), 52 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 e73eef4592256..05af88af13916 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 @@ -27,32 +27,27 @@ class Z { Z(Z&&) { TEST_THROW(6); } }; -int main(int, char**) { - { - typedef int T; - constexpr optional opt(T(5)); - static_assert(static_cast(opt) == true, ""); - static_assert(*opt == 5, ""); - - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(T&&) {} - }; - } +template +constexpr void test_rvalueT(U arg) { { - typedef double T; - constexpr optional opt(T(3)); - static_assert(static_cast(opt) == true, ""); - static_assert(*opt == 3, ""); - - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(T&&) {} - }; + const optional opt(arg); + assert(bool(opt)); + assert(*opt == T(arg)); } + { - const int x = 42; - optional o(std::move(x)); - assert(*o == 42); + T t(arg); + optional opt(std::move(t)); + assert(*opt == T(arg)); } + + struct test_constexpr_ctor : public optional { + 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(opt) == true); assert(opt.value().value == 3); } - { - typedef ConstexprTestTypes::TestType T; - constexpr optional opt = {T(3)}; - static_assert(static_cast(opt) == true, ""); - static_assert(opt.value().value == 3, ""); - - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(const T&) {} - }; - } - { - typedef ConstexprTestTypes::TestType T; - constexpr optional opt = {3}; - static_assert(static_cast(opt) == true, ""); - static_assert(opt.value().value == 3, ""); - - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(const T&) {} - }; - } - { - typedef ExplicitConstexprTestTypes::TestType T; - static_assert(!std::is_convertible>::value, ""); - constexpr optional opt(T{3}); - static_assert(static_cast(opt) == true, ""); - static_assert(opt.value().value == 3, ""); +} - struct test_constexpr_ctor : public optional { - 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(5); + test_rvalueT(3.0); + test_rvalueT(42); + + { + using T = ConstexprTestTypes::TestType; + test_rvalueT(T(3)); + } + + { + using T = ConstexprTestTypes::TestType; + test_rvalueT(3); + } + + { + using T = ExplicitConstexprTestTypes::TestType; + static_assert(!std::is_convertible>::value); + test_rvalueT(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 ade226065d355f5214e33e0de36a5172652c58ec Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sun, 23 Nov 2025 02:05:46 -0500 Subject: [PATCH 11/17] Format U.pass --- .../optional.object/optional.object.ctor/U.pass.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 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 1e951ebdf1d74..d09e5a2ef5466 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,19 +5,18 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// -// UNSUPPORTED: c++03, c++11, c++14 + +// REQUIRED: std-at-least-c++17 // // template -// constexpr EXPLICIT optional(U&& u); +// constexpr explicit optional(U&& u); #include #include #include -#include "test_macros.h" #include "archetypes.h" #include "test_convertible.h" From 04066ceccd98288e85077f214f1e83661fe23ded Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sun, 23 Nov 2025 02:19:27 -0500 Subject: [PATCH 12/17] 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 d09e5a2ef5466..965085846bc4c 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 @@ -44,80 +44,47 @@ struct ImplicitAny { template constexpr bool implicit_conversion(optional&& opt, const From& v) { using O = optional; - static_assert(test_convertible(), ""); - static_assert(!test_convertible(), ""); - static_assert(!test_convertible(), ""); - return opt && *opt == static_cast(v); + assert((test_convertible())); + assert(!(test_convertible())); + assert(!(test_convertible())); + assert(opt); + assert(*opt == static_cast(v)); + + return true; } template constexpr bool explicit_conversion(Input&& in, const Expect& v) { using O = optional; - static_assert(std::is_constructible::value, ""); - static_assert(!std::is_convertible::value, ""); - static_assert(!std::is_constructible::value, ""); - static_assert(!std::is_constructible::value, ""); + assert((std::is_constructible::value)); + assert(!(std::is_convertible::value)); + assert(!(std::is_constructible::value)); + assert(!(std::is_constructible::value)); + optional opt(std::forward(in)); optional opt2{std::forward(in)}; - return opt && *opt == static_cast(v) && (opt2 && *opt2 == static_cast(v)); + assert(opt); + assert(opt2); + assert(*opt == static_cast(v)); + assert(*opt2 == static_cast(v)); + + return true; } void test_implicit() { - { - static_assert(implicit_conversion(42, 42), ""); - } - { - static_assert(implicit_conversion(3.14, 3.14), ""); - } - { - int x = 42; - optional o(&x); - assert(*o == &x); - } - { - using T = TrivialTestTypes::TestType; - static_assert(implicit_conversion(42, 42), ""); - } - { - using T = TestTypes::TestType; - assert(implicit_conversion(3, T(3))); - } { using T = TestTypes::TestType; optional opt({3}); assert(opt && *opt == static_cast(3)); } + { - using O = optional; - static_assert(!test_convertible(), ""); - static_assert(!test_convertible(), ""); - static_assert(!test_convertible(), ""); - static_assert(!test_convertible(), ""); - static_assert(!test_convertible(), ""); - } -#ifndef TEST_HAS_NO_EXCEPTIONS - { - try { - using T = ImplicitThrow; - optional t = 42; - assert(false); - ((void)t); - } catch (int) { - } + using T = TestTypes::TestType; + assert((implicit_conversion(3, T(3)))); } -#endif } void test_explicit() { - { - using T = ExplicitTrivialTestTypes::TestType; - static_assert(explicit_conversion(42, 42), ""); - } - { - using T = ExplicitConstexprTestTypes::TestType; - static_assert(explicit_conversion(42, 42), ""); - static_assert(!std::is_convertible::value, ""); - } { using T = ExplicitTestTypes::TestType; T::reset(); @@ -136,7 +103,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 = 42; + assert(false); + ((void)t); + } catch (int) { + } + } + { try { using T = ExplicitThrow; @@ -148,9 +128,68 @@ void test_explicit() { #endif } +constexpr bool test() { + { + assert((implicit_conversion(42, 42))); + } + + { + assert((implicit_conversion(3.14, 3.14))); + } + + { + int x = 42; + optional o(&x); + assert(*o == &x); + } + + { + using T = TrivialTestTypes::TestType; + assert((implicit_conversion(42, 42))); + } + + { + using O = optional; + assert(!(test_convertible())); + assert(!(test_convertible())); + assert(!(test_convertible())); + assert(!(test_convertible())); + assert(!(test_convertible())); + } + + { + using T = ExplicitTrivialTestTypes::TestType; + assert((explicit_conversion(42, 42))); + } + + { + using T = ExplicitConstexprTestTypes::TestType; + assert(explicit_conversion(42, 42)); + assert(!(std::is_convertible::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; } From 242e5eb671af3f0ec94cc22393da705f5d3cf4a7 Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Sun, 23 Nov 2025 13:51:24 -0500 Subject: [PATCH 13/17] Typo'd some REQUIRES directives --- .../optional/optional.object/optional.object.ctor/U.pass.cpp | 2 +- .../optional.object.ctor/explicit_const_optional_U.pass.cpp | 2 +- .../optional.object/optional.object.ctor/in_place_t.pass.cpp | 2 +- .../optional.object/optional.object.ctor/rvalue_T.pass.cpp | 2 +- 4 files changed, 4 insertions(+), 4 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 965085846bc4c..8701cb6dabed8 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 @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// REQUIRED: std-at-least-c++17 +// REQUIRES: std-at-least-c++17 // 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 fa9a96c39b8fa..da51b6a3c4350 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,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// REQUIRED: std-at-least-c++17 +// REQUIRES: std-at-least-c++17 // // template 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 ae3d76eff4a42..f69f189acfdfd 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,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// REQUIRED: std-at-least-c++17 +// REQUIRES: std-at-least-c++17 // 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 05af88af13916..5988159832fe9 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 // //===----------------------------------------------------------------------===// -// + // UNSUPPORTED: c++03, c++11, c++14 // From 91bb309bd314d55071e53e4f56fe3ae6272a0bab Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Tue, 25 Nov 2025 21:34:48 -0500 Subject: [PATCH 14/17] Add a optional copy and move test --- .../const_optional_U.pass.cpp | 2 +- .../optional.object.ctor/copy.pass.cpp | 69 ++++++++++++------- .../optional.object.ctor/move.pass.cpp | 41 ++++++++--- 3 files changed, 78 insertions(+), 34 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 ab424a6509183..95aa7b33c3a96 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 @@ -87,6 +87,7 @@ constexpr bool test_all() { } constexpr bool test() { + static_assert(!(std::is_constructible, const optional&>::value)); test_all(); test_all(); test_all(); @@ -126,6 +127,5 @@ int main(int, char**) { test_throwing(); } - static_assert(!(std::is_constructible, const optional&>::value)); return 0; } 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 bd4741154e6d8..9d711d7fb91f2 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 @@ -65,9 +65,26 @@ void test_ref(InitArgs&&... args) { assert(&(*lhs) == &(*rhs)); } -// TODO: Add constexpr tests -void test_reference_extension() { #if TEST_STD_VER >= 26 +struct X { + int copy_count = 0; + + constexpr X() {} + constexpr X(const X&) { copy_count++; } +}; + +constexpr void test_ref() { + { + X x{}; + std::optional o1(x); + std::optional o2(o1); + assert(o1.has_value() && o2.has_value()); + assert(x.copy_count == 0); + assert(&*o1 == &*o2); + } +} + +void test_reference_extension() { using T = TestTypes::TestType; T::reset(); { @@ -103,13 +120,15 @@ void test_reference_extension() { static_assert(!std::is_copy_constructible>::value); } # endif -#endif } +#endif constexpr bool test() { test(); test(3); test(42); + test(); + test(42); // FIXME: Why is this in ctor copy.pass.cpp? { @@ -129,34 +148,19 @@ constexpr bool test() { } } - { - using T = TrivialTestTypes::TestType; - test(); - test(42); - } +#if TEST_STD_VER >= 26 + test_ref(); // TODO: Enable once P3068R6 is implemented -#if TEST_STD_VER >= 26 && 0 +# if 0 test_throwing_ctor(); +# endif #endif return true; } -int main(int, char**) { - test(); - static_assert(test()); - - { - test_throwing_ctor(); - } - -#if TEST_STD_VER >= 26 - { - test_reference_extension(); - } -#endif - +void test_rt() { { // FIXME: Shouldn't this be able to pass in a constexpr context since C++17? using T = ConstexprTestTypes::TestType; test(); @@ -189,6 +193,25 @@ int main(int, char**) { } TestTypes::TestType::reset(); +} + +int main(int, char**) { + test(); + static_assert(test()); + + { + test_rt(); + } + + { + test_throwing_ctor(); + } + +#if TEST_STD_VER >= 26 + { + test_reference_extension(); + } +#endif return 0; } 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 ba37fad3f1e2c..5bb8146f08338 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 @@ -59,16 +59,33 @@ TEST_CONSTEXPR_CXX26 void test_throwing_ctor() { template void test_ref(InitArgs&&... args) { optional rhs(std::forward(args)...); - bool rhs_engaged = static_cast(rhs); - optional lhs = std::move(rhs); - assert(static_cast(lhs) == rhs_engaged); - if (rhs_engaged) - assert(&(*lhs) == &(*rhs)); + optional lhs(std::move(rhs)); + + assert(lhs.has_value() == rhs.has_value()); + assert(rhs.has_value() ? &*lhs == &*rhs : true); } -// TODO: Add constexpr tests -void test_reference_extension() { +struct F { + int move_count = 0; + + constexpr F() {} + constexpr F(F&&) { move_count++; } +}; + #if TEST_STD_VER >= 26 + +constexpr void test_ref() { + { // Test that moving from an optional doesn't also move the object it's referencing + F f{}; + std::optional o1(f); + std::optional o2(std::move(o1)); + assert(f.move_count == 0); + assert(o1.has_value() && o2.has_value()); + assert(&*o1 == &*o2); + } +} + +void test_reference_extension() { using T = TestTypes::TestType; T::reset(); { @@ -129,8 +146,8 @@ void test_reference_extension() { static_assert(!std::is_copy_constructible_v>); } # endif -#endif } +#endif constexpr bool test() { test(); @@ -143,6 +160,10 @@ constexpr bool test() { test(42); } +#if TEST_STD_VER >= 26 + test_ref(); +#endif + #if TEST_STD_VER >= 26 && 0 { test_throwing_ctor(); @@ -152,7 +173,7 @@ constexpr bool test() { return true; } -bool rt_test() { +bool test_rt() { { using T = TestTypes::TestType; T::reset(); @@ -213,7 +234,7 @@ int main(int, char**) { static_assert(test()); { - rt_test(); + test_rt(); } { From ea768b4a85aa17154222a48434dae16bbb3b759a Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Thu, 27 Nov 2025 13:19:50 -0500 Subject: [PATCH 15/17] REQUIRES -> unsupported for the C++17 --- .../optional/optional.object/optional.object.ctor/U.pass.cpp | 2 +- .../optional.object/optional.object.ctor/const_T.pass.cpp | 2 +- .../optional.object.ctor/const_optional_U.pass.cpp | 3 ++- .../optional.object/optional.object.ctor/copy.pass.cpp | 3 ++- .../optional.object/optional.object.ctor/ctor.verify.cpp | 1 + .../optional.object/optional.object.ctor/default.pass.cpp | 3 ++- .../empty_in_place_t_does_not_clobber.pass.cpp | 1 + .../optional.object.ctor/explicit_const_optional_U.pass.cpp | 3 ++- .../optional.object.ctor/explicit_optional_U.pass.cpp | 3 ++- .../optional.object/optional.object.ctor/in_place_t.pass.cpp | 4 ++-- .../optional.object.ctor/initializer_list.pass.cpp | 1 + .../optional.object/optional.object.ctor/nullopt_t.pass.cpp | 3 ++- .../optional.object/optional.object.ctor/optional_U.pass.cpp | 1 + 13 files changed, 20 insertions(+), 10 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 8701cb6dabed8..61dfe1166a980 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 @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// REQUIRES: std-at-least-c++17 +// UNSUPPORTED: c++03, c++11, c++14 // 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 61cfc056dadd6..2f045bd19be77 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,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// + // UNSUPPORTED: c++03, c++11, c++14 // 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 95aa7b33c3a96..8f2105e409a8f 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,7 +6,8 @@ // //===----------------------------------------------------------------------===// -// REQUIRES: std-at-least-c++17 +// UNSUPPORTED: c++03, c++11, c++14 + // // template 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 9d711d7fb91f2..722eb95b5bef7 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,7 +6,8 @@ // //===----------------------------------------------------------------------===// -// REQUIRES: std-at-least-c++17 +// UNSUPPORTED: c++03, c++11, c++14 + // // constexpr optional(const optional& rhs); 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 00ca941668eb2..08b2b43faacd4 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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // T shall be an object type other than cv in_place_t or cv nullopt_t 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 540863b2b19c4..6fdf8d8898e38 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,7 +6,8 @@ // //===----------------------------------------------------------------------===// -// REQUIRES: std-at-least-c++17 +// UNSUPPORTED: c++03, c++11, c++14 + // // constexpr optional() noexcept; 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 f19174841813c..c624911cb8c25 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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // constexpr optional(in_place_t); 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 da51b6a3c4350..3f8bfb3a60e5e 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,7 +6,8 @@ // //===----------------------------------------------------------------------===// -// REQUIRES: std-at-least-c++17 +// UNSUPPORTED: c++03, c++11, c++14 + // // template 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 f89ba1319a9ed..07e36a54872c4 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,7 +6,8 @@ // //===----------------------------------------------------------------------===// -// REQUIRES: std-at-least-c++17 +// UNSUPPORTED: c++03, c++11, c++14 + // // template 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 f69f189acfdfd..2b78968ae521c 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 @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// -// REQUIRES: std-at-least-c++17 + +// UNSUPPORTED: c++03, c++11, c++14 // 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 1993476792878..be1edc8f6c190 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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // template 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 9e06b9b609a0a..60db025c3ffaa 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,8 @@ // //===----------------------------------------------------------------------===// -// REQUIRES: std-at-least-c++17 +// UNSUPPORTED: c++03, c++11, c++14 + // // constexpr optional(nullopt_t) noexcept; 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 ff315de570a4d..f03ccaa0a0257 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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // template From 03fd8796ab0054908cc1f297d4a2890fb4e6db47 Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Thu, 27 Nov 2025 13:22:51 -0500 Subject: [PATCH 16/17] Break verify test comments into their own lines and re-format --- .../optional.object.ctor/ctor.verify.cpp | 38 ++++++++++++------- .../optional.object.ctor/deduct.verify.cpp | 4 -- 2 files changed, 24 insertions(+), 18 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 08b2b43faacd4..10f3defbd6f44 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 @@ -24,30 +24,40 @@ struct NonDestructible { }; int main(int, char**) { - // clang-format off { #if TEST_STD_VER >= 26 - std::optional opt2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an rvalue reference type is ill-formed}} + std::optional opt2; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an rvalue reference type is ill-formed}} #else - std::optional o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}} + std::optional o1; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a reference type is ill-formed}} #endif - std::optional o2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a non-destructible type is ill-formed}} - std::optional o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an array type is ill-formed}} + std::optional o2; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with a non-destructible type is ill-formed}} + std::optional o3; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with an array type is ill-formed}} } { - std::optional< std::in_place_t> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} - std::optional o2; // expected-error-re@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@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} - std::optional o4; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} + std::optional< std::in_place_t> o1; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} + std::optional o2; + // expected-error-re@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@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} + std::optional o4; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with in_place_t is ill-formed}} } { - std::optional< std::nullopt_t> o1; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} - std::optional o2; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} - std::optional< volatile std::nullopt_t> o3; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} - std::optional o4; // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} + std::optional< std::nullopt_t> o1; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} + std::optional o2; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} + std::optional< volatile std::nullopt_t> o3; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} + std::optional o4; + // expected-error-re@optional:* {{static assertion failed{{.*}}instantiation of optional with nullopt_t is ill-formed}} } - // clang-format on return 0; } 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 7ab842bf68c51..5616b2e0676e3 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 @@ -19,10 +19,6 @@ struct A {}; int main(int, char**) { - // Test the explicit deduction guides - - // Test the implicit deduction guides - // clang-format off { // optional() From bcf9f55b72a6e24d9e22bbb7308d1a05cb4e2645 Mon Sep 17 00:00:00 2001 From: William Tran-Viet Date: Thu, 27 Nov 2025 13:36:10 -0500 Subject: [PATCH 17/17] Fold some tests into the runtime tests --- .../optional.object.ctor/copy.pass.cpp | 18 +++++------ .../optional.object.ctor/move.pass.cpp | 18 ++++++----- .../optional.object.ctor/rvalue_T.pass.cpp | 32 ++++++++++--------- 3 files changed, 36 insertions(+), 32 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 722eb95b5bef7..0237cfd1ca596 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 @@ -194,15 +194,6 @@ void test_rt() { } TestTypes::TestType::reset(); -} - -int main(int, char**) { - test(); - static_assert(test()); - - { - test_rt(); - } { test_throwing_ctor(); @@ -213,6 +204,15 @@ int main(int, char**) { test_reference_extension(); } #endif +} + +int main(int, char**) { + test(); + static_assert(test()); + + { + test_rt(); + } return 0; } 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 5bb8146f08338..b4df9c4e43bbb 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 @@ -226,6 +226,16 @@ bool test_rt() { static_assert(std::is_nothrow_move_constructible>::value, ""); } + { + test_throwing_ctor(); + } + +#if TEST_STD_VER >= 26 + { + test_reference_extension(); + } +#endif + return true; } @@ -237,13 +247,5 @@ int main(int, char**) { test_rt(); } - { - test_throwing_ctor(); - } - - { - test_reference_extension(); - } - return 0; } 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 5988159832fe9..e851cc82d60fb 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 @@ -47,6 +47,20 @@ constexpr void test_rvalueT(U arg) { }; } +TEST_CONSTEXPR_CXX26 void test_throwing() { +#ifndef TEST_HAS_NO_EXCEPTIONS + { + try { + Z z(3); + optional opt(std::move(z)); + assert(false); + } catch (int i) { + assert(i == 6); + } + } +#endif +} + void test_rt() { { typedef TestTypes::TestType T; @@ -57,6 +71,7 @@ void test_rt() { assert(static_cast(opt) == true); assert(opt.value().value == 3); } + { typedef ExplicitTestTypes::TestType T; static_assert(!std::is_convertible>::value, ""); @@ -67,6 +82,7 @@ void test_rt() { assert(static_cast(opt) == true); assert(opt.value().value == 3); } + { typedef TestTypes::TestType T; T::reset(); @@ -78,20 +94,10 @@ void test_rt() { assert(static_cast(opt) == true); assert(opt.value().value == 3); } -} -TEST_CONSTEXPR_CXX26 void test_throwing() { -#ifndef TEST_HAS_NO_EXCEPTIONS { - try { - Z z(3); - optional opt(std::move(z)); - assert(false); - } catch (int i) { - assert(i == 6); - } + test_throwing(); } -#endif } constexpr bool test() { @@ -132,9 +138,5 @@ int main(int, char**) { test_rt(); } - { - test_throwing(); - } - return 0; }