Tested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps
14?
-- >8 --
This implements the changes of this C++26 paper as a DR against C++20.
libstdc++-v3/ChangeLog:
* include/bits/iterator_concepts.h (indirectly_unary_invocable):
Relax as per P2997R1.
(indirectly_regular_unary_invocable): Likewise.
(indirect_unary_predicate): Likewise.
(indirect_binary_predicate): Likewise.
(indirect_equivalence_relation): Likewise.
(indirect_strict_weak_order): Likewise.
* version.def (ranges): Update value for C++26.
* version.h: Regenerate.
* testsuite/24_iterators/indirect_callable/p2997r1.cc: New test.
* testsuite/std/ranges/version_c++23.cc: Restrict to C++23 mode.
* testsuite/std/ranges/version_c++26.cc: New test.
---
libstdc++-v3/include/bits/iterator_concepts.h | 17 ++-------
libstdc++-v3/include/bits/version.def | 5 +++
libstdc++-v3/include/bits/version.h | 7 +++-
.../24_iterators/indirect_callable/p2997r1.cc | 37 +++++++++++++++++++
.../testsuite/std/ranges/version_c++23.cc | 2 +-
.../testsuite/std/ranges/version_c++26.cc | 10 +++++
6 files changed, 63 insertions(+), 15 deletions(-)
create mode 100644
libstdc++-v3/testsuite/24_iterators/indirect_callable/p2997r1.cc
create mode 100644 libstdc++-v3/testsuite/std/ranges/version_c++26.cc
diff --git a/libstdc++-v3/include/bits/iterator_concepts.h
b/libstdc++-v3/include/bits/iterator_concepts.h
index 9306b7bd194..d849ddc32fc 100644
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -724,7 +724,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
concept indirectly_unary_invocable = indirectly_readable<_Iter>
&& copy_constructible<_Fn> && invocable<_Fn&, __indirect_value_t<_Iter>>
&& invocable<_Fn&, iter_reference_t<_Iter>>
- && invocable<_Fn&, iter_common_reference_t<_Iter>>
&& common_reference_with<invoke_result_t<_Fn&,
__indirect_value_t<_Iter>>,
invoke_result_t<_Fn&, iter_reference_t<_Iter>>>;
@@ -733,15 +732,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& copy_constructible<_Fn>
&& regular_invocable<_Fn&, __indirect_value_t<_Iter>>
&& regular_invocable<_Fn&, iter_reference_t<_Iter>>
- && regular_invocable<_Fn&, iter_common_reference_t<_Iter>>
&& common_reference_with<invoke_result_t<_Fn&,
__indirect_value_t<_Iter>>,
invoke_result_t<_Fn&, iter_reference_t<_Iter>>>;
template<typename _Fn, typename _Iter>
concept indirect_unary_predicate = indirectly_readable<_Iter>
&& copy_constructible<_Fn> && predicate<_Fn&, __indirect_value_t<_Iter>>
- && predicate<_Fn&, iter_reference_t<_Iter>>
- && predicate<_Fn&, iter_common_reference_t<_Iter>>;
+ && predicate<_Fn&, iter_reference_t<_Iter>>;
template<typename _Fn, typename _I1, typename _I2>
concept indirect_binary_predicate
@@ -750,9 +747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& predicate<_Fn&, __indirect_value_t<_I1>, __indirect_value_t<_I2>>
&& predicate<_Fn&, __indirect_value_t<_I1>, iter_reference_t<_I2>>
&& predicate<_Fn&, iter_reference_t<_I1>, __indirect_value_t<_I2>>
- && predicate<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>
- && predicate<_Fn&, iter_common_reference_t<_I1>,
- iter_common_reference_t<_I2>>;
+ && predicate<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>;
template<typename _Fn, typename _I1, typename _I2 = _I1>
concept indirect_equivalence_relation
@@ -762,9 +757,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& equivalence_relation<_Fn&, __indirect_value_t<_I1>,
iter_reference_t<_I2>>
&& equivalence_relation<_Fn&, iter_reference_t<_I1>,
__indirect_value_t<_I2>>
&& equivalence_relation<_Fn&, iter_reference_t<_I1>,
- iter_reference_t<_I2>>
- && equivalence_relation<_Fn&, iter_common_reference_t<_I1>,
- iter_common_reference_t<_I2>>;
+ iter_reference_t<_I2>>;
template<typename _Fn, typename _I1, typename _I2 = _I1>
concept indirect_strict_weak_order
@@ -773,9 +766,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& strict_weak_order<_Fn&, __indirect_value_t<_I1>,
__indirect_value_t<_I2>>
&& strict_weak_order<_Fn&, __indirect_value_t<_I1>,
iter_reference_t<_I2>>
&& strict_weak_order<_Fn&, iter_reference_t<_I1>,
__indirect_value_t<_I2>>
- && strict_weak_order<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>
- && strict_weak_order<_Fn&, iter_common_reference_t<_I1>,
- iter_common_reference_t<_I2>>;
+ && strict_weak_order<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>;
template<typename _Fn, typename... _Is>
requires (indirectly_readable<_Is> && ...)
diff --git a/libstdc++-v3/include/bits/version.def
b/libstdc++-v3/include/bits/version.def
index ea82c6fa2ca..bd3af9cba99 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1071,6 +1071,11 @@ ftms = {
ftms = {
name = ranges;
+ values = {
+ v = 202406;
+ cxxmin = 26;
+ extra_cond = "__glibcxx_concepts";
+ };
values = {
v = 202302;
cxxmin = 23;
diff --git a/libstdc++-v3/include/bits/version.h
b/libstdc++-v3/include/bits/version.h
index 981f0b7caea..364e3a05f0e 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1204,7 +1204,12 @@
#undef __glibcxx_want_shift
#if !defined(__cpp_lib_ranges)
-# if (__cplusplus >= 202100L) && (__glibcxx_concepts)
+# if (__cplusplus > 202302L) && (__glibcxx_concepts)
+# define __glibcxx_ranges 202406L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges)
+# define __cpp_lib_ranges 202406L
+# endif
+# elif (__cplusplus >= 202100L) && (__glibcxx_concepts)
# define __glibcxx_ranges 202302L
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges)
# define __cpp_lib_ranges 202302L
diff --git a/libstdc++-v3/testsuite/24_iterators/indirect_callable/p2997r1.cc
b/libstdc++-v3/testsuite/24_iterators/indirect_callable/p2997r1.cc
new file mode 100644
index 00000000000..6a66b0f2a96
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/indirect_callable/p2997r1.cc
@@ -0,0 +1,37 @@
+// Test the example from P2997R1 "Removing the common reference requirement
+// from the indirectly invocable concepts".
+// { dg-do compile { target c++20 } }
+
+#include <algorithm>
+#include <ranges>
+
+struct C {
+ auto f() -> void;
+};
+
+struct Iterator {
+ using value_type = C;
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::input_iterator_tag;
+
+ auto operator*() const -> C&&;
+ auto operator++() -> Iterator&;
+ auto operator++(int) -> void;
+ auto operator==(Iterator const&) const -> bool;
+};
+
+static_assert(std::input_iterator<Iterator>);
+static_assert(std::same_as<std::iter_value_t<Iterator>, C>);
+static_assert(std::same_as<std::iter_reference_t<Iterator>, C&&>);
+
+struct R {
+ auto begin() -> Iterator;
+ auto end() -> Iterator;
+};
+
+static_assert(std::ranges::range<R>);
+static_assert(std::same_as<std::ranges::range_reference_t<R>, C&&>);
+
+auto f(R r) -> void {
+ std::ranges::for_each(r, [](auto&& c){ c.f(); });
+}
diff --git a/libstdc++-v3/testsuite/std/ranges/version_c++23.cc
b/libstdc++-v3/testsuite/std/ranges/version_c++23.cc
index 01871156a75..b30874f9d1e 100644
--- a/libstdc++-v3/testsuite/std/ranges/version_c++23.cc
+++ b/libstdc++-v3/testsuite/std/ranges/version_c++23.cc
@@ -1,4 +1,4 @@
-// { dg-do preprocess { target c++23 } }
+// { dg-do preprocess { target c++23_only } }
// { dg-add-options no_pch }
#include <version>
diff --git a/libstdc++-v3/testsuite/std/ranges/version_c++26.cc
b/libstdc++-v3/testsuite/std/ranges/version_c++26.cc
new file mode 100644
index 00000000000..350ad0cc711
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/version_c++26.cc
@@ -0,0 +1,10 @@
+// { dg-do preprocess { target c++26_only } }
+// { dg-add-options no_pch }
+
+#include <version>
+
+#if __STDC_HOSTED__
+# if __cpp_lib_ranges != 202406L
+# error "Feature-test macro __cpp_lib_ranges has wrong value in <version>"
+# endif
+#endif
--
2.46.0.267.gbb9c16bd4f