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 ]
The class template istream_iterator is an input iterator ([input.iterators]) 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 { template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t> class istream_iterator: public iterator<input_iterator_tag, T, Distance, const T*, const T&> { public: typedef charT char_type; typedef traits traits_type; typedef basic_istream<charT,traits> istream_type; see below istream_iterator(); 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<T,charT,traits,Distance>& operator++(); istream_iterator<T,charT,traits,Distance> 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!=(const istream_iterator<T,charT,traits,Distance>& x, const istream_iterator<T,charT,traits,Distance>& y); }
Effects: Constructs the end-of-stream iterator. If T is a literal type, then this constructor shall be a constexpr constructor.
Postcondition: in_stream == 0.
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.
Returns: value.
Returns: &(operator*()).
istream_iterator<T,charT,traits,Distance>& operator++();
Requires: in_stream != 0.
Effects: *in_stream >> value.
Returns: *this.
istream_iterator<T,charT,traits,Distance> operator++(int);
Requires: in_stream != 0.
Effects:
istream_iterator<T,charT,traits,Distance> 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);
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 == y)
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 { template <class T, class charT = char, class traits = char_traits<charT> > class ostream_iterator: public iterator<output_iterator_tag, void, void, void, void> { public: typedef charT char_type; typedef traits traits_type; typedef basic_ostream<charT,traits> ostream_type; ostream_iterator(ostream_type& s); ostream_iterator(ostream_type& s, const charT* delimiter); ostream_iterator(const ostream_iterator<T,charT,traits>& x); ~ostream_iterator(); ostream_iterator<T,charT,traits>& operator=(const T& value); ostream_iterator<T,charT,traits>& operator*(); ostream_iterator<T,charT,traits>& operator++(); ostream_iterator<T,charT,traits>& operator++(int); private: basic_ostream<charT,traits>* out_stream; // exposition only const charT* delim; // exposition only }; }
ostream_iterator(ostream_type& s);
Effects: Initializes out_stream with &s and delim with null.
ostream_iterator(ostream_type& s, const charT* delimiter);
Effects: Initializes out_stream with &s and delim with delimiter.
ostream_iterator(const ostream_iterator& x);
Effects: Constructs a copy of x.
Effects: The iterator is destroyed.
ostream_iterator& operator=(const T& value);
Effects:
*out_stream << value; if (delim != 0) *out_stream << delim; return *this;
ostream_iterator& operator*();
Returns: *this.
ostream_iterator& operator++();
ostream_iterator& operator++(int);
Returns: *this.
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 iterator<input_iterator_tag, charT, typename traits::off_type, unspecified, charT> { public: 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; 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<charT,traits>& 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); }
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.
constexpr istreambuf_iterator() 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.
Returns: The character obtained via the streambuf member sbuf_->sgetc().
istreambuf_iterator<charT,traits>&
istreambuf_iterator<charT,traits>::operator++();
Effects: sbuf_->sbumpc().
Returns: *this.
proxy istreambuf_iterator<charT,traits>::operator++(int);
Returns: proxy(sbuf_->sbumpc(), sbuf_).
bool equal(const istreambuf_iterator<charT,traits>& 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).
template <class charT, class traits>
bool operator!=(const istreambuf_iterator<charT,traits>& a,
const istreambuf_iterator<charT,traits>& b);
Returns: !a.equal(b).
namespace std {
template <class charT, class traits = char_traits<charT> >
class ostreambuf_iterator :
public iterator<output_iterator_tag, void, void, void, void> {
public:
typedef charT char_type;
typedef traits traits_type;
typedef basic_streambuf<charT,traits> streambuf_type;
typedef basic_ostream<charT,traits> ostream_type;
public:
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.
ostreambuf_iterator(ostream_type& s) noexcept;
Requires: s.rdbuf() shall not be a null pointer.
Effects: Initializes sbuf_ with s.rdbuf().
ostreambuf_iterator(streambuf_type* s) noexcept;
Requires: s shall not be a null pointer.
Effects: Initializes sbuf_ with s.
ostreambuf_iterator<charT,traits>&
operator=(charT c);
Effects: If failed() yields false, calls sbuf_->sputc(c); otherwise has no effect.
Returns: *this.
ostreambuf_iterator<charT,traits>& operator*();
Returns: *this.
ostreambuf_iterator<charT,traits>& operator++();
ostreambuf_iterator<charT,traits>& operator++(int);
Returns: *this.
Returns: true if in any prior use of member operator=, the call to sbuf_->sputc() returned traits::eof(); or false otherwise.