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