9 Iterators library [iterators]

9.8 Stream iterators [iterators.stream]

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 ]

9.8.1 Class template istream_iterator [istream.iterator]

The class template istream_iterator is an input iterator ([iterators.input]) that reads (using operator>>) successive elements from the input stream for which it was constructed. After it is constructed, and every time ++ is used, the iterator reads and stores a value of T. If the iterator fails to read and store a value of T (fail() on the stream returns true), the iterator becomes equal to the end-of-stream iterator value. The constructor with no arguments istream_iterator() always constructs an end-of-stream input iterator object, which is the only legitimate iterator to be used for the end condition. The result of operator* on an end-of-stream iterator is not defined. For any other iterator value a const T& is returned. The result of operator-> on an end-of-stream iterator is not defined. For any other iterator value a const T* is returned. The behavior of a program that applies operator++() to an end-of-stream iterator is undefined. It is impossible to store things into istream iterators.

Two end-of-stream iterators are always equal. An end-of-stream iterator is not equal to a non-end-of-stream iterator. Two non-end-of-stream iterators are equal when they are constructed from the same stream.

namespace std { namespace experimental { namespace ranges { inline namespace v1 {
  template <class T, class charT = char, class traits = char_traits<charT>,
      class Distance = ptrdiff_t>
  class istream_iterator {
  public:
    typedef input_iterator_tag iterator_category;
    typedef Distance difference_type;
    typedef T value_type;
    typedef const T& reference;
    typedef const T* pointer;
    typedef charT char_type;
    typedef traits traits_type;
    typedef basic_istream<charT, traits> istream_type;
    constexpr istream_iterator();
    constexpr istream_iterator(default_sentinel);
    istream_iterator(istream_type& s);
    istream_iterator(const istream_iterator& x) = default;
    ~istream_iterator() = default;

    const T& operator*() const;
    const T* operator->() const;
    istream_iterator& operator++();
    istream_iterator  operator++(int);
  private:
    basic_istream<charT, traits>* in_stream; // exposition only
    T value;                                 // exposition only
  };

  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);
  template <class T, class charT, class traits, class Distance>
    bool operator==(default_sentinel x,
            const istream_iterator<T, charT, traits, Distance>& y);
  template <class T, class charT, class traits, class Distance>
    bool operator==(const istream_iterator<T, charT, traits, Distance>& x,
            default_sentinel y);
  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);
  template <class T, class charT, class traits, class Distance>
    bool operator!=(default_sentinel x,
            const istream_iterator<T, charT, traits, Distance>& y);
  template <class T, class charT, class traits, class Distance>
    bool operator!=(const istream_iterator<T, charT, traits, Distance>& x,
            default_sentinel y);
}}}}

9.8.1.1 istream_iterator constructors and destructor [istream.iterator.cons]

constexpr istream_iterator(); constexpr istream_iterator(default_sentinel);

Effects: Constructs the end-of-stream iterator. If T is a literal type, then these constructors shall be constexpr constructors.

Postcondition: in_stream == nullptr.

istream_iterator(istream_type& s);

Effects: Initializes in_stream with &s. value may be initialized during construction or the first time it is referenced.

Postcondition: in_stream == &s.

istream_iterator(const istream_iterator& x) = default;

Effects: Constructs a copy of x. If T is a literal type, then this constructor shall be a trivial copy constructor.

Postcondition: in_stream == x.in_stream.

~istream_iterator() = default;

Effects: The iterator is destroyed. If T is a literal type, then this destructor shall be a trivial destructor.

9.8.1.2 istream_iterator operations [istream.iterator.ops]

const T& operator*() const;

Returns: value.

const T* operator->() const;

Effects: Equivalent to: return addressof(operator*()).

istream_iterator& operator++();

Requires: in_stream != nullptr.

Effects: *in_stream >> value.

Returns: *this.

istream_iterator operator++(int);

Requires: in_stream != nullptr.

Effects:

istream_iterator tmp = *this;
*in_stream >> value;
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.

template <class T, class charT, class traits, class Distance> bool operator==(default_sentinel x, const istream_iterator<T, charT, traits, Distance> &y);

Returns: nullptr == y.in_stream.

template <class T, class charT, class traits, class Distance> bool operator==(const istream_iterator<T, charT, traits, Distance> &x, default_sentinel y);

Returns: x.in_stream == nullptr.

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); template <class T, class charT, class traits, class Distance> bool operator!=(default_sentinel x, const istream_iterator<T, charT, traits, Distance>& y); template <class T, class charT, class traits, class Distance> bool operator!=(const istream_iterator<T, charT, traits, Distance>& x, default_sentinel y);

Returns: !(x == y)

9.8.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. It is not possible to get a value out of the output iterator. Its only use is as an output iterator in situations like

while (first != last)
  *result++ = *first++;

ostream_iterator is defined as:

namespace std { namespace experimental { namespace ranges { inline namespace v1 {
  template <class T, class charT = char, class traits = char_traits<charT>>
  class ostream_iterator {
  public:
    typedef ptrdiff_t difference_type;
    typedef charT char_type;
    typedef traits traits_type;
    typedef basic_ostream<charT, traits> ostream_type;
    constexpr ostream_iterator() noexcept;
    ostream_iterator(ostream_type& s) noexcept;
    ostream_iterator(ostream_type& s, const charT* delimiter) noexcept;
    ostream_iterator(const ostream_iterator& x) noexcept;
    ~ostream_iterator();
    ostream_iterator& operator=(const T& value);

    ostream_iterator& operator*();
    ostream_iterator& operator++();
    ostream_iterator& operator++(int);
  private:
    basic_ostream<charT, traits>* out_stream;  // exposition only
    const charT* delim;                        // exposition only
  };
}}}}

9.8.2.1 ostream_iterator constructors and destructor [ostream.iterator.cons.des]

constexpr ostream_iterator() noexcept;

Effects: Initializes out_stream and delim with nullptr.

ostream_iterator(ostream_type& s) noexcept;

Effects: Initializes out_stream with &s and delim with nullptr.

ostream_iterator(ostream_type& s, const charT* delimiter) noexcept;

Effects: Initializes out_stream with &s and delim with delimiter.

ostream_iterator(const ostream_iterator& x) noexcept;

Effects: Constructs a copy of x.

~ostream_iterator();

Effects: The iterator is destroyed.

9.8.2.2 ostream_iterator operations [ostream.iterator.ops]

ostream_iterator& operator=(const T& value);

Effects: Equivalent to:

*out_stream << value;
if(delim != nullptr)
  *out_stream << delim;
return *this;

ostream_iterator& operator*();

Returns: *this.

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

Returns: *this.

9.8.3 Class template istreambuf_iterator [istreambuf.iterator]

The class template istreambuf_iterator defines an input iterator ([iterators.input]) 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 { namespace experimental { namespace ranges { inline namespace v1 {
  template <class charT, class traits = char_traits<charT>>
  class istreambuf_iterator {
  public:
    typedef input_iterator_tag             iterator_category;
    typedef charT                          value_type;
    typedef typename traits::off_type      difference_type;
    typedef charT                          reference;
    typedef unspecified                   pointer;
    typedef charT                          char_type;
    typedef traits                         traits_type;
    typedef typename traits::int_type      int_type;
    typedef basic_streambuf<charT, traits> streambuf_type;
    typedef basic_istream<charT, traits>   istream_type;

    class proxy;                           // exposition only

    constexpr istreambuf_iterator() noexcept;
    constexpr istreambuf_iterator(default_sentinel) 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;
    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==(default_sentinel a,
            const istreambuf_iterator<charT, traits>& b);
  template <class charT, class traits>
    bool operator==(const istreambuf_iterator<charT, traits>& a,
            default_sentinel b);
  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!=(default_sentinel a,
            const istreambuf_iterator<charT, traits>& b);
  template <class charT, class traits>
    bool operator!=(const istreambuf_iterator<charT, traits>& a,
            default_sentinel b);
}}}}

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

namespace std { namespace experimental { namespace ranges { inline namespace v1 {
  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.

9.8.3.2 istreambuf_iterator constructors [istreambuf.iterator.cons]

constexpr istreambuf_iterator() noexcept; constexpr istreambuf_iterator(default_sentinel) noexcept;

Effects: Constructs the end-of-stream iterator.

istreambuf_iterator(basic_istream<charT, traits>& s) noexcept; istreambuf_iterator(basic_streambuf<charT, traits>* s) noexcept;

Effects: Constructs an istreambuf_iterator that uses the basic_streambuf object *(s.rdbuf()), or *s, respectively. Constructs an end-of-stream iterator if s.rdbuf() is null.

istreambuf_iterator(const proxy& p) noexcept;

Effects: Constructs a istreambuf_iterator that uses the basic_streambuf object pointed to by the proxy object's constructor argument p.

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

charT operator*() const

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

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

istreambuf_iterator& istreambuf_iterator<charT, traits>::operator++();

Effects: Equivalent to sbuf_->sbumpc().

Returns: *this.

proxy istreambuf_iterator<charT, traits>::operator++(int);

Effects: Equivalent to: return proxy(sbuf_->sbumpc(), sbuf_);

9.8.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.

9.8.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);

Effects: Equivalent to: return a.equal(b);

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

Effects: Equivalent to: return istreambuf_iterator<charT, traits>{}.equal(b);

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

Effects: Equivalent to: return a.equal(istreambuf_iterator<charT, traits>{});

9.8.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); template <class charT, class traits> bool operator!=(default_sentinel a, const istreambuf_iterator<charT, traits>& b); template <class charT, class traits> bool operator!=(const istreambuf_iterator<charT, traits>& a, default_sentinel b);

Effects: Equivalent to: return !(a == b);

9.8.4 Class template ostreambuf_iterator [ostreambuf.iterator]

namespace std { namespace experimental { namespace ranges { inline namespace v1 {
  template <class charT, class traits = char_traits<charT>>
  class ostreambuf_iterator {
  public:
    typedef ptrdiff_t                      difference_type;
    typedef charT                          char_type;
    typedef traits                         traits_type;
    typedef basic_streambuf<charT, traits> streambuf_type;
    typedef basic_ostream<charT, traits>   ostream_type;

    constexpr ostreambuf_iterator() noexcept;
    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_;                // exposition only
  };
}}}}

The class template ostreambuf_iterator writes successive characters onto the output stream from which it was constructed. It is not possible to get a character value out of the output iterator.

9.8.4.1 ostreambuf_iterator constructors [ostreambuf.iter.cons]

constexpr ostreambuf_iterator() noexcept;

Effects: Initializes sbuf_ with nullptr.

ostreambuf_iterator(ostream_type& s) noexcept;

Requires: s.rdbuf() != nullptr.

Effects: Initializes sbuf_ with s.rdbuf().

ostreambuf_iterator(streambuf_type* s) noexcept;

Requires: s != nullptr.

Effects: Initializes sbuf_ with s.

9.8.4.2 ostreambuf_iterator operations [ostreambuf.iter.ops]

ostreambuf_iterator& operator=(charT c);

Requires: sbuf_ != nullptr.

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;

Requires: sbuf_ != nullptr.

Returns: true if in any prior use of member operator=, the call to sbuf_->sputc() returned traits::eof(); or false otherwise.