[libcxx-commits] [libcxx] [libc++][iterator][ranges] P2997R1: Removing the common reference requirement from the indirectly invocable concepts (PR #98817)

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 16 10:14:46 PDT 2024


https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/98817

>From 6357b31038eb2ea986b21f83f62c90ad28d6dd42 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 14 Jul 2024 17:59:53 +0300
Subject: [PATCH 1/9] [libc++][iterator] P2997R1: Removing the common reference
 requirement from the indirectly invocable concepts

Implements: https://wg21.link/P2997R1
---
 libcxx/include/__iterator/concepts.h              | 15 ++++++---------
 .../indirect_binary_predicate.compile.pass.cpp    |  4 ++--
 ...indirect_equivalence_relation.compile.pass.cpp |  4 ++--
 .../indirect_strict_weak_order.compile.pass.cpp   |  4 ++--
 .../indirect_unary_predicate.compile.pass.cpp     |  4 ++--
 ...ectly_regular_unary_invocable.compile.pass.cpp |  4 ++--
 .../indirectly_unary_invocable.compile.pass.cpp   |  4 ++--
 7 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h
index afb7b821a99ce..0a4878308d55f 100644
--- a/libcxx/include/__iterator/concepts.h
+++ b/libcxx/include/__iterator/concepts.h
@@ -177,19 +177,19 @@ concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip
 template <class _Fp, class _It>
 concept indirectly_unary_invocable =
     indirectly_readable<_It> && copy_constructible<_Fp> && invocable<_Fp&, iter_value_t<_It>&> &&
-    invocable<_Fp&, iter_reference_t<_It>> && invocable<_Fp&, iter_common_reference_t<_It>> &&
+    invocable<_Fp&, iter_reference_t<_It>> &&
     common_reference_with< invoke_result_t<_Fp&, iter_value_t<_It>&>, invoke_result_t<_Fp&, iter_reference_t<_It>>>;
 
 template <class _Fp, class _It>
 concept indirectly_regular_unary_invocable =
     indirectly_readable<_It> && copy_constructible<_Fp> && regular_invocable<_Fp&, iter_value_t<_It>&> &&
-    regular_invocable<_Fp&, iter_reference_t<_It>> && regular_invocable<_Fp&, iter_common_reference_t<_It>> &&
+    regular_invocable<_Fp&, iter_reference_t<_It>> &&
     common_reference_with< invoke_result_t<_Fp&, iter_value_t<_It>&>, invoke_result_t<_Fp&, iter_reference_t<_It>>>;
 
 template <class _Fp, class _It>
 concept indirect_unary_predicate =
     indirectly_readable<_It> && copy_constructible<_Fp> && predicate<_Fp&, iter_value_t<_It>&> &&
-    predicate<_Fp&, iter_reference_t<_It>> && predicate<_Fp&, iter_common_reference_t<_It>>;
+    predicate<_Fp&, iter_reference_t<_It>>;
 
 template <class _Fp, class _It1, class _It2>
 concept indirect_binary_predicate =
@@ -197,8 +197,7 @@ concept indirect_binary_predicate =
     predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
     predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
     predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
-    predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
-    predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
+    predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>>;
 
 template <class _Fp, class _It1, class _It2 = _It1>
 concept indirect_equivalence_relation =
@@ -206,8 +205,7 @@ concept indirect_equivalence_relation =
     equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
     equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
     equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
-    equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
-    equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
+    equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>>;
 
 template <class _Fp, class _It1, class _It2 = _It1>
 concept indirect_strict_weak_order =
@@ -215,8 +213,7 @@ concept indirect_strict_weak_order =
     strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
     strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
     strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
-    strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> &&
-    strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
+    strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>>;
 
 template <class _Fp, class... _Its>
   requires(indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...>
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
index e04c508852820..5058cbb06dabe 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
@@ -76,12 +76,12 @@ struct BadPredicate5 {
 };
 static_assert(!std::indirect_binary_predicate<BadPredicate5, It1, It2>);
 
-// Should fail when the predicate can't be called with (iter_common_reference_t, iter_common_reference_t)
+// P2997R1: Should succeed when the predicate can't be called with (iter_common_reference_t, iter_common_reference_t)
 struct BadPredicate6 {
     template <class T, class U> bool operator()(T const&, U const&) const;
     bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
 };
-static_assert(!std::indirect_binary_predicate<BadPredicate6, It1, It2>);
+static_assert(std::indirect_binary_predicate<BadPredicate6, It1, It2>);
 
 // Test ADL-proofing (P2538R1)
 #if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
index 56f52f28ff6fe..20206db6c6eaf 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
@@ -91,12 +91,12 @@ struct BadRelation5 {
 };
 static_assert(!std::indirect_equivalence_relation<BadRelation5, It1, It2>);
 
-// Should fail when the function can't be called with (iter_common_reference_t, iter_common_reference_t)
+// P2997R1: Should succeed when the function can't be called with (iter_common_reference_t, iter_common_reference_t)
 struct BadRelation6 {
     template <class T, class U> bool operator()(T const&, U const&) const;
     bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
 };
-static_assert(!std::indirect_equivalence_relation<BadRelation6, It1, It2>);
+static_assert(std::indirect_equivalence_relation<BadRelation6, It1, It2>);
 
 // Test ADL-proofing (P2538R1)
 #if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
index f36431c89f288..32bc3aef10057 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
@@ -91,12 +91,12 @@ struct BadOrder5 {
 };
 static_assert(!std::indirect_strict_weak_order<BadOrder5, It1, It2>);
 
-// Should fail when the function can't be called with (iter_common_reference_t, iter_common_reference_t)
+// P2997R1: Should succeed when the function can't be called with (iter_common_reference_t, iter_common_reference_t)
 struct BadOrder6 {
     template <class T, class U> bool operator()(T const&, U const&) const;
     bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
 };
-static_assert(!std::indirect_strict_weak_order<BadOrder6, It1, It2>);
+static_assert(std::indirect_strict_weak_order<BadOrder6, It1, It2>);
 
 // Test ADL-proofing (P2538R1)
 #if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
index 4551113af82e8..32b63d27b4eb1 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
@@ -57,12 +57,12 @@ struct BadPredicate3 {
 };
 static_assert(!std::indirect_unary_predicate<BadPredicate3, It>);
 
-// Should fail when the predicate can't be called with std::iter_common_reference_t<It>
+// P2997R1: Should succeed when the predicate can't be called with std::iter_common_reference_t<It>
 struct BadPredicate4 {
     template <class T> bool operator()(T const&) const;
     bool operator()(std::iter_common_reference_t<It>) const = delete;
 };
-static_assert(!std::indirect_unary_predicate<BadPredicate4, It>);
+static_assert(std::indirect_unary_predicate<BadPredicate4, It>);
 
 // Test ADL-proofing (P2538R1)
 #if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
index 9e0c3c99dee98..69b3909806ac8 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
@@ -56,12 +56,12 @@ struct BadInvocable3 {
 };
 static_assert(!std::indirectly_regular_unary_invocable<BadInvocable3, It>);
 
-// Should fail when the invocable can't be called with (iter_common_reference_t)
+// P2997R1: Should succeed when the invocable can't be called with (iter_common_reference_t)
 struct BadInvocable4 {
     template <class T> R1 operator()(T const&) const;
     R1 operator()(std::iter_common_reference_t<It>) const = delete;
 };
-static_assert(!std::indirectly_regular_unary_invocable<BadInvocable4, It>);
+static_assert(std::indirectly_regular_unary_invocable<BadInvocable4, It>);
 
 // Should fail when the invocable doesn't have a common reference between its return types
 struct BadInvocable5 {
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
index fc955eb88585a..06f9c72ec1053 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
@@ -56,12 +56,12 @@ struct BadInvocable3 {
 };
 static_assert(!std::indirectly_unary_invocable<BadInvocable3, It>);
 
-// Should fail when the invocable can't be called with (iter_common_reference_t)
+// P2997R1: Should succeed when the invocable can't be called with (iter_common_reference_t)
 struct BadInvocable4 {
     template <class T> R1 operator()(T const&) const;
     R1 operator()(std::iter_common_reference_t<It>) const = delete;
 };
-static_assert(!std::indirectly_unary_invocable<BadInvocable4, It>);
+static_assert(std::indirectly_unary_invocable<BadInvocable4, It>);
 
 // Should fail when the invocable doesn't have a common reference between its return types
 struct BadInvocable5 {

>From 246850a33cb5b14915e227a57b900179da9ec8f9 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 14 Jul 2024 18:30:34 +0300
Subject: [PATCH 2/9] Run generator scripts

---
 libcxx/docs/FeatureTestMacroTable.rst                        | 2 ++
 libcxx/include/version                                       | 5 ++++-
 .../algorithm.version.compile.pass.cpp                       | 5 +++--
 .../functional.version.compile.pass.cpp                      | 5 +++--
 .../support.limits.general/iterator.version.compile.pass.cpp | 5 +++--
 .../support.limits.general/memory.version.compile.pass.cpp   | 5 +++--
 .../support.limits.general/ranges.version.compile.pass.cpp   | 5 +++--
 .../support.limits.general/version.version.compile.pass.cpp  | 5 +++--
 libcxx/utils/generate_feature_test_macro_components.py       | 2 +-
 9 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 7cd20acc6ff4a..82cfa76b744b7 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -452,6 +452,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_philox_engine``                                *unimplemented*
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_ranges``                                       ``202406L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_ranges_concat``                                *unimplemented*
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_ratio``                                        ``202306L``
diff --git a/libcxx/include/version b/libcxx/include/version
index 1f66bce40df8a..0c5cec87b7b01 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -181,8 +181,9 @@ __cpp_lib_philox_engine                                 202406L <random>
 __cpp_lib_polymorphic_allocator                         201902L <memory_resource>
 __cpp_lib_print                                         202207L <ostream> <print>
 __cpp_lib_quoted_string_io                              201304L <iomanip>
-__cpp_lib_ranges                                        202207L <algorithm> <functional> <iterator>
+__cpp_lib_ranges                                        202406L <algorithm> <functional> <iterator>
                                                                 <memory> <ranges>
+                                                        202207L // C++20
 __cpp_lib_ranges_as_const                               202207L <ranges>
 __cpp_lib_ranges_as_rvalue                              202207L <ranges>
 __cpp_lib_ranges_chunk                                  202202L <ranges>
@@ -534,6 +535,8 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # undef  __cpp_lib_out_ptr
 // # define __cpp_lib_out_ptr                              202311L
 // # define __cpp_lib_philox_engine                        202406L
+# undef  __cpp_lib_ranges
+# define __cpp_lib_ranges                               202406L
 // # define __cpp_lib_ranges_concat                        202403L
 # define __cpp_lib_ratio                                202306L
 // # define __cpp_lib_rcu                                  202306L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
index 8ccd252115ac8..f9be4ef6ec1f6 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
@@ -22,6 +22,7 @@
     __cpp_lib_freestanding_algorithm                        202311L [C++26]
     __cpp_lib_parallel_algorithm                            201603L [C++17]
     __cpp_lib_ranges                                        202207L [C++20]
+                                                            202406L [C++26]
     __cpp_lib_ranges_contains                               202207L [C++23]
     __cpp_lib_ranges_starts_ends_with                       202106L [C++23]
     __cpp_lib_robust_nonmodifying_seq_ops                   201304L [C++14]
@@ -401,8 +402,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202207L
-#   error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+#   error "__cpp_lib_ranges should have the value 202406L in c++26"
 # endif
 
 # ifndef __cpp_lib_ranges_contains
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
index 27e76e5b2b05a..e4eb94aad60c5 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
@@ -28,6 +28,7 @@
     __cpp_lib_move_only_function       202110L [C++23]
     __cpp_lib_not_fn                   201603L [C++17]
     __cpp_lib_ranges                   202207L [C++20]
+                                       202406L [C++26]
     __cpp_lib_reference_wrapper        202403L [C++26]
     __cpp_lib_result_of_sfinae         201210L [C++14]
     __cpp_lib_transparent_operators    201210L [C++14]
@@ -531,8 +532,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202207L
-#   error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+#   error "__cpp_lib_ranges should have the value 202406L in c++26"
 # endif
 
 # ifndef __cpp_lib_reference_wrapper
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
index 700907ce9bb07..4e29f3db51c3b 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
@@ -24,6 +24,7 @@
     __cpp_lib_nonmember_container_access    201411L [C++17]
     __cpp_lib_null_iterators                201304L [C++14]
     __cpp_lib_ranges                        202207L [C++20]
+                                            202406L [C++26]
     __cpp_lib_ssize                         201902L [C++20]
 */
 
@@ -313,8 +314,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202207L
-#   error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+#   error "__cpp_lib_ranges should have the value 202406L in c++26"
 # endif
 
 # ifndef __cpp_lib_ssize
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index 45d9271faa578..e44474a4c0aff 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -29,6 +29,7 @@
     __cpp_lib_out_ptr                             202106L [C++23]
                                                   202311L [C++26]
     __cpp_lib_ranges                              202207L [C++20]
+                                                  202406L [C++26]
     __cpp_lib_raw_memory_algorithms               201606L [C++17]
     __cpp_lib_shared_ptr_arrays                   201611L [C++17]
                                                   201707L [C++20]
@@ -638,8 +639,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202207L
-#   error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+#   error "__cpp_lib_ranges should have the value 202406L in c++26"
 # endif
 
 # ifndef __cpp_lib_raw_memory_algorithms
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
index 30feacd796d8e..6c558eafbc333 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
@@ -18,6 +18,7 @@
 /*  Constant                                                Value
     __cpp_lib_default_template_type_for_algorithm_values    202403L [C++26]
     __cpp_lib_ranges                                        202207L [C++20]
+                                                            202406L [C++26]
     __cpp_lib_ranges_as_const                               202207L [C++23]
     __cpp_lib_ranges_as_rvalue                              202207L [C++23]
     __cpp_lib_ranges_chunk                                  202202L [C++23]
@@ -364,8 +365,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202207L
-#   error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+#   error "__cpp_lib_ranges should have the value 202406L in c++26"
 # endif
 
 # if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index aa5ff80afb56a..a39425c968e3e 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -166,6 +166,7 @@
     __cpp_lib_print                                         202207L [C++23]
     __cpp_lib_quoted_string_io                              201304L [C++14]
     __cpp_lib_ranges                                        202207L [C++20]
+                                                            202406L [C++26]
     __cpp_lib_ranges_as_const                               202207L [C++23]
     __cpp_lib_ranges_as_rvalue                              202207L [C++23]
     __cpp_lib_ranges_chunk                                  202202L [C++23]
@@ -7456,8 +7457,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202207L
-#   error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+#   error "__cpp_lib_ranges should have the value 202406L in c++26"
 # endif
 
 # if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 7bc11aa401829..317e5a3391417 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -993,7 +993,7 @@ def add_version_header(tc):
             "name": "__cpp_lib_ranges",
             "values": {
                 "c++20": 202207,
-                # "c++26": 202406, # P2997R1 Removing the common reference requirement from the indirectly invocable concepts
+                "c++26": 202406, # P2997R1 Removing the common reference requirement from the indirectly invocable concepts
             },
             "headers": ["algorithm", "functional", "iterator", "memory", "ranges"],
         },

>From a48f88ac69d6a0abc1000d4b8be5563c6fcb3094 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 14 Jul 2024 18:38:41 +0300
Subject: [PATCH 3/9] Fixed formatting

---
 libcxx/utils/generate_feature_test_macro_components.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 317e5a3391417..04fd71292d30b 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -993,7 +993,7 @@ def add_version_header(tc):
             "name": "__cpp_lib_ranges",
             "values": {
                 "c++20": 202207,
-                "c++26": 202406, # P2997R1 Removing the common reference requirement from the indirectly invocable concepts
+                "c++26": 202406,  # P2997R1 Removing the common reference requirement from the indirectly invocable concepts
             },
             "headers": ["algorithm", "functional", "iterator", "memory", "ranges"],
         },

>From c16f814525aa4b367b7fba54da993ce9c72e855f Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 14 Jul 2024 19:33:40 +0300
Subject: [PATCH 4/9] Minor tweak

---
 .../indirect_binary_predicate.compile.pass.cpp                  | 2 +-
 .../indirect_equivalence_relation.compile.pass.cpp              | 2 +-
 .../indirect_strict_weak_order.compile.pass.cpp                 | 2 +-
 .../indirectinvocable/indirect_unary_predicate.compile.pass.cpp | 2 +-
 .../indirectly_regular_unary_invocable.compile.pass.cpp         | 2 +-
 .../indirectly_unary_invocable.compile.pass.cpp                 | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
index 5058cbb06dabe..76f38232b4e04 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
@@ -76,7 +76,7 @@ struct BadPredicate5 {
 };
 static_assert(!std::indirect_binary_predicate<BadPredicate5, It1, It2>);
 
-// P2997R1: Should succeed when the predicate can't be called with (iter_common_reference_t, iter_common_reference_t)
+// This case was made valid by P2997R1.
 struct BadPredicate6 {
     template <class T, class U> bool operator()(T const&, U const&) const;
     bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
index 20206db6c6eaf..06a0291e439cc 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
@@ -91,7 +91,7 @@ struct BadRelation5 {
 };
 static_assert(!std::indirect_equivalence_relation<BadRelation5, It1, It2>);
 
-// P2997R1: Should succeed when the function can't be called with (iter_common_reference_t, iter_common_reference_t)
+// This case was made valid by P2997R1.
 struct BadRelation6 {
     template <class T, class U> bool operator()(T const&, U const&) const;
     bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
index 32bc3aef10057..9ca335a98c550 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
@@ -91,7 +91,7 @@ struct BadOrder5 {
 };
 static_assert(!std::indirect_strict_weak_order<BadOrder5, It1, It2>);
 
-// P2997R1: Should succeed when the function can't be called with (iter_common_reference_t, iter_common_reference_t)
+// This case was made valid by P2997R1.
 struct BadOrder6 {
     template <class T, class U> bool operator()(T const&, U const&) const;
     bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
index 32b63d27b4eb1..870f82cc8c3c0 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
@@ -57,7 +57,7 @@ struct BadPredicate3 {
 };
 static_assert(!std::indirect_unary_predicate<BadPredicate3, It>);
 
-// P2997R1: Should succeed when the predicate can't be called with std::iter_common_reference_t<It>
+// This case was made valid by P2997R1.
 struct BadPredicate4 {
     template <class T> bool operator()(T const&) const;
     bool operator()(std::iter_common_reference_t<It>) const = delete;
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
index 69b3909806ac8..5ebbba6e24861 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
@@ -56,7 +56,7 @@ struct BadInvocable3 {
 };
 static_assert(!std::indirectly_regular_unary_invocable<BadInvocable3, It>);
 
-// P2997R1: Should succeed when the invocable can't be called with (iter_common_reference_t)
+// This case was made valid by P2997R1.
 struct BadInvocable4 {
     template <class T> R1 operator()(T const&) const;
     R1 operator()(std::iter_common_reference_t<It>) const = delete;
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
index 06f9c72ec1053..d6a26f50eb748 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
@@ -56,7 +56,7 @@ struct BadInvocable3 {
 };
 static_assert(!std::indirectly_unary_invocable<BadInvocable3, It>);
 
-// P2997R1: Should succeed when the invocable can't be called with (iter_common_reference_t)
+// This case was made valid by P2997R1.
 struct BadInvocable4 {
     template <class T> R1 operator()(T const&) const;
     R1 operator()(std::iter_common_reference_t<It>) const = delete;

>From bda678ea66c9da08323997b7ebb21eb83ad2e758 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 14 Jul 2024 20:24:15 +0300
Subject: [PATCH 5/9] Release notes

---
 libcxx/docs/ReleaseNotes/19.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index a4cf411d2a6c1..c572dcd2a9761 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -47,6 +47,7 @@ Implemented Papers
 - P3142R0 - Printing Blank Lines with ``println`` (as DR against C++23)
 - P2944R3 - Comparisons for ``reference_wrapper`` (comparison operators for ``reference_wrapper`` only)
 - P2968R2 - Make ``std::ignore`` a first-class object
+- P2997R1 - Removing the common reference requirement from the indirectly invocable concepts
 - P2302R4 - ``std::ranges::contains``
 - P1659R3 - ``std::ranges::starts_with`` and ``std::ranges::ends_with``
 - P3029R1 - Better ``mdspan``'s CTAD

>From cbf570f53868beebadbb8816acb90bb6c248aad9 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 15 Jul 2024 16:24:58 +0300
Subject: [PATCH 6/9] Don't set FTM

---
 libcxx/docs/FeatureTestMacroTable.rst                        | 2 --
 libcxx/include/version                                       | 5 +----
 .../algorithm.version.compile.pass.cpp                       | 5 ++---
 .../functional.version.compile.pass.cpp                      | 5 ++---
 .../support.limits.general/iterator.version.compile.pass.cpp | 5 ++---
 .../support.limits.general/memory.version.compile.pass.cpp   | 5 ++---
 .../support.limits.general/ranges.version.compile.pass.cpp   | 5 ++---
 .../support.limits.general/version.version.compile.pass.cpp  | 5 ++---
 libcxx/utils/generate_feature_test_macro_components.py       | 3 ++-
 9 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 82cfa76b744b7..7cd20acc6ff4a 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -452,8 +452,6 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_philox_engine``                                *unimplemented*
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_ranges``                                       ``202406L``
-    ---------------------------------------------------------- -----------------
     ``__cpp_lib_ranges_concat``                                *unimplemented*
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_ratio``                                        ``202306L``
diff --git a/libcxx/include/version b/libcxx/include/version
index 0c5cec87b7b01..1f66bce40df8a 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -181,9 +181,8 @@ __cpp_lib_philox_engine                                 202406L <random>
 __cpp_lib_polymorphic_allocator                         201902L <memory_resource>
 __cpp_lib_print                                         202207L <ostream> <print>
 __cpp_lib_quoted_string_io                              201304L <iomanip>
-__cpp_lib_ranges                                        202406L <algorithm> <functional> <iterator>
+__cpp_lib_ranges                                        202207L <algorithm> <functional> <iterator>
                                                                 <memory> <ranges>
-                                                        202207L // C++20
 __cpp_lib_ranges_as_const                               202207L <ranges>
 __cpp_lib_ranges_as_rvalue                              202207L <ranges>
 __cpp_lib_ranges_chunk                                  202202L <ranges>
@@ -535,8 +534,6 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # undef  __cpp_lib_out_ptr
 // # define __cpp_lib_out_ptr                              202311L
 // # define __cpp_lib_philox_engine                        202406L
-# undef  __cpp_lib_ranges
-# define __cpp_lib_ranges                               202406L
 // # define __cpp_lib_ranges_concat                        202403L
 # define __cpp_lib_ratio                                202306L
 // # define __cpp_lib_rcu                                  202306L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
index f9be4ef6ec1f6..8ccd252115ac8 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
@@ -22,7 +22,6 @@
     __cpp_lib_freestanding_algorithm                        202311L [C++26]
     __cpp_lib_parallel_algorithm                            201603L [C++17]
     __cpp_lib_ranges                                        202207L [C++20]
-                                                            202406L [C++26]
     __cpp_lib_ranges_contains                               202207L [C++23]
     __cpp_lib_ranges_starts_ends_with                       202106L [C++23]
     __cpp_lib_robust_nonmodifying_seq_ops                   201304L [C++14]
@@ -402,8 +401,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202406L
-#   error "__cpp_lib_ranges should have the value 202406L in c++26"
+# if __cpp_lib_ranges != 202207L
+#   error "__cpp_lib_ranges should have the value 202207L in c++26"
 # endif
 
 # ifndef __cpp_lib_ranges_contains
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
index e4eb94aad60c5..27e76e5b2b05a 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
@@ -28,7 +28,6 @@
     __cpp_lib_move_only_function       202110L [C++23]
     __cpp_lib_not_fn                   201603L [C++17]
     __cpp_lib_ranges                   202207L [C++20]
-                                       202406L [C++26]
     __cpp_lib_reference_wrapper        202403L [C++26]
     __cpp_lib_result_of_sfinae         201210L [C++14]
     __cpp_lib_transparent_operators    201210L [C++14]
@@ -532,8 +531,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202406L
-#   error "__cpp_lib_ranges should have the value 202406L in c++26"
+# if __cpp_lib_ranges != 202207L
+#   error "__cpp_lib_ranges should have the value 202207L in c++26"
 # endif
 
 # ifndef __cpp_lib_reference_wrapper
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
index 4e29f3db51c3b..700907ce9bb07 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
@@ -24,7 +24,6 @@
     __cpp_lib_nonmember_container_access    201411L [C++17]
     __cpp_lib_null_iterators                201304L [C++14]
     __cpp_lib_ranges                        202207L [C++20]
-                                            202406L [C++26]
     __cpp_lib_ssize                         201902L [C++20]
 */
 
@@ -314,8 +313,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202406L
-#   error "__cpp_lib_ranges should have the value 202406L in c++26"
+# if __cpp_lib_ranges != 202207L
+#   error "__cpp_lib_ranges should have the value 202207L in c++26"
 # endif
 
 # ifndef __cpp_lib_ssize
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index e44474a4c0aff..45d9271faa578 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -29,7 +29,6 @@
     __cpp_lib_out_ptr                             202106L [C++23]
                                                   202311L [C++26]
     __cpp_lib_ranges                              202207L [C++20]
-                                                  202406L [C++26]
     __cpp_lib_raw_memory_algorithms               201606L [C++17]
     __cpp_lib_shared_ptr_arrays                   201611L [C++17]
                                                   201707L [C++20]
@@ -639,8 +638,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202406L
-#   error "__cpp_lib_ranges should have the value 202406L in c++26"
+# if __cpp_lib_ranges != 202207L
+#   error "__cpp_lib_ranges should have the value 202207L in c++26"
 # endif
 
 # ifndef __cpp_lib_raw_memory_algorithms
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
index 6c558eafbc333..30feacd796d8e 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
@@ -18,7 +18,6 @@
 /*  Constant                                                Value
     __cpp_lib_default_template_type_for_algorithm_values    202403L [C++26]
     __cpp_lib_ranges                                        202207L [C++20]
-                                                            202406L [C++26]
     __cpp_lib_ranges_as_const                               202207L [C++23]
     __cpp_lib_ranges_as_rvalue                              202207L [C++23]
     __cpp_lib_ranges_chunk                                  202202L [C++23]
@@ -365,8 +364,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202406L
-#   error "__cpp_lib_ranges should have the value 202406L in c++26"
+# if __cpp_lib_ranges != 202207L
+#   error "__cpp_lib_ranges should have the value 202207L in c++26"
 # endif
 
 # if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index a39425c968e3e..aa5ff80afb56a 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -166,7 +166,6 @@
     __cpp_lib_print                                         202207L [C++23]
     __cpp_lib_quoted_string_io                              201304L [C++14]
     __cpp_lib_ranges                                        202207L [C++20]
-                                                            202406L [C++26]
     __cpp_lib_ranges_as_const                               202207L [C++23]
     __cpp_lib_ranges_as_rvalue                              202207L [C++23]
     __cpp_lib_ranges_chunk                                  202202L [C++23]
@@ -7457,8 +7456,8 @@
 # ifndef __cpp_lib_ranges
 #   error "__cpp_lib_ranges should be defined in c++26"
 # endif
-# if __cpp_lib_ranges != 202406L
-#   error "__cpp_lib_ranges should have the value 202406L in c++26"
+# if __cpp_lib_ranges != 202207L
+#   error "__cpp_lib_ranges should have the value 202207L in c++26"
 # endif
 
 # if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 04fd71292d30b..d7bed080f17ba 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -993,7 +993,8 @@ def add_version_header(tc):
             "name": "__cpp_lib_ranges",
             "values": {
                 "c++20": 202207,
-                "c++26": 202406,  # P2997R1 Removing the common reference requirement from the indirectly invocable concepts
+                # "c++23": 202302,  # Relaxing Ranges Just A Smidge
+                # "c++26": 202406,  # P2997R1 Removing the common reference requirement from the indirectly invocable concepts
             },
             "headers": ["algorithm", "functional", "iterator", "memory", "ranges"],
         },

>From 6e5edc15cc0e94294f7350bd5333a97ce72aa607 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 16 Jul 2024 20:02:56 +0300
Subject: [PATCH 7/9] Addressed review comments

---
 libcxx/docs/ReleaseNotes/19.rst                               | 2 +-
 libcxx/docs/Status/Cxx2c.rst                                  | 1 +
 libcxx/docs/Status/Cxx2cPapers.csv                            | 2 +-
 .../indirect_binary_predicate.compile.pass.cpp                | 4 ++--
 .../indirect_equivalence_relation.compile.pass.cpp            | 4 ++--
 .../indirect_strict_weak_order.compile.pass.cpp               | 4 ++--
 .../indirect_unary_predicate.compile.pass.cpp                 | 4 ++--
 .../indirectly_regular_unary_invocable.compile.pass.cpp       | 4 ++--
 .../indirectly_unary_invocable.compile.pass.cpp               | 4 ++--
 libcxx/utils/generate_feature_test_macro_components.py        | 2 +-
 10 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index c572dcd2a9761..c49bd29b4c448 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -47,7 +47,7 @@ Implemented Papers
 - P3142R0 - Printing Blank Lines with ``println`` (as DR against C++23)
 - P2944R3 - Comparisons for ``reference_wrapper`` (comparison operators for ``reference_wrapper`` only)
 - P2968R2 - Make ``std::ignore`` a first-class object
-- P2997R1 - Removing the common reference requirement from the indirectly invocable concepts
+- P2997R1 - Removing the common reference requirement from the indirectly invocable concepts (as DR against C++20)
 - P2302R4 - ``std::ranges::contains``
 - P1659R3 - ``std::ranges::starts_with`` and ``std::ranges::ends_with``
 - P3029R1 - Better ``mdspan``'s CTAD
diff --git a/libcxx/docs/Status/Cxx2c.rst b/libcxx/docs/Status/Cxx2c.rst
index 03a6eeaa40c79..1b8d96588c3cb 100644
--- a/libcxx/docs/Status/Cxx2c.rst
+++ b/libcxx/docs/Status/Cxx2c.rst
@@ -43,6 +43,7 @@ Paper Status
    .. [#note-P3142R0] This paper is applied as DR against C++23. (MSVC STL and libstdc++ will do the same.)
    .. [#note-P2944R3] Implemented comparisons for ``reference_wrapper`` only.
    .. [#note-P2422R1] Libc++ keeps the ``nodiscard`` attributes as a conforming extension.
+   .. [#note-P2997R1] This paper is applied as DR against C++20. (MSVC STL and libstdc++ will do the same.)
 
 .. _issues-status-cxx2c:
 
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index aea413dd33588..f0db3f5cca1a6 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -64,7 +64,7 @@
 "`P3029R1 <https://wg21.link/P3029R1>`__","LWG","Better ``mdspan``'s CTAD","Tokyo March 2024","|Complete|","19.0",""
 "","","","","","",""
 "`P2747R2 <https://wg21.link/P2747R2>`__","CWG","``constexpr`` placement new","St. Louis June 2024","","",""
-"`P2997R1 <https://wg21.link/P2997R1>`__","LWG","Removing the common reference requirement from the indirectly invocable concepts","St. Louis June 2024","","",""
+"`P2997R1 <https://wg21.link/P2997R1>`__","LWG","Removing the common reference requirement from the indirectly invocable concepts","St. Louis June 2024",""|Complete| [#note-P2997R1]_","19.0",""
 "`P2389R2 <https://wg21.link/P2389R2>`__","LWG","``dextents`` Index Type Parameter","St. Louis June 2024","","",""
 "`P3168R2 <https://wg21.link/P3168R2>`__","LWG","Give ``std::optional`` Range Support","St. Louis June 2024","","","|ranges|"
 "`P3217R0 <https://wg21.link/P3217R0>`__","LWG","Adjoints to 'Enabling list-initialization for algorithms': find_last","St. Louis June 2024","","",""
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
index 76f38232b4e04..a9a5d23271ebf 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
@@ -77,11 +77,11 @@ struct BadPredicate5 {
 static_assert(!std::indirect_binary_predicate<BadPredicate5, It1, It2>);
 
 // This case was made valid by P2997R1.
-struct BadPredicate6 {
+struct GoodPredicate6 {
     template <class T, class U> bool operator()(T const&, U const&) const;
     bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
 };
-static_assert(std::indirect_binary_predicate<BadPredicate6, It1, It2>);
+static_assert(std::indirect_binary_predicate<GoodPredicate6, It1, It2>);
 
 // Test ADL-proofing (P2538R1)
 #if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
index 06a0291e439cc..c7e5675af28fd 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
@@ -92,11 +92,11 @@ struct BadRelation5 {
 static_assert(!std::indirect_equivalence_relation<BadRelation5, It1, It2>);
 
 // This case was made valid by P2997R1.
-struct BadRelation6 {
+struct GoodRelation6 {
     template <class T, class U> bool operator()(T const&, U const&) const;
     bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
 };
-static_assert(std::indirect_equivalence_relation<BadRelation6, It1, It2>);
+static_assert(std::indirect_equivalence_relation<GoodRelation6, It1, It2>);
 
 // Test ADL-proofing (P2538R1)
 #if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
index 9ca335a98c550..49daaf3784ee6 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
@@ -92,11 +92,11 @@ struct BadOrder5 {
 static_assert(!std::indirect_strict_weak_order<BadOrder5, It1, It2>);
 
 // This case was made valid by P2997R1.
-struct BadOrder6 {
+struct GoodOrder6 {
     template <class T, class U> bool operator()(T const&, U const&) const;
     bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
 };
-static_assert(std::indirect_strict_weak_order<BadOrder6, It1, It2>);
+static_assert(std::indirect_strict_weak_order<GoodOrder6, It1, It2>);
 
 // Test ADL-proofing (P2538R1)
 #if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
index 870f82cc8c3c0..0f1b1d03887bf 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
@@ -58,11 +58,11 @@ struct BadPredicate3 {
 static_assert(!std::indirect_unary_predicate<BadPredicate3, It>);
 
 // This case was made valid by P2997R1.
-struct BadPredicate4 {
+struct GoodPredicate4 {
     template <class T> bool operator()(T const&) const;
     bool operator()(std::iter_common_reference_t<It>) const = delete;
 };
-static_assert(std::indirect_unary_predicate<BadPredicate4, It>);
+static_assert(std::indirect_unary_predicate<GoodPredicate4, It>);
 
 // Test ADL-proofing (P2538R1)
 #if TEST_STD_VER >= 26 || defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
index 5ebbba6e24861..207b9b3937c02 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
@@ -57,11 +57,11 @@ struct BadInvocable3 {
 static_assert(!std::indirectly_regular_unary_invocable<BadInvocable3, It>);
 
 // This case was made valid by P2997R1.
-struct BadInvocable4 {
+struct GoodInvocable4 {
     template <class T> R1 operator()(T const&) const;
     R1 operator()(std::iter_common_reference_t<It>) const = delete;
 };
-static_assert(std::indirectly_regular_unary_invocable<BadInvocable4, It>);
+static_assert(std::indirectly_regular_unary_invocable<GoodInvocable4, It>);
 
 // Should fail when the invocable doesn't have a common reference between its return types
 struct BadInvocable5 {
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
index d6a26f50eb748..2308a3636d092 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
@@ -57,11 +57,11 @@ struct BadInvocable3 {
 static_assert(!std::indirectly_unary_invocable<BadInvocable3, It>);
 
 // This case was made valid by P2997R1.
-struct BadInvocable4 {
+struct GoodInvocable4 {
     template <class T> R1 operator()(T const&) const;
     R1 operator()(std::iter_common_reference_t<It>) const = delete;
 };
-static_assert(std::indirectly_unary_invocable<BadInvocable4, It>);
+static_assert(std::indirectly_unary_invocable<GoodInvocable4, It>);
 
 // Should fail when the invocable doesn't have a common reference between its return types
 struct BadInvocable5 {
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index d7bed080f17ba..75d97f9427d46 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -994,7 +994,7 @@ def add_version_header(tc):
             "values": {
                 "c++20": 202207,
                 # "c++23": 202302,  # Relaxing Ranges Just A Smidge
-                # "c++26": 202406,  # P2997R1 Removing the common reference requirement from the indirectly invocable concepts
+                # "c++26": 202406,  # P2997R1 Removing the common reference requirement from the indirectly invocable concepts (already implemented as a DR)
             },
             "headers": ["algorithm", "functional", "iterator", "memory", "ranges"],
         },

>From 1cde068b0cd8cd12e040e3151fde35b499d99408 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 16 Jul 2024 20:12:04 +0300
Subject: [PATCH 8/9] Try to fix CI

---
 libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index fc54c98d35872..90401d6b9e58e 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -64,7 +64,7 @@
 "`P3029R1 <https://wg21.link/P3029R1>`__","LWG","Better ``mdspan``'s CTAD","Tokyo March 2024","|Complete|","19.0",""
 "","","","","","",""
 "`P2747R2 <https://wg21.link/P2747R2>`__","CWG","``constexpr`` placement new","St. Louis June 2024","","",""
-"`P2997R1 <https://wg21.link/P2997R1>`__","LWG","Removing the common reference requirement from the indirectly invocable concepts","St. Louis June 2024",""|Complete| [#note-P2997R1]_","19.0",""
+"`P2997R1 <https://wg21.link/P2997R1>`__","LWG","Removing the common reference requirement from the indirectly invocable concepts","St. Louis June 2024","|Complete| [#note-P2997R1]_","19.0",""
 "`P2389R2 <https://wg21.link/P2389R2>`__","LWG","``dextents`` Index Type Parameter","St. Louis June 2024","|Complete|","19.0",""
 "`P3168R2 <https://wg21.link/P3168R2>`__","LWG","Give ``std::optional`` Range Support","St. Louis June 2024","","","|ranges|"
 "`P3217R0 <https://wg21.link/P3217R0>`__","LWG","Adjoints to 'Enabling list-initialization for algorithms': find_last","St. Louis June 2024","","",""

>From da85151fedbbcc47dc0f3d402694f5263100e448 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 16 Jul 2024 20:14:26 +0300
Subject: [PATCH 9/9] Try to fix CI: Formatting

---
 .../indirect_binary_predicate.compile.pass.cpp               | 5 +++--
 .../indirect_equivalence_relation.compile.pass.cpp           | 5 +++--
 .../indirect_strict_weak_order.compile.pass.cpp              | 5 +++--
 .../indirect_unary_predicate.compile.pass.cpp                | 5 +++--
 .../indirectly_regular_unary_invocable.compile.pass.cpp      | 5 +++--
 .../indirectly_unary_invocable.compile.pass.cpp              | 5 +++--
 6 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
index a9a5d23271ebf..38dcd70d850e6 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp
@@ -78,8 +78,9 @@ static_assert(!std::indirect_binary_predicate<BadPredicate5, It1, It2>);
 
 // This case was made valid by P2997R1.
 struct GoodPredicate6 {
-    template <class T, class U> bool operator()(T const&, U const&) const;
-    bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
+  template <class T, class U>
+  bool operator()(T const&, U const&) const;
+  bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
 };
 static_assert(std::indirect_binary_predicate<GoodPredicate6, It1, It2>);
 
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
index c7e5675af28fd..8ea7e8a6d9e1e 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp
@@ -93,8 +93,9 @@ static_assert(!std::indirect_equivalence_relation<BadRelation5, It1, It2>);
 
 // This case was made valid by P2997R1.
 struct GoodRelation6 {
-    template <class T, class U> bool operator()(T const&, U const&) const;
-    bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
+  template <class T, class U>
+  bool operator()(T const&, U const&) const;
+  bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
 };
 static_assert(std::indirect_equivalence_relation<GoodRelation6, It1, It2>);
 
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
index 49daaf3784ee6..074725f97bf32 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp
@@ -93,8 +93,9 @@ static_assert(!std::indirect_strict_weak_order<BadOrder5, It1, It2>);
 
 // This case was made valid by P2997R1.
 struct GoodOrder6 {
-    template <class T, class U> bool operator()(T const&, U const&) const;
-    bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
+  template <class T, class U>
+  bool operator()(T const&, U const&) const;
+  bool operator()(std::iter_common_reference_t<It1>, std::iter_common_reference_t<It2>) const = delete;
 };
 static_assert(std::indirect_strict_weak_order<GoodOrder6, It1, It2>);
 
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
index 0f1b1d03887bf..f52ea8f9151c3 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp
@@ -59,8 +59,9 @@ static_assert(!std::indirect_unary_predicate<BadPredicate3, It>);
 
 // This case was made valid by P2997R1.
 struct GoodPredicate4 {
-    template <class T> bool operator()(T const&) const;
-    bool operator()(std::iter_common_reference_t<It>) const = delete;
+  template <class T>
+  bool operator()(T const&) const;
+  bool operator()(std::iter_common_reference_t<It>) const = delete;
 };
 static_assert(std::indirect_unary_predicate<GoodPredicate4, It>);
 
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
index 207b9b3937c02..fceae03a4b324 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp
@@ -58,8 +58,9 @@ static_assert(!std::indirectly_regular_unary_invocable<BadInvocable3, It>);
 
 // This case was made valid by P2997R1.
 struct GoodInvocable4 {
-    template <class T> R1 operator()(T const&) const;
-    R1 operator()(std::iter_common_reference_t<It>) const = delete;
+  template <class T>
+  R1 operator()(T const&) const;
+  R1 operator()(std::iter_common_reference_t<It>) const = delete;
 };
 static_assert(std::indirectly_regular_unary_invocable<GoodInvocable4, It>);
 
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
index 2308a3636d092..27c078baeb194 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp
@@ -58,8 +58,9 @@ static_assert(!std::indirectly_unary_invocable<BadInvocable3, It>);
 
 // This case was made valid by P2997R1.
 struct GoodInvocable4 {
-    template <class T> R1 operator()(T const&) const;
-    R1 operator()(std::iter_common_reference_t<It>) const = delete;
+  template <class T>
+  R1 operator()(T const&) const;
+  R1 operator()(std::iter_common_reference_t<It>) const = delete;
 };
 static_assert(std::indirectly_unary_invocable<GoodInvocable4, It>);
 



More information about the libcxx-commits mailing list