1*e4b17023SJohn Marino // Streambuf iterators 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4*e4b17023SJohn Marino // 2006, 2007, 2009, 2010, 2011 5*e4b17023SJohn Marino // Free Software Foundation, Inc. 6*e4b17023SJohn Marino // 7*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 8*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 9*e4b17023SJohn Marino // terms of the GNU General Public License as published by the 10*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 11*e4b17023SJohn Marino // any later version. 12*e4b17023SJohn Marino 13*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 14*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 15*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*e4b17023SJohn Marino // GNU General Public License for more details. 17*e4b17023SJohn Marino 18*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 19*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 20*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 21*e4b17023SJohn Marino 22*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 23*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 24*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 26*e4b17023SJohn Marino 27*e4b17023SJohn Marino /** @file bits/streambuf_iterator.h 28*e4b17023SJohn Marino * This is an internal header file, included by other library headers. 29*e4b17023SJohn Marino * Do not attempt to use it directly. @headername{iterator} 30*e4b17023SJohn Marino */ 31*e4b17023SJohn Marino 32*e4b17023SJohn Marino #ifndef _STREAMBUF_ITERATOR_H 33*e4b17023SJohn Marino #define _STREAMBUF_ITERATOR_H 1 34*e4b17023SJohn Marino 35*e4b17023SJohn Marino #pragma GCC system_header 36*e4b17023SJohn Marino 37*e4b17023SJohn Marino #include <streambuf> 38*e4b17023SJohn Marino #include <debug/debug.h> 39*e4b17023SJohn Marino 40*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 41*e4b17023SJohn Marino { 42*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 43*e4b17023SJohn Marino 44*e4b17023SJohn Marino /** 45*e4b17023SJohn Marino * @addtogroup iterators 46*e4b17023SJohn Marino * @{ 47*e4b17023SJohn Marino */ 48*e4b17023SJohn Marino 49*e4b17023SJohn Marino // 24.5.3 Template class istreambuf_iterator 50*e4b17023SJohn Marino /// Provides input iterator semantics for streambufs. 51*e4b17023SJohn Marino template<typename _CharT, typename _Traits> 52*e4b17023SJohn Marino class istreambuf_iterator 53*e4b17023SJohn Marino : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, 54*e4b17023SJohn Marino _CharT*, 55*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 56*e4b17023SJohn Marino // LWG 445. 57*e4b17023SJohn Marino _CharT> 58*e4b17023SJohn Marino #else 59*e4b17023SJohn Marino _CharT&> 60*e4b17023SJohn Marino #endif 61*e4b17023SJohn Marino { 62*e4b17023SJohn Marino public: 63*e4b17023SJohn Marino // Types: 64*e4b17023SJohn Marino //@{ 65*e4b17023SJohn Marino /// Public typedefs 66*e4b17023SJohn Marino typedef _CharT char_type; 67*e4b17023SJohn Marino typedef _Traits traits_type; 68*e4b17023SJohn Marino typedef typename _Traits::int_type int_type; 69*e4b17023SJohn Marino typedef basic_streambuf<_CharT, _Traits> streambuf_type; 70*e4b17023SJohn Marino typedef basic_istream<_CharT, _Traits> istream_type; 71*e4b17023SJohn Marino //@} 72*e4b17023SJohn Marino 73*e4b17023SJohn Marino template<typename _CharT2> 74*e4b17023SJohn Marino friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, 75*e4b17023SJohn Marino ostreambuf_iterator<_CharT2> >::__type 76*e4b17023SJohn Marino copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, 77*e4b17023SJohn Marino ostreambuf_iterator<_CharT2>); 78*e4b17023SJohn Marino 79*e4b17023SJohn Marino template<bool _IsMove, typename _CharT2> 80*e4b17023SJohn Marino friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, 81*e4b17023SJohn Marino _CharT2*>::__type 82*e4b17023SJohn Marino __copy_move_a2(istreambuf_iterator<_CharT2>, 83*e4b17023SJohn Marino istreambuf_iterator<_CharT2>, _CharT2*); 84*e4b17023SJohn Marino 85*e4b17023SJohn Marino template<typename _CharT2> 86*e4b17023SJohn Marino friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, 87*e4b17023SJohn Marino istreambuf_iterator<_CharT2> >::__type 88*e4b17023SJohn Marino find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, 89*e4b17023SJohn Marino const _CharT2&); 90*e4b17023SJohn Marino 91*e4b17023SJohn Marino private: 92*e4b17023SJohn Marino // 24.5.3 istreambuf_iterator 93*e4b17023SJohn Marino // p 1 94*e4b17023SJohn Marino // If the end of stream is reached (streambuf_type::sgetc() 95*e4b17023SJohn Marino // returns traits_type::eof()), the iterator becomes equal to 96*e4b17023SJohn Marino // the "end of stream" iterator value. 97*e4b17023SJohn Marino // NB: This implementation assumes the "end of stream" value 98*e4b17023SJohn Marino // is EOF, or -1. 99*e4b17023SJohn Marino mutable streambuf_type* _M_sbuf; 100*e4b17023SJohn Marino mutable int_type _M_c; 101*e4b17023SJohn Marino 102*e4b17023SJohn Marino public: 103*e4b17023SJohn Marino /// Construct end of input stream iterator. 104*e4b17023SJohn Marino _GLIBCXX_CONSTEXPR istreambuf_iterator() _GLIBCXX_USE_NOEXCEPT 105*e4b17023SJohn Marino : _M_sbuf(0), _M_c(traits_type::eof()) { } 106*e4b17023SJohn Marino 107*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 108*e4b17023SJohn Marino istreambuf_iterator(const istreambuf_iterator&) noexcept = default; 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino ~istreambuf_iterator() = default; 111*e4b17023SJohn Marino #endif 112*e4b17023SJohn Marino 113*e4b17023SJohn Marino /// Construct start of input stream iterator. 114*e4b17023SJohn Marino istreambuf_iterator(istream_type& __s) _GLIBCXX_USE_NOEXCEPT 115*e4b17023SJohn Marino : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } 116*e4b17023SJohn Marino 117*e4b17023SJohn Marino /// Construct start of streambuf iterator. 118*e4b17023SJohn Marino istreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT 119*e4b17023SJohn Marino : _M_sbuf(__s), _M_c(traits_type::eof()) { } 120*e4b17023SJohn Marino 121*e4b17023SJohn Marino /// Return the current character pointed to by iterator. This returns 122*e4b17023SJohn Marino /// streambuf.sgetc(). It cannot be assigned. NB: The result of 123*e4b17023SJohn Marino /// operator*() on an end of stream is undefined. 124*e4b17023SJohn Marino char_type 125*e4b17023SJohn Marino operator*() const 126*e4b17023SJohn Marino { 127*e4b17023SJohn Marino #ifdef _GLIBCXX_DEBUG_PEDANTIC 128*e4b17023SJohn Marino // Dereferencing a past-the-end istreambuf_iterator is a 129*e4b17023SJohn Marino // libstdc++ extension 130*e4b17023SJohn Marino __glibcxx_requires_cond(!_M_at_eof(), 131*e4b17023SJohn Marino _M_message(__gnu_debug::__msg_deref_istreambuf) 132*e4b17023SJohn Marino ._M_iterator(*this)); 133*e4b17023SJohn Marino #endif 134*e4b17023SJohn Marino return traits_type::to_char_type(_M_get()); 135*e4b17023SJohn Marino } 136*e4b17023SJohn Marino 137*e4b17023SJohn Marino /// Advance the iterator. Calls streambuf.sbumpc(). 138*e4b17023SJohn Marino istreambuf_iterator& 139*e4b17023SJohn Marino operator++() 140*e4b17023SJohn Marino { 141*e4b17023SJohn Marino __glibcxx_requires_cond(!_M_at_eof(), 142*e4b17023SJohn Marino _M_message(__gnu_debug::__msg_inc_istreambuf) 143*e4b17023SJohn Marino ._M_iterator(*this)); 144*e4b17023SJohn Marino if (_M_sbuf) 145*e4b17023SJohn Marino { 146*e4b17023SJohn Marino _M_sbuf->sbumpc(); 147*e4b17023SJohn Marino _M_c = traits_type::eof(); 148*e4b17023SJohn Marino } 149*e4b17023SJohn Marino return *this; 150*e4b17023SJohn Marino } 151*e4b17023SJohn Marino 152*e4b17023SJohn Marino /// Advance the iterator. Calls streambuf.sbumpc(). 153*e4b17023SJohn Marino istreambuf_iterator 154*e4b17023SJohn Marino operator++(int) 155*e4b17023SJohn Marino { 156*e4b17023SJohn Marino __glibcxx_requires_cond(!_M_at_eof(), 157*e4b17023SJohn Marino _M_message(__gnu_debug::__msg_inc_istreambuf) 158*e4b17023SJohn Marino ._M_iterator(*this)); 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino istreambuf_iterator __old = *this; 161*e4b17023SJohn Marino if (_M_sbuf) 162*e4b17023SJohn Marino { 163*e4b17023SJohn Marino __old._M_c = _M_sbuf->sbumpc(); 164*e4b17023SJohn Marino _M_c = traits_type::eof(); 165*e4b17023SJohn Marino } 166*e4b17023SJohn Marino return __old; 167*e4b17023SJohn Marino } 168*e4b17023SJohn Marino 169*e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 170*e4b17023SJohn Marino // 110 istreambuf_iterator::equal not const 171*e4b17023SJohn Marino // NB: there is also number 111 (NAD, Future) pending on this function. 172*e4b17023SJohn Marino /// Return true both iterators are end or both are not end. 173*e4b17023SJohn Marino bool 174*e4b17023SJohn Marino equal(const istreambuf_iterator& __b) const 175*e4b17023SJohn Marino { return _M_at_eof() == __b._M_at_eof(); } 176*e4b17023SJohn Marino 177*e4b17023SJohn Marino private: 178*e4b17023SJohn Marino int_type 179*e4b17023SJohn Marino _M_get() const 180*e4b17023SJohn Marino { 181*e4b17023SJohn Marino const int_type __eof = traits_type::eof(); 182*e4b17023SJohn Marino int_type __ret = __eof; 183*e4b17023SJohn Marino if (_M_sbuf) 184*e4b17023SJohn Marino { 185*e4b17023SJohn Marino if (!traits_type::eq_int_type(_M_c, __eof)) 186*e4b17023SJohn Marino __ret = _M_c; 187*e4b17023SJohn Marino else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), 188*e4b17023SJohn Marino __eof)) 189*e4b17023SJohn Marino _M_c = __ret; 190*e4b17023SJohn Marino else 191*e4b17023SJohn Marino _M_sbuf = 0; 192*e4b17023SJohn Marino } 193*e4b17023SJohn Marino return __ret; 194*e4b17023SJohn Marino } 195*e4b17023SJohn Marino 196*e4b17023SJohn Marino bool 197*e4b17023SJohn Marino _M_at_eof() const 198*e4b17023SJohn Marino { 199*e4b17023SJohn Marino const int_type __eof = traits_type::eof(); 200*e4b17023SJohn Marino return traits_type::eq_int_type(_M_get(), __eof); 201*e4b17023SJohn Marino } 202*e4b17023SJohn Marino }; 203*e4b17023SJohn Marino 204*e4b17023SJohn Marino template<typename _CharT, typename _Traits> 205*e4b17023SJohn Marino inline bool 206*e4b17023SJohn Marino operator==(const istreambuf_iterator<_CharT, _Traits>& __a, 207*e4b17023SJohn Marino const istreambuf_iterator<_CharT, _Traits>& __b) 208*e4b17023SJohn Marino { return __a.equal(__b); } 209*e4b17023SJohn Marino 210*e4b17023SJohn Marino template<typename _CharT, typename _Traits> 211*e4b17023SJohn Marino inline bool 212*e4b17023SJohn Marino operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, 213*e4b17023SJohn Marino const istreambuf_iterator<_CharT, _Traits>& __b) 214*e4b17023SJohn Marino { return !__a.equal(__b); } 215*e4b17023SJohn Marino 216*e4b17023SJohn Marino /// Provides output iterator semantics for streambufs. 217*e4b17023SJohn Marino template<typename _CharT, typename _Traits> 218*e4b17023SJohn Marino class ostreambuf_iterator 219*e4b17023SJohn Marino : public iterator<output_iterator_tag, void, void, void, void> 220*e4b17023SJohn Marino { 221*e4b17023SJohn Marino public: 222*e4b17023SJohn Marino // Types: 223*e4b17023SJohn Marino //@{ 224*e4b17023SJohn Marino /// Public typedefs 225*e4b17023SJohn Marino typedef _CharT char_type; 226*e4b17023SJohn Marino typedef _Traits traits_type; 227*e4b17023SJohn Marino typedef basic_streambuf<_CharT, _Traits> streambuf_type; 228*e4b17023SJohn Marino typedef basic_ostream<_CharT, _Traits> ostream_type; 229*e4b17023SJohn Marino //@} 230*e4b17023SJohn Marino 231*e4b17023SJohn Marino template<typename _CharT2> 232*e4b17023SJohn Marino friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, 233*e4b17023SJohn Marino ostreambuf_iterator<_CharT2> >::__type 234*e4b17023SJohn Marino copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, 235*e4b17023SJohn Marino ostreambuf_iterator<_CharT2>); 236*e4b17023SJohn Marino 237*e4b17023SJohn Marino private: 238*e4b17023SJohn Marino streambuf_type* _M_sbuf; 239*e4b17023SJohn Marino bool _M_failed; 240*e4b17023SJohn Marino 241*e4b17023SJohn Marino public: 242*e4b17023SJohn Marino /// Construct output iterator from ostream. 243*e4b17023SJohn Marino ostreambuf_iterator(ostream_type& __s) _GLIBCXX_USE_NOEXCEPT 244*e4b17023SJohn Marino : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } 245*e4b17023SJohn Marino 246*e4b17023SJohn Marino /// Construct output iterator from streambuf. 247*e4b17023SJohn Marino ostreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT 248*e4b17023SJohn Marino : _M_sbuf(__s), _M_failed(!_M_sbuf) { } 249*e4b17023SJohn Marino 250*e4b17023SJohn Marino /// Write character to streambuf. Calls streambuf.sputc(). 251*e4b17023SJohn Marino ostreambuf_iterator& 252*e4b17023SJohn Marino operator=(_CharT __c) 253*e4b17023SJohn Marino { 254*e4b17023SJohn Marino if (!_M_failed && 255*e4b17023SJohn Marino _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) 256*e4b17023SJohn Marino _M_failed = true; 257*e4b17023SJohn Marino return *this; 258*e4b17023SJohn Marino } 259*e4b17023SJohn Marino 260*e4b17023SJohn Marino /// Return *this. 261*e4b17023SJohn Marino ostreambuf_iterator& 262*e4b17023SJohn Marino operator*() 263*e4b17023SJohn Marino { return *this; } 264*e4b17023SJohn Marino 265*e4b17023SJohn Marino /// Return *this. 266*e4b17023SJohn Marino ostreambuf_iterator& 267*e4b17023SJohn Marino operator++(int) 268*e4b17023SJohn Marino { return *this; } 269*e4b17023SJohn Marino 270*e4b17023SJohn Marino /// Return *this. 271*e4b17023SJohn Marino ostreambuf_iterator& 272*e4b17023SJohn Marino operator++() 273*e4b17023SJohn Marino { return *this; } 274*e4b17023SJohn Marino 275*e4b17023SJohn Marino /// Return true if previous operator=() failed. 276*e4b17023SJohn Marino bool 277*e4b17023SJohn Marino failed() const _GLIBCXX_USE_NOEXCEPT 278*e4b17023SJohn Marino { return _M_failed; } 279*e4b17023SJohn Marino 280*e4b17023SJohn Marino ostreambuf_iterator& 281*e4b17023SJohn Marino _M_put(const _CharT* __ws, streamsize __len) 282*e4b17023SJohn Marino { 283*e4b17023SJohn Marino if (__builtin_expect(!_M_failed, true) 284*e4b17023SJohn Marino && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, 285*e4b17023SJohn Marino false)) 286*e4b17023SJohn Marino _M_failed = true; 287*e4b17023SJohn Marino return *this; 288*e4b17023SJohn Marino } 289*e4b17023SJohn Marino }; 290*e4b17023SJohn Marino 291*e4b17023SJohn Marino // Overloads for streambuf iterators. 292*e4b17023SJohn Marino template<typename _CharT> 293*e4b17023SJohn Marino typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 294*e4b17023SJohn Marino ostreambuf_iterator<_CharT> >::__type 295*e4b17023SJohn Marino copy(istreambuf_iterator<_CharT> __first, 296*e4b17023SJohn Marino istreambuf_iterator<_CharT> __last, 297*e4b17023SJohn Marino ostreambuf_iterator<_CharT> __result) 298*e4b17023SJohn Marino { 299*e4b17023SJohn Marino if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed) 300*e4b17023SJohn Marino { 301*e4b17023SJohn Marino bool __ineof; 302*e4b17023SJohn Marino __copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof); 303*e4b17023SJohn Marino if (!__ineof) 304*e4b17023SJohn Marino __result._M_failed = true; 305*e4b17023SJohn Marino } 306*e4b17023SJohn Marino return __result; 307*e4b17023SJohn Marino } 308*e4b17023SJohn Marino 309*e4b17023SJohn Marino template<bool _IsMove, typename _CharT> 310*e4b17023SJohn Marino typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 311*e4b17023SJohn Marino ostreambuf_iterator<_CharT> >::__type 312*e4b17023SJohn Marino __copy_move_a2(_CharT* __first, _CharT* __last, 313*e4b17023SJohn Marino ostreambuf_iterator<_CharT> __result) 314*e4b17023SJohn Marino { 315*e4b17023SJohn Marino const streamsize __num = __last - __first; 316*e4b17023SJohn Marino if (__num > 0) 317*e4b17023SJohn Marino __result._M_put(__first, __num); 318*e4b17023SJohn Marino return __result; 319*e4b17023SJohn Marino } 320*e4b17023SJohn Marino 321*e4b17023SJohn Marino template<bool _IsMove, typename _CharT> 322*e4b17023SJohn Marino typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 323*e4b17023SJohn Marino ostreambuf_iterator<_CharT> >::__type 324*e4b17023SJohn Marino __copy_move_a2(const _CharT* __first, const _CharT* __last, 325*e4b17023SJohn Marino ostreambuf_iterator<_CharT> __result) 326*e4b17023SJohn Marino { 327*e4b17023SJohn Marino const streamsize __num = __last - __first; 328*e4b17023SJohn Marino if (__num > 0) 329*e4b17023SJohn Marino __result._M_put(__first, __num); 330*e4b17023SJohn Marino return __result; 331*e4b17023SJohn Marino } 332*e4b17023SJohn Marino 333*e4b17023SJohn Marino template<bool _IsMove, typename _CharT> 334*e4b17023SJohn Marino typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 335*e4b17023SJohn Marino _CharT*>::__type 336*e4b17023SJohn Marino __copy_move_a2(istreambuf_iterator<_CharT> __first, 337*e4b17023SJohn Marino istreambuf_iterator<_CharT> __last, _CharT* __result) 338*e4b17023SJohn Marino { 339*e4b17023SJohn Marino typedef istreambuf_iterator<_CharT> __is_iterator_type; 340*e4b17023SJohn Marino typedef typename __is_iterator_type::traits_type traits_type; 341*e4b17023SJohn Marino typedef typename __is_iterator_type::streambuf_type streambuf_type; 342*e4b17023SJohn Marino typedef typename traits_type::int_type int_type; 343*e4b17023SJohn Marino 344*e4b17023SJohn Marino if (__first._M_sbuf && !__last._M_sbuf) 345*e4b17023SJohn Marino { 346*e4b17023SJohn Marino streambuf_type* __sb = __first._M_sbuf; 347*e4b17023SJohn Marino int_type __c = __sb->sgetc(); 348*e4b17023SJohn Marino while (!traits_type::eq_int_type(__c, traits_type::eof())) 349*e4b17023SJohn Marino { 350*e4b17023SJohn Marino const streamsize __n = __sb->egptr() - __sb->gptr(); 351*e4b17023SJohn Marino if (__n > 1) 352*e4b17023SJohn Marino { 353*e4b17023SJohn Marino traits_type::copy(__result, __sb->gptr(), __n); 354*e4b17023SJohn Marino __sb->__safe_gbump(__n); 355*e4b17023SJohn Marino __result += __n; 356*e4b17023SJohn Marino __c = __sb->underflow(); 357*e4b17023SJohn Marino } 358*e4b17023SJohn Marino else 359*e4b17023SJohn Marino { 360*e4b17023SJohn Marino *__result++ = traits_type::to_char_type(__c); 361*e4b17023SJohn Marino __c = __sb->snextc(); 362*e4b17023SJohn Marino } 363*e4b17023SJohn Marino } 364*e4b17023SJohn Marino } 365*e4b17023SJohn Marino return __result; 366*e4b17023SJohn Marino } 367*e4b17023SJohn Marino 368*e4b17023SJohn Marino template<typename _CharT> 369*e4b17023SJohn Marino typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, 370*e4b17023SJohn Marino istreambuf_iterator<_CharT> >::__type 371*e4b17023SJohn Marino find(istreambuf_iterator<_CharT> __first, 372*e4b17023SJohn Marino istreambuf_iterator<_CharT> __last, const _CharT& __val) 373*e4b17023SJohn Marino { 374*e4b17023SJohn Marino typedef istreambuf_iterator<_CharT> __is_iterator_type; 375*e4b17023SJohn Marino typedef typename __is_iterator_type::traits_type traits_type; 376*e4b17023SJohn Marino typedef typename __is_iterator_type::streambuf_type streambuf_type; 377*e4b17023SJohn Marino typedef typename traits_type::int_type int_type; 378*e4b17023SJohn Marino 379*e4b17023SJohn Marino if (__first._M_sbuf && !__last._M_sbuf) 380*e4b17023SJohn Marino { 381*e4b17023SJohn Marino const int_type __ival = traits_type::to_int_type(__val); 382*e4b17023SJohn Marino streambuf_type* __sb = __first._M_sbuf; 383*e4b17023SJohn Marino int_type __c = __sb->sgetc(); 384*e4b17023SJohn Marino while (!traits_type::eq_int_type(__c, traits_type::eof()) 385*e4b17023SJohn Marino && !traits_type::eq_int_type(__c, __ival)) 386*e4b17023SJohn Marino { 387*e4b17023SJohn Marino streamsize __n = __sb->egptr() - __sb->gptr(); 388*e4b17023SJohn Marino if (__n > 1) 389*e4b17023SJohn Marino { 390*e4b17023SJohn Marino const _CharT* __p = traits_type::find(__sb->gptr(), 391*e4b17023SJohn Marino __n, __val); 392*e4b17023SJohn Marino if (__p) 393*e4b17023SJohn Marino __n = __p - __sb->gptr(); 394*e4b17023SJohn Marino __sb->__safe_gbump(__n); 395*e4b17023SJohn Marino __c = __sb->sgetc(); 396*e4b17023SJohn Marino } 397*e4b17023SJohn Marino else 398*e4b17023SJohn Marino __c = __sb->snextc(); 399*e4b17023SJohn Marino } 400*e4b17023SJohn Marino 401*e4b17023SJohn Marino if (!traits_type::eq_int_type(__c, traits_type::eof())) 402*e4b17023SJohn Marino __first._M_c = __c; 403*e4b17023SJohn Marino else 404*e4b17023SJohn Marino __first._M_sbuf = 0; 405*e4b17023SJohn Marino } 406*e4b17023SJohn Marino return __first; 407*e4b17023SJohn Marino } 408*e4b17023SJohn Marino 409*e4b17023SJohn Marino // @} group iterators 410*e4b17023SJohn Marino 411*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 412*e4b17023SJohn Marino } // namespace 413*e4b17023SJohn Marino 414*e4b17023SJohn Marino #endif 415