-
Notifications
You must be signed in to change notification settings - Fork 14.6k
release/21.x: [libc++] Implement comparison operators for tuple
added in C++23 (#148799)
#151808
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/21.x
Are you sure you want to change the base?
Conversation
…lvm#148799) And constrain the new `operator==` since C++26. This patch implements parts of P2165R4, P2944R3, and a possibly improved resolution of LWG3882. Currently, libstdc++ and MSVC STL constrain the new overloads in the same way. Also set feature-test macro `__cpp_lib_constrained_equality` and add related release note, as P2944R3 will completed with this patch. Fixes llvm#136765 Fixes llvm#136770 Fixes llvm#105424
@llvm/pr-subscribers-libcxx Author: A. Jiang (frederick-vs-ja) ChangesAnd constrain the new This patch implements parts of P2165R4, P2944R3, and a possibly improved resolution of LWG3882. Currently, libstdc++ and MSVC STL constrain the new overloads in the same way. Also set feature-test macro Manually backport 4a509f8. Patch is 55.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/151808.diff 18 Files Affected:
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 61805726a4ff0..a36848ebd24b4 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -432,7 +432,7 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_constexpr_queue`` ``202502L``
---------------------------------------------------------- -----------------
- ``__cpp_lib_constrained_equality`` *unimplemented*
+ ``__cpp_lib_constrained_equality`` ``202411L``
---------------------------------------------------------- -----------------
``__cpp_lib_copyable_function`` *unimplemented*
---------------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index 74bfa97fd21c2..91123ffa3e34b 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -53,6 +53,8 @@ Implemented Papers
- P2711R1: Making multi-param constructors of ``views`` ``explicit`` (`Github <https://github.com/llvm/llvm-project/issues/105252>`__)
- P2770R0: Stashing stashing ``iterators`` for proper flattening (`Github <https://github.com/llvm/llvm-project/issues/105250>`__)
- P2655R3: ``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type (`Github <https://github.com/llvm/llvm-project/issues/105260>`__)
+- P2944R3: Comparisons for ``reference_wrapper`` (`Github <https://github.com/llvm/llvm-project/issues/105424>`__)
+- P3379R0: Constrain ``std::expected equality`` operators (`Github <https://github.com/llvm/llvm-project/issues/118135>`__)
Improvements and New Features
-----------------------------
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index e4fa07d82289d..f1d8e9a2bd09c 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -60,7 +60,7 @@
"`P1642R11 <https://wg21.link/P1642R11>`__","Freestanding ``[utilities]``, ``[ranges]``, and ``[iterators]``","2022-07 (Virtual)","","",""
"`P1899R3 <https://wg21.link/P1899R3>`__","``stride_view``","2022-07 (Virtual)","","",""
"`P2093R14 <https://wg21.link/P2093R14>`__","Formatted output","2022-07 (Virtual)","|Complete|","18",""
-"`P2165R4 <https://wg21.link/P2165R4>`__","Compatibility between ``tuple``, ``pair`` and ``tuple-like`` objects","2022-07 (Virtual)","|Partial|","","Only the part for ``zip_view`` is implemented."
+"`P2165R4 <https://wg21.link/P2165R4>`__","Compatibility between ``tuple``, ``pair`` and ``tuple-like`` objects","2022-07 (Virtual)","|Partial|","","Changes of ``tuple``, ``adjacent_view``, and ``cartesian_product_view`` are not yet implemented."
"`P2278R4 <https://wg21.link/P2278R4>`__","``cbegin`` should always return a constant iterator","2022-07 (Virtual)","","",""
"`P2286R8 <https://wg21.link/P2286R8>`__","Formatting Ranges","2022-07 (Virtual)","|Complete|","16",""
"`P2291R3 <https://wg21.link/P2291R3>`__","Add Constexpr Modifiers to Functions ``to_chars`` and ``from_chars`` for Integral Types in ``<charconv>`` Header","2022-07 (Virtual)","|Complete|","16",""
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index c8a3aa95b7480..70ef723cd2b02 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -149,4 +149,5 @@
"`LWG3343 <https://wg21.link/LWG3343>`__","Ordering of calls to ``unlock()`` and ``notify_all()`` in Effects element of ``notify_all_at_thread_exit()`` should be reversed","Not Adopted Yet","|Complete|","16",""
"`LWG4139 <https://wg21.link/LWG4139>`__","§[time.zone.leap] recursive constraint in <=>","Not Adopted Yet","|Complete|","20",""
"`LWG3456 <https://wg21.link/LWG3456>`__","Pattern used by std::from_chars is underspecified (option B)","Not Adopted Yet","|Complete|","20",""
+"`LWG3882 <https://wg21.link/LWG3882>`__","``tuple`` relational operators have confused friendships","Not Adopted Yet","|Complete|","21","The comparsion operators are constrained harder than the proposed resolution. libstdc++ and MSVC STL do the same."
"","","","","",""
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 98efd3e46ebee..e41b6a10e10f4 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -59,7 +59,7 @@
"`P2248R8 <https://wg21.link/P2248R8>`__","Enabling list-initialization for algorithms","2024-03 (Tokyo)","","",""
"`P2810R4 <https://wg21.link/P2810R4>`__","``is_debugger_present`` ``is_replaceable``","2024-03 (Tokyo)","","",""
"`P1068R11 <https://wg21.link/P1068R11>`__","Vector API for random number generation","2024-03 (Tokyo)","","",""
-"`P2944R3 <https://wg21.link/P2944R3>`__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Partial|","","The changes to ``tuple``'s equality overload from P2165R4 are not yet implemented."
+"`P2944R3 <https://wg21.link/P2944R3>`__","Comparisons for ``reference_wrapper``","2024-03 (Tokyo)","|Complete|","21",""
"`P2642R6 <https://wg21.link/P2642R6>`__","Padded ``mdspan`` layouts","2024-03 (Tokyo)","","",""
"`P3029R1 <https://wg21.link/P3029R1>`__","Better ``mdspan``'s CTAD","2024-03 (Tokyo)","|Complete|","19",""
"","","","","",""
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 75021f0ea51f6..b7d4edab65e31 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -106,6 +106,11 @@ public:
void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20
constexpr void swap(const tuple&) const noexcept(see-below); // C++23
+
+ template<tuple-like UTuple>
+ friend constexpr bool operator==(const tuple& t, const UTuple& u); // C++23
+ template<tuple-like UTuple>
+ friend constexpr auto operator<=>(const tuple& t, const UTuple& u); // C++23
};
@@ -220,6 +225,7 @@ template <class... Types>
# include <__config>
# include <__cstddef/size_t.h>
# include <__fwd/array.h>
+# include <__fwd/get.h>
# include <__fwd/pair.h>
# include <__fwd/tuple.h>
# include <__memory/allocator_arg_t.h>
@@ -230,6 +236,7 @@ template <class... Types>
# 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>
@@ -288,6 +295,68 @@ _LIBCPP_BEGIN_NAMESPACE_STD
# ifndef _LIBCPP_CXX03_LANG
+template <size_t _Ip, class _Tp, class _Up>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __tuple_compare_equal(const _Tp& __x, const _Up& __y) {
+ if constexpr (_Ip == 0)
+ return true;
+ else
+ return std::__tuple_compare_equal<_Ip - 1>(__x, __y) && std::get<_Ip - 1>(__x) == std::get<_Ip - 1>(__y);
+}
+
+# if _LIBCPP_STD_VER >= 26
+template <class _Tp, class _Up, class _IndexSeq = make_index_sequence<tuple_size_v<_Tp>>>
+inline constexpr bool __can_tuple_compare_equal = false;
+
+// TODO(LLVM 22): Remove `tuple_size_v<_Tp> == tuple_size_v<_Up>` here once once LLVM-20 support ends
+// because the resolution of CWG2369 landed in LLVM-21.
+template <class _Tp, class _Up, size_t... _Is>
+ requires(tuple_size_v<_Tp> == tuple_size_v<_Up>)
+inline constexpr bool __can_tuple_compare_equal<_Tp, _Up, index_sequence<_Is...>> =
+ __all<requires(const tuple_element_t<_Is, _Tp>& __t, const tuple_element_t<_Is, _Up>& __u) {
+ { __t == __u } -> __boolean_testable;
+ }...>::value;
+# endif // _LIBCPP_STD_VER >= 26
+
+# if _LIBCPP_STD_VER >= 20
+template <class _Ret, class _Tp, class _Up, size_t... _Is>
+_LIBCPP_HIDE_FROM_ABI constexpr _Ret __tuple_compare_three_way(const _Tp& __x, const _Up& __y, index_sequence<_Is...>) {
+ _Ret __result = strong_ordering::equal;
+ static_cast<void>(
+ ((__result = std::__synth_three_way(std::get<_Is>(__x), std::get<_Is>(__y)), __result != 0) || ...));
+ return __result;
+}
+# endif // _LIBCPP_STD_VER >= 20
+
+# if _LIBCPP_STD_VER >= 23
+template <class>
+inline constexpr bool __is_tuple_v = false;
+
+template <class... _Tp>
+inline constexpr bool __is_tuple_v<tuple<_Tp...>> = true;
+
+template <class _Tp>
+concept __tuple_like_no_tuple = __tuple_like<_Tp> && !__is_tuple_v<_Tp>;
+
+template <class _Tp, class _Up, class _IndexSeq>
+struct __tuple_common_comparison_category_impl {};
+
+// TODO(LLVM 22): Remove `tuple_size_v<_Tp> == tuple_size_v<_Up>` here once once LLVM-20 support ends
+// because the resolution of CWG2369 landed in LLVM-21.
+template <class _Tp, class _Up, size_t... _Is>
+ requires(tuple_size_v<_Tp> == tuple_size_v<_Up>) && requires {
+ typename common_comparison_category_t<
+ __synth_three_way_result<tuple_element_t<_Is, _Tp>, tuple_element_t<_Is, _Up>>...>;
+ }
+struct __tuple_common_comparison_category_impl<_Tp, _Up, index_sequence<_Is...>> {
+ using type _LIBCPP_NODEBUG =
+ common_comparison_category_t<__synth_three_way_result<tuple_element_t<_Is, _Tp>, tuple_element_t<_Is, _Up>>...>;
+};
+
+template <__tuple_like _Tp, __tuple_like _Up>
+using __tuple_common_comparison_category _LIBCPP_NODEBUG =
+ __tuple_common_comparison_category_impl<_Tp, _Up, make_index_sequence<tuple_size_v<_Tp>>>::type;
+# endif // _LIBCPP_STD_VER >= 23
+
// __tuple_leaf
template <size_t _Ip, class _Hp, bool = is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value >
@@ -997,7 +1066,24 @@ public:
noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) {
__base_.swap(__t.__base_);
}
-# endif // _LIBCPP_STD_VER >= 23
+
+ template <__tuple_like_no_tuple _UTuple>
+# if _LIBCPP_STD_VER >= 26
+ requires __can_tuple_compare_equal<tuple, _UTuple> && (sizeof...(_Tp) == tuple_size_v<_UTuple>)
+# endif // _LIBCPP_STD_VER >= 26
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const tuple& __x, const _UTuple& __y) {
+ static_assert(sizeof...(_Tp) == tuple_size_v<_UTuple>, "Can't compare tuple-like values of different sizes");
+ return std::__tuple_compare_equal<sizeof...(_Tp)>(__x, __y);
+ }
+
+ template <__tuple_like_no_tuple _UTuple>
+ requires(sizeof...(_Tp) == tuple_size_v<_UTuple>)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr __tuple_common_comparison_category<tuple, _UTuple>
+ operator<=>(const tuple& __x, const _UTuple& __y) {
+ return std::__tuple_compare_three_way<__tuple_common_comparison_category<tuple, _UTuple>>(
+ __x, __y, index_sequence_for<_Tp...>{});
+ }
+# endif // _LIBCPP_STD_VER >= 23
};
_LIBCPP_DIAGNOSTIC_PUSH
@@ -1019,6 +1105,21 @@ public:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(tuple&) _NOEXCEPT {}
# if _LIBCPP_STD_VER >= 23
_LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {}
+
+ template <__tuple_like_no_tuple _UTuple>
+# if _LIBCPP_STD_VER >= 26
+ requires(tuple_size_v<_UTuple> == 0)
+# endif // _LIBCPP_STD_VER >= 26
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const tuple&, const _UTuple&) {
+ static_assert(tuple_size_v<_UTuple> == 0, "Can't compare tuple-like values of different sizes");
+ return true;
+ }
+
+ template <__tuple_like_no_tuple _UTuple>
+ requires(tuple_size_v<_UTuple> == 0)
+ _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering operator<=>(const tuple&, const _UTuple&) {
+ return strong_ordering::equal;
+ }
# endif
};
_LIBCPP_DIAGNOSTIC_POP
@@ -1137,22 +1238,6 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&&...> forwa
return tuple<_Tp&&...>(std::forward<_Tp>(__t)...);
}
-template <size_t _Ip>
-struct __tuple_equal {
- template <class _Tp, class _Up>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __x, const _Up& __y) {
- return __tuple_equal<_Ip - 1>()(__x, __y) && std::get<_Ip - 1>(__x) == std::get<_Ip - 1>(__y);
- }
-};
-
-template <>
-struct __tuple_equal<0> {
- template <class _Tp, class _Up>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp&, const _Up&) {
- return true;
- }
-};
-
template <class... _Tp, class... _Up>
# if _LIBCPP_STD_VER >= 26
requires(__all<requires(const _Tp& __t, const _Up& __u) {
@@ -1162,27 +1247,19 @@ template <class... _Tp, class... _Up>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) {
static_assert(sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
- return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
+ return std::__tuple_compare_equal<sizeof...(_Tp)>(__x, __y);
}
# if _LIBCPP_STD_VER >= 20
// operator<=>
-template <class... _Tp, class... _Up, size_t... _Is>
-_LIBCPP_HIDE_FROM_ABI constexpr auto
-__tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) {
- common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal;
- static_cast<void>(
- ((__result = std::__synth_three_way(std::get<_Is>(__x), std::get<_Is>(__y)), __result != 0) || ...));
- return __result;
-}
-
template <class... _Tp, class... _Up>
requires(sizeof...(_Tp) == sizeof...(_Up))
_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>
operator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) {
- return std::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
+ return std::__tuple_compare_three_way<common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>>(
+ __x, __y, index_sequence_for<_Tp...>{});
}
# else // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/version b/libcxx/include/version
index d98049bd57046..aae9277a7dfc6 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -555,7 +555,7 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_constexpr_new 202406L
# endif
# define __cpp_lib_constexpr_queue 202502L
-// # define __cpp_lib_constrained_equality 202411L
+# define __cpp_lib_constrained_equality 202411L
// # define __cpp_lib_copyable_function 202306L
// # define __cpp_lib_debugging 202311L
// # define __cpp_lib_default_template_type_for_algorithm_values 202403L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp
index 9c7a84f145dde..2115da20af369 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp
@@ -93,17 +93,11 @@
#elif TEST_STD_VER > 23
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_constrained_equality
-# error "__cpp_lib_constrained_equality should be defined in c++26"
-# endif
-# if __cpp_lib_constrained_equality != 202411L
-# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
-# endif
-# else
-# ifdef __cpp_lib_constrained_equality
-# error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_constrained_equality
+# error "__cpp_lib_constrained_equality should be defined in c++26"
+# endif
+# if __cpp_lib_constrained_equality != 202411L
+# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# ifndef __cpp_lib_expected
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp
index 32685972d6019..6e1ab17821074 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp
@@ -119,17 +119,11 @@
#elif TEST_STD_VER > 23
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_constrained_equality
-# error "__cpp_lib_constrained_equality should be defined in c++26"
-# endif
-# if __cpp_lib_constrained_equality != 202411L
-# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
-# endif
-# else
-# ifdef __cpp_lib_constrained_equality
-# error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_constrained_equality
+# error "__cpp_lib_constrained_equality should be defined in c++26"
+# endif
+# if __cpp_lib_constrained_equality != 202411L
+# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp
index b583edfc43ad0..df30228802e8e 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp
@@ -270,17 +270,11 @@
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++26"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_constrained_equality
-# error "__cpp_lib_constrained_equality should be defined in c++26"
-# endif
-# if __cpp_lib_constrained_equality != 202411L
-# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
-# endif
-# else
-# ifdef __cpp_lib_constrained_equality
-# error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_constrained_equality
+# error "__cpp_lib_constrained_equality should be defined in c++26"
+# endif
+# if __cpp_lib_constrained_equality != 202411L
+# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# ifndef __cpp_lib_make_from_tuple
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
index 7dd3478576331..c11c3682ae9a3 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
@@ -401,17 +401,11 @@
# error "__cpp_lib_constexpr_utility should have the value 201811L in c++26"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_constrained_equality
-# error "__cpp_lib_constrained_equality should be defined in c++26"
-# endif
-# if __cpp_lib_constrained_equality != 202411L
-# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
-# endif
-# else
-# ifdef __cpp_lib_constrained_equality
-# error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_constrained_equality
+# error "__cpp_lib_constrained_equality should be defined in c++26"
+# endif
+# if __cpp_lib_constrained_equality != 202411L
+# error "__cpp_lib_constrained_equality should have the value 202411L in c++26"
# endif
# ifndef __cpp_lib_exchange_function
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/variant.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/variant.version.compile.pass.cpp
index 4a7b9f7431a81..30537dc97090b 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/variant.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/sup...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we want to back-port this? This looks to me very much like feature work.
See also #148799 (review). I'm inclined to backport this, but I will be also fine if backport is eventually rejected. |
And constrain the new
operator==
since C++26.This patch implements parts of P2165R4, P2944R3, and a possibly improved resolution of LWG3882. Currently, libstdc++ and MSVC STL constrain the new overloads in the same way.
Also set feature-test macro
__cpp_lib_constrained_equality
and add related release note, as P2944R3 will completed with this patch.Manually backport 4a509f8.