[gcc(refs/vendors/ARM/heads/arm-struct-reorg-wip)] libstdc++: Forward second argument of views::iota using the correct type

Tamar Christina tnfchris@gcc.gnu.org
Fri Jul 17 13:03:36 GMT 2020


https://gcc.gnu.org/g:5586e5060fb6a30ade7a7ef854c21bb89b7065c9

commit 5586e5060fb6a30ade7a7ef854c21bb89b7065c9
Author: Patrick Palka <ppalka@redhat.com>
Date:   Wed Feb 19 23:14:02 2020 -0500

    libstdc++: Forward second argument of views::iota using the correct type
    
    We are forwarding the second argument of views::iota using the wrong type,
    causing compile errors when calling views::iota with a value and bound of
    different types, like in the test case below.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/ranges (iota_view): Forward declare _Sentinel.
            (iota_view::_Iterator): Befriend _Sentinel.
            (iota_view::_Sentinel::_M_equal): New member function.
            (iota_view::_Sentinel::operator==): Use it.
            (views::_Iota::operator()): Forward __f using the correct type.
            * testsuite/std/ranges/access/ssize.cc (test06): Don't call views::iota
            with integers of different signedness, to appease iota_view's deduction
            guide.
            * testsuite/std/ranges/iota/iota_view.cc: Augment test.

Diff:
---
 libstdc++-v3/ChangeLog                              | 12 ++++++++++++
 libstdc++-v3/include/std/ranges                     | 12 ++++++++++--
 libstdc++-v3/testsuite/std/ranges/access/ssize.cc   |  2 +-
 libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc | 17 +++++++++++++++++
 4 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 30cf706cdae..deade1c29c0 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,15 @@
+2020-02-20  Patrick Palka  <ppalka@redhat.com>
+
+	* include/std/ranges (iota_view): Forward declare _Sentinel.
+	(iota_view::_Iterator): Befriend _Sentinel.
+	(iota_view::_Sentinel::_M_equal): New member function.
+	(iota_view::_Sentinel::operator==): Use it.
+	(views::_Iota::operator()): Forward __f using the correct type.
+	* testsuite/std/ranges/access/ssize.cc (test06): Don't call views::iota
+	with integers of different signedness, to appease iota_view's deduction
+	guide.
+	* testsuite/std/ranges/iota/iota_view.cc: Augment test.
+
 2020-02-20  Jonathan Wakely  <jwakely@redhat.com>
 
 	* include/bits/range_access.h (ranges::begin): Reject array of
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 7a66491f2e4..6358ce86f79 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -635,6 +635,8 @@ namespace ranges
     class iota_view : public view_interface<iota_view<_Winc, _Bound>>
     {
     private:
+      struct _Sentinel;
+
       struct _Iterator
       {
       private:
@@ -811,11 +813,17 @@ namespace ranges
 
       private:
 	_Winc _M_value = _Winc();
+
+        friend _Sentinel;
       };
 
       struct _Sentinel
       {
       private:
+	constexpr bool
+	_M_equal(const _Iterator& __x) const
+	{ return __x._M_value == _M_bound; }
+
 	_Bound _M_bound = _Bound();
 
       public:
@@ -827,7 +835,7 @@ namespace ranges
 
 	friend constexpr bool
 	operator==(const _Iterator& __x, const _Sentinel& __y)
-	{ return __x._M_value == __y._M_bound; }
+	{ return __y._M_equal(__x); }
 
 	friend constexpr iter_difference_t<_Winc>
 	operator-(const _Iterator& __x, const _Sentinel& __y)
@@ -933,7 +941,7 @@ namespace views
     template<typename _Tp, typename _Up>
       constexpr auto
       operator()(_Tp&& __e, _Up&& __f) const
-      { return iota_view{std::forward<_Tp>(__e), std::forward<_Tp>(__f)}; }
+      { return iota_view{std::forward<_Tp>(__e), std::forward<_Up>(__f)}; }
   };
 
   inline constexpr _Iota iota{};
diff --git a/libstdc++-v3/testsuite/std/ranges/access/ssize.cc b/libstdc++-v3/testsuite/std/ranges/access/ssize.cc
index 6f5478e2bb1..8423654c5f7 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/ssize.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/ssize.cc
@@ -75,7 +75,7 @@ test05()
 void
 test06()
 {
-  auto i = std::views::iota(1ull, 5);
+  auto i = std::views::iota(1ull, 5u);
   auto s = std::ranges::ssize(i);
   using R = std::ranges::range_difference_t<decltype(i)>;
   static_assert( std::same_as<decltype(s), R> );
diff --git a/libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc b/libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc
index 798e745d3f0..65d166fbd3b 100644
--- a/libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc
+++ b/libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc
@@ -61,10 +61,27 @@ test03()
   VERIFY( it == v.end() );
 }
 
+void
+test04()
+{
+  int x[] = {1,2,3};
+  auto v = std::ranges::views::iota(std::counted_iterator(x, 3),
+				    std::default_sentinel);
+  auto it = v.begin();
+  VERIFY( (*it).base() == x );
+  ++it;
+  VERIFY( (*it).base() == x+1 );
+  ++it;
+  VERIFY( (*it).base() == x+2 );
+  ++it;
+  VERIFY( it == v.end() );
+}
+
 int
 main()
 {
   test01();
   test02();
   test03();
+  test04();
 }


More information about the Libstdc++-cvs mailing list