24 Iterators library [iterators]

24.6 Stream iterators [stream.iterators]

24.6.3 Class template istreambuf_iterator [istreambuf.iterator]

The class template istreambuf_iterator defines an input iterator ([input.iterators]) that reads successive characters from the streambuf for which it was constructed. operator* provides access to the current input character, if any. [ Note: operator-> may return a proxy.  — end note ] Each time operator++ is evaluated, the iterator advances to the next input character. If the end of stream is reached (streambuf_type::sgetc() returns traits::eof()), the iterator becomes equal to the end-of-stream iterator value. The default constructor istreambuf_iterator() and the constructor istreambuf_iterator(0) both construct an end-of-stream iterator object suitable for use as an end-of-range. All specializations of istreambuf_iterator shall have a trivial copy constructor, a constexpr default constructor, and a trivial destructor.

The result of operator*() on an end-of-stream iterator is undefined. For any other iterator value a char_type value is returned. It is impossible to assign a character via an input iterator.

namespace std {
  template<class charT, class traits = char_traits<charT>>
  class istreambuf_iterator {
  public:
    using iterator_category = input_iterator_tag;
    using value_type        = charT;
    using difference_type   = typename traits::off_type;
    using pointer           = unspecified;
    using reference         = charT;
    using char_type         = charT;
    using traits_type       = traits;
    using int_type          = typename traits::int_type;
    using streambuf_type    = basic_streambuf<charT,traits>;
    using istream_type      = basic_istream<charT,traits>;

    class proxy;                          // exposition only

    constexpr istreambuf_iterator() noexcept;
    istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
    ~istreambuf_iterator() = default;
    istreambuf_iterator(istream_type& s) noexcept;
    istreambuf_iterator(streambuf_type* s) noexcept;
    istreambuf_iterator(const proxy& p) noexcept;
    charT operator*() const;
    pointer operator->() const;
    istreambuf_iterator& operator++();
    proxy operator++(int);
    bool equal(const istreambuf_iterator& b) const;
  private:
    streambuf_type* sbuf_;                // exposition only
  };

  template <class charT, class traits>
    bool operator==(const istreambuf_iterator<charT,traits>& a,
            const istreambuf_iterator<charT,traits>& b);
  template <class charT, class traits>
    bool operator!=(const istreambuf_iterator<charT,traits>& a,
            const istreambuf_iterator<charT,traits>& b);
}

24.6.3.1 Class template istreambuf_iterator::proxy [istreambuf.iterator::proxy]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class istreambuf_iterator<charT, traits>::proxy { // exposition only
    charT keep_;
    basic_streambuf<charT,traits>* sbuf_;
    proxy(charT c, basic_streambuf<charT,traits>* sbuf)
      : keep_(c), sbuf_(sbuf) { }
  public:
    charT operator*() { return keep_; }
  };
}

Class istreambuf_iterator<charT,traits>::proxy is for exposition only. An implementation is permitted to provide equivalent functionality without providing a class with this name. Class istreambuf_iterator<charT, traits>::proxy provides a temporary placeholder as the return value of the post-increment operator (operator++). It keeps the character pointed to by the previous value of the iterator for some possible future access to get the character.

24.6.3.2 istreambuf_iterator constructors [istreambuf.iterator.cons]

For each istreambuf_iterator constructor in this section, an end-of-stream iterator is constructed if and only if the exposition-only member sbuf_ is initialized with a null pointer value.

constexpr istreambuf_iterator() noexcept;

Effects: Initializes sbuf_ with nullptr.

istreambuf_iterator(istream_type& s) noexcept;

Effects: Initializes sbuf_ with s.rdbuf().

istreambuf_iterator(streambuf_type* s) noexcept;

Effects: Initializes sbuf_ with s.

istreambuf_iterator(const proxy& p) noexcept;

Effects: Initializes sbuf_ with p.sbuf_.

24.6.3.3 istreambuf_iterator::operator* [istreambuf.iterator::op*]

charT operator*() const

Returns: The character obtained via the streambuf member sbuf_->sgetc().

24.6.3.4 istreambuf_iterator::operator++ [istreambuf.iterator::op++]

istreambuf_iterator& operator++();

Effects: As if by sbuf_->sbumpc().

Returns: *this.

proxy operator++(int);

Returns: proxy(sbuf_->sbumpc(), sbuf_).

24.6.3.5 istreambuf_iterator::equal [istreambuf.iterator::equal]

bool equal(const istreambuf_iterator& b) const;

Returns: true if and only if both iterators are at end-of-stream, or neither is at end-of-stream, regardless of what streambuf object they use.

24.6.3.6 operator== [istreambuf.iterator::op==]

template <class charT, class traits> bool operator==(const istreambuf_iterator<charT,traits>& a, const istreambuf_iterator<charT,traits>& b);

Returns: a.equal(b).

24.6.3.7 operator!= [istreambuf.iterator::op!=]

template <class charT, class traits> bool operator!=(const istreambuf_iterator<charT,traits>& a, const istreambuf_iterator<charT,traits>& b);

Returns: !a.equal(b).