Skip to content

[libc++][concepts] P2404R3: Move-only types for equality_comparable_with, totally_ordered_with, and three_way_comparable_with #99420

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 17 commits into
base: main
Choose a base branch
from

Conversation

randomnetcat
Copy link
Contributor

@randomnetcat randomnetcat commented Jul 18, 2024

This should implement all of P2404R3's concept changes.

This would be my first contribution, so I apologize if I've done anything wrong here.

@randomnetcat randomnetcat requested a review from a team as a code owner July 18, 2024 02:54
Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jul 18, 2024
@llvmbot
Copy link
Member

llvmbot commented Jul 18, 2024

@llvm/pr-subscribers-libcxx

Author: Janet Cobb (randomnetcat)

Changes

This should implement all of P2404R3's concept changes.

This would be my first contribution, so I apologize if I've done anything wrong here.


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

11 Files Affected:

  • (modified) libcxx/docs/ReleaseNotes/19.rst (+1)
  • (modified) libcxx/docs/Status/Cxx23Papers.csv (+1-1)
  • (modified) libcxx/docs/Status/SpaceshipPapers.csv (+1-1)
  • (modified) libcxx/include/CMakeLists.txt (+1)
  • (modified) libcxx/include/__compare/three_way_comparable.h (+17)
  • (added) libcxx/include/__concepts/comparison_common_type.h (+39)
  • (modified) libcxx/include/__concepts/equality_comparable.h (+19)
  • (modified) libcxx/include/module.modulemap (+23-22)
  • (modified) libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp (+10)
  • (modified) libcxx/test/std/language.support/cmp/cmp.concept/three_way_comparable_with.compile.pass.cpp (+28)
  • (modified) libcxx/test/support/compare_types.h (+23)
diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index e6d8acb74aeb2..1699c97652488 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -55,6 +55,7 @@ Implemented Papers
 - P2231R1 - Missing ``constexpr`` in ``std::optional`` and ``std::variant``
 - P0019R8 - ``std::atomic_ref``
 - P2389R2 - Alias template ``dims`` for the ``extents`` of ``mdspan``
+- P2404R3 - Move-only types for ``equality_comparable_with``, ``totally_ordered_with``, and ``three_way_comparable_with``
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index 4f589cd938d7c..bc13e4d9ebfd3 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -67,7 +67,7 @@
 "`P2302R4 <https://wg21.link/P2302R4>`__","LWG","``std::ranges::contains``","July 2022","|Complete|","19.0","|ranges|"
 "`P2322R6 <https://wg21.link/P2322R6>`__","LWG","``ranges::fold``","July 2022","","","|ranges|"
 "`P2374R4 <https://wg21.link/P2374R4>`__","LWG","``views::cartesian_product``","July 2022","","","|ranges|"
-"`P2404R3 <https://wg21.link/P2404R3>`__","LWG","Move-only types for ``equality_comparable_with``, ``totally_ordered_with``, and ``three_way_comparable_with``","July 2022","",""
+"`P2404R3 <https://wg21.link/P2404R3>`__","LWG","Move-only types for ``equality_comparable_with``, ``totally_ordered_with``, and ``three_way_comparable_with``","July 2022","|Complete|","19.0"
 "`P2408R5 <https://wg21.link/P2408R5>`__","LWG","Ranges iterators as inputs to non-Ranges algorithms","July 2022","","","|ranges|"
 "`P2417R2 <https://wg21.link/P2417R2>`__","LWG","A more ``constexpr`` ``bitset``","July 2022","|Complete|","16.0"
 "`P2419R2 <https://wg21.link/P2419R2>`__","LWG","Clarify handling of encodings in localized formatting of chrono types","July 2022","",""
diff --git a/libcxx/docs/Status/SpaceshipPapers.csv b/libcxx/docs/Status/SpaceshipPapers.csv
index 39e1f968c1754..5fbf6a53b6db7 100644
--- a/libcxx/docs/Status/SpaceshipPapers.csv
+++ b/libcxx/docs/Status/SpaceshipPapers.csv
@@ -1,6 +1,6 @@
 "Number","Name","Status","First released version"
 `P1614R2 <https://wg21.link/P1614R2>`_,The Mothership has Landed,|In Progress|,
-`P2404R3 <https://wg21.link/P2404R3>`_,"Relaxing ``equality_comparable_with``'s, ``totally_ordered_with``'s, and ``three_way_comparable_with``'s common reference requirements to support move-only types",,
+`P2404R3 <https://wg21.link/P2404R3>`_,"Relaxing ``equality_comparable_with``'s, ``totally_ordered_with``'s, and ``three_way_comparable_with``'s common reference requirements to support move-only types","|Complete|","19.0"
 `LWG3330 <https://wg21.link/LWG3330>`_,Include ``<compare>`` from most library headers,"|Complete|","13.0"
 `LWG3347 <https://wg21.link/LWG3347>`_,"``std::pair<T, U>`` now requires ``T`` and ``U`` to be *less-than-comparable*",|Nothing To Do|,
 `LWG3350 <https://wg21.link/LWG3350>`_,Simplify return type of ``lexicographical_compare_three_way``,|Nothing To Do|,
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index cd64fe91449c2..e618847b1e27c 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -296,6 +296,7 @@ set(files
   __concepts/class_or_enum.h
   __concepts/common_reference_with.h
   __concepts/common_with.h
+  __concepts/comparison_common_type.h
   __concepts/constructible.h
   __concepts/convertible_to.h
   __concepts/copyable.h
diff --git a/libcxx/include/__compare/three_way_comparable.h b/libcxx/include/__compare/three_way_comparable.h
index 7a44ea9158a6f..3b14725be3309 100644
--- a/libcxx/include/__compare/three_way_comparable.h
+++ b/libcxx/include/__compare/three_way_comparable.h
@@ -12,6 +12,7 @@
 #include <__compare/common_comparison_category.h>
 #include <__compare/ordering.h>
 #include <__concepts/common_reference_with.h>
+#include <__concepts/comparison_common_type.h>
 #include <__concepts/equality_comparable.h>
 #include <__concepts/same_as.h>
 #include <__concepts/totally_ordered.h>
@@ -37,6 +38,20 @@ concept three_way_comparable =
       { __a <=> __b } -> __compares_as<_Cat>;
     };
 
+#  if _LIBCPP_STD_VER >= 23
+
+template <class _Tp, class _Up, class _cat = partial_ordering>
+concept three_way_comparable_with =
+    three_way_comparable<_Tp, _cat> && three_way_comparable<_Up, _cat> && __comparison_common_type_with<_Tp, _Up> &&
+    three_way_comparable<common_reference_t<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>>, _cat> &&
+    __weakly_equality_comparable_with<_Tp, _Up> && __partially_ordered_with<_Tp, _Up> &&
+    requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) {
+      { __t <=> __u } -> __compares_as<_cat>;
+      { __u <=> __t } -> __compares_as<_cat>;
+    };
+
+#  else
+
 template <class _Tp, class _Up, class _Cat = partial_ordering>
 concept three_way_comparable_with =
     three_way_comparable<_Tp, _Cat> && three_way_comparable<_Up, _Cat> &&
@@ -48,6 +63,8 @@ concept three_way_comparable_with =
       { __u <=> __t } -> __compares_as<_Cat>;
     };
 
+#  endif // _LIBCPP_STD_VER >= 23
+
 #endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__concepts/comparison_common_type.h b/libcxx/include/__concepts/comparison_common_type.h
new file mode 100644
index 0000000000000..a1f246d2a6dca
--- /dev/null
+++ b/libcxx/include/__concepts/comparison_common_type.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___CONCEPTS_COMPARISON_COMMON_TYPE_H
+#define _LIBCPP___CONCEPTS_COMPARISON_COMMON_TYPE_H
+
+#include "__concepts/convertible_to.h"
+#include "__concepts/same_as.h"
+#include "__config"
+#include "__type_traits/common_reference.h"
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+template <class _Tp, class _Up, class _C = common_reference_t<const _Tp&, const _Up&>>
+concept __comparison_common_type_with_impl =
+    same_as<common_reference_t<const _Tp&, const _Up&>, common_reference_t<const _Up&, const _Tp&>> && requires {
+      requires convertible_to<const _Tp&, const _C&> || convertible_to<_Tp, const _C&>;
+      requires convertible_to<const _Up&, const _C&> || convertible_to<_Up, const _C&>;
+    };
+
+template <class _Tp, class _Up>
+concept __comparison_common_type_with = __comparison_common_type_with_impl<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CONCEPTS_COMPARISON_COMMON_TYPE_H
diff --git a/libcxx/include/__concepts/equality_comparable.h b/libcxx/include/__concepts/equality_comparable.h
index 278fc76409289..1904b2e451a8d 100644
--- a/libcxx/include/__concepts/equality_comparable.h
+++ b/libcxx/include/__concepts/equality_comparable.h
@@ -11,6 +11,7 @@
 
 #include <__concepts/boolean_testable.h>
 #include <__concepts/common_reference_with.h>
+#include <__concepts/comparison_common_type.h>
 #include <__config>
 #include <__type_traits/common_reference.h>
 #include <__type_traits/make_const_lvalue_ref.h>
@@ -37,6 +38,22 @@ concept __weakly_equality_comparable_with =
 template <class _Tp>
 concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>;
 
+#  if _LIBCPP_STD_VER >= 23
+
+// clang-format off
+template <class _Tp, class _Up>
+concept equality_comparable_with =
+    equality_comparable<_Tp> && equality_comparable<_Up> &&
+    __comparison_common_type_with<_Tp, _Up> &&
+    equality_comparable<
+        common_reference_t<
+            __make_const_lvalue_ref<_Tp>,
+            __make_const_lvalue_ref<_Up>>> &&
+    __weakly_equality_comparable_with<_Tp, _Up>;
+// clang-format on
+
+#  else
+
 // clang-format off
 template <class _Tp, class _Up>
 concept equality_comparable_with =
@@ -49,6 +66,8 @@ concept equality_comparable_with =
     __weakly_equality_comparable_with<_Tp, _Up>;
 // clang-format on
 
+#  endif // _LIBCPP_STD_VER >= 23
+
 #endif // _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index f4aaa14c1c2ee..eabb32daf2c96 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1173,43 +1173,44 @@ module std_private_compare_weak_order                     [system] { header "__c
 
 module std_private_complex_complex_fwd            [system] { header "__fwd/complex.h" }
 
-module std_private_concepts_arithmetic            [system] { header "__concepts/arithmetic.h" }
-module std_private_concepts_assignable            [system] { header "__concepts/assignable.h" }
-module std_private_concepts_boolean_testable      [system] { header "__concepts/boolean_testable.h" }
-module std_private_concepts_class_or_enum         [system] { header "__concepts/class_or_enum.h" }
-module std_private_concepts_common_reference_with [system] { header "__concepts/common_reference_with.h" }
-module std_private_concepts_common_with           [system] { header "__concepts/common_with.h" }
-module std_private_concepts_constructible         [system] {
+module std_private_concepts_arithmetic              [system] { header "__concepts/arithmetic.h" }
+module std_private_concepts_assignable              [system] { header "__concepts/assignable.h" }
+module std_private_concepts_boolean_testable        [system] { header "__concepts/boolean_testable.h" }
+module std_private_concepts_class_or_enum           [system] { header "__concepts/class_or_enum.h" }
+module std_private_concepts_common_reference_with   [system] { header "__concepts/common_reference_with.h" }
+module std_private_concepts_common_with             [system] { header "__concepts/common_with.h" }
+module std_private_cooncepts_comparison_common_type [system] { header "__concepts/comparison_common_type.h" }
+module std_private_concepts_constructible           [system] {
   header "__concepts/constructible.h"
   export std_private_concepts_destructible
 }
-module std_private_concepts_convertible_to        [system] { header "__concepts/convertible_to.h" }
-module std_private_concepts_copyable              [system] { header "__concepts/copyable.h" }
-module std_private_concepts_derived_from          [system] { header "__concepts/derived_from.h" }
-module std_private_concepts_destructible          [system] {
+module std_private_concepts_convertible_to          [system] { header "__concepts/convertible_to.h" }
+module std_private_concepts_copyable                [system] { header "__concepts/copyable.h" }
+module std_private_concepts_derived_from            [system] { header "__concepts/derived_from.h" }
+module std_private_concepts_destructible            [system] {
   header "__concepts/destructible.h"
   export std_private_type_traits_is_nothrow_destructible
 }
-module std_private_concepts_different_from        [system] { header "__concepts/different_from.h" }
-module std_private_concepts_equality_comparable   [system] {
+module std_private_concepts_different_from          [system] { header "__concepts/different_from.h" }
+module std_private_concepts_equality_comparable     [system] {
   header "__concepts/equality_comparable.h"
   export std_private_type_traits_common_reference
 }
-module std_private_concepts_invocable             [system] { header "__concepts/invocable.h" }
-module std_private_concepts_movable               [system] {
+module std_private_concepts_invocable               [system] { header "__concepts/invocable.h" }
+module std_private_concepts_movable                 [system] {
   header "__concepts/movable.h"
   export std_private_type_traits_is_object
 }
-module std_private_concepts_predicate             [system] { header "__concepts/predicate.h" }
-module std_private_concepts_regular               [system] { header "__concepts/regular.h" }
-module std_private_concepts_relation              [system] { header "__concepts/relation.h" }
-module std_private_concepts_same_as               [system] {
+module std_private_concepts_predicate               [system] { header "__concepts/predicate.h" }
+module std_private_concepts_regular                 [system] { header "__concepts/regular.h" }
+module std_private_concepts_relation                [system] { header "__concepts/relation.h" }
+module std_private_concepts_same_as                 [system] {
   header "__concepts/same_as.h"
   export std_private_type_traits_is_same
 }
-module std_private_concepts_semiregular           [system] { header "__concepts/semiregular.h" }
-module std_private_concepts_swappable             [system] { header "__concepts/swappable.h" }
-module std_private_concepts_totally_ordered       [system] { header "__concepts/totally_ordered.h" }
+module std_private_concepts_semiregular             [system] { header "__concepts/semiregular.h" }
+module std_private_concepts_swappable               [system] { header "__concepts/swappable.h" }
+module std_private_concepts_totally_ordered         [system] { header "__concepts/totally_ordered.h" }
 
 module std_private_condition_variable_condition_variable [system] {
   header "__condition_variable/condition_variable.h"
diff --git a/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp
index e0edd1f332f81..45e3e88a10d14 100644
--- a/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp
@@ -1119,4 +1119,14 @@ static_assert(
     std::common_reference_with<one_way_ne const&, explicit_operators const&>);
 static_assert(
     !check_equality_comparable_with<one_way_ne, explicit_operators>());
+
+#if TEST_STD_VER >= 23
+static_assert(check_equality_comparable_with<move_only_equality_with_int, int>());
+static_assert(check_equality_comparable_with<std::unique_ptr<int>, std::nullptr_t>());
+#else
+static_assert(!check_equality_comparable_with<move_only_equality_with_int, int>());
+static_assert(!check_equality_comparable_with<std::unique_ptr<int>, std::nullptr_t>());
+#endif // TEST_STD_VER >= 23
+
+static_assert(!check_equality_comparable_with<immobile_comparable_with_int, int>());
 } // namespace types_fit_for_purpose
diff --git a/libcxx/test/std/language.support/cmp/cmp.concept/three_way_comparable_with.compile.pass.cpp b/libcxx/test/std/language.support/cmp/cmp.concept/three_way_comparable_with.compile.pass.cpp
index 50d9722aa29c0..2920240dddf55 100644
--- a/libcxx/test/std/language.support/cmp/cmp.concept/three_way_comparable_with.compile.pass.cpp
+++ b/libcxx/test/std/language.support/cmp/cmp.concept/three_way_comparable_with.compile.pass.cpp
@@ -14,6 +14,7 @@
 #include <compare>
 
 #include "compare_types.h"
+#include "test_macros.h"
 
 template <class T, class U = T, typename Cat = std::partial_ordering>
 constexpr bool check_three_way_comparable_with() {
@@ -223,4 +224,31 @@ struct SpaceshipNonConstArgument {
 };
 
 static_assert(!check_three_way_comparable_with<SpaceshipNonConstArgument>());
+
+struct MoveOnlyIntComparable {
+  MoveOnlyIntComparable(int) {}
+
+  MoveOnlyIntComparable(MoveOnlyIntComparable&&)            = default;
+  MoveOnlyIntComparable& operator=(MoveOnlyIntComparable&&) = default;
+
+  friend auto operator<=>(MoveOnlyIntComparable const&, MoveOnlyIntComparable const&) = default;
+};
+
+#if TEST_STD_VER >= 23
+static_assert(check_three_way_comparable_with<MoveOnlyIntComparable, int>());
+#else
+static_assert(!check_three_way_comparable_with<MoveOnlyIntComparable, int>());
+#endif // TEST_STD_VER >= 23
+
+struct ImmobileIntComparable {
+  ImmobileIntComparable(int) {}
+
+  ImmobileIntComparable(ImmobileIntComparable&&)            = delete;
+  ImmobileIntComparable& operator=(ImmobileIntComparable&&) = delete;
+
+  friend auto operator<=>(ImmobileIntComparable const&, ImmobileIntComparable const&) = default;
+};
+
+static_assert(!check_three_way_comparable_with<ImmobileIntComparable, int>());
+
 } // namespace user_defined
diff --git a/libcxx/test/support/compare_types.h b/libcxx/test/support/compare_types.h
index 8155f6221540c..eea219d033ae9 100644
--- a/libcxx/test/support/compare_types.h
+++ b/libcxx/test/support/compare_types.h
@@ -529,4 +529,27 @@ struct ForwardingTestObject {
   constexpr bool operator>=(const ForwardingTestObject&) const& { return false; }
 };
 
+struct move_only_equality_with_int {
+  move_only_equality_with_int(int);
+
+  move_only_equality_with_int(move_only_equality_with_int&&)            = default;
+  move_only_equality_with_int& operator=(move_only_equality_with_int&&) = default;
+
+  move_only_equality_with_int(move_only_equality_with_int const&)            = delete;
+  move_only_equality_with_int& operator=(move_only_equality_with_int const&) = delete;
+
+  friend bool operator==(move_only_equality_with_int const&, move_only_equality_with_int const&) = default;
+  friend bool operator==(move_only_equality_with_int const&, int);
+};
+
+struct immobile_comparable_with_int {
+  immobile_comparable_with_int(int);
+
+  immobile_comparable_with_int(immobile_comparable_with_int&&)            = delete;
+  immobile_comparable_with_int& operator=(immobile_comparable_with_int&&) = delete;
+
+  friend bool operator==(immobile_comparable_with_int const&, immobile_comparable_with_int const&) = default;
+  friend bool operator==(immobile_comparable_with_int const&, int);
+};
+
 #endif // TEST_SUPPORT_COMPARE_TYPES_H

@Zingam
Copy link
Contributor

Zingam commented Jul 18, 2024

The link to the paper in the description of the PR doesn't seem to be a valid one.

@randomnetcat
Copy link
Contributor Author

Fixed, sorry.

@Zingam
Copy link
Contributor

Zingam commented Jul 18, 2024

@randomnetcat Since I am not an approver I only skimmed over this patch. I hope it gets into LLVM19 release. Please make sure to fix the CI errors. There seem to be some affected tests.

Copy link
Contributor

@cjdb cjdb 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 working on this!

I'm inclined to suggest that we treat this as if it were a defect report, and backport this to C++20, so that we have a canonical definition of these concepts across standards. I think that will, in the long term, be more beneficial to users than having the concept change between standards.

@randomnetcat randomnetcat changed the title [libc++][spaceship] P2404R3: Move-only types for equality_comparable_with, totally_ordered_with, and three_way_comparable_with [libc++][concepts] P2404R3: Move-only types for equality_comparable_with, totally_ordered_with, and three_way_comparable_with Jul 18, 2024
@randomnetcat
Copy link
Contributor Author

I'm inclined to suggest that we treat this as if it were a defect report, and backport this to C++20, so that we have a canonical definition of these concepts across standards. I think that will, in the long term, be more beneficial to users than having the concept change between standards.

Addressed the review comments, but haven't done this. I'm not sure if you meant "please do this" or "this is something we could consider".

@cjdb
Copy link
Contributor

cjdb commented Jul 18, 2024

I'm inclined to suggest that we treat this as if it were a defect report, and backport this to C++20, so that we have a canonical definition of these concepts across standards. I think that will, in the long term, be more beneficial to users than having the concept change between standards.

I'm not sure if you meant "please do this" or "this is something we could consider".

Definitely the latter. We typically don't make unilateral decisions, and doing it for something like this would definitely be not okay.

@frederick-vs-ja
Copy link
Contributor

I'm inclined to suggest that we treat this as if it were a defect report, and backport this to C++20, so that we have a canonical definition of these concepts across standards. I think that will, in the long term, be more beneficial to users than having the concept change between standards.

Currently, only MSVC STL has implemented this paper and leaves it C++23-only. I'd like to ask what do implementors/maintainers of other implementations think "as usual". (I'm personally neutral.)

CC @JMazurkiewicz @StephanTLavavej @jwakely

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 your first contribution! This looks pretty good, but I have a few comments.

In terms of applying this as a DR, I would be OK with doing that if the other implementers also do it.

@StephanTLavavej
Copy link
Member

I would be fine with changing MSVC's STL to align with making this a de facto DR, if libstdc++ is also on-board. This doesn't take any new publicly-visible names, and it seems like a highly compatible change (Annex C lists a theoretical break but you have to be looking pretty hard for it).

@randomnetcat
Copy link
Contributor Author

So... should I be looking at implementing this without the version check?

@ldionne
Copy link
Member

ldionne commented Jul 31, 2024

@jwakely Do you think it makes sense to apply P2404R3 as a DR or do you see this as a real feature?

libc++ and MSVC STL are fine with a DR.

@cjdb
Copy link
Contributor

cjdb commented Jul 31, 2024

So... should I be looking at implementing this without the version check?

Let's hold off until we get an answer from Jonathan, but assuming libstdc++ consents, yes please.

@ldionne
Copy link
Member

ldionne commented Nov 28, 2024

@randomnetcat Let's rebase this onto main and implement it as a DR (i.e. no version check). When you're ready, please ping me and I'll commit some time to it so we can get it across the finish line.

@randomnetcat randomnetcat force-pushed the p2404 branch 2 times, most recently from 5c6b58e to f67c4de Compare June 9, 2025 15:07
Copy link

github-actions bot commented Jun 9, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@randomnetcat
Copy link
Contributor Author

Well, I've (6 months later, oops) finally gotten around to implementing this as a DR instead. @ldionne, you requested a ping for this.

Sorry for the delay.

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.

7 participants