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 |
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.
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 --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(); }