[PATCH 4/3] Add [range.istream]
Patrick Palka
ppalka@redhat.com
Fri Feb 7 14:46:00 GMT 2020
On Fri, 7 Feb 2020, Jonathan Wakely wrote:
> On 06/02/20 19:52 -0500, Patrick Palka wrote:
> > This patch adds ranges::basic_istream_view and ranges::istream_view. This
> > seems
> > to be the last missing part of the ranges header.
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/std/ranges (ranges::__detail::__stream_extractable,
> > ranges::basic_istream_view, ranges::istream_view): Define.
> > * testsuite/std/ranges/istream_view: New test.
> > ---
> > libstdc++-v3/include/std/ranges | 94 +++++++++++++++++++
> > .../testsuite/std/ranges/istream_view.cc | 76 +++++++++++++++
> > 2 files changed, 170 insertions(+)
> > create mode 100644 libstdc++-v3/testsuite/std/ranges/istream_view.cc
> >
> > diff --git a/libstdc++-v3/include/std/ranges
> > b/libstdc++-v3/include/std/ranges
> > index 8a8fefb6f19..88b98310ef9 100644
> > --- a/libstdc++-v3/include/std/ranges
> > +++ b/libstdc++-v3/include/std/ranges
> > @@ -951,6 +951,100 @@ namespace views
> > inline constexpr _Iota iota{};
> > } // namespace views
> >
> > + namespace __detail
> > + {
> > + template<typename _Val, typename _CharT, typename _Traits>
> > + concept __stream_extractable
> > + = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
>
> I was going to ask for "is" and "t" to use reserved names, but those
> names are actually reserved. std::ctype::is is present since C++98 and
> std::binomial_distribution::t() since C++11. So the names are OK.
Phew! :) I just forgot to uglify those names.
>
> > + } // namespace __detail
> > +
> > + template<movable _Val, typename _CharT, typename _Traits>
> > + requires default_initializable<_Val>
> > + && __detail::__stream_extractable<_Val, _CharT, _Traits>
> > + class basic_istream_view
> > + : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
> > + {
> > + public:
> > + basic_istream_view() = default;
> > +
> > + constexpr explicit
> > + basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
> > + : _M_stream(std::__addressof(__stream))
> > + { }
> > +
> > + constexpr auto
> > + begin()
> > + {
> > + if (_M_stream != nullptr)
> > + *_M_stream >> _M_object;
> > + return _Iterator{*this};
> > + }
> > +
> > + constexpr default_sentinel_t
> > + end() const noexcept
> > + { return default_sentinel; }
> > +
> > + private:
> > + basic_istream<_CharT, _Traits>* _M_stream = nullptr;
> > + _Val _M_object = _Val();
> > +
> > + struct _Iterator
> > + {
> > + public:
> > + using iterator_category = input_iterator_tag;
> > + using difference_type = ptrdiff_t;
> > + using value_type = _Val;
> > +
> > + _Iterator() = default;
> > +
> > + constexpr explicit
> > + _Iterator(basic_istream_view& __parent) noexcept
> > + : _M_parent(std::__addressof(__parent))
> > + { }
> > +
> > + _Iterator(const _Iterator&) = delete;
> > + _Iterator(_Iterator&&) = default;
> > + _Iterator& operator=(const _Iterator&) = delete;
> > + _Iterator& operator=(_Iterator&&) = default;
> > +
> > + _Iterator&
> > + operator++()
> > + {
> > + __glibcxx_assert(_M_parent->_M_stream != nullptr);
> > + *_M_parent->_M_stream >> _M_parent->_M_object;
> > + }
> > +
> > + void
> > + operator++(int)
> > + { ++*this; }
> > +
> > + _Val&
> > + operator*() const
> > + {
> > + __glibcxx_assert(_M_parent->_M_stream != nullptr);
> > + return _M_parent->_M_object;
> > + }
> > +
> > + friend bool
> > + operator==(const _Iterator& __x, default_sentinel_t)
> > + { return __x.__at_end(); }
> > +
> > + private:
> > + basic_istream_view* _M_parent = nullptr;
> > +
> > + bool
> > + __at_end() const
>
> Please rename this to _M_at_end for consistency with the rest of the
> library.
>
> OK for master with that tweak, thanks.
Fixed and committed with that change. Thanks for the review!
More information about the Libstdc++
mailing list