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!

Reply via email to