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..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 @@ -5,19 +5,18 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// + // UNSUPPORTED: c++03, c++11, c++14 // // 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" @@ -45,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(); @@ -137,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; @@ -149,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; } 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..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 // @@ -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); + + assert(static_cast(opt)); + assert(*opt == t); + + 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); -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, ""); - - 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&) {} - }; - } { - 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 { 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..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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // template @@ -68,7 +69,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 +87,21 @@ constexpr bool test_all() { return true; } -int main(int, char**) { +constexpr bool test() { + static_assert(!(std::is_constructible, const optional&>::value)); 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 +115,18 @@ 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(); + } 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 f61a22c23a04d..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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // constexpr optional(const optional& rhs); @@ -21,24 +22,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 +52,8 @@ void test_throwing_ctor() { assert(i == 6); } #endif + + return true; } template @@ -69,8 +66,26 @@ void test_ref(InitArgs&&... args) { assert(&(*lhs) == &(*rhs)); } +#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() { -#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled. using T = TestTypes::TestType; T::reset(); { @@ -99,24 +114,60 @@ 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 } +#endif -int main(int, char**) { +constexpr bool test() { test(); test(3); - static_assert(constexpr_test(), ""); - static_assert(constexpr_test(3), ""); + test(42); + test(); + test(42); + // FIXME: Why is this in ctor copy.pass.cpp? { - const optional o(42); - optional o2(o); - assert(*o2 == 42); + 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()); + } + } + +#if TEST_STD_VER >= 26 + test_ref(); + + // TODO: Enable once P3068R6 is implemented +# if 0 + test_throwing_ctor(); +# endif +#endif + + return true; +} + +void test_rt() { + { // 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 +177,9 @@ int main(int, char**) { assert(lhs.has_value() == false); assert(T::alive == 0); } + TestTypes::TestType::reset(); + { using T = TestTypes::TestType; T::reset(); @@ -139,36 +192,26 @@ 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(); } + +#if TEST_STD_VER >= 26 { test_reference_extension(); } - { - constexpr std::optional o1{4}; - constexpr std::optional o2 = o1; - static_assert(*o2 == 4, ""); - } +#endif +} + +int main(int, char**) { + test(); + static_assert(test()); - // 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()); + test_rt(); } return 0; 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..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 @@ -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 @@ -23,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.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; } 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() 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..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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // constexpr optional() noexcept; @@ -18,56 +19,64 @@ #include "test_macros.h" #include "archetypes.h" -using std::optional; - -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, ""); +template +constexpr void test() { + static_assert(std::is_nothrow_default_constructible_v>); + static_assert(std::is_trivially_destructible_v == std::is_trivially_destructible_v>); - 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; } 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 1b9882fb25633..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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // template @@ -22,7 +23,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 +70,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 +88,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 +102,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..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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // template @@ -22,7 +23,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 +58,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 +81,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; 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..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,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// + // UNSUPPORTED: c++03, c++11, c++14 // @@ -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) {} - - ~X() {} - - friend bool operator==(const X& x, const X& y) { return x.i_ == y.i_ && x.j_ == y.j_; } -}; + constexpr X() : i_(0) {} + constexpr X(int i) : i_(i) {} + constexpr X(int i, int j) : i_(i), j_(j) {} -class Y { - int i_; - int j_ = 0; + ~X() = default; -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; } 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/move.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.pass.cpp index 583debcaac650..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 @@ -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) {} @@ -65,15 +59,33 @@ 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); } -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(); { @@ -134,20 +146,34 @@ void test_reference_extension() { static_assert(!std::is_copy_constructible_v>); } # endif -#endif } +#endif -int main(int, char**) { +constexpr bool test() { test(); test(3); - static_assert(constexpr_test(), ""); - static_assert(constexpr_test(3), ""); + test(42); { - optional o(42); - optional o2(std::move(o)); - assert(*o2 == 42); + using T = TrivialTestTypes::TestType; + test(); + test(42); } + +#if TEST_STD_VER >= 26 + test_ref(); +#endif + +#if TEST_STD_VER >= 26 && 0 + { + test_throwing_ctor(); + } +#endif + + return true; +} + +bool test_rt() { { using T = TestTypes::TestType; T::reset(); @@ -158,7 +184,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 +202,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 +225,26 @@ int main(int, char**) { }; static_assert(std::is_nothrow_move_constructible>::value, ""); } + + { + test_throwing_ctor(); + } + +#if TEST_STD_VER >= 26 { test_reference_extension(); } +#endif + + return true; +} + +int main(int, char**) { + assert(test()); + static_assert(test()); + { - constexpr std::optional o1{4}; - constexpr std::optional o2 = std::move(o1); - static_assert(*o2 == 4, ""); + test_rt(); } return 0; 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..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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14 + // // constexpr optional(nullopt_t) noexcept; @@ -19,49 +20,56 @@ #include "test_macros.h" -using std::nullopt; -using std::nullopt_t; -using std::optional; - -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, ""); +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>); - constexpr Opt opt(nullopt); - static_assert(static_cast(opt) == false, ""); + constexpr std::optional opt(std::nullopt); + assert(!static_cast(opt)); - 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; } 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..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 @@ -68,13 +69,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 +80,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; } 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..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 @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// + // UNSUPPORTED: c++03, c++11, c++14 // @@ -27,32 +27,41 @@ class Z { Z(Z&&) { TEST_THROW(6); } }; -int main(int, char**) { +template +constexpr void test_rvalueT(U arg) { { - 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&&) {} - }; + const optional opt(arg); + assert(bool(opt)); + assert(*opt == T(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&&) {} - }; + 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&) {} + }; +} + +TEST_CONSTEXPR_CXX26 void test_throwing() { +#ifndef TEST_HAS_NO_EXCEPTIONS { - const int x = 42; - optional o(std::move(x)); - assert(*o == 42); + 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; T::reset(); @@ -62,6 +71,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, ""); @@ -72,6 +82,7 @@ int main(int, char**) { assert(static_cast(opt) == true); assert(opt.value().value == 3); } + { typedef TestTypes::TestType T; T::reset(); @@ -83,48 +94,49 @@ 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&) {} - }; + test_throwing(); } +} + +constexpr bool test() { + test_rvalueT(5); + test_rvalueT(3.0); + test_rvalueT(42); + { - 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&) {} - }; + using T = ConstexprTestTypes::TestType; + test_rvalueT(T(3)); } + { - 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, ""); + using T = ConstexprTestTypes::TestType; + test_rvalueT(3); + } - struct test_constexpr_ctor : public optional { - constexpr test_constexpr_ctor(T&&) {} - }; + { + using T = ExplicitConstexprTestTypes::TestType; + static_assert(!std::is_convertible>::value); + test_rvalueT(T(3)); } -#ifndef TEST_HAS_NO_EXCEPTIONS +#if TEST_STD_VER >= 26 && 0 { - try { - Z z(3); - optional opt(std::move(z)); - assert(false); - } catch (int i) { - assert(i == 6); - } + test_throwing(); } + #endif + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + { + test_rt(); + } + return 0; }