public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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).