9 Iterators library [iterators]

9.8 Stream iterators [iterators.stream]

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)