[gcc r13-9242] libstdc++: Fix get<0> constraint for lvalue ranges::subrange (LWG 3589)
Jonathan Wakely
redi@gcc.gnu.org
Sat Dec 7 10:10:18 GMT 2024
https://gcc.gnu.org/g:8fda1b0f513129861729eed25067438031fb6ec5
commit r13-9242-g8fda1b0f513129861729eed25067438031fb6ec5
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Nov 14 17:31:43 2024 +0000
libstdc++: Fix get<0> constraint for lvalue ranges::subrange (LWG 3589)
Approved at October 2021 plenary.
libstdc++-v3/ChangeLog:
* include/bits/ranges_util.h (subrange::begin): Fix constraint,
as per LWG 3589.
* testsuite/std/ranges/subrange/lwg3589.cc: New test.
(cherry picked from commit 4a3a0be34f723df192361e43bb48b9292dfe3a54)
Diff:
---
libstdc++-v3/include/bits/ranges_util.h | 5 +++-
.../testsuite/std/ranges/subrange/lwg3589.cc | 30 ++++++++++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h
index 5f6a1d360ed0..ddb0260c3772 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.h
@@ -432,8 +432,11 @@ namespace ranges
__detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
-> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>;
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3589. The const lvalue reference overload of get for subrange does not
+ // constrain I to be copyable when N == 0
template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
- requires (_Num < 2)
+ requires ((_Num == 0 && copyable<_It>) || _Num == 1)
constexpr auto
get(const subrange<_It, _Sent, _Kind>& __r)
{
diff --git a/libstdc++-v3/testsuite/std/ranges/subrange/lwg3589.cc b/libstdc++-v3/testsuite/std/ranges/subrange/lwg3589.cc
new file mode 100644
index 000000000000..1ccc52d81f8a
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/subrange/lwg3589.cc
@@ -0,0 +1,30 @@
+// { dg-do compile { target c++20 } }
+
+// LWG 3589. The const lvalue reference overload of get for subrange does not
+// constrain I to be copyable when N == 0
+
+#include <ranges>
+#include <testsuite_iterators.h>
+
+void
+test_lwg3589()
+{
+ int a[2]{};
+ __gnu_test::test_range<int, __gnu_test::input_iterator_wrapper_nocopy> r(a);
+
+ // Use a generic lambda so we have a dependent context.
+ auto test = [](auto& x)
+ {
+ // This was wrong before the LWG 3589 change:
+ if constexpr (requires { std::ranges::get<0>(x); })
+ (void) std::ranges::get<0>(x);
+
+ // These always worked unconditionally:
+ (void) std::ranges::get<1>(x);
+ (void) std::ranges::get<0>(std::move(x));
+ (void) std::ranges::get<1>(std::move(x));
+ };
+
+ std::ranges::subrange sr(r.begin(), r.end());
+ test(sr);
+}
More information about the Libstdc++-cvs
mailing list