xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/streambuf_iterator.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg // Streambuf iterators
21debfc3dSmrg 
3*8feb0f0bSmrg // Copyright (C) 1997-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg /** @file bits/streambuf_iterator.h
261debfc3dSmrg  *  This is an internal header file, included by other library headers.
271debfc3dSmrg  *  Do not attempt to use it directly. @headername{iterator}
281debfc3dSmrg  */
291debfc3dSmrg 
301debfc3dSmrg #ifndef _STREAMBUF_ITERATOR_H
311debfc3dSmrg #define _STREAMBUF_ITERATOR_H 1
321debfc3dSmrg 
331debfc3dSmrg #pragma GCC system_header
341debfc3dSmrg 
351debfc3dSmrg #include <streambuf>
361debfc3dSmrg #include <debug/debug.h>
371debfc3dSmrg 
_GLIBCXX_VISIBILITY(default)381debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
391debfc3dSmrg {
401debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
411debfc3dSmrg 
421debfc3dSmrg   /**
431debfc3dSmrg    * @addtogroup iterators
441debfc3dSmrg    * @{
451debfc3dSmrg    */
461debfc3dSmrg 
471debfc3dSmrg   // 24.5.3 Template class istreambuf_iterator
481debfc3dSmrg   /// Provides input iterator semantics for streambufs.
491debfc3dSmrg   template<typename _CharT, typename _Traits>
501debfc3dSmrg     class istreambuf_iterator
511debfc3dSmrg     : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type,
52*8feb0f0bSmrg 		      _CharT*, _CharT>
531debfc3dSmrg     {
541debfc3dSmrg     public:
551debfc3dSmrg       // Types:
56*8feb0f0bSmrg       ///@{
571debfc3dSmrg       /// Public typedefs
58*8feb0f0bSmrg #if __cplusplus < 201103L
59*8feb0f0bSmrg       typedef _CharT& reference; // Changed to _CharT by LWG 445
60*8feb0f0bSmrg #elif __cplusplus > 201703L
61*8feb0f0bSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
62*8feb0f0bSmrg       // 3188. istreambuf_iterator::pointer should not be unspecified
63*8feb0f0bSmrg       using pointer = void;
64*8feb0f0bSmrg #endif
65*8feb0f0bSmrg 
661debfc3dSmrg       typedef _CharT					char_type;
671debfc3dSmrg       typedef _Traits					traits_type;
681debfc3dSmrg       typedef typename _Traits::int_type		int_type;
691debfc3dSmrg       typedef basic_streambuf<_CharT, _Traits>		streambuf_type;
701debfc3dSmrg       typedef basic_istream<_CharT, _Traits>		istream_type;
71*8feb0f0bSmrg       ///@}
721debfc3dSmrg 
731debfc3dSmrg       template<typename _CharT2>
741debfc3dSmrg 	friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
751debfc3dSmrg 				    ostreambuf_iterator<_CharT2> >::__type
761debfc3dSmrg 	copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
771debfc3dSmrg 	     ostreambuf_iterator<_CharT2>);
781debfc3dSmrg 
791debfc3dSmrg       template<bool _IsMove, typename _CharT2>
801debfc3dSmrg 	friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
811debfc3dSmrg 					       _CharT2*>::__type
821debfc3dSmrg 	__copy_move_a2(istreambuf_iterator<_CharT2>,
831debfc3dSmrg 		       istreambuf_iterator<_CharT2>, _CharT2*);
841debfc3dSmrg 
85*8feb0f0bSmrg #if __cplusplus >= 201103L
86*8feb0f0bSmrg       template<typename _CharT2, typename _Size>
87*8feb0f0bSmrg 	friend __enable_if_t<__is_char<_CharT2>::__value, _CharT2*>
88*8feb0f0bSmrg 	__copy_n_a(istreambuf_iterator<_CharT2>, _Size, _CharT2*);
89*8feb0f0bSmrg #endif
90*8feb0f0bSmrg 
911debfc3dSmrg       template<typename _CharT2>
921debfc3dSmrg 	friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
931debfc3dSmrg 				    istreambuf_iterator<_CharT2> >::__type
941debfc3dSmrg 	find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
951debfc3dSmrg 	     const _CharT2&);
961debfc3dSmrg 
97a2dc1f3fSmrg       template<typename _CharT2, typename _Distance>
98a2dc1f3fSmrg 	friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
99a2dc1f3fSmrg 					       void>::__type
100a2dc1f3fSmrg 	advance(istreambuf_iterator<_CharT2>&, _Distance);
101a2dc1f3fSmrg 
1021debfc3dSmrg     private:
1031debfc3dSmrg       // 24.5.3 istreambuf_iterator
1041debfc3dSmrg       // p 1
1051debfc3dSmrg       // If the end of stream is reached (streambuf_type::sgetc()
1061debfc3dSmrg       // returns traits_type::eof()), the iterator becomes equal to
1071debfc3dSmrg       // the "end of stream" iterator value.
1081debfc3dSmrg       // NB: This implementation assumes the "end of stream" value
1091debfc3dSmrg       // is EOF, or -1.
1101debfc3dSmrg       mutable streambuf_type*	_M_sbuf;
111a2dc1f3fSmrg       int_type			_M_c;
1121debfc3dSmrg 
1131debfc3dSmrg     public:
1141debfc3dSmrg       ///  Construct end of input stream iterator.
1151debfc3dSmrg       _GLIBCXX_CONSTEXPR istreambuf_iterator() _GLIBCXX_USE_NOEXCEPT
1161debfc3dSmrg       : _M_sbuf(0), _M_c(traits_type::eof()) { }
1171debfc3dSmrg 
118*8feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
119*8feb0f0bSmrg       constexpr istreambuf_iterator(default_sentinel_t) noexcept
120*8feb0f0bSmrg       : istreambuf_iterator() { }
121*8feb0f0bSmrg #endif
122*8feb0f0bSmrg 
1231debfc3dSmrg #if __cplusplus >= 201103L
1241debfc3dSmrg       istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
1251debfc3dSmrg 
1261debfc3dSmrg       ~istreambuf_iterator() = default;
1271debfc3dSmrg #endif
1281debfc3dSmrg 
1291debfc3dSmrg       ///  Construct start of input stream iterator.
1301debfc3dSmrg       istreambuf_iterator(istream_type& __s) _GLIBCXX_USE_NOEXCEPT
1311debfc3dSmrg       : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { }
1321debfc3dSmrg 
1331debfc3dSmrg       ///  Construct start of streambuf iterator.
1341debfc3dSmrg       istreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT
1351debfc3dSmrg       : _M_sbuf(__s), _M_c(traits_type::eof()) { }
1361debfc3dSmrg 
137c0a68be4Smrg #if __cplusplus >= 201103L
138c0a68be4Smrg       istreambuf_iterator&
139c0a68be4Smrg       operator=(const istreambuf_iterator&) noexcept = default;
140c0a68be4Smrg #endif
141c0a68be4Smrg 
1421debfc3dSmrg       ///  Return the current character pointed to by iterator.  This returns
1431debfc3dSmrg       ///  streambuf.sgetc().  It cannot be assigned.  NB: The result of
1441debfc3dSmrg       ///  operator*() on an end of stream is undefined.
1451debfc3dSmrg       char_type
1461debfc3dSmrg       operator*() const
1471debfc3dSmrg       {
148a2dc1f3fSmrg 	int_type __c = _M_get();
149a2dc1f3fSmrg 
1501debfc3dSmrg #ifdef _GLIBCXX_DEBUG_PEDANTIC
1511debfc3dSmrg 	// Dereferencing a past-the-end istreambuf_iterator is a
1521debfc3dSmrg 	// libstdc++ extension
153a2dc1f3fSmrg 	__glibcxx_requires_cond(!_S_is_eof(__c),
1541debfc3dSmrg 				_M_message(__gnu_debug::__msg_deref_istreambuf)
1551debfc3dSmrg 				._M_iterator(*this));
1561debfc3dSmrg #endif
157a2dc1f3fSmrg 	return traits_type::to_char_type(__c);
1581debfc3dSmrg       }
1591debfc3dSmrg 
1601debfc3dSmrg       /// Advance the iterator.  Calls streambuf.sbumpc().
1611debfc3dSmrg       istreambuf_iterator&
1621debfc3dSmrg       operator++()
1631debfc3dSmrg       {
164a2dc1f3fSmrg 	__glibcxx_requires_cond(_M_sbuf &&
165a2dc1f3fSmrg 				(!_S_is_eof(_M_c) || !_S_is_eof(_M_sbuf->sgetc())),
1661debfc3dSmrg 				_M_message(__gnu_debug::__msg_inc_istreambuf)
1671debfc3dSmrg 				._M_iterator(*this));
168a2dc1f3fSmrg 
1691debfc3dSmrg 	_M_sbuf->sbumpc();
1701debfc3dSmrg 	_M_c = traits_type::eof();
1711debfc3dSmrg 	return *this;
1721debfc3dSmrg       }
1731debfc3dSmrg 
1741debfc3dSmrg       /// Advance the iterator.  Calls streambuf.sbumpc().
1751debfc3dSmrg       istreambuf_iterator
1761debfc3dSmrg       operator++(int)
1771debfc3dSmrg       {
178a2dc1f3fSmrg 	__glibcxx_requires_cond(_M_sbuf &&
179a2dc1f3fSmrg 				(!_S_is_eof(_M_c) || !_S_is_eof(_M_sbuf->sgetc())),
1801debfc3dSmrg 				_M_message(__gnu_debug::__msg_inc_istreambuf)
1811debfc3dSmrg 				._M_iterator(*this));
1821debfc3dSmrg 
1831debfc3dSmrg 	istreambuf_iterator __old = *this;
1841debfc3dSmrg 	__old._M_c = _M_sbuf->sbumpc();
1851debfc3dSmrg 	_M_c = traits_type::eof();
1861debfc3dSmrg 	return __old;
1871debfc3dSmrg       }
1881debfc3dSmrg 
1891debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
1901debfc3dSmrg       // 110 istreambuf_iterator::equal not const
191a2dc1f3fSmrg       // NB: there is also number 111 (NAD) relevant to this function.
1921debfc3dSmrg       /// Return true both iterators are end or both are not end.
1931debfc3dSmrg       bool
1941debfc3dSmrg       equal(const istreambuf_iterator& __b) const
1951debfc3dSmrg       { return _M_at_eof() == __b._M_at_eof(); }
1961debfc3dSmrg 
1971debfc3dSmrg     private:
1981debfc3dSmrg       int_type
1991debfc3dSmrg       _M_get() const
2001debfc3dSmrg       {
201a2dc1f3fSmrg 	int_type __ret = _M_c;
202a2dc1f3fSmrg 	if (_M_sbuf && _S_is_eof(__ret) && _S_is_eof(__ret = _M_sbuf->sgetc()))
2031debfc3dSmrg 	  _M_sbuf = 0;
2041debfc3dSmrg 	return __ret;
2051debfc3dSmrg       }
2061debfc3dSmrg 
2071debfc3dSmrg       bool
2081debfc3dSmrg       _M_at_eof() const
209a2dc1f3fSmrg       { return _S_is_eof(_M_get()); }
210a2dc1f3fSmrg 
211a2dc1f3fSmrg       static bool
212a2dc1f3fSmrg       _S_is_eof(int_type __c)
2131debfc3dSmrg       {
2141debfc3dSmrg 	const int_type __eof = traits_type::eof();
215a2dc1f3fSmrg 	return traits_type::eq_int_type(__c, __eof);
2161debfc3dSmrg       }
217*8feb0f0bSmrg 
218*8feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
219*8feb0f0bSmrg       friend bool
220*8feb0f0bSmrg       operator==(const istreambuf_iterator& __i, default_sentinel_t __s)
221*8feb0f0bSmrg       { return __i._M_at_eof(); }
222*8feb0f0bSmrg #endif
2231debfc3dSmrg     };
2241debfc3dSmrg 
2251debfc3dSmrg   template<typename _CharT, typename _Traits>
2261debfc3dSmrg     inline bool
2271debfc3dSmrg     operator==(const istreambuf_iterator<_CharT, _Traits>& __a,
2281debfc3dSmrg 	       const istreambuf_iterator<_CharT, _Traits>& __b)
2291debfc3dSmrg     { return __a.equal(__b); }
2301debfc3dSmrg 
2311debfc3dSmrg   template<typename _CharT, typename _Traits>
2321debfc3dSmrg     inline bool
2331debfc3dSmrg     operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
2341debfc3dSmrg 	       const istreambuf_iterator<_CharT, _Traits>& __b)
2351debfc3dSmrg     { return !__a.equal(__b); }
2361debfc3dSmrg 
2371debfc3dSmrg   /// Provides output iterator semantics for streambufs.
2381debfc3dSmrg   template<typename _CharT, typename _Traits>
2391debfc3dSmrg     class ostreambuf_iterator
2401debfc3dSmrg     : public iterator<output_iterator_tag, void, void, void, void>
2411debfc3dSmrg     {
2421debfc3dSmrg     public:
2431debfc3dSmrg       // Types:
244*8feb0f0bSmrg       ///@{
2451debfc3dSmrg       /// Public typedefs
246*8feb0f0bSmrg #if __cplusplus > 201703L
247*8feb0f0bSmrg       using difference_type = ptrdiff_t;
248*8feb0f0bSmrg #endif
2491debfc3dSmrg       typedef _CharT			       char_type;
2501debfc3dSmrg       typedef _Traits			       traits_type;
2511debfc3dSmrg       typedef basic_streambuf<_CharT, _Traits> streambuf_type;
2521debfc3dSmrg       typedef basic_ostream<_CharT, _Traits>   ostream_type;
253*8feb0f0bSmrg       ///@}
2541debfc3dSmrg 
2551debfc3dSmrg       template<typename _CharT2>
2561debfc3dSmrg 	friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
2571debfc3dSmrg 				    ostreambuf_iterator<_CharT2> >::__type
2581debfc3dSmrg 	copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>,
2591debfc3dSmrg 	     ostreambuf_iterator<_CharT2>);
2601debfc3dSmrg 
2611debfc3dSmrg     private:
2621debfc3dSmrg       streambuf_type*	_M_sbuf;
2631debfc3dSmrg       bool		_M_failed;
2641debfc3dSmrg 
2651debfc3dSmrg     public:
266*8feb0f0bSmrg 
267*8feb0f0bSmrg #if __cplusplus > 201703L
268*8feb0f0bSmrg       constexpr
269*8feb0f0bSmrg       ostreambuf_iterator() noexcept
270*8feb0f0bSmrg       : _M_sbuf(nullptr), _M_failed(true) { }
271*8feb0f0bSmrg #endif
272*8feb0f0bSmrg 
2731debfc3dSmrg       ///  Construct output iterator from ostream.
2741debfc3dSmrg       ostreambuf_iterator(ostream_type& __s) _GLIBCXX_USE_NOEXCEPT
2751debfc3dSmrg       : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { }
2761debfc3dSmrg 
2771debfc3dSmrg       ///  Construct output iterator from streambuf.
2781debfc3dSmrg       ostreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT
2791debfc3dSmrg       : _M_sbuf(__s), _M_failed(!_M_sbuf) { }
2801debfc3dSmrg 
2811debfc3dSmrg       ///  Write character to streambuf.  Calls streambuf.sputc().
2821debfc3dSmrg       ostreambuf_iterator&
2831debfc3dSmrg       operator=(_CharT __c)
2841debfc3dSmrg       {
2851debfc3dSmrg 	if (!_M_failed &&
2861debfc3dSmrg 	    _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof()))
2871debfc3dSmrg 	  _M_failed = true;
2881debfc3dSmrg 	return *this;
2891debfc3dSmrg       }
2901debfc3dSmrg 
2911debfc3dSmrg       /// Return *this.
2921debfc3dSmrg       ostreambuf_iterator&
2931debfc3dSmrg       operator*()
2941debfc3dSmrg       { return *this; }
2951debfc3dSmrg 
2961debfc3dSmrg       /// Return *this.
2971debfc3dSmrg       ostreambuf_iterator&
2981debfc3dSmrg       operator++(int)
2991debfc3dSmrg       { return *this; }
3001debfc3dSmrg 
3011debfc3dSmrg       /// Return *this.
3021debfc3dSmrg       ostreambuf_iterator&
3031debfc3dSmrg       operator++()
3041debfc3dSmrg       { return *this; }
3051debfc3dSmrg 
3061debfc3dSmrg       /// Return true if previous operator=() failed.
3071debfc3dSmrg       bool
3081debfc3dSmrg       failed() const _GLIBCXX_USE_NOEXCEPT
3091debfc3dSmrg       { return _M_failed; }
3101debfc3dSmrg 
3111debfc3dSmrg       ostreambuf_iterator&
3121debfc3dSmrg       _M_put(const _CharT* __ws, streamsize __len)
3131debfc3dSmrg       {
3141debfc3dSmrg 	if (__builtin_expect(!_M_failed, true)
3151debfc3dSmrg 	    && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len,
3161debfc3dSmrg 				false))
3171debfc3dSmrg 	  _M_failed = true;
3181debfc3dSmrg 	return *this;
3191debfc3dSmrg       }
3201debfc3dSmrg     };
3211debfc3dSmrg 
3221debfc3dSmrg   // Overloads for streambuf iterators.
3231debfc3dSmrg   template<typename _CharT>
3241debfc3dSmrg     typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
3251debfc3dSmrg 				    ostreambuf_iterator<_CharT> >::__type
3261debfc3dSmrg     copy(istreambuf_iterator<_CharT> __first,
3271debfc3dSmrg 	 istreambuf_iterator<_CharT> __last,
3281debfc3dSmrg 	 ostreambuf_iterator<_CharT> __result)
3291debfc3dSmrg     {
3301debfc3dSmrg       if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed)
3311debfc3dSmrg 	{
3321debfc3dSmrg 	  bool __ineof;
3331debfc3dSmrg 	  __copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof);
3341debfc3dSmrg 	  if (!__ineof)
3351debfc3dSmrg 	    __result._M_failed = true;
3361debfc3dSmrg 	}
3371debfc3dSmrg       return __result;
3381debfc3dSmrg     }
3391debfc3dSmrg 
3401debfc3dSmrg   template<bool _IsMove, typename _CharT>
3411debfc3dSmrg     typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
3421debfc3dSmrg 				    ostreambuf_iterator<_CharT> >::__type
3431debfc3dSmrg     __copy_move_a2(_CharT* __first, _CharT* __last,
3441debfc3dSmrg 		   ostreambuf_iterator<_CharT> __result)
3451debfc3dSmrg     {
3461debfc3dSmrg       const streamsize __num = __last - __first;
3471debfc3dSmrg       if (__num > 0)
3481debfc3dSmrg 	__result._M_put(__first, __num);
3491debfc3dSmrg       return __result;
3501debfc3dSmrg     }
3511debfc3dSmrg 
3521debfc3dSmrg   template<bool _IsMove, typename _CharT>
3531debfc3dSmrg     typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
3541debfc3dSmrg 				    ostreambuf_iterator<_CharT> >::__type
3551debfc3dSmrg     __copy_move_a2(const _CharT* __first, const _CharT* __last,
3561debfc3dSmrg 		   ostreambuf_iterator<_CharT> __result)
3571debfc3dSmrg     {
3581debfc3dSmrg       const streamsize __num = __last - __first;
3591debfc3dSmrg       if (__num > 0)
3601debfc3dSmrg 	__result._M_put(__first, __num);
3611debfc3dSmrg       return __result;
3621debfc3dSmrg     }
3631debfc3dSmrg 
3641debfc3dSmrg   template<bool _IsMove, typename _CharT>
3651debfc3dSmrg     typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
3661debfc3dSmrg 				    _CharT*>::__type
3671debfc3dSmrg     __copy_move_a2(istreambuf_iterator<_CharT> __first,
3681debfc3dSmrg 		   istreambuf_iterator<_CharT> __last, _CharT* __result)
3691debfc3dSmrg     {
3701debfc3dSmrg       typedef istreambuf_iterator<_CharT>		   __is_iterator_type;
3711debfc3dSmrg       typedef typename __is_iterator_type::traits_type	   traits_type;
3721debfc3dSmrg       typedef typename __is_iterator_type::streambuf_type  streambuf_type;
3731debfc3dSmrg       typedef typename traits_type::int_type		   int_type;
3741debfc3dSmrg 
3751debfc3dSmrg       if (__first._M_sbuf && !__last._M_sbuf)
3761debfc3dSmrg 	{
3771debfc3dSmrg 	  streambuf_type* __sb = __first._M_sbuf;
3781debfc3dSmrg 	  int_type __c = __sb->sgetc();
3791debfc3dSmrg 	  while (!traits_type::eq_int_type(__c, traits_type::eof()))
3801debfc3dSmrg 	    {
3811debfc3dSmrg 	      const streamsize __n = __sb->egptr() - __sb->gptr();
3821debfc3dSmrg 	      if (__n > 1)
3831debfc3dSmrg 		{
3841debfc3dSmrg 		  traits_type::copy(__result, __sb->gptr(), __n);
3851debfc3dSmrg 		  __sb->__safe_gbump(__n);
3861debfc3dSmrg 		  __result += __n;
3871debfc3dSmrg 		  __c = __sb->underflow();
3881debfc3dSmrg 		}
3891debfc3dSmrg 	      else
3901debfc3dSmrg 		{
3911debfc3dSmrg 		  *__result++ = traits_type::to_char_type(__c);
3921debfc3dSmrg 		  __c = __sb->snextc();
3931debfc3dSmrg 		}
3941debfc3dSmrg 	    }
3951debfc3dSmrg 	}
3961debfc3dSmrg       return __result;
3971debfc3dSmrg     }
3981debfc3dSmrg 
399*8feb0f0bSmrg #if __cplusplus >= 201103L
400*8feb0f0bSmrg   template<typename _CharT, typename _Size>
401*8feb0f0bSmrg     __enable_if_t<__is_char<_CharT>::__value, _CharT*>
402*8feb0f0bSmrg     __copy_n_a(istreambuf_iterator<_CharT> __it, _Size __n, _CharT* __result)
403*8feb0f0bSmrg     {
404*8feb0f0bSmrg       if (__n == 0)
405*8feb0f0bSmrg 	return __result;
406*8feb0f0bSmrg 
407*8feb0f0bSmrg       __glibcxx_requires_cond(__it._M_sbuf,
408*8feb0f0bSmrg 			      _M_message(__gnu_debug::__msg_inc_istreambuf)
409*8feb0f0bSmrg 			      ._M_iterator(__it));
410*8feb0f0bSmrg       _CharT* __beg = __result;
411*8feb0f0bSmrg       __result += __it._M_sbuf->sgetn(__beg, __n);
412*8feb0f0bSmrg       __glibcxx_requires_cond(__result - __beg == __n,
413*8feb0f0bSmrg 			      _M_message(__gnu_debug::__msg_inc_istreambuf)
414*8feb0f0bSmrg 			      ._M_iterator(__it));
415*8feb0f0bSmrg       return __result;
416*8feb0f0bSmrg     }
417*8feb0f0bSmrg #endif // C++11
418*8feb0f0bSmrg 
4191debfc3dSmrg   template<typename _CharT>
4201debfc3dSmrg     typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
4211debfc3dSmrg 		  		    istreambuf_iterator<_CharT> >::__type
4221debfc3dSmrg     find(istreambuf_iterator<_CharT> __first,
4231debfc3dSmrg 	 istreambuf_iterator<_CharT> __last, const _CharT& __val)
4241debfc3dSmrg     {
4251debfc3dSmrg       typedef istreambuf_iterator<_CharT>		   __is_iterator_type;
4261debfc3dSmrg       typedef typename __is_iterator_type::traits_type     traits_type;
4271debfc3dSmrg       typedef typename __is_iterator_type::streambuf_type  streambuf_type;
4281debfc3dSmrg       typedef typename traits_type::int_type		   int_type;
429a2dc1f3fSmrg       const int_type __eof = traits_type::eof();
4301debfc3dSmrg 
4311debfc3dSmrg       if (__first._M_sbuf && !__last._M_sbuf)
4321debfc3dSmrg 	{
4331debfc3dSmrg 	  const int_type __ival = traits_type::to_int_type(__val);
4341debfc3dSmrg 	  streambuf_type* __sb = __first._M_sbuf;
4351debfc3dSmrg 	  int_type __c = __sb->sgetc();
436a2dc1f3fSmrg 	  while (!traits_type::eq_int_type(__c, __eof)
4371debfc3dSmrg 		 && !traits_type::eq_int_type(__c, __ival))
4381debfc3dSmrg 	    {
4391debfc3dSmrg 	      streamsize __n = __sb->egptr() - __sb->gptr();
4401debfc3dSmrg 	      if (__n > 1)
4411debfc3dSmrg 		{
4421debfc3dSmrg 		  const _CharT* __p = traits_type::find(__sb->gptr(),
4431debfc3dSmrg 							__n, __val);
4441debfc3dSmrg 		  if (__p)
4451debfc3dSmrg 		    __n = __p - __sb->gptr();
4461debfc3dSmrg 		  __sb->__safe_gbump(__n);
4471debfc3dSmrg 		  __c = __sb->sgetc();
4481debfc3dSmrg 		}
4491debfc3dSmrg 	      else
4501debfc3dSmrg 		__c = __sb->snextc();
4511debfc3dSmrg 	    }
4521debfc3dSmrg 
453a2dc1f3fSmrg 	  __first._M_c = __eof;
4541debfc3dSmrg 	}
455a2dc1f3fSmrg 
4561debfc3dSmrg       return __first;
4571debfc3dSmrg     }
4581debfc3dSmrg 
459a2dc1f3fSmrg   template<typename _CharT, typename _Distance>
460a2dc1f3fSmrg     typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value,
461a2dc1f3fSmrg 				    void>::__type
462a2dc1f3fSmrg     advance(istreambuf_iterator<_CharT>& __i, _Distance __n)
463a2dc1f3fSmrg     {
464a2dc1f3fSmrg       if (__n == 0)
465a2dc1f3fSmrg 	return;
466a2dc1f3fSmrg 
467a2dc1f3fSmrg       __glibcxx_assert(__n > 0);
468a2dc1f3fSmrg       __glibcxx_requires_cond(!__i._M_at_eof(),
469a2dc1f3fSmrg 			      _M_message(__gnu_debug::__msg_inc_istreambuf)
470a2dc1f3fSmrg 			      ._M_iterator(__i));
471a2dc1f3fSmrg 
472a2dc1f3fSmrg       typedef istreambuf_iterator<_CharT>		   __is_iterator_type;
473a2dc1f3fSmrg       typedef typename __is_iterator_type::traits_type	   traits_type;
474a2dc1f3fSmrg       typedef typename __is_iterator_type::streambuf_type  streambuf_type;
475a2dc1f3fSmrg       typedef typename traits_type::int_type		   int_type;
476a2dc1f3fSmrg       const int_type __eof = traits_type::eof();
477a2dc1f3fSmrg 
478a2dc1f3fSmrg       streambuf_type* __sb = __i._M_sbuf;
479a2dc1f3fSmrg       while (__n > 0)
480a2dc1f3fSmrg 	{
481a2dc1f3fSmrg 	  streamsize __size = __sb->egptr() - __sb->gptr();
482a2dc1f3fSmrg 	  if (__size > __n)
483a2dc1f3fSmrg 	    {
484a2dc1f3fSmrg 	      __sb->__safe_gbump(__n);
485a2dc1f3fSmrg 	      break;
486a2dc1f3fSmrg 	    }
487a2dc1f3fSmrg 
488a2dc1f3fSmrg 	  __sb->__safe_gbump(__size);
489a2dc1f3fSmrg 	  __n -= __size;
490a2dc1f3fSmrg 	  if (traits_type::eq_int_type(__sb->underflow(), __eof))
491a2dc1f3fSmrg 	    {
492a2dc1f3fSmrg 	      __glibcxx_requires_cond(__n == 0,
493a2dc1f3fSmrg 				_M_message(__gnu_debug::__msg_inc_istreambuf)
494a2dc1f3fSmrg 				._M_iterator(__i));
495a2dc1f3fSmrg 	      break;
496a2dc1f3fSmrg 	    }
497a2dc1f3fSmrg 	}
498a2dc1f3fSmrg 
499a2dc1f3fSmrg       __i._M_c = __eof;
500a2dc1f3fSmrg     }
501a2dc1f3fSmrg 
502*8feb0f0bSmrg /// @} group iterators
5031debfc3dSmrg 
5041debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
5051debfc3dSmrg } // namespace
5061debfc3dSmrg 
5071debfc3dSmrg #endif
508