100db7afdSDavid E. O'Brien // Streambuf iterators
200db7afdSDavid E. O'Brien
3f8a1b7d9SAlexander Kabaev // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
400db7afdSDavid E. O'Brien // Free Software Foundation, Inc.
500db7afdSDavid E. O'Brien //
600db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library. This library is free
700db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
800db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
900db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
1000db7afdSDavid E. O'Brien // any later version.
1100db7afdSDavid E. O'Brien
1200db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1300db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1400db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1500db7afdSDavid E. O'Brien // GNU General Public License for more details.
1600db7afdSDavid E. O'Brien
1700db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1800db7afdSDavid E. O'Brien // with this library; see the file COPYING. If not, write to the Free
19f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2000db7afdSDavid E. O'Brien // USA.
2100db7afdSDavid E. O'Brien
2200db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2300db7afdSDavid E. O'Brien // library without restriction. Specifically, if other files instantiate
2400db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2500db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2600db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2700db7afdSDavid E. O'Brien // the GNU General Public License. This exception does not however
2800db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
2900db7afdSDavid E. O'Brien // the GNU General Public License.
3000db7afdSDavid E. O'Brien
3100db7afdSDavid E. O'Brien /** @file streambuf_iterator.h
3200db7afdSDavid E. O'Brien * This is an internal header file, included by other library headers.
3300db7afdSDavid E. O'Brien * You should not attempt to use it directly.
3400db7afdSDavid E. O'Brien */
3500db7afdSDavid E. O'Brien
36ffeaf689SAlexander Kabaev #ifndef _STREAMBUF_ITERATOR_H
37ffeaf689SAlexander Kabaev #define _STREAMBUF_ITERATOR_H 1
3800db7afdSDavid E. O'Brien
3900db7afdSDavid E. O'Brien #pragma GCC system_header
4000db7afdSDavid E. O'Brien
411b86b14eSAlexander Kabaev #include <streambuf>
42ffeaf689SAlexander Kabaev #include <debug/debug.h>
431b86b14eSAlexander Kabaev
_GLIBCXX_BEGIN_NAMESPACE(std)44f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(std)
451b86b14eSAlexander Kabaev
4600db7afdSDavid E. O'Brien // 24.5.3 Template class istreambuf_iterator
47ffeaf689SAlexander Kabaev /// Provides input iterator semantics for streambufs.
4800db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits>
4900db7afdSDavid E. O'Brien class istreambuf_iterator
5000db7afdSDavid E. O'Brien : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
5100db7afdSDavid E. O'Brien _CharT*, _CharT&>
5200db7afdSDavid E. O'Brien {
5300db7afdSDavid E. O'Brien public:
5400db7afdSDavid E. O'Brien // Types:
55ffeaf689SAlexander Kabaev //@{
56ffeaf689SAlexander Kabaev /// Public typedefs
5700db7afdSDavid E. O'Brien typedef _CharT char_type;
5800db7afdSDavid E. O'Brien typedef _Traits traits_type;
5900db7afdSDavid E. O'Brien typedef typename _Traits::int_type int_type;
6000db7afdSDavid E. O'Brien typedef basic_streambuf<_CharT, _Traits> streambuf_type;
6100db7afdSDavid E. O'Brien typedef basic_istream<_CharT, _Traits> istream_type;
62ffeaf689SAlexander Kabaev //@}
6300db7afdSDavid E. O'Brien
64f8a1b7d9SAlexander Kabaev template<typename _CharT2>
65f8a1b7d9SAlexander Kabaev friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
66f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT2> >::__type
67f8a1b7d9SAlexander Kabaev copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
68f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT2>);
69f8a1b7d9SAlexander Kabaev
70f8a1b7d9SAlexander Kabaev template<typename _CharT2>
71f8a1b7d9SAlexander Kabaev friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
72f8a1b7d9SAlexander Kabaev _CharT2*>::__type
73f8a1b7d9SAlexander Kabaev __copy_aux(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
74f8a1b7d9SAlexander Kabaev _CharT2*);
75f8a1b7d9SAlexander Kabaev
76f8a1b7d9SAlexander Kabaev template<typename _CharT2>
77f8a1b7d9SAlexander Kabaev friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
78f8a1b7d9SAlexander Kabaev istreambuf_iterator<_CharT2> >::__type
79f8a1b7d9SAlexander Kabaev find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
80f8a1b7d9SAlexander Kabaev const _CharT2&);
81f8a1b7d9SAlexander Kabaev
8200db7afdSDavid E. O'Brien private:
8300db7afdSDavid E. O'Brien // 24.5.3 istreambuf_iterator
8400db7afdSDavid E. O'Brien // p 1
8500db7afdSDavid E. O'Brien // If the end of stream is reached (streambuf_type::sgetc()
8600db7afdSDavid E. O'Brien // returns traits_type::eof()), the iterator becomes equal to
8700db7afdSDavid E. O'Brien // the "end of stream" iterator value.
8800db7afdSDavid E. O'Brien // NB: This implementation assumes the "end of stream" value
8900db7afdSDavid E. O'Brien // is EOF, or -1.
9000db7afdSDavid E. O'Brien mutable streambuf_type* _M_sbuf;
91f8a1b7d9SAlexander Kabaev mutable int_type _M_c;
9200db7afdSDavid E. O'Brien
9300db7afdSDavid E. O'Brien public:
94ffeaf689SAlexander Kabaev /// Construct end of input stream iterator.
9500db7afdSDavid E. O'Brien istreambuf_iterator() throw()
96ca6500fcSAlexander Kabaev : _M_sbuf(0), _M_c(traits_type::eof()) { }
9700db7afdSDavid E. O'Brien
98ffeaf689SAlexander Kabaev /// Construct start of input stream iterator.
9900db7afdSDavid E. O'Brien istreambuf_iterator(istream_type& __s) throw()
100ca6500fcSAlexander Kabaev : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
10100db7afdSDavid E. O'Brien
102ffeaf689SAlexander Kabaev /// Construct start of streambuf iterator.
10300db7afdSDavid E. O'Brien istreambuf_iterator(streambuf_type* __s) throw()
104ca6500fcSAlexander Kabaev : _M_sbuf(__s), _M_c(traits_type::eof()) { }
10500db7afdSDavid E. O'Brien
106ffeaf689SAlexander Kabaev /// Return the current character pointed to by iterator. This returns
107ffeaf689SAlexander Kabaev /// streambuf.sgetc(). It cannot be assigned. NB: The result of
108ffeaf689SAlexander Kabaev /// operator*() on an end of stream is undefined.
10900db7afdSDavid E. O'Brien char_type
11000db7afdSDavid E. O'Brien operator*() const
111ffeaf689SAlexander Kabaev {
112ffeaf689SAlexander Kabaev #ifdef _GLIBCXX_DEBUG_PEDANTIC
113ffeaf689SAlexander Kabaev // Dereferencing a past-the-end istreambuf_iterator is a
114ffeaf689SAlexander Kabaev // libstdc++ extension
115ffeaf689SAlexander Kabaev __glibcxx_requires_cond(!_M_at_eof(),
116ffeaf689SAlexander Kabaev _M_message(__gnu_debug::__msg_deref_istreambuf)
117ffeaf689SAlexander Kabaev ._M_iterator(*this));
118ffeaf689SAlexander Kabaev #endif
119ffeaf689SAlexander Kabaev return traits_type::to_char_type(_M_get());
120ffeaf689SAlexander Kabaev }
12100db7afdSDavid E. O'Brien
122ffeaf689SAlexander Kabaev /// Advance the iterator. Calls streambuf.sbumpc().
12300db7afdSDavid E. O'Brien istreambuf_iterator&
12400db7afdSDavid E. O'Brien operator++()
12500db7afdSDavid E. O'Brien {
126ffeaf689SAlexander Kabaev __glibcxx_requires_cond(!_M_at_eof(),
127ffeaf689SAlexander Kabaev _M_message(__gnu_debug::__msg_inc_istreambuf)
128ffeaf689SAlexander Kabaev ._M_iterator(*this));
129f8a1b7d9SAlexander Kabaev if (_M_sbuf)
130f8a1b7d9SAlexander Kabaev {
131f8a1b7d9SAlexander Kabaev _M_sbuf->sbumpc();
132f8a1b7d9SAlexander Kabaev _M_c = traits_type::eof();
133f8a1b7d9SAlexander Kabaev }
13400db7afdSDavid E. O'Brien return *this;
13500db7afdSDavid E. O'Brien }
13600db7afdSDavid E. O'Brien
137ffeaf689SAlexander Kabaev /// Advance the iterator. Calls streambuf.sbumpc().
13800db7afdSDavid E. O'Brien istreambuf_iterator
13900db7afdSDavid E. O'Brien operator++(int)
14000db7afdSDavid E. O'Brien {
141ffeaf689SAlexander Kabaev __glibcxx_requires_cond(!_M_at_eof(),
142ffeaf689SAlexander Kabaev _M_message(__gnu_debug::__msg_inc_istreambuf)
143ffeaf689SAlexander Kabaev ._M_iterator(*this));
144ffeaf689SAlexander Kabaev
14500db7afdSDavid E. O'Brien istreambuf_iterator __old = *this;
146f8a1b7d9SAlexander Kabaev if (_M_sbuf)
147f8a1b7d9SAlexander Kabaev {
148f8a1b7d9SAlexander Kabaev __old._M_c = _M_sbuf->sbumpc();
149f8a1b7d9SAlexander Kabaev _M_c = traits_type::eof();
150f8a1b7d9SAlexander Kabaev }
15100db7afdSDavid E. O'Brien return __old;
15200db7afdSDavid E. O'Brien }
15300db7afdSDavid E. O'Brien
154ffeaf689SAlexander Kabaev // _GLIBCXX_RESOLVE_LIB_DEFECTS
15500db7afdSDavid E. O'Brien // 110 istreambuf_iterator::equal not const
15600db7afdSDavid E. O'Brien // NB: there is also number 111 (NAD, Future) pending on this function.
157ffeaf689SAlexander Kabaev /// Return true both iterators are end or both are not end.
15800db7afdSDavid E. O'Brien bool
15900db7afdSDavid E. O'Brien equal(const istreambuf_iterator& __b) const
16000db7afdSDavid E. O'Brien {
161ffeaf689SAlexander Kabaev const bool __thiseof = _M_at_eof();
162ffeaf689SAlexander Kabaev const bool __beof = __b._M_at_eof();
163*a23701e5SDimitry Andric return ((__thiseof && __beof) || (!__thiseof && !__beof));
16400db7afdSDavid E. O'Brien }
16500db7afdSDavid E. O'Brien
16600db7afdSDavid E. O'Brien private:
16700db7afdSDavid E. O'Brien int_type
16800db7afdSDavid E. O'Brien _M_get() const
16900db7afdSDavid E. O'Brien {
170ca6500fcSAlexander Kabaev const int_type __eof = traits_type::eof();
171ca6500fcSAlexander Kabaev int_type __ret = __eof;
17200db7afdSDavid E. O'Brien if (_M_sbuf)
17300db7afdSDavid E. O'Brien {
174ca6500fcSAlexander Kabaev if (!traits_type::eq_int_type(_M_c, __eof))
17500db7afdSDavid E. O'Brien __ret = _M_c;
176f8a1b7d9SAlexander Kabaev else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()),
177ffeaf689SAlexander Kabaev __eof))
178f8a1b7d9SAlexander Kabaev _M_c = __ret;
179f8a1b7d9SAlexander Kabaev else
18000db7afdSDavid E. O'Brien _M_sbuf = 0;
18100db7afdSDavid E. O'Brien }
18200db7afdSDavid E. O'Brien return __ret;
18300db7afdSDavid E. O'Brien }
184ffeaf689SAlexander Kabaev
185ffeaf689SAlexander Kabaev bool
186ffeaf689SAlexander Kabaev _M_at_eof() const
187ffeaf689SAlexander Kabaev {
188ffeaf689SAlexander Kabaev const int_type __eof = traits_type::eof();
189ffeaf689SAlexander Kabaev return traits_type::eq_int_type(_M_get(), __eof);
190ffeaf689SAlexander Kabaev }
19100db7afdSDavid E. O'Brien };
19200db7afdSDavid E. O'Brien
19300db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits>
19400db7afdSDavid E. O'Brien inline bool
19500db7afdSDavid E. O'Brien operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
19600db7afdSDavid E. O'Brien const istreambuf_iterator<_CharT, _Traits>& __b)
19700db7afdSDavid E. O'Brien { return __a.equal(__b); }
19800db7afdSDavid E. O'Brien
19900db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits>
20000db7afdSDavid E. O'Brien inline bool
20100db7afdSDavid E. O'Brien operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
20200db7afdSDavid E. O'Brien const istreambuf_iterator<_CharT, _Traits>& __b)
20300db7afdSDavid E. O'Brien { return !__a.equal(__b); }
20400db7afdSDavid E. O'Brien
205ffeaf689SAlexander Kabaev /// Provides output iterator semantics for streambufs.
20600db7afdSDavid E. O'Brien template<typename _CharT, typename _Traits>
20700db7afdSDavid E. O'Brien class ostreambuf_iterator
20800db7afdSDavid E. O'Brien : public iterator<output_iterator_tag, void, void, void, void>
20900db7afdSDavid E. O'Brien {
21000db7afdSDavid E. O'Brien public:
21100db7afdSDavid E. O'Brien // Types:
212ffeaf689SAlexander Kabaev //@{
213ffeaf689SAlexander Kabaev /// Public typedefs
21400db7afdSDavid E. O'Brien typedef _CharT char_type;
21500db7afdSDavid E. O'Brien typedef _Traits traits_type;
21600db7afdSDavid E. O'Brien typedef basic_streambuf<_CharT, _Traits> streambuf_type;
21700db7afdSDavid E. O'Brien typedef basic_ostream<_CharT, _Traits> ostream_type;
218ffeaf689SAlexander Kabaev //@}
21900db7afdSDavid E. O'Brien
220f8a1b7d9SAlexander Kabaev template<typename _CharT2>
221f8a1b7d9SAlexander Kabaev friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
222f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT2> >::__type
223f8a1b7d9SAlexander Kabaev copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
224f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT2>);
225f8a1b7d9SAlexander Kabaev
22600db7afdSDavid E. O'Brien private:
22700db7afdSDavid E. O'Brien streambuf_type* _M_sbuf;
22800db7afdSDavid E. O'Brien bool _M_failed;
22900db7afdSDavid E. O'Brien
23000db7afdSDavid E. O'Brien public:
231ffeaf689SAlexander Kabaev /// Construct output iterator from ostream.
ostreambuf_iterator(ostream_type & __s)23200db7afdSDavid E. O'Brien ostreambuf_iterator(ostream_type& __s) throw ()
23300db7afdSDavid E. O'Brien : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
23400db7afdSDavid E. O'Brien
235ffeaf689SAlexander Kabaev /// Construct output iterator from streambuf.
throw()23600db7afdSDavid E. O'Brien ostreambuf_iterator(streambuf_type* __s) throw ()
23700db7afdSDavid E. O'Brien : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
23800db7afdSDavid E. O'Brien
239ffeaf689SAlexander Kabaev /// Write character to streambuf. Calls streambuf.sputc().
24000db7afdSDavid E. O'Brien ostreambuf_iterator&
2411b86b14eSAlexander Kabaev operator=(_CharT __c)
2421b86b14eSAlexander Kabaev {
2431b86b14eSAlexander Kabaev if (!_M_failed &&
2441b86b14eSAlexander Kabaev _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
2451b86b14eSAlexander Kabaev _M_failed = true;
2461b86b14eSAlexander Kabaev return *this;
2471b86b14eSAlexander Kabaev }
24800db7afdSDavid E. O'Brien
249ffeaf689SAlexander Kabaev /// Return *this.
25000db7afdSDavid E. O'Brien ostreambuf_iterator&
251ffeaf689SAlexander Kabaev operator*()
25200db7afdSDavid E. O'Brien { return *this; }
25300db7afdSDavid E. O'Brien
254ffeaf689SAlexander Kabaev /// Return *this.
25500db7afdSDavid E. O'Brien ostreambuf_iterator&
256ffeaf689SAlexander Kabaev operator++(int)
25700db7afdSDavid E. O'Brien { return *this; }
25800db7afdSDavid E. O'Brien
259ffeaf689SAlexander Kabaev /// Return *this.
26000db7afdSDavid E. O'Brien ostreambuf_iterator&
261ffeaf689SAlexander Kabaev operator++()
26200db7afdSDavid E. O'Brien { return *this; }
26300db7afdSDavid E. O'Brien
264ffeaf689SAlexander Kabaev /// Return true if previous operator=() failed.
26500db7afdSDavid E. O'Brien bool
failed()26600db7afdSDavid E. O'Brien failed() const throw()
26700db7afdSDavid E. O'Brien { return _M_failed; }
26800db7afdSDavid E. O'Brien
2691b86b14eSAlexander Kabaev ostreambuf_iterator&
_M_put(const _CharT * __ws,streamsize __len)2701b86b14eSAlexander Kabaev _M_put(const _CharT* __ws, streamsize __len)
27100db7afdSDavid E. O'Brien {
272ffeaf689SAlexander Kabaev if (__builtin_expect(!_M_failed, true)
273ffeaf689SAlexander Kabaev && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len,
274ffeaf689SAlexander Kabaev false))
27500db7afdSDavid E. O'Brien _M_failed = true;
27600db7afdSDavid E. O'Brien return *this;
27700db7afdSDavid E. O'Brien }
2781b86b14eSAlexander Kabaev };
279f8a1b7d9SAlexander Kabaev
280f8a1b7d9SAlexander Kabaev // Overloads for streambuf iterators.
281f8a1b7d9SAlexander Kabaev template<typename _CharT>
282f8a1b7d9SAlexander Kabaev typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
283f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT> >::__type
copy(istreambuf_iterator<_CharT> __first,istreambuf_iterator<_CharT> __last,ostreambuf_iterator<_CharT> __result)284f8a1b7d9SAlexander Kabaev copy(istreambuf_iterator<_CharT> __first,
285f8a1b7d9SAlexander Kabaev istreambuf_iterator<_CharT> __last,
286f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT> __result)
287f8a1b7d9SAlexander Kabaev {
288f8a1b7d9SAlexander Kabaev if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed)
289f8a1b7d9SAlexander Kabaev {
290f8a1b7d9SAlexander Kabaev bool __ineof;
291f8a1b7d9SAlexander Kabaev __copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof);
292f8a1b7d9SAlexander Kabaev if (!__ineof)
293f8a1b7d9SAlexander Kabaev __result._M_failed = true;
294f8a1b7d9SAlexander Kabaev }
295f8a1b7d9SAlexander Kabaev return __result;
296f8a1b7d9SAlexander Kabaev }
297f8a1b7d9SAlexander Kabaev
298f8a1b7d9SAlexander Kabaev template<typename _CharT>
299f8a1b7d9SAlexander Kabaev typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
300f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT> >::__type
__copy_aux(_CharT * __first,_CharT * __last,ostreambuf_iterator<_CharT> __result)301f8a1b7d9SAlexander Kabaev __copy_aux(_CharT* __first, _CharT* __last,
302f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT> __result)
303f8a1b7d9SAlexander Kabaev {
304f8a1b7d9SAlexander Kabaev const streamsize __num = __last - __first;
305f8a1b7d9SAlexander Kabaev if (__num > 0)
306f8a1b7d9SAlexander Kabaev __result._M_put(__first, __num);
307f8a1b7d9SAlexander Kabaev return __result;
308f8a1b7d9SAlexander Kabaev }
309f8a1b7d9SAlexander Kabaev
310f8a1b7d9SAlexander Kabaev template<typename _CharT>
311f8a1b7d9SAlexander Kabaev typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
312f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT> >::__type
__copy_aux(const _CharT * __first,const _CharT * __last,ostreambuf_iterator<_CharT> __result)313f8a1b7d9SAlexander Kabaev __copy_aux(const _CharT* __first, const _CharT* __last,
314f8a1b7d9SAlexander Kabaev ostreambuf_iterator<_CharT> __result)
315f8a1b7d9SAlexander Kabaev {
316f8a1b7d9SAlexander Kabaev const streamsize __num = __last - __first;
317f8a1b7d9SAlexander Kabaev if (__num > 0)
318f8a1b7d9SAlexander Kabaev __result._M_put(__first, __num);
319f8a1b7d9SAlexander Kabaev return __result;
320f8a1b7d9SAlexander Kabaev }
321f8a1b7d9SAlexander Kabaev
322f8a1b7d9SAlexander Kabaev template<typename _CharT>
323f8a1b7d9SAlexander Kabaev typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
324f8a1b7d9SAlexander Kabaev _CharT*>::__type
__copy_aux(istreambuf_iterator<_CharT> __first,istreambuf_iterator<_CharT> __last,_CharT * __result)325f8a1b7d9SAlexander Kabaev __copy_aux(istreambuf_iterator<_CharT> __first,
326f8a1b7d9SAlexander Kabaev istreambuf_iterator<_CharT> __last, _CharT* __result)
327f8a1b7d9SAlexander Kabaev {
328f8a1b7d9SAlexander Kabaev typedef istreambuf_iterator<_CharT> __is_iterator_type;
329f8a1b7d9SAlexander Kabaev typedef typename __is_iterator_type::traits_type traits_type;
330f8a1b7d9SAlexander Kabaev typedef typename __is_iterator_type::streambuf_type streambuf_type;
331f8a1b7d9SAlexander Kabaev typedef typename traits_type::int_type int_type;
332f8a1b7d9SAlexander Kabaev
333f8a1b7d9SAlexander Kabaev if (__first._M_sbuf && !__last._M_sbuf)
334f8a1b7d9SAlexander Kabaev {
335f8a1b7d9SAlexander Kabaev streambuf_type* __sb = __first._M_sbuf;
336f8a1b7d9SAlexander Kabaev int_type __c = __sb->sgetc();
337f8a1b7d9SAlexander Kabaev while (!traits_type::eq_int_type(__c, traits_type::eof()))
338f8a1b7d9SAlexander Kabaev {
339f8a1b7d9SAlexander Kabaev const streamsize __n = __sb->egptr() - __sb->gptr();
340f8a1b7d9SAlexander Kabaev if (__n > 1)
341f8a1b7d9SAlexander Kabaev {
342f8a1b7d9SAlexander Kabaev traits_type::copy(__result, __sb->gptr(), __n);
343f8a1b7d9SAlexander Kabaev __sb->gbump(__n);
344f8a1b7d9SAlexander Kabaev __result += __n;
345f8a1b7d9SAlexander Kabaev __c = __sb->underflow();
346f8a1b7d9SAlexander Kabaev }
347f8a1b7d9SAlexander Kabaev else
348f8a1b7d9SAlexander Kabaev {
349f8a1b7d9SAlexander Kabaev *__result++ = traits_type::to_char_type(__c);
350f8a1b7d9SAlexander Kabaev __c = __sb->snextc();
351f8a1b7d9SAlexander Kabaev }
352f8a1b7d9SAlexander Kabaev }
353f8a1b7d9SAlexander Kabaev }
354f8a1b7d9SAlexander Kabaev return __result;
355f8a1b7d9SAlexander Kabaev }
356f8a1b7d9SAlexander Kabaev
357f8a1b7d9SAlexander Kabaev template<typename _CharT>
358f8a1b7d9SAlexander Kabaev typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
359f8a1b7d9SAlexander Kabaev istreambuf_iterator<_CharT> >::__type
find(istreambuf_iterator<_CharT> __first,istreambuf_iterator<_CharT> __last,const _CharT & __val)360f8a1b7d9SAlexander Kabaev find(istreambuf_iterator<_CharT> __first,
361f8a1b7d9SAlexander Kabaev istreambuf_iterator<_CharT> __last, const _CharT& __val)
362f8a1b7d9SAlexander Kabaev {
363f8a1b7d9SAlexander Kabaev typedef istreambuf_iterator<_CharT> __is_iterator_type;
364f8a1b7d9SAlexander Kabaev typedef typename __is_iterator_type::traits_type traits_type;
365f8a1b7d9SAlexander Kabaev typedef typename __is_iterator_type::streambuf_type streambuf_type;
366f8a1b7d9SAlexander Kabaev typedef typename traits_type::int_type int_type;
367f8a1b7d9SAlexander Kabaev
368f8a1b7d9SAlexander Kabaev if (__first._M_sbuf && !__last._M_sbuf)
369f8a1b7d9SAlexander Kabaev {
370f8a1b7d9SAlexander Kabaev const int_type __ival = traits_type::to_int_type(__val);
371f8a1b7d9SAlexander Kabaev streambuf_type* __sb = __first._M_sbuf;
372f8a1b7d9SAlexander Kabaev int_type __c = __sb->sgetc();
373f8a1b7d9SAlexander Kabaev while (!traits_type::eq_int_type(__c, traits_type::eof())
374f8a1b7d9SAlexander Kabaev && !traits_type::eq_int_type(__c, __ival))
375f8a1b7d9SAlexander Kabaev {
376f8a1b7d9SAlexander Kabaev streamsize __n = __sb->egptr() - __sb->gptr();
377f8a1b7d9SAlexander Kabaev if (__n > 1)
378f8a1b7d9SAlexander Kabaev {
379f8a1b7d9SAlexander Kabaev const _CharT* __p = traits_type::find(__sb->gptr(),
380f8a1b7d9SAlexander Kabaev __n, __val);
381f8a1b7d9SAlexander Kabaev if (__p)
382f8a1b7d9SAlexander Kabaev __n = __p - __sb->gptr();
383f8a1b7d9SAlexander Kabaev __sb->gbump(__n);
384f8a1b7d9SAlexander Kabaev __c = __sb->sgetc();
385f8a1b7d9SAlexander Kabaev }
386f8a1b7d9SAlexander Kabaev else
387f8a1b7d9SAlexander Kabaev __c = __sb->snextc();
388f8a1b7d9SAlexander Kabaev }
389f8a1b7d9SAlexander Kabaev
390f8a1b7d9SAlexander Kabaev if (!traits_type::eq_int_type(__c, traits_type::eof()))
391f8a1b7d9SAlexander Kabaev __first._M_c = __c;
392f8a1b7d9SAlexander Kabaev else
393f8a1b7d9SAlexander Kabaev __first._M_sbuf = 0;
394f8a1b7d9SAlexander Kabaev }
395f8a1b7d9SAlexander Kabaev return __first;
396f8a1b7d9SAlexander Kabaev }
397f8a1b7d9SAlexander Kabaev
398f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
399f8a1b7d9SAlexander Kabaev
40000db7afdSDavid E. O'Brien #endif
401