Skip to content

[libc++] P2167R3: Improved Proposed Wording for LWG 2114 #109102

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

Merged
merged 1 commit into from
Oct 2, 2024

Conversation

frederick-vs-ja
Copy link
Contributor

@frederick-vs-ja frederick-vs-ja commented Sep 18, 2024

Only the [cmp.alg] part (for comparison_meow_fallback CPOs) in the paper required changes. Other parts merely fixed preconditions of some standard library functions.

I strongly feel that P2167R3 should be a DR despite that it is not a DR officially: CPOs -> C++20; remain parts -> C++98/11 (except that boolean-testable should be transformed into the original BooleanTestable requirements in the old resolution of LWG2114).

Note that P2167R3 damaged the resolution of LWG3465: the type of F < E was left underconstrained. I've tried to submit an LWG issue for this, which is now LWG4157.

Drive-by change:

Closes #105241.

@frederick-vs-ja frederick-vs-ja requested a review from a team as a code owner September 18, 2024 08:57
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Sep 18, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2024

@llvm/pr-subscribers-libcxx

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

Changes

Only the [cmp.alg] part (for comparison_meow_fallback CPOs) in the paper required changes. Other parts merely fixed preconditions of some standard library functions.

I strongly feel that P2167R3 should be a DR despite that it is not a DR officially: CPOs -> C++20; remain parts -> C++98/11 (except that boolean-testable should be transformed into the original BooleanTestable requirements in the old resolution of LWG2114).

Note that P2167R3 damaged the resolution of LWG3465: the type of F &lt; E was left underconstrained. I've tried to submit an LWG issue for this.

Drive-by change:

  • enable some test coverages in compare_strong_order_fallback.pass.cpp when TEST_LONG_DOUBLE_IS_DOUBLE, following up #106742

Closes #105241.


Full diff: https://github.com/llvm/llvm-project/pull/109102.diff

7 Files Affected:

  • (modified) libcxx/docs/Status/Cxx23Papers.csv (+1-1)
  • (modified) libcxx/include/__compare/compare_partial_order_fallback.h (+10-12)
  • (modified) libcxx/include/__compare/compare_strong_order_fallback.h (+8-10)
  • (modified) libcxx/include/__compare/compare_weak_order_fallback.h (+6-7)
  • (modified) libcxx/test/std/language.support/cmp/cmp.alg/compare_partial_order_fallback.pass.cpp (+53)
  • (modified) libcxx/test/std/language.support/cmp/cmp.alg/compare_strong_order_fallback.pass.cpp (+58-2)
  • (modified) libcxx/test/std/language.support/cmp/cmp.alg/compare_weak_order_fallback.pass.cpp (+52)
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index 2c8a91d8401b53..21c4bfe7e4a244 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -96,7 +96,7 @@
 "`P1202R5 <https://wg21.link/P1202R5>`__","Asymmetric Fences","2022-11 (Kona)","","",""
 "`P1264R2 <https://wg21.link/P1264R2>`__","Revising the wording of ``stream`` input operations","2022-11 (Kona)","|Complete|","9.0",""
 "`P1478R8 <https://wg21.link/P1478R8>`__","``Byte-wise`` ``atomic`` ``memcpy``","2022-11 (Kona)","","",""
-"`P2167R3 <https://wg21.link/P2167R3>`__","Improved Proposed Wording for LWG 2114","2022-11 (Kona)","","",""
+"`P2167R3 <https://wg21.link/P2167R3>`__","Improved Proposed Wording for LWG 2114","2022-11 (Kona)","|Complete|","20.0","The `[cmp.alg] <https://eel.is/c++draft/cmp.alg>`__ part is implemented as a DR against C++20. MSVC STL does the same. Other parts are Nothing To Do."
 "`P2396R1 <https://wg21.link/P2396R1>`__","Concurrency TS 2 fixes ","2022-11 (Kona)","","",""
 "`P2505R5 <https://wg21.link/P2505R5>`__","Monadic Functions for ``std::expected``","2022-11 (Kona)","|Complete|","17.0",""
 "`P2539R4 <https://wg21.link/P2539R4>`__","Should the output of ``std::print`` to a terminal be synchronized with the underlying stream?","2022-11 (Kona)","|Complete|","18.0",""
diff --git a/libcxx/include/__compare/compare_partial_order_fallback.h b/libcxx/include/__compare/compare_partial_order_fallback.h
index e0efa3ccb88db7..fbbd3c3d4ba259 100644
--- a/libcxx/include/__compare/compare_partial_order_fallback.h
+++ b/libcxx/include/__compare/compare_partial_order_fallback.h
@@ -11,6 +11,7 @@
 
 #include <__compare/ordering.h>
 #include <__compare/partial_order.h>
+#include <__concepts/boolean_testable.h>
 #include <__config>
 #include <__type_traits/decay.h>
 #include <__type_traits/is_same.h>
@@ -37,18 +38,15 @@ struct __fn {
   }
 
   template <class _Tp, class _Up>
-    requires is_same_v<decay_t<_Tp>, decay_t<_Up>>
-  _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept(
-      std::forward<_Tp>(__t) == std::forward<_Up>(__u)  ? partial_ordering::equivalent
-      : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less
-      : std::forward<_Up>(__u) < std::forward<_Tp>(__t)
-          ? partial_ordering::greater
-          : partial_ordering::unordered))
-      -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u)  ? partial_ordering::equivalent
-                  : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less
-                  : std::forward<_Up>(__u) < std::forward<_Tp>(__t)
-                      ? partial_ordering::greater
-                      : partial_ordering::unordered) {
+    requires is_same_v<decay_t<_Tp>, decay_t<_Up>> &&
+             __boolean_testable<decltype(std::declval<_Tp>() == std::declval<_Up>())> &&
+             __boolean_testable<decltype(std::declval<_Tp>() < std::declval<_Up>())> &&
+             __boolean_testable<decltype(std::declval<_Up>() < std::declval<_Tp>())>
+  _LIBCPP_HIDE_FROM_ABI static constexpr partial_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(
+      noexcept(std::forward<_Tp>(__t) == std::forward<_Up>(__u)  ? partial_ordering::equivalent
+               : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less
+               : std::forward<_Up>(__u) < std::forward<_Tp>(__t) ? partial_ordering::greater
+                                                                 : partial_ordering::unordered)) {
     return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent
          : std::forward<_Tp>(__t) < std::forward<_Up>(__u)  ? partial_ordering::less
          : std::forward<_Up>(__u) < std::forward<_Tp>(__t)
diff --git a/libcxx/include/__compare/compare_strong_order_fallback.h b/libcxx/include/__compare/compare_strong_order_fallback.h
index a94d517ed30fce..4a4155cf9aacc1 100644
--- a/libcxx/include/__compare/compare_strong_order_fallback.h
+++ b/libcxx/include/__compare/compare_strong_order_fallback.h
@@ -11,6 +11,7 @@
 
 #include <__compare/ordering.h>
 #include <__compare/strong_order.h>
+#include <__concepts/boolean_testable.h>
 #include <__config>
 #include <__type_traits/decay.h>
 #include <__type_traits/is_same.h>
@@ -37,16 +38,13 @@ struct __fn {
   }
 
   template <class _Tp, class _Up>
-    requires is_same_v<decay_t<_Tp>, decay_t<_Up>>
-  _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept(
-      std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal
-      : std::forward<_Tp>(__t) < std::forward<_Up>(__u)
-          ? strong_ordering::less
-          : strong_ordering::greater))
-      -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal
-                  : std::forward<_Tp>(__t) < std::forward<_Up>(__u)
-                      ? strong_ordering::less
-                      : strong_ordering::greater) {
+    requires is_same_v<decay_t<_Tp>, decay_t<_Up>> &&
+             __boolean_testable<decltype(std::declval<_Tp>() == std::declval<_Up>())> &&
+             __boolean_testable<decltype(std::declval<_Tp>() < std::declval<_Up>())>
+  _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(
+      noexcept(std::forward<_Tp>(__t) == std::forward<_Up>(__u)  ? strong_ordering::equal
+               : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? strong_ordering::less
+                                                                 : strong_ordering::greater)) {
     return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal
          : std::forward<_Tp>(__t) < std::forward<_Up>(__u)
              ? strong_ordering::less
diff --git a/libcxx/include/__compare/compare_weak_order_fallback.h b/libcxx/include/__compare/compare_weak_order_fallback.h
index 062b7b582cd7eb..48c6dab7ca3769 100644
--- a/libcxx/include/__compare/compare_weak_order_fallback.h
+++ b/libcxx/include/__compare/compare_weak_order_fallback.h
@@ -11,6 +11,7 @@
 
 #include <__compare/ordering.h>
 #include <__compare/weak_order.h>
+#include <__concepts/boolean_testable.h>
 #include <__config>
 #include <__type_traits/decay.h>
 #include <__type_traits/is_same.h>
@@ -37,16 +38,14 @@ struct __fn {
   }
 
   template <class _Tp, class _Up>
-    requires is_same_v<decay_t<_Tp>, decay_t<_Up>>
-  _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept(
+    requires is_same_v<decay_t<_Tp>, decay_t<_Up>> &&
+             __boolean_testable<decltype(std::declval<_Tp>() == std::declval<_Up>())> &&
+             __boolean_testable<decltype(std::declval<_Tp>() < std::declval<_Up>())>
+  _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept(
       std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent
       : std::forward<_Tp>(__t) < std::forward<_Up>(__u)
           ? weak_ordering::less
-          : weak_ordering::greater))
-      -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent
-                  : std::forward<_Tp>(__t) < std::forward<_Up>(__u)
-                      ? weak_ordering::less
-                      : weak_ordering::greater) {
+          : weak_ordering::greater)) {
     return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent
          : std::forward<_Tp>(__t) < std::forward<_Up>(__u)
              ? weak_ordering::less
diff --git a/libcxx/test/std/language.support/cmp/cmp.alg/compare_partial_order_fallback.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.alg/compare_partial_order_fallback.pass.cpp
index a057a34136e0f5..f3fdd2ecb04ced 100644
--- a/libcxx/test/std/language.support/cmp/cmp.alg/compare_partial_order_fallback.pass.cpp
+++ b/libcxx/test/std/language.support/cmp/cmp.alg/compare_partial_order_fallback.pass.cpp
@@ -267,6 +267,44 @@ namespace N2 {
         friend bool operator<(const VC2&, VC2&);
         friend bool operator<(VC2&, const VC2&);
     };
+
+    enum class comparison_result_kind : bool {
+      convertible_bool,
+      boolean_testable,
+    };
+
+    template <comparison_result_kind K>
+    struct comparison_result {
+      bool value;
+
+      constexpr operator bool() const noexcept { return value; }
+
+      constexpr auto operator!() const noexcept {
+        if constexpr (K == comparison_result_kind::boolean_testable) {
+          return comparison_result{!value};
+        }
+      }
+    };
+
+    template <comparison_result_kind EqKind, comparison_result_kind LeKind>
+    struct boolean_tested_type {
+      friend constexpr comparison_result<EqKind> operator==(boolean_tested_type, boolean_tested_type) noexcept {
+        return comparison_result<EqKind>{true};
+      }
+
+      friend constexpr comparison_result<LeKind> operator<(boolean_tested_type, boolean_tested_type) noexcept {
+        return comparison_result<LeKind>{false};
+      }
+    };
+
+    using test_only_convertible =
+        boolean_tested_type<comparison_result_kind::convertible_bool, comparison_result_kind::convertible_bool>;
+    using test_eq_boolean_testable =
+        boolean_tested_type<comparison_result_kind::boolean_testable, comparison_result_kind::convertible_bool>;
+    using test_le_boolean_testable =
+        boolean_tested_type<comparison_result_kind::convertible_bool, comparison_result_kind::boolean_testable>;
+    using test_boolean_testable =
+        boolean_tested_type<comparison_result_kind::boolean_testable, comparison_result_kind::boolean_testable>;
 }
 
 constexpr bool test_2()
@@ -306,6 +344,21 @@ constexpr bool test_2()
         assert( has_partial_order(cvc, vc));
         assert(!has_partial_order(vc, cvc));
     }
+    {
+      // P2167R3 as modified by the intent of LWG3465:
+      //   All of decltype(e == f), decltype(e < f), and decltype(f < e) need to be well-formed and boolean-testable.
+      N2::test_only_convertible tc;
+      N2::test_eq_boolean_testable teq;
+      N2::test_le_boolean_testable tle;
+      N2::test_boolean_testable tbt;
+
+      assert(!has_partial_order(tc, tc));
+      assert(!has_partial_order(teq, teq));
+      assert(!has_partial_order(tle, tle));
+      assert(has_partial_order(tbt, tbt));
+
+      assert(std::compare_partial_order_fallback(tbt, tbt) == std::partial_ordering::equivalent);
+    }
     return true;
 }
 
diff --git a/libcxx/test/std/language.support/cmp/cmp.alg/compare_strong_order_fallback.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.alg/compare_strong_order_fallback.pass.cpp
index 2ad05cb1ec6dd3..e1e7bc37b1d799 100644
--- a/libcxx/test/std/language.support/cmp/cmp.alg/compare_strong_order_fallback.pass.cpp
+++ b/libcxx/test/std/language.support/cmp/cmp.alg/compare_strong_order_fallback.pass.cpp
@@ -473,6 +473,44 @@ namespace N2 {
         friend bool operator<(const VC2&, VC2&);
         friend bool operator<(VC2&, const VC2&);
     };
+
+    enum class comparison_result_kind : bool {
+      convertible_bool,
+      boolean_testable,
+    };
+
+    template <comparison_result_kind K>
+    struct comparison_result {
+      bool value;
+
+      constexpr operator bool() const noexcept { return value; }
+
+      constexpr auto operator!() const noexcept {
+        if constexpr (K == comparison_result_kind::boolean_testable) {
+          return comparison_result{!value};
+        }
+      }
+    };
+
+    template <comparison_result_kind EqKind, comparison_result_kind LeKind>
+    struct boolean_tested_type {
+      friend constexpr comparison_result<EqKind> operator==(boolean_tested_type, boolean_tested_type) noexcept {
+        return comparison_result<EqKind>{true};
+      }
+
+      friend constexpr comparison_result<LeKind> operator<(boolean_tested_type, boolean_tested_type) noexcept {
+        return comparison_result<LeKind>{false};
+      }
+    };
+
+    using test_only_convertible =
+        boolean_tested_type<comparison_result_kind::convertible_bool, comparison_result_kind::convertible_bool>;
+    using test_eq_boolean_testable =
+        boolean_tested_type<comparison_result_kind::boolean_testable, comparison_result_kind::convertible_bool>;
+    using test_le_boolean_testable =
+        boolean_tested_type<comparison_result_kind::convertible_bool, comparison_result_kind::boolean_testable>;
+    using test_boolean_testable =
+        boolean_tested_type<comparison_result_kind::boolean_testable, comparison_result_kind::boolean_testable>;
 }
 
 constexpr bool test_2()
@@ -506,6 +544,20 @@ constexpr bool test_2()
         assert( has_strong_order(cvc, vc));
         assert(!has_strong_order(vc, cvc));
     }
+    {
+      // P2167R3: Both decltype(e == f) and decltype(e < f) need to be well-formed and boolean-testable.
+      N2::test_only_convertible tc;
+      N2::test_eq_boolean_testable teq;
+      N2::test_le_boolean_testable tle;
+      N2::test_boolean_testable tbt;
+
+      assert(!has_strong_order(tc, tc));
+      assert(!has_strong_order(teq, teq));
+      assert(!has_strong_order(tle, tle));
+      assert(has_strong_order(tbt, tbt));
+
+      assert(std::compare_strong_order_fallback(tbt, tbt) == std::strong_ordering::equal);
+    }
     return true;
 }
 
@@ -515,13 +567,17 @@ int main(int, char**)
     test_1_2();
     test_1_3<float>();
     test_1_3<double>();
-    // test_1_3<long double>();  // UNIMPLEMENTED
+#ifdef TEST_LONG_DOUBLE_IS_DOUBLE
+    test_1_3<long double>(); // UNIMPLEMENTED when long double is a distinct type
+#endif
     test_1_4();
     test_2();
 
     static_assert(test_1_3<float>());
     static_assert(test_1_3<double>());
-    // static_assert(test_1_3<long double>());  // UNIMPLEMENTED
+#ifdef TEST_LONG_DOUBLE_IS_DOUBLE
+    static_assert(test_1_3<long double>()); // UNIMPLEMENTED when long double is a distinct type
+#endif
     static_assert(test_1_4());
     static_assert(test_2());
 
diff --git a/libcxx/test/std/language.support/cmp/cmp.alg/compare_weak_order_fallback.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.alg/compare_weak_order_fallback.pass.cpp
index 65674b4006fc89..07b5fcd0a6d178 100644
--- a/libcxx/test/std/language.support/cmp/cmp.alg/compare_weak_order_fallback.pass.cpp
+++ b/libcxx/test/std/language.support/cmp/cmp.alg/compare_weak_order_fallback.pass.cpp
@@ -520,6 +520,44 @@ namespace N2 {
         friend bool operator<(const VC2&, VC2&);
         friend bool operator<(VC2&, const VC2&);
     };
+
+    enum class comparison_result_kind : bool {
+      convertible_bool,
+      boolean_testable,
+    };
+
+    template <comparison_result_kind K>
+    struct comparison_result {
+      bool value;
+
+      constexpr operator bool() const noexcept { return value; }
+
+      constexpr auto operator!() const noexcept {
+        if constexpr (K == comparison_result_kind::boolean_testable) {
+          return comparison_result{!value};
+        }
+      }
+    };
+
+    template <comparison_result_kind EqKind, comparison_result_kind LeKind>
+    struct boolean_tested_type {
+      friend constexpr comparison_result<EqKind> operator==(boolean_tested_type, boolean_tested_type) noexcept {
+        return comparison_result<EqKind>{true};
+      }
+
+      friend constexpr comparison_result<LeKind> operator<(boolean_tested_type, boolean_tested_type) noexcept {
+        return comparison_result<LeKind>{false};
+      }
+    };
+
+    using test_only_convertible =
+        boolean_tested_type<comparison_result_kind::convertible_bool, comparison_result_kind::convertible_bool>;
+    using test_eq_boolean_testable =
+        boolean_tested_type<comparison_result_kind::boolean_testable, comparison_result_kind::convertible_bool>;
+    using test_le_boolean_testable =
+        boolean_tested_type<comparison_result_kind::convertible_bool, comparison_result_kind::boolean_testable>;
+    using test_boolean_testable =
+        boolean_tested_type<comparison_result_kind::boolean_testable, comparison_result_kind::boolean_testable>;
 }
 
 constexpr bool test_2()
@@ -553,6 +591,20 @@ constexpr bool test_2()
         assert( has_weak_order(cvc, vc));
         assert(!has_weak_order(vc, cvc));
     }
+    {
+      // P2167R3: Both decltype(e == f) and decltype(e < f) need to be well-formed and boolean-testable.
+      N2::test_only_convertible tc;
+      N2::test_eq_boolean_testable teq;
+      N2::test_le_boolean_testable tle;
+      N2::test_boolean_testable tbt;
+
+      assert(!has_weak_order(tc, tc));
+      assert(!has_weak_order(teq, teq));
+      assert(!has_weak_order(tle, tle));
+      assert(has_weak_order(tbt, tbt));
+
+      assert(std::compare_weak_order_fallback(tbt, tbt) == std::weak_ordering::equivalent);
+    }
     return true;
 }
 

@frederick-vs-ja frederick-vs-ja force-pushed the p2167r3 branch 2 times, most recently from dac24da to 8e12487 Compare September 19, 2024 07:52
Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the patch! I have a few questions but I think I'm fine with everything in the patch, once the questions have been answered.

I strongly feel that P2167R3 should be a DR despite that it is not a DR officially: CPOs -> C++20; remain parts -> C++98/11 (except that boolean-testable should be transformed into the original BooleanTestable requirements in the old resolution of LWG2114).

I didn't see any changes related to CPOs in the paper (which I only skimmed). Did I miss something?

Note that P2167R3 damaged the resolution of LWG3465: the type of F < E was left underconstrained. I've tried to submit an LWG issue for this.

I don't think I see test changes reflecting that. Did we have proper coverage for LWG3465?

@frederick-vs-ja
Copy link
Contributor Author

I didn't see any changes related to CPOs in the paper (which I only skimmed). Did I miss something?

The paper changed compare_{strong,weak,partial}_order_fallback CPOs in

  1. Modify 17.12.6 [cmp.alg] as indicated: [...]

I don't think I see test changes reflecting that. Did we have proper coverage for LWG3465?

Yes, the test coverage for LWG3465 is here - although it didn't cover convertibility to bool.

{
// LWG3465: (cvc < vc) is well-formed, (vc < cvc) is not. Substitution failure.
N2::VC1 vc;
const N2::VC1 cvc;
assert(!has_partial_order(cvc, vc));
assert(!has_partial_order(vc, cvc));
}

I think it's OK to just keep the existing test cases above. Perhaps the test coverage should be extended...

Only the [cmp.alg] part (for `comparison_meow_fallback` CPOs) in the paper required changes. Other parts merely fixed preconditions of some standard library functions.

I strongly feel that P2167R3 should be a DR despite that it is not a DR officially: CPOs -> C++20; remain parts -> C++98/11 (except that _`boolean-testable`_ should be transformed into the original BooleanTestable requirements in the old resolution of LWG2114).

Note that P2167R3 damaged the resolution of LWG3465: the type of `F < E` was left underconstrained. I've tried to submit an LWG issue for this.

Drive-by change:
- enable some test coverages in `compare_strong_order_fallback.pass.cpp` when `TEST_LONG_DOUBLE_IS_DOUBLE`
@frederick-vs-ja frederick-vs-ja merged commit 557f7e1 into llvm:main Oct 2, 2024
66 checks passed
@frederick-vs-ja frederick-vs-ja deleted the p2167r3 branch October 2, 2024 17:09
Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Oct 3, 2024
Only the [cmp.alg] part (for `comparison_meow_fallback` CPOs) in the
paper required changes. Other parts merely fixed preconditions of some
standard library functions.

I strongly feel that P2167R3 should be a DR despite that it is not a DR
officially: CPOs -> C++20; remain parts -> C++98/11 (except that
_`boolean-testable`_ should be transformed into the original
_BooleanTestable_ requirements in the old resolution of LWG2114).

Note that P2167R3 damaged the resolution of LWG3465: the type of `F < E`
was left underconstrained. I've tried to submit an LWG issue for this,
which is now LWG4157.

Drive-by change:
- enable some test coverages in `compare_strong_order_fallback.pass.cpp`
when `TEST_LONG_DOUBLE_IS_DOUBLE`, following up llvm#106742

Closes llvm#105241.
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.

P2167R3: Improved Proposed Wording for LWG 2114
3 participants