xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/streambuf_iterator.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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