diff mbox series

libstdc++: Make sure iterator_traits<ranges::istream_view::iterator> is populated

Message ID 20200207185926.1861315-1-ppalka@redhat.com
State New
Headers show
Series libstdc++: Make sure iterator_traits<ranges::istream_view::iterator> is populated | expand

Commit Message

Patrick Palka Feb. 7, 2020, 6:59 p.m. UTC
Since basic_istream_view::iterator is neither a cpp17 iterator (because it's
move-only) nor does it define all four of the types {difference_type,
value_type, reference, iterator_category}, then by the rule in
[iterator.traits], its iterator_traits has no members.

More concretely this means that it can't e.g. be composed with a
views::transform or a views::filter because they look at the iterator_traits of
the underlying view.

This seems to be a defect in the current spec.

libstdc++-v3/ChangeLog:

	* include/std/ranges (ranges::basic_istream_view::iterator::reference):
	Define it so that this iterator's iterator_traits is populated.
	* testsuite/std/ranges/istream_view.cc: Augment test.
---
 libstdc++-v3/include/std/ranges                   |  1 +
 libstdc++-v3/testsuite/std/ranges/istream_view.cc | 11 +++++++++++
 2 files changed, 12 insertions(+)

Comments

Jonathan Wakely Feb. 10, 2020, 8:47 a.m. UTC | #1
On 07/02/20 13:59 -0500, Patrick Palka wrote:
>Since basic_istream_view::iterator is neither a cpp17 iterator (because it's
>move-only) nor does it define all four of the types {difference_type,
>value_type, reference, iterator_category}, then by the rule in
>[iterator.traits], its iterator_traits has no members.
>
>More concretely this means that it can't e.g. be composed with a
>views::transform or a views::filter because they look at the iterator_traits of
>the underlying view.
>
>This seems to be a defect in the current spec.

Agreed, but Casey Carter doesn't think this fix is correct, as it
would make this iterator appear to be a Cpp17InputIterator, which is
unwanted.

Please don't make this change, we should wait for guidance from LWG.
Patrick Palka Feb. 10, 2020, 3:13 p.m. UTC | #2
On Mon, 10 Feb 2020, Jonathan Wakely wrote:

> On 07/02/20 13:59 -0500, Patrick Palka wrote:
> > Since basic_istream_view::iterator is neither a cpp17 iterator (because it's
> > move-only) nor does it define all four of the types {difference_type,
> > value_type, reference, iterator_category}, then by the rule in
> > [iterator.traits], its iterator_traits has no members.
> > 
> > More concretely this means that it can't e.g. be composed with a
> > views::transform or a views::filter because they look at the iterator_traits
> > of
> > the underlying view.
> > 
> > This seems to be a defect in the current spec.
> 
> Agreed, but Casey Carter doesn't think this fix is correct, as it
> would make this iterator appear to be a Cpp17InputIterator, which is
> unwanted.
> 
> Please don't make this change, we should wait for guidance from LWG.

Sounds good.
diff mbox series

Patch

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 891ecf75eff..6e982d6ded3 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -996,6 +996,7 @@  namespace views
 	using iterator_category = input_iterator_tag;
 	using difference_type = ptrdiff_t;
 	using value_type = _Val;
+	using reference = _Val&;
 
 	_Iterator() = default;
 
diff --git a/libstdc++-v3/testsuite/std/ranges/istream_view.cc b/libstdc++-v3/testsuite/std/ranges/istream_view.cc
index 1729459bce3..7feb3ff4b0a 100644
--- a/libstdc++-v3/testsuite/std/ranges/istream_view.cc
+++ b/libstdc++-v3/testsuite/std/ranges/istream_view.cc
@@ -68,10 +68,21 @@  test03()
   VERIFY( ranges::equal(v, (int[]){0,1,2,3,4}) );
 }
 
+void
+test04()
+{
+  std::string s = "0123456789";
+  auto ss = std::istringstream{s};
+  static_assert(ranges::input_range<decltype(ranges::istream_view<X>(ss))>);
+  auto v = ranges::istream_view<X>(ss) | views::transform(&X::c);
+  VERIFY( ranges::equal(v, s) );
+}
+
 int
 main()
 {
   test01();
   test02();
   test03();
+  test04();
 }