From a7517fdb7493d8c57c836099bccacc51cba691c4 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Sun, 11 May 2025 01:48:15 +0300 Subject: [PATCH 01/13] [libc++] P2944R3: Constrained comparisions - optional and reference_wrapper Implements `variant`: https://wg21.link/P2944R3 Closes #136769 --- libcxx/include/variant | 31 +++++++++ .../variant/variant.relops/relops.pass.cpp | 43 ++++++++++++ libcxx/test/support/test_comparisons.h | 66 ++++++++++++++++++- 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/libcxx/include/variant b/libcxx/include/variant index bf611aec704ca..8dc3e9fb0f93b 100644 --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -242,6 +242,7 @@ namespace std { # include <__type_traits/is_assignable.h> # include <__type_traits/is_constructible.h> # include <__type_traits/is_convertible.h> +# include <__type_traits/is_core_convertible.h> # include <__type_traits/is_destructible.h> # include <__type_traits/is_nothrow_assignable.h> # include <__type_traits/is_nothrow_constructible.h> @@ -1453,6 +1454,11 @@ struct __convert_to_bool { }; template +# if _LIBCPP_STD_VER >= 26 + requires(requires(const _Types& __t) { + { __t == __t } -> __core_convertible_to + } && ...) +# endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { using __variant_detail::__visitation::__variant; if (__lhs.index() != __rhs.index()) @@ -1485,6 +1491,11 @@ operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { # endif // _LIBCPP_STD_VER >= 20 template +# if _LIBCPP_STD_VER >= 26 + requires(requires(const _Types& __t) { + { __t != __t } -> __core_convertible_to + } && ...) +# endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { using __variant_detail::__visitation::__variant; if (__lhs.index() != __rhs.index()) @@ -1495,6 +1506,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const variant<_Types...>& __lhs, } template +# if _LIBCPP_STD_VER >= 26 + requires(requires(const _Types& __t) { + { __t < __t } -> __core_convertible_to + } && ...) +# endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { using __variant_detail::__visitation::__variant; if (__rhs.valueless_by_exception()) @@ -1509,6 +1525,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const variant<_Types...>& __lhs, } template +# if _LIBCPP_STD_VER >= 26 + requires(requires(const _Types& __t) { + { __t > __t } -> __core_convertible_to + } && ...) +# endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { using __variant_detail::__visitation::__variant; if (__lhs.valueless_by_exception()) @@ -1523,6 +1544,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const variant<_Types...>& __lhs, } template +# if _LIBCPP_STD_VER >= 26 + requires(requires(const _Types& __t) { + { __t <= __t } -> __core_convertible_to + } && ...) +# endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { using __variant_detail::__visitation::__variant; if (__lhs.valueless_by_exception()) @@ -1537,6 +1563,11 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const variant<_Types...>& __lhs, } template +# if _LIBCPP_STD_VER >= 26 + requires(requires(const _Types& __t) { + { __t >= __t } -> __core_convertible_to + } && ...) +# endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { using __variant_detail::__visitation::__variant; if (__rhs.valueless_by_exception()) diff --git a/libcxx/test/std/utilities/variant/variant.relops/relops.pass.cpp b/libcxx/test/std/utilities/variant/variant.relops/relops.pass.cpp index c1a5b8e474a74..b8b2a41c888d1 100644 --- a/libcxx/test/std/utilities/variant/variant.relops/relops.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.relops/relops.pass.cpp @@ -39,8 +39,51 @@ #include #include +#include "test_comparisons.h" #include "test_macros.h" +#if TEST_STD_VER >= 26 + +// Test SFINAE. + +// == +static_assert(HasOperatorEqual>); +static_assert(HasOperatorEqual>); + +static_assert(!HasOperatorEqual>); + +// > +static_assert(HasOperatorGreaterThan>); +static_assert(HasOperatorGreaterThan>); + +static_assert(!HasOperatorGreaterThan>); + +// >= +static_assert(HasOperatorGreaterThanEqual>); +static_assert(HasOperatorGreaterThanEqual>); + +static_assert(!HasOperatorGreaterThanEqual>); + +// < +static_assert(HasOperatorLessThan>); +static_assert(HasOperatorLessThan>); + +static_assert(!HasOperatorLessThan>); + +// <= +static_assert(HasOperatorLessThanEqual>); +static_assert(HasOperatorLessThanEqual>); + +static_assert(!HasOperatorLessThanEqual>); + +// != +static_assert(HasOperatorNotEqual>); +static_assert(HasOperatorNotEqual>); + +static_assert(!HasOperatorNotEqual>); + +#endif + #ifndef TEST_HAS_NO_EXCEPTIONS struct MakeEmptyT { MakeEmptyT() = default; diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h index db6977a96a2fe..e37ab44828c70 100644 --- a/libcxx/test/support/test_comparisons.h +++ b/libcxx/test/support/test_comparisons.h @@ -268,6 +268,70 @@ struct PartialOrder { } }; -#endif +template +concept HasOperatorEqual = requires(T1 t1, T2 t2) { t1 == t2; }; + +template +concept HasOperatorGreaterThan = requires(T1 t1, T2 t2) { t1 > t2; }; + +template +concept HasOperatorGreaterThanEqual = requires(T1 t1, T2 t2) { t1 >= t2; }; +template +concept HasOperatorLessThan = requires(T1 t1, T2 t2) { t1 < t2; }; + +template +concept HasOperatorLessThanEqual = requires(T1 t1, T2 t2) { t1 <= t2; }; + +template +concept HasOperatorNotEqual = requires(T1 t1, T2 t2) { t1 != t2; }; + +template +concept HasOperatorSpaceship = requires(T1 t1, T2 t2) { t1 <=> t2; }; + +struct NonComparable {}; +static_assert(!std::equality_comparable); +static_assert(!HasOperatorEqual); +static_assert(!HasOperatorGreaterThan); +static_assert(!HasOperatorGreaterThanEqual); +static_assert(!HasOperatorLessThan); +static_assert(!HasOperatorLessThanEqual); +static_assert(!HasOperatorNotEqual); +static_assert(!HasOperatorSpaceship); + +class EqualityComparable { +public: + constexpr EqualityComparable(int value) : value_{value} {}; + + friend constexpr bool operator==(const EqualityComparable&, const EqualityComparable&) noexcept = default; + +private: + int value_; +}; +static_assert(std::equality_comparable); +static_assert(HasOperatorEqual); +static_assert(HasOperatorNotEqual); + +class ThreeWayComparable { +public: + constexpr ThreeWayComparable(int value) : value_{value} {}; + + friend constexpr bool operator==(const ThreeWayComparable&, const ThreeWayComparable&) noexcept = default; + friend constexpr std::strong_ordering + operator<=>(const ThreeWayComparable&, const ThreeWayComparable&) noexcept = default; + +private: + int value_; +}; +static_assert(std::equality_comparable); +static_assert(std::three_way_comparable); +static_assert(HasOperatorEqual); +static_assert(HasOperatorGreaterThan); +static_assert(HasOperatorGreaterThanEqual); +static_assert(HasOperatorLessThan); +static_assert(HasOperatorLessThanEqual); +static_assert(HasOperatorNotEqual); +static_assert(HasOperatorSpaceship); + +#endif // TEST_STD_VER >= 20 #endif // TEST_COMPARISONS_H From ab710f4b2c1850b81003531e8e7f8cd2396feb36 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Tue, 13 May 2025 10:58:13 +0300 Subject: [PATCH 02/13] Implement tuple --- libcxx/include/tuple | 24 +++++++++ libcxx/include/variant | 12 ++--- .../tuple/tuple.tuple/tuple.rel/eq.pass.cpp | 50 +++++++++++++++++-- .../size_incompatible_comparison.verify.cpp | 6 +++ 4 files changed, 82 insertions(+), 10 deletions(-) diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 8dd62ae624f5e..8327c337b7f47 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -229,6 +229,7 @@ template # include <__tuple/sfinae_helpers.h> # include <__tuple/tuple_element.h> # include <__tuple/tuple_indices.h> +// # include <__tuple/tuple_like.h> # include <__tuple/tuple_like_ext.h> # include <__tuple/tuple_size.h> # include <__tuple/tuple_types.h> @@ -1161,12 +1162,35 @@ struct __tuple_equal<0> { }; template +# if _LIBCPP_STD_VER >= 26 + requires(requires(const _Tp& __t, const _Up& __u) { + { __t == __u } -> __boolean_testable; + } && ...) && (sizeof...(_Tp) == sizeof...(_Up)) +# endif inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { +# if _LIBCPP_STD_VER < 26 static_assert(sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes"); +# endif return __tuple_equal()(__x, __y); } +// # if _LIBCPP_STD_VER >= 23 +// template +// # if _LIBCPP_STD_VER >= 26 +// requires((requires(const _Tp& __t, const _UTuple& __u) { +// { __t == __u } -> __boolean_testable; +// } && ...) && (sizeof...(_Tp) == tuple_size_v<_UTuple>)) +// # endif +// _LIBCPP_HIDE_FROM_ABI constexpr bool +// operator==(const tuple<_Tp...>& __t, const _UTuple& __u) { +// # if _LIBCPP_STD_VER < 26 +// static_assert(sizeof...(_Tp) == tuple_size_v<_UTuple>, "Can't compare a tuple and a tuple-like of different sizes"); +// # endif +// return __tuple_equal()(__t, __u); +// } +// # endif + # if _LIBCPP_STD_VER >= 20 // operator<=> diff --git a/libcxx/include/variant b/libcxx/include/variant index 8dc3e9fb0f93b..f33058b708528 100644 --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -1456,7 +1456,7 @@ struct __convert_to_bool { template # if _LIBCPP_STD_VER >= 26 requires(requires(const _Types& __t) { - { __t == __t } -> __core_convertible_to + { __t == __t } -> __core_convertible_to; } && ...) # endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { @@ -1493,7 +1493,7 @@ operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { template # if _LIBCPP_STD_VER >= 26 requires(requires(const _Types& __t) { - { __t != __t } -> __core_convertible_to + { __t != __t } -> __core_convertible_to; } && ...) # endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { @@ -1508,7 +1508,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const variant<_Types...>& __lhs, template # if _LIBCPP_STD_VER >= 26 requires(requires(const _Types& __t) { - { __t < __t } -> __core_convertible_to + { __t < __t } -> __core_convertible_to; } && ...) # endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { @@ -1527,7 +1527,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const variant<_Types...>& __lhs, template # if _LIBCPP_STD_VER >= 26 requires(requires(const _Types& __t) { - { __t > __t } -> __core_convertible_to + { __t > __t } -> __core_convertible_to; } && ...) # endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { @@ -1546,7 +1546,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const variant<_Types...>& __lhs, template # if _LIBCPP_STD_VER >= 26 requires(requires(const _Types& __t) { - { __t <= __t } -> __core_convertible_to + { __t <= __t } -> __core_convertible_to; } && ...) # endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { @@ -1565,7 +1565,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const variant<_Types...>& __lhs, template # if _LIBCPP_STD_VER >= 26 requires(requires(const _Types& __t) { - { __t >= __t } -> __core_convertible_to + { __t >= __t } -> __core_convertible_to; } && ...) # endif _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp index a8de656313d45..d18bd1f29783f 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp @@ -11,19 +11,61 @@ // template class tuple; // template -// bool -// operator==(const tuple& t, const tuple& u); +// constexpr bool operator==(const tuple&, const tuple&); // constexpr since C++14 + +// constexpr bool operator==(const tuple&, const UTuple&); +// template // Since C++23 // UNSUPPORTED: c++03 -#include -#include +#include #include +#include +#include "test_comparisons.h" #include "test_macros.h" +#if TEST_STD_VER >= 26 + +// Test SFINAE. + +// ==(const tuple<>&, const tuple<>&); + +static_assert(std::equality_comparable>); +static_assert(std::equality_comparable>); + +static_assert(!std::equality_comparable>); +static_assert(!std::equality_comparable>); +static_assert(!std::equality_comparable>); +static_assert(!std::equality_comparable_with, std::tuple>); +static_assert(!std::equality_comparable_with, std::tuple>); +// Size mismatch. +static_assert(!std::equality_comparable_with, std::tuple>); +static_assert(!std::equality_comparable_with, std::tuple>); + +// ==(const tuple<>&, const tuple-like&); + +// static_assert(std::equality_comparable_with, std::pair>); +// static_assert(std::equality_comparable_with, std::array>); + +// static_assert(!std::equality_comparable_with, std::pair>); +// static_assert(!std::equality_comparable_with, std::array>); +// // Size mismatch. +// static_assert(!std::equality_comparable_with, std::pair>); +// static_assert(!std::equality_comparable_with, std::array>); + +#endif + int main(int, char**) { + // { + // using T1 = std::tuple; + // using T2 = std::array; + // const T1 t1(1); + // const T2 t2{1}; + // assert(t1 == t2); + // assert(!(t1 != t2)); + // } { typedef std::tuple<> T1; typedef std::tuple<> T2; diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_comparison.verify.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_comparison.verify.cpp index 851f6fcd1fbac..a5dbb6b313e6a 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_comparison.verify.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_comparison.verify.cpp @@ -21,9 +21,15 @@ #include +#include "test_macros.h" + +#if TEST_STD_VER >= 26 +// expected-no-diagnostics +#else void f(std::tuple t1, std::tuple t2) { // We test only the core comparison operators and trust that the others // fall back on the same implementations prior to C++20. static_cast(t1 == t2); // expected-error@*:* {{}} static_cast(t1 < t2); // expected-error@*:* {{}} } +#endif From dd32d6c515281346347b6d9a4515671bebccc596 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Tue, 13 May 2025 11:00:25 +0300 Subject: [PATCH 03/13] Cleanup --- libcxx/include/tuple | 17 ------------ .../tuple/tuple.tuple/tuple.rel/eq.pass.cpp | 27 ++----------------- 2 files changed, 2 insertions(+), 42 deletions(-) diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 8327c337b7f47..35ea37a5ea5ed 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -229,7 +229,6 @@ template # include <__tuple/sfinae_helpers.h> # include <__tuple/tuple_element.h> # include <__tuple/tuple_indices.h> -// # include <__tuple/tuple_like.h> # include <__tuple/tuple_like_ext.h> # include <__tuple/tuple_size.h> # include <__tuple/tuple_types.h> @@ -1175,22 +1174,6 @@ operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { return __tuple_equal()(__x, __y); } -// # if _LIBCPP_STD_VER >= 23 -// template -// # if _LIBCPP_STD_VER >= 26 -// requires((requires(const _Tp& __t, const _UTuple& __u) { -// { __t == __u } -> __boolean_testable; -// } && ...) && (sizeof...(_Tp) == tuple_size_v<_UTuple>)) -// # endif -// _LIBCPP_HIDE_FROM_ABI constexpr bool -// operator==(const tuple<_Tp...>& __t, const _UTuple& __u) { -// # if _LIBCPP_STD_VER < 26 -// static_assert(sizeof...(_Tp) == tuple_size_v<_UTuple>, "Can't compare a tuple and a tuple-like of different sizes"); -// # endif -// return __tuple_equal()(__t, __u); -// } -// # endif - # if _LIBCPP_STD_VER >= 20 // operator<=> diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp index d18bd1f29783f..baca362f7783b 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp @@ -11,10 +11,8 @@ // template class tuple; // template -// constexpr bool operator==(const tuple&, const tuple&); // constexpr since C++14 - -// constexpr bool operator==(const tuple&, const UTuple&); -// template // Since C++23 +// bool +// operator==(const tuple& t, const tuple& u); // UNSUPPORTED: c++03 @@ -29,8 +27,6 @@ // Test SFINAE. -// ==(const tuple<>&, const tuple<>&); - static_assert(std::equality_comparable>); static_assert(std::equality_comparable>); @@ -43,29 +39,10 @@ static_assert(!std::equality_comparable_with, std::tup static_assert(!std::equality_comparable_with, std::tuple>); static_assert(!std::equality_comparable_with, std::tuple>); -// ==(const tuple<>&, const tuple-like&); - -// static_assert(std::equality_comparable_with, std::pair>); -// static_assert(std::equality_comparable_with, std::array>); - -// static_assert(!std::equality_comparable_with, std::pair>); -// static_assert(!std::equality_comparable_with, std::array>); -// // Size mismatch. -// static_assert(!std::equality_comparable_with, std::pair>); -// static_assert(!std::equality_comparable_with, std::array>); - #endif int main(int, char**) { - // { - // using T1 = std::tuple; - // using T2 = std::array; - // const T1 t1(1); - // const T2 t2{1}; - // assert(t1 == t2); - // assert(!(t1 != t2)); - // } { typedef std::tuple<> T1; typedef std::tuple<> T2; From 23ebfd7e95f3fc97df572da0583786779cf48a54 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Tue, 13 May 2025 11:15:40 +0300 Subject: [PATCH 04/13] `variant` more tests --- .../variant/variant.relops/relops.pass.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/libcxx/test/std/utilities/variant/variant.relops/relops.pass.cpp b/libcxx/test/std/utilities/variant/variant.relops/relops.pass.cpp index b8b2a41c888d1..2c00703662687 100644 --- a/libcxx/test/std/utilities/variant/variant.relops/relops.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.relops/relops.pass.cpp @@ -47,40 +47,46 @@ // Test SFINAE. // == -static_assert(HasOperatorEqual>); static_assert(HasOperatorEqual>); +static_assert(HasOperatorEqual>); static_assert(!HasOperatorEqual>); +static_assert(!HasOperatorEqual>); // > -static_assert(HasOperatorGreaterThan>); static_assert(HasOperatorGreaterThan>); +static_assert(HasOperatorGreaterThan>); static_assert(!HasOperatorGreaterThan>); +static_assert(!HasOperatorGreaterThan>); // >= -static_assert(HasOperatorGreaterThanEqual>); static_assert(HasOperatorGreaterThanEqual>); +static_assert(HasOperatorGreaterThanEqual>); static_assert(!HasOperatorGreaterThanEqual>); +static_assert(!HasOperatorGreaterThanEqual>); // < -static_assert(HasOperatorLessThan>); static_assert(HasOperatorLessThan>); +static_assert(HasOperatorLessThan>); static_assert(!HasOperatorLessThan>); +static_assert(!HasOperatorLessThan>); // <= -static_assert(HasOperatorLessThanEqual>); static_assert(HasOperatorLessThanEqual>); +static_assert(HasOperatorLessThanEqual>); static_assert(!HasOperatorLessThanEqual>); +static_assert(!HasOperatorLessThanEqual>); // != -static_assert(HasOperatorNotEqual>); static_assert(HasOperatorNotEqual>); +static_assert(HasOperatorNotEqual>); static_assert(!HasOperatorNotEqual>); +static_assert(!HasOperatorNotEqual>); #endif From f862580a83cee9b7a73eb3ab804d057322fcf484 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Thu, 5 Jun 2025 06:48:47 +0300 Subject: [PATCH 05/13] Added missing include --- libcxx/include/tuple | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 35ea37a5ea5ed..15c9a1d743636 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -213,6 +213,7 @@ template #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) # include <__cxx03/__config> #else +# include <__concepts/boolean_testable.h> # include <__compare/common_comparison_category.h> # include <__compare/ordering.h> # include <__compare/synth_three_way.h> From 8483790796bd64608a8945c4cf4334b27d04ce08 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Thu, 5 Jun 2025 06:52:56 +0300 Subject: [PATCH 06/13] Formatting --- .../std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp index baca362f7783b..779a89b163f04 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp @@ -36,8 +36,10 @@ static_assert(!std::equality_comparable, std::tuple>); static_assert(!std::equality_comparable_with, std::tuple>); // Size mismatch. -static_assert(!std::equality_comparable_with, std::tuple>); -static_assert(!std::equality_comparable_with, std::tuple>); +static_assert( + !std::equality_comparable_with, std::tuple>); +static_assert( + !std::equality_comparable_with, std::tuple>); #endif From 98b05c43238fc7b56eefa84476bba97603e3a106 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Thu, 5 Jun 2025 07:31:06 +0300 Subject: [PATCH 07/13] Fix --- libcxx/include/tuple | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/tuple b/libcxx/include/tuple index fdcf789be8373..c7580f1000df2 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -213,10 +213,10 @@ template #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) # include <__cxx03/__config> #else -# include <__concepts/boolean_testable.h> # include <__compare/common_comparison_category.h> # include <__compare/ordering.h> # include <__compare/synth_three_way.h> +# include <__concepts/boolean_testable.h> # include <__config> # include <__cstddef/size_t.h> # include <__fwd/array.h> From 2b671b5db60c776a75d12b4e80b1ddb3ffcf1d76 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Sun, 15 Jun 2025 08:18:16 +0300 Subject: [PATCH 08/13] Cleanup --- libcxx/test/support/test_comparisons.h | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h index c52d841916757..e37ab44828c70 100644 --- a/libcxx/test/support/test_comparisons.h +++ b/libcxx/test/support/test_comparisons.h @@ -271,29 +271,6 @@ struct PartialOrder { template concept HasOperatorEqual = requires(T1 t1, T2 t2) { t1 == t2; }; -template -concept HasOperatorSpaceship = requires(T1 t1, T2 t2) { t1 <=> t2; }; - -struct NonComparable {}; -static_assert(!std::equality_comparable); -static_assert(!HasOperatorEqual); -static_assert(!HasOperatorSpaceship); - -class EqualityComparable { -public: - constexpr EqualityComparable(int value) : value_{value} {}; - - friend constexpr bool operator==(const EqualityComparable&, const EqualityComparable&) noexcept = default; - -private: - int value_; -}; -static_assert(std::equality_comparable); -static_assert(HasOperatorEqual); - -template -concept HasOperatorEqual = requires(T1 t1, T2 t2) { t1 == t2; }; - template concept HasOperatorGreaterThan = requires(T1 t1, T2 t2) { t1 > t2; }; @@ -355,6 +332,6 @@ static_assert(HasOperatorLessThanEqual); static_assert(HasOperatorNotEqual); static_assert(HasOperatorSpaceship); -#endif // TEST_STD_VER >= 20 // TEST_STD_VER >= 20 +#endif // TEST_STD_VER >= 20 #endif // TEST_COMPARISONS_H From 3cb270b473c4e3a79bda9a502c82d41568d78e41 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Sun, 15 Jun 2025 09:31:35 +0300 Subject: [PATCH 09/13] Fix CI --- .../variant/variant.relops/relops_bool_conv.verify.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp b/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp index 64248171d1146..96ecb46883207 100644 --- a/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp +++ b/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp @@ -41,7 +41,9 @@ #include "test_macros.h" - +#if TEST_STD_VER >= 26 +// expected-no-diagnostics +#else struct MyBoolExplicit { bool value; constexpr explicit MyBoolExplicit(bool v) : value(v) {} @@ -71,7 +73,7 @@ inline constexpr MyBoolExplicit operator>=(const ComparesToMyBoolExplicit& LHS, } -int main(int, char**) { +void test() { using V = std::variant; V v1(42); V v2(101); @@ -83,6 +85,6 @@ int main(int, char**) { (void)(v1 <= v2); // expected-note {{here}} (void)(v1 > v2); // expected-note {{here}} (void)(v1 >= v2); // expected-note {{here}} - - return 0; } + +#endif From d1cfb12ff094cf4c9ca464a69f1b40aed4d8ab05 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Sun, 15 Jun 2025 09:55:13 +0300 Subject: [PATCH 10/13] Update libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp --- .../variant/variant.relops/relops_bool_conv.verify.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp b/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp index 96ecb46883207..3a1c21d6b705e 100644 --- a/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp +++ b/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp @@ -71,8 +71,6 @@ inline constexpr MyBoolExplicit operator>(const ComparesToMyBoolExplicit& LHS, c inline constexpr MyBoolExplicit operator>=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept { return MyBoolExplicit(LHS.value >= RHS.value); } - - void test() { using V = std::variant; V v1(42); From 3c9e9c3a1aba74e73150e9da401f1e61b340160f Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Sun, 15 Jun 2025 09:57:17 +0300 Subject: [PATCH 11/13] Fix formatting --- .../utilities/variant/variant.relops/relops_bool_conv.verify.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp b/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp index 3a1c21d6b705e..392a234e6a9b2 100644 --- a/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp +++ b/libcxx/test/std/utilities/variant/variant.relops/relops_bool_conv.verify.cpp @@ -71,6 +71,7 @@ inline constexpr MyBoolExplicit operator>(const ComparesToMyBoolExplicit& LHS, c inline constexpr MyBoolExplicit operator>=(const ComparesToMyBoolExplicit& LHS, const ComparesToMyBoolExplicit& RHS) noexcept { return MyBoolExplicit(LHS.value >= RHS.value); } + void test() { using V = std::variant; V v1(42); From df79b72c6fc046806802b9e477f9dc61a38d1b10 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Wed, 25 Jun 2025 00:57:16 +0300 Subject: [PATCH 12/13] Removed `tuple` --- libcxx/include/tuple | 8 ------ .../tuple/tuple.tuple/tuple.rel/eq.pass.cpp | 25 ++----------------- .../size_incompatible_comparison.verify.cpp | 6 ----- 3 files changed, 2 insertions(+), 37 deletions(-) diff --git a/libcxx/include/tuple b/libcxx/include/tuple index c7580f1000df2..6e7a430d219ea 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -216,7 +216,6 @@ template # include <__compare/common_comparison_category.h> # include <__compare/ordering.h> # include <__compare/synth_three_way.h> -# include <__concepts/boolean_testable.h> # include <__config> # include <__cstddef/size_t.h> # include <__fwd/array.h> @@ -1154,16 +1153,9 @@ struct __tuple_equal<0> { }; template -# if _LIBCPP_STD_VER >= 26 - requires(requires(const _Tp& __t, const _Up& __u) { - { __t == __u } -> __boolean_testable; - } && ...) && (sizeof...(_Tp) == sizeof...(_Up)) -# endif inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) { -# if _LIBCPP_STD_VER < 26 static_assert(sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes"); -# endif return __tuple_equal()(__x, __y); } diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp index 779a89b163f04..a8de656313d45 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp @@ -16,33 +16,12 @@ // UNSUPPORTED: c++03 -#include -#include #include +#include +#include -#include "test_comparisons.h" #include "test_macros.h" -#if TEST_STD_VER >= 26 - -// Test SFINAE. - -static_assert(std::equality_comparable>); -static_assert(std::equality_comparable>); - -static_assert(!std::equality_comparable>); -static_assert(!std::equality_comparable>); -static_assert(!std::equality_comparable>); -static_assert(!std::equality_comparable_with, std::tuple>); -static_assert(!std::equality_comparable_with, std::tuple>); -// Size mismatch. -static_assert( - !std::equality_comparable_with, std::tuple>); -static_assert( - !std::equality_comparable_with, std::tuple>); - -#endif - int main(int, char**) { { diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_comparison.verify.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_comparison.verify.cpp index a5dbb6b313e6a..851f6fcd1fbac 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_comparison.verify.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_comparison.verify.cpp @@ -21,15 +21,9 @@ #include -#include "test_macros.h" - -#if TEST_STD_VER >= 26 -// expected-no-diagnostics -#else void f(std::tuple t1, std::tuple t2) { // We test only the core comparison operators and trust that the others // fall back on the same implementations prior to C++20. static_cast(t1 == t2); // expected-error@*:* {{}} static_cast(t1 < t2); // expected-error@*:* {{}} } -#endif From e08025e583378140c3bfbed8090194aacd02de26 Mon Sep 17 00:00:00 2001 From: Hristo Hristov Date: Wed, 25 Jun 2025 00:59:24 +0300 Subject: [PATCH 13/13] Updated status pages --- libcxx/docs/Status/Cxx2cPapers.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv index 8a0417e120d75..4ad827c72fa54 100644 --- a/libcxx/docs/Status/Cxx2cPapers.csv +++ b/libcxx/docs/Status/Cxx2cPapers.csv @@ -59,7 +59,7 @@ "`P2248R8 `__","Enabling list-initialization for algorithms","2024-03 (Tokyo)","","","" "`P2810R4 `__","``is_debugger_present`` ``is_replaceable``","2024-03 (Tokyo)","","","" "`P1068R11 `__","Vector API for random number generation","2024-03 (Tokyo)","","","" -"`P2944R3 `__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","","The changes to ``optional``, ``tuple`` and ``variant`` are not yet implemented" +"`P2944R3 `__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","","The changes to ``optional`` and ``tuple`` are not yet implemented" "`P2642R6 `__","Padded ``mdspan`` layouts","2024-03 (Tokyo)","","","" "`P3029R1 `__","Better ``mdspan``'s CTAD","2024-03 (Tokyo)","|Complete|","19","" "","","","","",""