diff mbox series

[1/2] libstdc++: Forward second argument of views::iota using the correct type

Message ID 20200220045332.1385014-1-ppalka@redhat.com
State New
Headers show
Series [1/2] libstdc++: Forward second argument of views::iota using the correct type | expand

Commit Message

Patrick Palka Feb. 20, 2020, 4:53 a.m. UTC
We are forwarding the second argument of views::iota using the wrong type,
causing compiling errors when calling it with a value and bound of different
types, like in the test case below.

libstdc++-v3/ChangeLog:

	* include/std/ranges (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.
---
 libstdc++-v3/include/std/ranges                 |  2 +-
 .../testsuite/std/ranges/access/ssize.cc        |  2 +-
 .../testsuite/std/ranges/iota/iota_view.cc      | 17 +++++++++++++++++
 3 files changed, 19 insertions(+), 2 deletions(-)

Comments

Jonathan Wakely Feb. 20, 2020, 9:24 a.m. UTC | #1
On 19/02/20 23:53 -0500, Patrick Palka wrote:
>We are forwarding the second argument of views::iota using the wrong type,
>causing compiling errors when calling it with a value and bound of different
>types, like in the test case below.

Good catch, OK for master.
Patrick Palka Feb. 20, 2020, 5:52 p.m. UTC | #2
On Thu, 20 Feb 2020, Jonathan Wakely wrote:

> On 19/02/20 23:53 -0500, Patrick Palka wrote:
> > We are forwarding the second argument of views::iota using the wrong type,
> > causing compiling errors when calling it with a value and bound of different
> > types, like in the test case below.
> 
> Good catch, OK for master.

Oops, the second patch in this series includes a friendship change that
should instead be a part of this patch: iota_view::_Iterator must
befriend iota_view::_Sentinel, so that iota_view::_Sentinel::operator==
can access its private members.  This is needed for the new test in
iota_view.cc to compile.

Tested on x86_64-pc-linux-gnu, does this look OK to commit?

-- >8 --

Subject: [PATCH] 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.
---
 libstdc++-v3/ChangeLog                          |  9 +++++++++
 libstdc++-v3/include/std/ranges                 | 12 ++++++++++--
 .../testsuite/std/ranges/access/ssize.cc        |  2 +-
 .../testsuite/std/ranges/iota/iota_view.cc      | 17 +++++++++++++++++
 4 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 30cf706cdae..90098fa9aa5 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,12 @@
+2020-02-20  Patrick Palka  <ppalka@redhat.com>
+
+	* include/std/ranges (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();
 }
Jonathan Wakely Feb. 20, 2020, 6:38 p.m. UTC | #3
On 20/02/20 12:52 -0500, Patrick Palka wrote:
>On Thu, 20 Feb 2020, Jonathan Wakely wrote:
>
>> On 19/02/20 23:53 -0500, Patrick Palka wrote:
>> > We are forwarding the second argument of views::iota using the wrong type,
>> > causing compiling errors when calling it with a value and bound of different
>> > types, like in the test case below.
>>
>> Good catch, OK for master.
>
>Oops, the second patch in this series includes a friendship change that
>should instead be a part of this patch: iota_view::_Iterator must
>befriend iota_view::_Sentinel, so that iota_view::_Sentinel::operator==
>can access its private members.  This is needed for the new test in
>iota_view.cc to compile.
>
>Tested on x86_64-pc-linux-gnu, does this look OK to commit?

Yes, OK for master.
diff mbox series

Patch

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 7a66491f2e4..1b2bf448e9c 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -933,7 +933,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 5aa05be8f20..31092056c76 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/ssize.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/ssize.cc
@@ -80,7 +80,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();
 }