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