[gcc r10-9568] libstdc++: Relax constraints on transform_view and elements_view iterators
Jonathan Wakely
redi@gcc.gnu.org
Mon Mar 29 20:01:12 GMT 2021
https://gcc.gnu.org/g:a03eb87585198a4426484f77aff8c5772b00784b
commit r10-9568-ga03eb87585198a4426484f77aff8c5772b00784b
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Sep 21 14:30:38 2020 +0100
libstdc++: Relax constraints on transform_view and elements_view iterators
libstdc++-v3/ChangeLog:
* include/std/ranges (transform_view, elements_view): Relax
constraints on operator- for iterators, as per LWG 3483.
* testsuite/std/ranges/adaptors/elements.cc: Check that we
can take the difference of two iterators from a non-random
access range.
* testsuite/std/ranges/adaptors/transform.cc: Likewise.
(cherry picked from commit 2ec58cfcea146a61755516ce4ed160827fe0b4ff)
Diff:
---
libstdc++-v3/include/std/ranges | 8 ++++++--
.../testsuite/std/ranges/adaptors/elements.cc | 24 ++++++++++++++++++++++
.../testsuite/std/ranges/adaptors/transform.cc | 24 ++++++++++++++++++++++
3 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 4b596d41a47..ea271150bd7 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1837,9 +1837,11 @@ namespace views
requires random_access_range<_Base>
{ return {*__i._M_parent, __i._M_current - __n}; }
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3483. transform_view::iterator's difference is overconstrained
friend constexpr difference_type
operator-(const _Iterator& __x, const _Iterator& __y)
- requires random_access_range<_Base>
+ requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
{ return __x._M_current - __y._M_current; }
friend constexpr decltype(auto)
@@ -3563,9 +3565,11 @@ namespace views
requires random_access_range<_Base>
{ return _Iterator{__x} -= __y; }
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3483. transform_view::iterator's difference is overconstrained
friend constexpr difference_type
operator-(const _Iterator& __x, const _Iterator& __y)
- requires random_access_range<_Base>
+ requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
{ return __x._M_current - __y._M_current; }
friend _Sentinel<_Const>;
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc
index 3026adf4f28..94dd7c94505 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc
@@ -66,9 +66,33 @@ test02()
VERIFY( ranges::equal(v2, (std::pair<char, int>[]){{1,2}}) );
}
+struct X
+{
+ using Iter = __gnu_test::forward_iterator_wrapper<std::pair<int, X>>;
+
+ friend auto operator-(Iter l, Iter r) { return l.ptr - r.ptr; }
+};
+
+void
+test03()
+{
+ // LWG 3483
+ std::pair<int, X> x[3];
+ __gnu_test::test_forward_range<std::pair<int, X>> r(x);
+ auto v = views::elements<1>(r);
+ auto b = begin(v);
+ static_assert( !ranges::random_access_range<decltype(r)> );
+ static_assert( std::sized_sentinel_for<decltype(b), decltype(b)> );
+ VERIFY( (next(b, 1) - b) == 1 );
+ const auto v_const = v;
+ auto b_const = begin(v_const);
+ VERIFY( (next(b_const, 2) - b_const) == 2 );
+}
+
int
main()
{
test01();
test02();
+ test03();
}
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc
index c14e36e0cef..41a7d3b3321 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc
@@ -122,6 +122,29 @@ test05()
b = ranges::end(v);
}
+struct Y
+{
+ using Iter = __gnu_test::forward_iterator_wrapper<Y>;
+
+ friend auto operator-(Iter l, Iter r) { return l.ptr - r.ptr; }
+};
+
+void
+test06()
+{
+ // LWG 3483
+ Y y[3];
+ __gnu_test::test_forward_range<Y> r(y);
+ auto v = views::transform(r, std::identity{});
+ auto b = begin(v);
+ static_assert( !ranges::random_access_range<decltype(r)> );
+ static_assert( std::sized_sentinel_for<decltype(b), decltype(b)> );
+ VERIFY( (next(b, 1) - b) == 1 );
+ const auto v_const = v;
+ auto b_const = begin(v_const);
+ VERIFY( (next(b_const, 2) - b_const) == 2 );
+}
+
int
main()
{
@@ -130,4 +153,5 @@ main()
test03();
test04();
test05();
+ test06();
}
More information about the Libstdc++-cvs
mailing list