23 Iterators library [iterators]

23.6 Stream iterators [stream.iterators]

To make it possible for algorithmic templates to work directly with input/output streams, appropriate iterator-like class templates are provided.
Example
:
partial_sum(istream_iterator<double, char>(cin),
  istream_iterator<double, char>(),
  ostream_iterator<double, char>(cout, "\n"));
reads a file containing floating-point numbers from cin, and prints the partial sums onto cout.
— end example
 ]

23.6.1 Class template istream_­iterator [istream.iterator]

The class template istream_­iterator is an input iterator ([input.iterators]) that reads successive elements from the input stream for which it was constructed.
namespace std {
  template<class T, class charT = char, class traits = char_traits<charT>,
           class Distance = ptrdiff_t>
  class istream_iterator {
  public:
    using iterator_category = input_iterator_tag;
    using value_type        = T;
    using difference_type   = Distance;
    using pointer           = const T*;
    using reference         = const T&;
    using char_type         = charT;
    using traits_type       = traits;
    using istream_type      = basic_istream<charT,traits>;

    constexpr istream_iterator();
    constexpr istream_iterator(default_sentinel_t);
    istream_iterator(istream_type& s);
    istream_iterator(const istream_iterator& x) = default;
    ~istream_iterator() = default;
    istream_iterator& operator=(const istream_iterator&) = default;

    const T& operator*() const;
    const T* operator->() const;
    istream_iterator& operator++();
    istream_iterator  operator++(int);

    friend bool operator==(const istream_iterator& i, default_sentinel_t);

  private:
    basic_istream<charT,traits>* in_stream; // exposition only
    T value;                                // exposition only
  };
}
The type T shall meet the Cpp17DefaultConstructible, Cpp17CopyConstructible, and Cpp17CopyAssignable requirements.

23.6.1.1 Constructors and destructor [istream.iterator.cons]

constexpr istream_iterator(); constexpr istream_iterator(default_sentinel_t);
Effects: Constructs the end-of-stream iterator, value-initializing value.
Postconditions: in_­stream == nullptr is true.
Remarks: If the initializer T() in the declaration auto x = T(); is a constant initializer ([expr.const]), then these constructors are constexpr constructors.
istream_iterator(istream_type& s);
Effects: Initializes in_­stream with addressof(s), value-initializes value, and then calls operator++().
istream_iterator(const istream_iterator& x) = default;
Postconditions: in_­stream == x.in_­stream is true.
Remarks: If is_­trivially_­copy_­constructible_­v<T> is true, then this constructor is trivial.
~istream_iterator() = default;
Remarks: If is_­trivially_­destructible_­v<T> is true, then this destructor is trivial.

23.6.1.2 Operations [istream.iterator.ops]

const T& operator*() const;
Preconditions: in_­stream != nullptr is true.
Returns: value.
const T* operator->() const;
Preconditions: in_­stream != nullptr is true.
Returns: addressof(value).
istream_iterator& operator++();
Preconditions: in_­stream != nullptr is true.
Effects: Equivalent to:
if (!(*in_stream >> value))
  in_stream = nullptr;
Returns: *this.
istream_iterator operator++(int);
Preconditions: in_­stream != nullptr is true.
Effects: Equivalent to:
istream_iterator tmp = *this;
++*this;
return tmp;
template<class T, class charT, class traits, class Distance> bool operator==(const istream_iterator<T,charT,traits,Distance>& x, const istream_iterator<T,charT,traits,Distance>& y);
Returns: x.in_­stream == y.in_­stream.
friend bool operator==(const istream_iterator& i, default_sentinel_t);
Returns: !i.in_­stream.

23.6.2 Class template ostream_­iterator [ostream.iterator]

ostream_­iterator writes (using operator<<) successive elements onto the output stream from which it was constructed.
If it was constructed with charT* as a constructor argument, this string, called a delimiter string, is written to the stream after every T is written.
namespace std {
  template<class T, class charT = char, class traits = char_traits<charT>>
  class ostream_iterator {
  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = ptrdiff_t;
    using pointer           = void;
    using reference         = void;
    using char_type         = charT;
    using traits_type       = traits;
    using ostream_type      = basic_ostream<charT,traits>;

    constexpr ostream_iterator() noexcept = default;
    ostream_iterator(ostream_type& s);
    ostream_iterator(ostream_type& s, const charT* delimiter);
    ostream_iterator(const ostream_iterator& x);
    ~ostream_iterator();
    ostream_iterator& operator=(const ostream_iterator&) = default;
    ostream_iterator& operator=(const T& value);

    ostream_iterator& operator*();
    ostream_iterator& operator++();
    ostream_iterator& operator++(int);

  private:
    basic_ostream<charT,traits>* out_stream = nullptr;          // exposition only
    const charT* delim = nullptr;                               // exposition only
  };
}

23.6.2.1 Constructors and destructor [ostream.iterator.cons.des]

ostream_iterator(ostream_type& s);
Effects: Initializes out_­stream with addressof(s) and delim with nullptr.
ostream_iterator(ostream_type& s, const charT* delimiter);
Effects: Initializes out_­stream with addressof(s) and delim with delimiter.

23.6.2.2 Operations [ostream.iterator.ops]

ostream_iterator& operator=(const T& value);
Effects: As if by:
*out_stream << value;
if (delim)
  *out_stream << delim;
return *this;
ostream_iterator& operator*();
Returns: *this.
ostream_iterator& operator++(); ostream_iterator& operator++(int);
Returns: *this.

23.6.3 Class template istreambuf_­iterator [istreambuf.iterator]

The class template istreambuf_­iterator defines an input iterator that reads successive characters from the streambuf for which it was constructed.
operator* provides access to the current input character, if any.
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(nullptr) 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;
    constexpr istreambuf_iterator(default_sentinel_t) 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;
    istreambuf_iterator& operator=(const istreambuf_iterator&) noexcept = default;
    charT operator*() const;
    istreambuf_iterator& operator++();
    proxy operator++(int);
    bool equal(const istreambuf_iterator& b) const;

    friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s);

  private:
    streambuf_type* sbuf_;              // exposition only
  };
}

23.6.3.1 Class istreambuf_­iterator​::​proxy [istreambuf.iterator.proxy]

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.
namespace std {
  template<class charT, class traits>
  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_; }
  };
}

23.6.3.2 Constructors [istreambuf.iterator.cons]

For each istreambuf_­iterator constructor in this subclause, 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; constexpr istreambuf_iterator(default_sentinel_t) 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_­.

23.6.3.3 Operations [istreambuf.iterator.ops]

charT operator*() const;
Returns: The character obtained via the streambuf member sbuf_­->sgetc().
istreambuf_iterator& operator++();
Effects: As if by sbuf_­->sbumpc().
Returns: *this.
proxy operator++(int);
Returns: proxy(sbuf_­->sbumpc(), sbuf_­).
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.
template<class charT, class traits> bool operator==(const istreambuf_iterator<charT,traits>& a, const istreambuf_iterator<charT,traits>& b);
Returns: a.equal(b).
friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s);
Returns: i.equal(s).

23.6.4 Class template ostreambuf_­iterator [ostreambuf.iterator]

The class template ostreambuf_­iterator writes successive characters onto the output stream from which it was constructed.
namespace std {
  template<class charT, class traits = char_traits<charT>>
  class ostreambuf_iterator {
  public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = ptrdiff_t;
    using pointer           = void;
    using reference         = void;
    using char_type         = charT;
    using traits_type       = traits;
    using streambuf_type    = basic_streambuf<charT,traits>;
    using ostream_type      = basic_ostream<charT,traits>;

    constexpr ostreambuf_iterator() noexcept = default;
    ostreambuf_iterator(ostream_type& s) noexcept;
    ostreambuf_iterator(streambuf_type* s) noexcept;
    ostreambuf_iterator& operator=(charT c);

    ostreambuf_iterator& operator*();
    ostreambuf_iterator& operator++();
    ostreambuf_iterator& operator++(int);
    bool failed() const noexcept;

  private:
    streambuf_type* sbuf_ = nullptr;    // exposition only
  };
}

23.6.4.1 Constructors [ostreambuf.iter.cons]

ostreambuf_iterator(ostream_type& s) noexcept;
Preconditions: s.rdbuf() is not a null pointer.
Effects: Initializes sbuf_­ with s.rdbuf().
ostreambuf_iterator(streambuf_type* s) noexcept;
Preconditions: s is not a null pointer.
Effects: Initializes sbuf_­ with s.

23.6.4.2 Operations [ostreambuf.iter.ops]

ostreambuf_iterator& operator=(charT c);
Effects: If failed() yields false, calls sbuf_­->sputc(c); otherwise has no effect.
Returns: *this.
ostreambuf_iterator& operator*();
Returns: *this.
ostreambuf_iterator& operator++(); ostreambuf_iterator& operator++(int);
Returns: *this.
bool failed() const noexcept;
Returns: true if in any prior use of member operator=, the call to sbuf_­->sputc() returned traits​::​eof(); or false otherwise.