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