[istreambuf.iterator]

# 24 Iterators library [[iterators]](./#iterators)

## 24.6 Stream iterators [[stream.iterators]](stream.iterators#istreambuf.iterator)

### 24.6.4 Class template istreambuf_iterator [istreambuf.iterator]

#### [24.6.4.1](#general) General [[istreambuf.iterator.general]](istreambuf.iterator.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6844)

The
class templateistreambuf_iterator defines an [input iterator](input.iterators "24.3.5.3 Input iterators [input.iterators]") that
reads successive*characters* from the streambuf for which it was constructed[.](#general-1.sentence-1)

operator* provides access to the current input character, if any[.](#general-1.sentence-2)

Each timeoperator++ is evaluated, the iterator advances to the next input character[.](#general-1.sentence-3)

If the end of stream is reached (streambuf_type​::​sgetc() returnstraits​::​eof()),
the iterator becomes equal to the[*end-of-stream*](#def:end-of-stream) iterator value[.](#general-1.sentence-4)

The default constructoristreambuf_iterator() and the constructoristreambuf_iterator(nullptr) both construct an end-of-stream iterator object suitable for use
as an end-of-range[.](#general-1.sentence-5)

All specializations of istreambuf_iterator shall have a trivial copy
constructor, a constexpr default constructor, and a trivial destructor[.](#general-1.sentence-6)

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6871)

The result ofoperator*() on an end-of-stream iterator is undefined[.](#general-2.sentence-1)

For any other iterator value achar_type value is returned[.](#general-2.sentence-2)

It is impossible to assign a character via an input iterator[.](#general-2.sentence-3)

[ð](#lib:istreambuf_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>; // [[istreambuf.iterator.proxy]](#proxy "24.6.4.2 Class istreambuf_­iterator​::​proxy"), class istreambuf_iterator​::​*proxy*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*};}

#### [24.6.4.2](#proxy) Class istreambuf_iterator​::​*proxy* [[istreambuf.iterator.proxy]](istreambuf.iterator.proxy)

[1](#proxy-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6924)

Classistreambuf_iterator<charT,traits>​::​*proxy* is for exposition only[.](#proxy-1.sentence-1)

An implementation is permitted to provide equivalent functionality without
providing a class with this name[.](#proxy-1.sentence-2)

Classistreambuf_iterator<charT, traits>​::​*proxy* provides a temporary
placeholder as the return value of the post-increment operator
(operator++)[.](#proxy-1.sentence-3)

It keeps the character pointed to by the previous value
of the iterator for some possible future access to get the character[.](#proxy-1.sentence-4)

[ð](#lib:proxy,istreambuf_iterator)

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_; }};}

#### [24.6.4.3](#cons) Constructors [[istreambuf.iterator.cons]](istreambuf.iterator.cons)

[1](#cons-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6955)

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[.](#cons-1.sentence-1)

[ð](#lib:istreambuf_iterator,constructor)

`constexpr istreambuf_iterator() noexcept;
constexpr istreambuf_iterator(default_sentinel_t) noexcept;
`

[2](#cons-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6968)

*Effects*: Initializes sbuf_ with nullptr[.](#cons-2.sentence-1)

[ð](#lib:istreambuf_iterator,constructor_)

`istreambuf_iterator(istream_type& s) noexcept;
`

[3](#cons-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6979)

*Effects*: Initializes sbuf_ with s.rdbuf()[.](#cons-3.sentence-1)

[ð](#lib:istreambuf_iterator,constructor__)

`istreambuf_iterator(streambuf_type* s) noexcept;
`

[4](#cons-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L6990)

*Effects*: Initializes sbuf_ with s[.](#cons-4.sentence-1)

[ð](#lib:istreambuf_iterator,constructor___)

`istreambuf_iterator(const proxy& p) noexcept;
`

[5](#cons-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L7001)

*Effects*: Initializes sbuf_ with p.sbuf_[.](#cons-5.sentence-1)

#### [24.6.4.4](#ops) Operations [[istreambuf.iterator.ops]](istreambuf.iterator.ops)

[ð](#lib:operator*,istreambuf_iterator)

`charT operator*() const;
`

[1](#ops-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L7014)

*Returns*: The character obtained via thestreambuf membersbuf_->sgetc()[.](#ops-1.sentence-1)

[ð](#lib:operator++,istreambuf_iterator)

`istreambuf_iterator& operator++();
`

[2](#ops-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L7028)

*Effects*: As if by sbuf_->sbumpc()[.](#ops-2.sentence-1)

[3](#ops-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L7032)

*Returns*: *this[.](#ops-3.sentence-1)

[ð](#lib:operator++,istreambuf_iterator_)

`proxy operator++(int);
`

[4](#ops-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L7043)

*Returns*: *proxy*(sbuf_->sbumpc(), sbuf_)[.](#ops-4.sentence-1)

[ð](#lib:equal,istreambuf_iterator)

`bool equal(const istreambuf_iterator& b) const;
`

[5](#ops-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L7054)

*Returns*: true if and only if both iterators are at end-of-stream,
or neither is at end-of-stream, regardless of whatstreambuf object they use[.](#ops-5.sentence-1)

[ð](#lib:operator==,istreambuf_iterator)

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

[6](#ops-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L7071)

*Returns*: a.equal(b)[.](#ops-6.sentence-1)

[ð](#lib:operator==,istreambuf_iterator_)

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

[7](#ops-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L7082)

*Returns*: i.equal(s)[.](#ops-7.sentence-1)
