Skip to content

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

Open
wants to merge 1 commit into
base: release/21.x
Choose a base branch
from

Conversation

frederick-vs-ja
Copy link
Contributor

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.

…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
@frederick-vs-ja frederick-vs-ja requested a review from ldionne August 2, 2025 08:54
@frederick-vs-ja frederick-vs-ja requested a review from a team as a code owner August 2, 2025 08:54
@frederick-vs-ja frederick-vs-ja added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Aug 2, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 2, 2025

@llvm/pr-subscribers-libcxx

Author: A. Jiang (frederick-vs-ja)

Changes

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.


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:

  • (modified) libcxx/docs/FeatureTestMacroTable.rst (+1-1)
  • (modified) libcxx/docs/ReleaseNotes/21.rst (+2)
  • (modified) libcxx/docs/Status/Cxx23Papers.csv (+1-1)
  • (modified) libcxx/docs/Status/Cxx2cIssues.csv (+1)
  • (modified) libcxx/docs/Status/Cxx2cPapers.csv (+1-1)
  • (modified) libcxx/include/tuple (+105-28)
  • (modified) libcxx/include/version (+1-1)
  • (modified) libcxx/test/std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp (+5-11)
  • (modified) libcxx/test/std/language.support/support.limits/support.limits.general/optional.version.compile.pass.cpp (+5-11)
  • (modified) libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp (+5-11)
  • (modified) libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp (+5-11)
  • (modified) libcxx/test/std/language.support/support.limits/support.limits.general/variant.version.compile.pass.cpp (+5-11)
  • (modified) libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp (+5-11)
  • (modified) libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/eq.pass.cpp (+249-131)
  • (modified) libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/lt.pass.cpp (+294-175)
  • (modified) libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/size_incompatible_three_way.compile.pass.cpp (+17-2)
  • (modified) libcxx/test/std/utilities/tuple/tuple.tuple/tuple.rel/three_way.pass.cpp (+150-17)
  • (modified) libcxx/utils/generate_feature_test_macro_components.py (-2)
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]

Copy link
Contributor

@philnik777 philnik777 left a 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.

@frederick-vs-ja
Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants