1*38fd1498Szrj // Streambuf iterators
2*38fd1498Szrj
3*38fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj
25*38fd1498Szrj /** @file bits/streambuf_iterator.h
26*38fd1498Szrj * This is an internal header file, included by other library headers.
27*38fd1498Szrj * Do not attempt to use it directly. @headername{iterator}
28*38fd1498Szrj */
29*38fd1498Szrj
30*38fd1498Szrj #ifndef _STREAMBUF_ITERATOR_H
31*38fd1498Szrj #define _STREAMBUF_ITERATOR_H 1
32*38fd1498Szrj
33*38fd1498Szrj #pragma GCC system_header
34*38fd1498Szrj
35*38fd1498Szrj #include <streambuf>
36*38fd1498Szrj #include <debug/debug.h>
37*38fd1498Szrj
_GLIBCXX_VISIBILITY(default)38*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
39*38fd1498Szrj {
40*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
41*38fd1498Szrj
42*38fd1498Szrj /**
43*38fd1498Szrj * @addtogroup iterators
44*38fd1498Szrj * @{
45*38fd1498Szrj */
46*38fd1498Szrj
47*38fd1498Szrj // 24.5.3 Template class istreambuf_iterator
48*38fd1498Szrj /// Provides input iterator semantics for streambufs.
49*38fd1498Szrj template<typename _CharT, typename _Traits>
50*38fd1498Szrj class istreambuf_iterator
51*38fd1498Szrj : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
52*38fd1498Szrj _CharT*,
53*38fd1498Szrj #if __cplusplus >= 201103L
54*38fd1498Szrj // LWG 445.
55*38fd1498Szrj _CharT>
56*38fd1498Szrj #else
57*38fd1498Szrj _CharT&>
58*38fd1498Szrj #endif
59*38fd1498Szrj {
60*38fd1498Szrj public:
61*38fd1498Szrj // Types:
62*38fd1498Szrj //@{
63*38fd1498Szrj /// Public typedefs
64*38fd1498Szrj typedef _CharT char_type;
65*38fd1498Szrj typedef _Traits traits_type;
66*38fd1498Szrj typedef typename _Traits::int_type int_type;
67*38fd1498Szrj typedef basic_streambuf<_CharT, _Traits> streambuf_type;
68*38fd1498Szrj typedef basic_istream<_CharT, _Traits> istream_type;
69*38fd1498Szrj //@}
70*38fd1498Szrj
71*38fd1498Szrj template<typename _CharT2>
72*38fd1498Szrj friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
73*38fd1498Szrj ostreambuf_iterator<_CharT2> >::__type
74*38fd1498Szrj copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
75*38fd1498Szrj ostreambuf_iterator<_CharT2>);
76*38fd1498Szrj
77*38fd1498Szrj template<bool _IsMove, typename _CharT2>
78*38fd1498Szrj friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
79*38fd1498Szrj _CharT2*>::__type
80*38fd1498Szrj __copy_move_a2(istreambuf_iterator<_CharT2>,
81*38fd1498Szrj istreambuf_iterator<_CharT2>, _CharT2*);
82*38fd1498Szrj
83*38fd1498Szrj template<typename _CharT2>
84*38fd1498Szrj friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
85*38fd1498Szrj istreambuf_iterator<_CharT2> >::__type
86*38fd1498Szrj find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
87*38fd1498Szrj const _CharT2&);
88*38fd1498Szrj
89*38fd1498Szrj template<typename _CharT2, typename _Distance>
90*38fd1498Szrj friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
91*38fd1498Szrj void>::__type
92*38fd1498Szrj advance(istreambuf_iterator<_CharT2>&, _Distance);
93*38fd1498Szrj
94*38fd1498Szrj private:
95*38fd1498Szrj // 24.5.3 istreambuf_iterator
96*38fd1498Szrj // p 1
97*38fd1498Szrj // If the end of stream is reached (streambuf_type::sgetc()
98*38fd1498Szrj // returns traits_type::eof()), the iterator becomes equal to
99*38fd1498Szrj // the "end of stream" iterator value.
100*38fd1498Szrj // NB: This implementation assumes the "end of stream" value
101*38fd1498Szrj // is EOF, or -1.
102*38fd1498Szrj mutable streambuf_type* _M_sbuf;
103*38fd1498Szrj int_type _M_c;
104*38fd1498Szrj
105*38fd1498Szrj public:
106*38fd1498Szrj /// Construct end of input stream iterator.
107*38fd1498Szrj _GLIBCXX_CONSTEXPR istreambuf_iterator() _GLIBCXX_USE_NOEXCEPT
108*38fd1498Szrj : _M_sbuf(0), _M_c(traits_type::eof()) { }
109*38fd1498Szrj
110*38fd1498Szrj #if __cplusplus >= 201103L
111*38fd1498Szrj istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
112*38fd1498Szrj
113*38fd1498Szrj ~istreambuf_iterator() = default;
114*38fd1498Szrj #endif
115*38fd1498Szrj
116*38fd1498Szrj /// Construct start of input stream iterator.
117*38fd1498Szrj istreambuf_iterator(istream_type& __s) _GLIBCXX_USE_NOEXCEPT
118*38fd1498Szrj : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
119*38fd1498Szrj
120*38fd1498Szrj /// Construct start of streambuf iterator.
121*38fd1498Szrj istreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT
122*38fd1498Szrj : _M_sbuf(__s), _M_c(traits_type::eof()) { }
123*38fd1498Szrj
124*38fd1498Szrj /// Return the current character pointed to by iterator. This returns
125*38fd1498Szrj /// streambuf.sgetc(). It cannot be assigned. NB: The result of
126*38fd1498Szrj /// operator*() on an end of stream is undefined.
127*38fd1498Szrj char_type
128*38fd1498Szrj operator*() const
129*38fd1498Szrj {
130*38fd1498Szrj int_type __c = _M_get();
131*38fd1498Szrj
132*38fd1498Szrj #ifdef _GLIBCXX_DEBUG_PEDANTIC
133*38fd1498Szrj // Dereferencing a past-the-end istreambuf_iterator is a
134*38fd1498Szrj // libstdc++ extension
135*38fd1498Szrj __glibcxx_requires_cond(!_S_is_eof(__c),
136*38fd1498Szrj _M_message(__gnu_debug::__msg_deref_istreambuf)
137*38fd1498Szrj ._M_iterator(*this));
138*38fd1498Szrj #endif
139*38fd1498Szrj return traits_type::to_char_type(__c);
140*38fd1498Szrj }
141*38fd1498Szrj
142*38fd1498Szrj /// Advance the iterator. Calls streambuf.sbumpc().
143*38fd1498Szrj istreambuf_iterator&
144*38fd1498Szrj operator++()
145*38fd1498Szrj {
146*38fd1498Szrj __glibcxx_requires_cond(_M_sbuf &&
147*38fd1498Szrj (!_S_is_eof(_M_c) || !_S_is_eof(_M_sbuf->sgetc())),
148*38fd1498Szrj _M_message(__gnu_debug::__msg_inc_istreambuf)
149*38fd1498Szrj ._M_iterator(*this));
150*38fd1498Szrj
151*38fd1498Szrj _M_sbuf->sbumpc();
152*38fd1498Szrj _M_c = traits_type::eof();
153*38fd1498Szrj return *this;
154*38fd1498Szrj }
155*38fd1498Szrj
156*38fd1498Szrj /// Advance the iterator. Calls streambuf.sbumpc().
157*38fd1498Szrj istreambuf_iterator
158*38fd1498Szrj operator++(int)
159*38fd1498Szrj {
160*38fd1498Szrj __glibcxx_requires_cond(_M_sbuf &&
161*38fd1498Szrj (!_S_is_eof(_M_c) || !_S_is_eof(_M_sbuf->sgetc())),
162*38fd1498Szrj _M_message(__gnu_debug::__msg_inc_istreambuf)
163*38fd1498Szrj ._M_iterator(*this));
164*38fd1498Szrj
165*38fd1498Szrj istreambuf_iterator __old = *this;
166*38fd1498Szrj __old._M_c = _M_sbuf->sbumpc();
167*38fd1498Szrj _M_c = traits_type::eof();
168*38fd1498Szrj return __old;
169*38fd1498Szrj }
170*38fd1498Szrj
171*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
172*38fd1498Szrj // 110 istreambuf_iterator::equal not const
173*38fd1498Szrj // NB: there is also number 111 (NAD) relevant to this function.
174*38fd1498Szrj /// Return true both iterators are end or both are not end.
175*38fd1498Szrj bool
176*38fd1498Szrj equal(const istreambuf_iterator& __b) const
177*38fd1498Szrj { return _M_at_eof() == __b._M_at_eof(); }
178*38fd1498Szrj
179*38fd1498Szrj private:
180*38fd1498Szrj int_type
181*38fd1498Szrj _M_get() const
182*38fd1498Szrj {
183*38fd1498Szrj int_type __ret = _M_c;
184*38fd1498Szrj if (_M_sbuf && _S_is_eof(__ret) && _S_is_eof(__ret = _M_sbuf->sgetc()))
185*38fd1498Szrj _M_sbuf = 0;
186*38fd1498Szrj return __ret;
187*38fd1498Szrj }
188*38fd1498Szrj
189*38fd1498Szrj bool
190*38fd1498Szrj _M_at_eof() const
191*38fd1498Szrj { return _S_is_eof(_M_get()); }
192*38fd1498Szrj
193*38fd1498Szrj static bool
194*38fd1498Szrj _S_is_eof(int_type __c)
195*38fd1498Szrj {
196*38fd1498Szrj const int_type __eof = traits_type::eof();
197*38fd1498Szrj return traits_type::eq_int_type(__c, __eof);
198*38fd1498Szrj }
199*38fd1498Szrj };
200*38fd1498Szrj
201*38fd1498Szrj template<typename _CharT, typename _Traits>
202*38fd1498Szrj inline bool
203*38fd1498Szrj operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
204*38fd1498Szrj const istreambuf_iterator<_CharT, _Traits>& __b)
205*38fd1498Szrj { return __a.equal(__b); }
206*38fd1498Szrj
207*38fd1498Szrj template<typename _CharT, typename _Traits>
208*38fd1498Szrj inline bool
209*38fd1498Szrj operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
210*38fd1498Szrj const istreambuf_iterator<_CharT, _Traits>& __b)
211*38fd1498Szrj { return !__a.equal(__b); }
212*38fd1498Szrj
213*38fd1498Szrj /// Provides output iterator semantics for streambufs.
214*38fd1498Szrj template<typename _CharT, typename _Traits>
215*38fd1498Szrj class ostreambuf_iterator
216*38fd1498Szrj : public iterator<output_iterator_tag, void, void, void, void>
217*38fd1498Szrj {
218*38fd1498Szrj public:
219*38fd1498Szrj // Types:
220*38fd1498Szrj //@{
221*38fd1498Szrj /// Public typedefs
222*38fd1498Szrj typedef _CharT char_type;
223*38fd1498Szrj typedef _Traits traits_type;
224*38fd1498Szrj typedef basic_streambuf<_CharT, _Traits> streambuf_type;
225*38fd1498Szrj typedef basic_ostream<_CharT, _Traits> ostream_type;
226*38fd1498Szrj //@}
227*38fd1498Szrj
228*38fd1498Szrj template<typename _CharT2>
229*38fd1498Szrj friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
230*38fd1498Szrj ostreambuf_iterator<_CharT2> >::__type
231*38fd1498Szrj copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
232*38fd1498Szrj ostreambuf_iterator<_CharT2>);
233*38fd1498Szrj
234*38fd1498Szrj private:
235*38fd1498Szrj streambuf_type* _M_sbuf;
236*38fd1498Szrj bool _M_failed;
237*38fd1498Szrj
238*38fd1498Szrj public:
239*38fd1498Szrj /// Construct output iterator from ostream.
240*38fd1498Szrj ostreambuf_iterator(ostream_type& __s) _GLIBCXX_USE_NOEXCEPT
241*38fd1498Szrj : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
242*38fd1498Szrj
243*38fd1498Szrj /// Construct output iterator from streambuf.
244*38fd1498Szrj ostreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT
245*38fd1498Szrj : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
246*38fd1498Szrj
247*38fd1498Szrj /// Write character to streambuf. Calls streambuf.sputc().
248*38fd1498Szrj ostreambuf_iterator&
249*38fd1498Szrj operator=(_CharT __c)
250*38fd1498Szrj {
251*38fd1498Szrj if (!_M_failed &&
252*38fd1498Szrj _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
253*38fd1498Szrj _M_failed = true;
254*38fd1498Szrj return *this;
255*38fd1498Szrj }
256*38fd1498Szrj
257*38fd1498Szrj /// Return *this.
258*38fd1498Szrj ostreambuf_iterator&
259*38fd1498Szrj operator*()
260*38fd1498Szrj { return *this; }
261*38fd1498Szrj
262*38fd1498Szrj /// Return *this.
263*38fd1498Szrj ostreambuf_iterator&
264*38fd1498Szrj operator++(int)
265*38fd1498Szrj { return *this; }
266*38fd1498Szrj
267*38fd1498Szrj /// Return *this.
268*38fd1498Szrj ostreambuf_iterator&
269*38fd1498Szrj operator++()
270*38fd1498Szrj { return *this; }
271*38fd1498Szrj
272*38fd1498Szrj /// Return true if previous operator=() failed.
273*38fd1498Szrj bool
274*38fd1498Szrj failed() const _GLIBCXX_USE_NOEXCEPT
275*38fd1498Szrj { return _M_failed; }
276*38fd1498Szrj
277*38fd1498Szrj ostreambuf_iterator&
278*38fd1498Szrj _M_put(const _CharT* __ws, streamsize __len)
279*38fd1498Szrj {
280*38fd1498Szrj if (__builtin_expect(!_M_failed, true)
281*38fd1498Szrj && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len,
282*38fd1498Szrj false))
283*38fd1498Szrj _M_failed = true;
284*38fd1498Szrj return *this;
285*38fd1498Szrj }
286*38fd1498Szrj };
287*38fd1498Szrj
288*38fd1498Szrj // Overloads for streambuf iterators.
289*38fd1498Szrj template<typename _CharT>
290*38fd1498Szrj typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
291*38fd1498Szrj ostreambuf_iterator<_CharT> >::__type
292*38fd1498Szrj copy(istreambuf_iterator<_CharT> __first,
293*38fd1498Szrj istreambuf_iterator<_CharT> __last,
294*38fd1498Szrj ostreambuf_iterator<_CharT> __result)
295*38fd1498Szrj {
296*38fd1498Szrj if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed)
297*38fd1498Szrj {
298*38fd1498Szrj bool __ineof;
299*38fd1498Szrj __copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof);
300*38fd1498Szrj if (!__ineof)
301*38fd1498Szrj __result._M_failed = true;
302*38fd1498Szrj }
303*38fd1498Szrj return __result;
304*38fd1498Szrj }
305*38fd1498Szrj
306*38fd1498Szrj template<bool _IsMove, typename _CharT>
307*38fd1498Szrj typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
308*38fd1498Szrj ostreambuf_iterator<_CharT> >::__type
309*38fd1498Szrj __copy_move_a2(_CharT* __first, _CharT* __last,
310*38fd1498Szrj ostreambuf_iterator<_CharT> __result)
311*38fd1498Szrj {
312*38fd1498Szrj const streamsize __num = __last - __first;
313*38fd1498Szrj if (__num > 0)
314*38fd1498Szrj __result._M_put(__first, __num);
315*38fd1498Szrj return __result;
316*38fd1498Szrj }
317*38fd1498Szrj
318*38fd1498Szrj template<bool _IsMove, typename _CharT>
319*38fd1498Szrj typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
320*38fd1498Szrj ostreambuf_iterator<_CharT> >::__type
321*38fd1498Szrj __copy_move_a2(const _CharT* __first, const _CharT* __last,
322*38fd1498Szrj ostreambuf_iterator<_CharT> __result)
323*38fd1498Szrj {
324*38fd1498Szrj const streamsize __num = __last - __first;
325*38fd1498Szrj if (__num > 0)
326*38fd1498Szrj __result._M_put(__first, __num);
327*38fd1498Szrj return __result;
328*38fd1498Szrj }
329*38fd1498Szrj
330*38fd1498Szrj template<bool _IsMove, typename _CharT>
331*38fd1498Szrj typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
332*38fd1498Szrj _CharT*>::__type
333*38fd1498Szrj __copy_move_a2(istreambuf_iterator<_CharT> __first,
334*38fd1498Szrj istreambuf_iterator<_CharT> __last, _CharT* __result)
335*38fd1498Szrj {
336*38fd1498Szrj typedef istreambuf_iterator<_CharT> __is_iterator_type;
337*38fd1498Szrj typedef typename __is_iterator_type::traits_type traits_type;
338*38fd1498Szrj typedef typename __is_iterator_type::streambuf_type streambuf_type;
339*38fd1498Szrj typedef typename traits_type::int_type int_type;
340*38fd1498Szrj
341*38fd1498Szrj if (__first._M_sbuf && !__last._M_sbuf)
342*38fd1498Szrj {
343*38fd1498Szrj streambuf_type* __sb = __first._M_sbuf;
344*38fd1498Szrj int_type __c = __sb->sgetc();
345*38fd1498Szrj while (!traits_type::eq_int_type(__c, traits_type::eof()))
346*38fd1498Szrj {
347*38fd1498Szrj const streamsize __n = __sb->egptr() - __sb->gptr();
348*38fd1498Szrj if (__n > 1)
349*38fd1498Szrj {
350*38fd1498Szrj traits_type::copy(__result, __sb->gptr(), __n);
351*38fd1498Szrj __sb->__safe_gbump(__n);
352*38fd1498Szrj __result += __n;
353*38fd1498Szrj __c = __sb->underflow();
354*38fd1498Szrj }
355*38fd1498Szrj else
356*38fd1498Szrj {
357*38fd1498Szrj *__result++ = traits_type::to_char_type(__c);
358*38fd1498Szrj __c = __sb->snextc();
359*38fd1498Szrj }
360*38fd1498Szrj }
361*38fd1498Szrj }
362*38fd1498Szrj return __result;
363*38fd1498Szrj }
364*38fd1498Szrj
365*38fd1498Szrj template<typename _CharT>
366*38fd1498Szrj typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
367*38fd1498Szrj istreambuf_iterator<_CharT> >::__type
368*38fd1498Szrj find(istreambuf_iterator<_CharT> __first,
369*38fd1498Szrj istreambuf_iterator<_CharT> __last, const _CharT& __val)
370*38fd1498Szrj {
371*38fd1498Szrj typedef istreambuf_iterator<_CharT> __is_iterator_type;
372*38fd1498Szrj typedef typename __is_iterator_type::traits_type traits_type;
373*38fd1498Szrj typedef typename __is_iterator_type::streambuf_type streambuf_type;
374*38fd1498Szrj typedef typename traits_type::int_type int_type;
375*38fd1498Szrj const int_type __eof = traits_type::eof();
376*38fd1498Szrj
377*38fd1498Szrj if (__first._M_sbuf && !__last._M_sbuf)
378*38fd1498Szrj {
379*38fd1498Szrj const int_type __ival = traits_type::to_int_type(__val);
380*38fd1498Szrj streambuf_type* __sb = __first._M_sbuf;
381*38fd1498Szrj int_type __c = __sb->sgetc();
382*38fd1498Szrj while (!traits_type::eq_int_type(__c, __eof)
383*38fd1498Szrj && !traits_type::eq_int_type(__c, __ival))
384*38fd1498Szrj {
385*38fd1498Szrj streamsize __n = __sb->egptr() - __sb->gptr();
386*38fd1498Szrj if (__n > 1)
387*38fd1498Szrj {
388*38fd1498Szrj const _CharT* __p = traits_type::find(__sb->gptr(),
389*38fd1498Szrj __n, __val);
390*38fd1498Szrj if (__p)
391*38fd1498Szrj __n = __p - __sb->gptr();
392*38fd1498Szrj __sb->__safe_gbump(__n);
393*38fd1498Szrj __c = __sb->sgetc();
394*38fd1498Szrj }
395*38fd1498Szrj else
396*38fd1498Szrj __c = __sb->snextc();
397*38fd1498Szrj }
398*38fd1498Szrj
399*38fd1498Szrj __first._M_c = __eof;
400*38fd1498Szrj }
401*38fd1498Szrj
402*38fd1498Szrj return __first;
403*38fd1498Szrj }
404*38fd1498Szrj
405*38fd1498Szrj template<typename _CharT, typename _Distance>
406*38fd1498Szrj typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
407*38fd1498Szrj void>::__type
408*38fd1498Szrj advance(istreambuf_iterator<_CharT>& __i, _Distance __n)
409*38fd1498Szrj {
410*38fd1498Szrj if (__n == 0)
411*38fd1498Szrj return;
412*38fd1498Szrj
413*38fd1498Szrj __glibcxx_assert(__n > 0);
414*38fd1498Szrj __glibcxx_requires_cond(!__i._M_at_eof(),
415*38fd1498Szrj _M_message(__gnu_debug::__msg_inc_istreambuf)
416*38fd1498Szrj ._M_iterator(__i));
417*38fd1498Szrj
418*38fd1498Szrj typedef istreambuf_iterator<_CharT> __is_iterator_type;
419*38fd1498Szrj typedef typename __is_iterator_type::traits_type traits_type;
420*38fd1498Szrj typedef typename __is_iterator_type::streambuf_type streambuf_type;
421*38fd1498Szrj typedef typename traits_type::int_type int_type;
422*38fd1498Szrj const int_type __eof = traits_type::eof();
423*38fd1498Szrj
424*38fd1498Szrj streambuf_type* __sb = __i._M_sbuf;
425*38fd1498Szrj while (__n > 0)
426*38fd1498Szrj {
427*38fd1498Szrj streamsize __size = __sb->egptr() - __sb->gptr();
428*38fd1498Szrj if (__size > __n)
429*38fd1498Szrj {
430*38fd1498Szrj __sb->__safe_gbump(__n);
431*38fd1498Szrj break;
432*38fd1498Szrj }
433*38fd1498Szrj
434*38fd1498Szrj __sb->__safe_gbump(__size);
435*38fd1498Szrj __n -= __size;
436*38fd1498Szrj if (traits_type::eq_int_type(__sb->underflow(), __eof))
437*38fd1498Szrj {
438*38fd1498Szrj __glibcxx_requires_cond(__n == 0,
439*38fd1498Szrj _M_message(__gnu_debug::__msg_inc_istreambuf)
440*38fd1498Szrj ._M_iterator(__i));
441*38fd1498Szrj break;
442*38fd1498Szrj }
443*38fd1498Szrj }
444*38fd1498Szrj
445*38fd1498Szrj __i._M_c = __eof;
446*38fd1498Szrj }
447*38fd1498Szrj
448*38fd1498Szrj // @} group iterators
449*38fd1498Szrj
450*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
451*38fd1498Szrj } // namespace
452*38fd1498Szrj
453*38fd1498Szrj #endif
454