* [committed] libstdc++: Relax constraints on transform_view and elements_view iterators
@ 2020-09-21 13:31 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2020-09-21 13:31 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 419 bytes --]
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.
Tested powerpc64le-linux. Committed to trunk.
I'll backport this to gcc-10 too.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 3967 bytes --]
commit 2ec58cfcea146a61755516ce4ed160827fe0b4ff
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Sep 21 14:30:38 2020
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.
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 23a04d61174..005e89f94b2 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1833,9 +1833,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)
@@ -3538,9 +3540,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();
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-09-21 13:31 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-21 13:31 [committed] libstdc++: Relax constraints on transform_view and elements_view iterators Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).