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