This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Finally implement Matt's "recipe"
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Cc: Matt Austern <austern at apple dot com>
- Date: Fri, 05 Nov 2004 23:17:35 +0100
- Subject: [Patch] Finally implement Matt's "recipe"
Hi,
the below finally *tries* to implement Matt's indications here:
http://gcc.gnu.org/ml/libstdc++/2004-04/msg00118.html
Basically, I have applied in this new context what we used to do once
upon a time in 3.3 for basic_filebuf::_M_underflow_common: I hope the
choice of an additional istream.cc looks ok to everyone.
Regtests are Ok on x86-linux and now I'm going to thoroughly check the
patch on other platforms and verify that the performance are also
still ok.
Matt, everyone, is this the way we want to go? Indeed, in this context
seems easy and neat progressively adding additional optimizations, as
originally envisaged in the thread above ;)
I'll wait for comments at least until monday.
Thanks,
Paolo.
///////////////
2004-11-XX Paolo Carlini <pcarlini@suse.de>
* include/bits/istream.tcc (getline(char_type*, streamsize,
char_type), ignore(), ignore(streamsize), ignore(streamsize,
int_type)): Restore a generic version of the functions, not
using the protected members of basic_streambuf.
* include/std/std_istream.h (getline(char_type*, streamsize,
char_type), ignore(streamsize), ignore(streamsize, int_type)):
Declare optimized specializations for char and wchar_t.
* src/istream.cc: New file, define the latter.
* src/Makefile.am: Add.
* src/Makefile.in: Regenerate.
diff -prN libstdc++-v3-orig/include/bits/istream.tcc libstdc++-v3/include/bits/istream.tcc
*** libstdc++-v3-orig/include/bits/istream.tcc Thu Sep 2 20:58:34 2004
--- libstdc++-v3/include/bits/istream.tcc Fri Nov 5 22:06:58 2004
*************** namespace std
*** 584,644 ****
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
sentry __cerb(*this, true);
if (__cerb)
! {
try
! {
! const int_type __idelim = traits_type::to_int_type(__delim);
! const int_type __eof = traits_type::eof();
! __streambuf_type* __sb = this->rdbuf();
! int_type __c = __sb->sgetc();
!
! while (_M_gcount + 1 < __n
! && !traits_type::eq_int_type(__c, __eof)
! && !traits_type::eq_int_type(__c, __idelim))
! {
! streamsize __size = std::min(streamsize(__sb->egptr()
! - __sb->gptr()),
! streamsize(__n - _M_gcount
! - 1));
! if (__size > 1)
! {
! const char_type* __p = traits_type::find(__sb->gptr(),
! __size,
! __delim);
! if (__p)
! __size = __p - __sb->gptr();
! traits_type::copy(__s, __sb->gptr(), __size);
! __s += __size;
! __sb->gbump(__size);
! _M_gcount += __size;
! __c = __sb->sgetc();
! }
! else
! {
! *__s++ = traits_type::to_char_type(__c);
! ++_M_gcount;
! __c = __sb->snextc();
! }
! }
!
! if (traits_type::eq_int_type(__c, __eof))
! __err |= ios_base::eofbit;
! else if (traits_type::eq_int_type(__c, __idelim))
! {
! ++_M_gcount;
! __sb->sbumpc();
! }
! else
! __err |= ios_base::failbit;
! }
! catch(...)
! { this->_M_setstate(ios_base::badbit); }
! }
*__s = char_type();
if (!_M_gcount)
! __err |= ios_base::failbit;
if (__err)
! this->setstate(__err);
return *this;
}
--- 584,626 ----
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
sentry __cerb(*this, true);
if (__cerb)
! {
try
! {
! const int_type __idelim = traits_type::to_int_type(__delim);
! const int_type __eof = traits_type::eof();
! __streambuf_type* __sb = this->rdbuf();
! int_type __c = __sb->sgetc();
!
! while (_M_gcount + 1 < __n
! && !traits_type::eq_int_type(__c, __eof)
! && !traits_type::eq_int_type(__c, __idelim))
! {
! *__s++ = traits_type::to_char_type(__c);
! __c = __sb->snextc();
! ++_M_gcount;
! }
! if (traits_type::eq_int_type(__c, __eof))
! __err |= ios_base::eofbit;
! else
! {
! if (traits_type::eq_int_type(__c, __idelim))
! {
! __sb->sbumpc();
! ++_M_gcount;
! }
! else
! __err |= ios_base::failbit;
! }
! }
! catch(...)
! { this->_M_setstate(ios_base::badbit); }
! }
*__s = char_type();
if (!_M_gcount)
! __err |= ios_base::failbit;
if (__err)
! this->setstate(__err);
return *this;
}
*************** namespace std
*** 680,727 ****
{
if (__n == 1)
return ignore();
!
_M_gcount = 0;
sentry __cerb(*this, true);
if (__cerb && __n > 0)
! {
! ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
! try
! {
! const int_type __eof = traits_type::eof();
! __streambuf_type* __sb = this->rdbuf();
! int_type __c = __sb->sgetc();
!
! const bool __bound = __n != numeric_limits<streamsize>::max();
! if (__bound)
! --__n;
! while (_M_gcount <= __n
! && !traits_type::eq_int_type(__c, __eof))
! {
! streamsize __size = __sb->egptr() - __sb->gptr();
! if (__bound)
! __size = std::min(__size, streamsize(__n - _M_gcount + 1));
!
! if (__size > 1)
! {
! __sb->gbump(__size);
! _M_gcount += __size;
! __c = __sb->sgetc();
! }
! else
! {
! ++_M_gcount;
! __c = __sb->snextc();
! }
! }
if (traits_type::eq_int_type(__c, __eof))
! __err |= ios_base::eofbit;
! }
! catch(...)
! { this->_M_setstate(ios_base::badbit); }
! if (__err)
! this->setstate(__err);
! }
return *this;
}
--- 662,692 ----
{
if (__n == 1)
return ignore();
!
_M_gcount = 0;
sentry __cerb(*this, true);
if (__cerb && __n > 0)
! {
! ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
! try
! {
! const int_type __eof = traits_type::eof();
! __streambuf_type* __sb = this->rdbuf();
! int_type __c = __eof;
!
! if (__n != numeric_limits<streamsize>::max())
! --__n;
! while (_M_gcount <= __n
! && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof))
! ++_M_gcount;
if (traits_type::eq_int_type(__c, __eof))
! __err |= ios_base::eofbit;
! }
! catch(...)
! { this->_M_setstate(ios_base::badbit); }
! if (__err)
! this->setstate(__err);
! }
return *this;
}
*************** namespace std
*** 736,791 ****
_M_gcount = 0;
sentry __cerb(*this, true);
if (__cerb && __n > 0)
! {
! ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
! try
! {
! const char_type __cdelim = traits_type::to_char_type(__delim);
! const int_type __eof = traits_type::eof();
! __streambuf_type* __sb = this->rdbuf();
! int_type __c = __sb->sgetc();
!
! const bool __bound = __n != numeric_limits<streamsize>::max();
! if (__bound)
! --__n;
! while (_M_gcount <= __n
! && !traits_type::eq_int_type(__c, __eof)
! && !traits_type::eq_int_type(__c, __delim))
! {
! streamsize __size = __sb->egptr() - __sb->gptr();
! if (__bound)
! __size = std::min(__size, streamsize(__n - _M_gcount + 1));
!
! if (__size > 1)
! {
! const char_type* __p = traits_type::find(__sb->gptr(),
! __size,
! __cdelim);
! if (__p)
! __size = __p - __sb->gptr();
! __sb->gbump(__size);
! _M_gcount += __size;
! __c = __sb->sgetc();
! }
! else
! {
! ++_M_gcount;
! __c = __sb->snextc();
! }
! }
! if (traits_type::eq_int_type(__c, __eof))
! __err |= ios_base::eofbit;
! else if (traits_type::eq_int_type(__c, __delim))
! {
! ++_M_gcount;
! __sb->sbumpc();
! }
! }
! catch(...)
! { this->_M_setstate(ios_base::badbit); }
! if (__err)
! this->setstate(__err);
! }
return *this;
}
--- 701,731 ----
_M_gcount = 0;
sentry __cerb(*this, true);
if (__cerb && __n > 0)
! {
! ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
! try
! {
! const int_type __eof = traits_type::eof();
! __streambuf_type* __sb = this->rdbuf();
! int_type __c = __eof;
!
! if (__n != numeric_limits<streamsize>::max())
! --__n;
! while (_M_gcount <= __n
! && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof))
! {
! ++_M_gcount;
! if (traits_type::eq_int_type(__c, __delim))
! break;
! }
! if (traits_type::eq_int_type(__c, __eof))
! __err |= ios_base::eofbit;
! }
! catch(...)
! { this->_M_setstate(ios_base::badbit); }
! if (__err)
! this->setstate(__err);
! }
return *this;
}
diff -prN libstdc++-v3-orig/include/std/std_istream.h libstdc++-v3/include/std/std_istream.h
*** libstdc++-v3-orig/include/std/std_istream.h Tue Jun 22 12:06:38 2004
--- libstdc++-v3/include/std/std_istream.h Fri Nov 5 22:28:06 2004
*************** namespace std
*** 574,579 ****
--- 574,612 ----
explicit
basic_istream(): _M_gcount(streamsize(0)) { }
};
+
+ // Explicit specialization declarations, defined in src/istream.cc.
+ template<>
+ basic_istream<char>&
+ basic_istream<char>::
+ getline(char_type* __s, streamsize __n, char_type __delim);
+
+ template<>
+ basic_istream<char>&
+ basic_istream<char>::
+ ignore(streamsize __n);
+
+ template<>
+ basic_istream<char>&
+ basic_istream<char>::
+ ignore(streamsize __n, int_type __delim);
+
+ #ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ basic_istream<wchar_t>&
+ basic_istream<wchar_t>::
+ getline(char_type* __s, streamsize __n, char_type __delim);
+
+ template<>
+ basic_istream<wchar_t>&
+ basic_istream<wchar_t>::
+ ignore(streamsize __n);
+
+ template<>
+ basic_istream<wchar_t>&
+ basic_istream<wchar_t>::
+ ignore(streamsize __n, int_type __delim);
+ #endif
/**
* @brief Performs setup work for input streams.
diff -prN libstdc++-v3-orig/src/Makefile.am libstdc++-v3/src/Makefile.am
*** libstdc++-v3-orig/src/Makefile.am Thu Oct 14 19:52:18 2004
--- libstdc++-v3/src/Makefile.am Fri Nov 5 22:10:00 2004
*************** sources = \
*** 126,131 ****
--- 126,132 ----
ext-inst.cc \
io-inst.cc \
istream-inst.cc \
+ istream.cc \
locale-inst.cc \
locale-misc-inst.cc \
misc-inst.cc \
diff -prN libstdc++-v3-orig/src/Makefile.in libstdc++-v3/src/Makefile.in
*** libstdc++-v3-orig/src/Makefile.in Thu Oct 14 19:52:17 2004
--- libstdc++-v3/src/Makefile.in Fri Nov 5 22:11:23 2004
*************** am__objects_3 = bitmap_allocator.lo pool
*** 71,78 ****
locale.lo locale_init.lo locale_facets.lo localename.lo \
stdexcept.lo strstream.lo tree.lo allocator-inst.lo \
concept-inst.lo fstream-inst.lo ext-inst.lo io-inst.lo \
! istream-inst.lo locale-inst.lo locale-misc-inst.lo misc-inst.lo \
! ostream-inst.lo sstream-inst.lo streambuf-inst.lo \
string-inst.lo valarray-inst.lo wlocale-inst.lo \
wstring-inst.lo $(am__objects_1) $(am__objects_2)
am_libstdc___la_OBJECTS = $(am__objects_3)
--- 71,78 ----
locale.lo locale_init.lo locale_facets.lo localename.lo \
stdexcept.lo strstream.lo tree.lo allocator-inst.lo \
concept-inst.lo fstream-inst.lo ext-inst.lo io-inst.lo \
! istream-inst.lo istream.lo locale-inst.lo locale-misc-inst.lo \
! misc-inst.lo ostream-inst.lo sstream-inst.lo streambuf-inst.lo \
string-inst.lo valarray-inst.lo wlocale-inst.lo \
wstring-inst.lo $(am__objects_1) $(am__objects_2)
am_libstdc___la_OBJECTS = $(am__objects_3)
*************** sources = \
*** 336,341 ****
--- 336,342 ----
ext-inst.cc \
io-inst.cc \
istream-inst.cc \
+ istream.cc \
locale-inst.cc \
locale-misc-inst.cc \
misc-inst.cc \
diff -prN libstdc++-v3-orig/src/istream.cc libstdc++-v3/src/istream.cc
*** libstdc++-v3-orig/src/istream.cc Thu Jan 1 01:00:00 1970
--- libstdc++-v3/src/istream.cc Fri Nov 5 22:28:55 2004
***************
*** 0 ****
--- 1,405 ----
+ // Input streams -*- C++ -*-
+
+ // Copyright (C) 2004 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library. This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING. If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction. Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License. This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+
+ //
+ // ISO C++ 14882: 27.6.1 Input streams
+ //
+
+ #include <istream>
+
+ namespace std
+ {
+ template<>
+ basic_istream<char>&
+ basic_istream<char>::
+ getline(char_type* __s, streamsize __n, char_type __delim)
+ {
+ _M_gcount = 0;
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ const int_type __idelim = traits_type::to_int_type(__delim);
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+ int_type __c = __sb->sgetc();
+
+ while (_M_gcount + 1 < __n
+ && !traits_type::eq_int_type(__c, __eof)
+ && !traits_type::eq_int_type(__c, __idelim))
+ {
+ streamsize __size = std::min(streamsize(__sb->egptr()
+ - __sb->gptr()),
+ streamsize(__n - _M_gcount
+ - 1));
+ if (__size > 1)
+ {
+ const char_type* __p = traits_type::find(__sb->gptr(),
+ __size,
+ __delim);
+ if (__p)
+ __size = __p - __sb->gptr();
+ traits_type::copy(__s, __sb->gptr(), __size);
+ __s += __size;
+ __sb->gbump(__size);
+ _M_gcount += __size;
+ __c = __sb->sgetc();
+ }
+ else
+ {
+ *__s++ = traits_type::to_char_type(__c);
+ ++_M_gcount;
+ __c = __sb->snextc();
+ }
+ }
+
+ if (traits_type::eq_int_type(__c, __eof))
+ __err |= ios_base::eofbit;
+ else if (traits_type::eq_int_type(__c, __idelim))
+ {
+ ++_M_gcount;
+ __sb->sbumpc();
+ }
+ else
+ __err |= ios_base::failbit;
+ }
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ }
+ *__s = char_type();
+ if (!_M_gcount)
+ __err |= ios_base::failbit;
+ if (__err)
+ this->setstate(__err);
+ return *this;
+ }
+
+ template<>
+ basic_istream<char>&
+ basic_istream<char>::
+ ignore(streamsize __n)
+ {
+ if (__n == 1)
+ return ignore();
+
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb && __n > 0)
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ try
+ {
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+ int_type __c = __sb->sgetc();
+
+ const bool __bound = __n != numeric_limits<streamsize>::max();
+ if (__bound)
+ --__n;
+ while (_M_gcount <= __n
+ && !traits_type::eq_int_type(__c, __eof))
+ {
+ streamsize __size = __sb->egptr() - __sb->gptr();
+ if (__bound)
+ __size = std::min(__size, streamsize(__n - _M_gcount + 1));
+
+ if (__size > 1)
+ {
+ __sb->gbump(__size);
+ _M_gcount += __size;
+ __c = __sb->sgetc();
+ }
+ else
+ {
+ ++_M_gcount;
+ __c = __sb->snextc();
+ }
+ }
+ if (traits_type::eq_int_type(__c, __eof))
+ __err |= ios_base::eofbit;
+ }
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ if (__err)
+ this->setstate(__err);
+ }
+ return *this;
+ }
+
+ template<>
+ basic_istream<char>&
+ basic_istream<char>::
+ ignore(streamsize __n, int_type __delim)
+ {
+ if (traits_type::eq_int_type(__delim, traits_type::eof()))
+ return ignore(__n);
+
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb && __n > 0)
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ try
+ {
+ const char_type __cdelim = traits_type::to_char_type(__delim);
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+ int_type __c = __sb->sgetc();
+
+ const bool __bound = __n != numeric_limits<streamsize>::max();
+ if (__bound)
+ --__n;
+ while (_M_gcount <= __n
+ && !traits_type::eq_int_type(__c, __eof)
+ && !traits_type::eq_int_type(__c, __delim))
+ {
+ streamsize __size = __sb->egptr() - __sb->gptr();
+ if (__bound)
+ __size = std::min(__size, streamsize(__n - _M_gcount + 1));
+
+ if (__size > 1)
+ {
+ const char_type* __p = traits_type::find(__sb->gptr(),
+ __size,
+ __cdelim);
+ if (__p)
+ __size = __p - __sb->gptr();
+ __sb->gbump(__size);
+ _M_gcount += __size;
+ __c = __sb->sgetc();
+ }
+ else
+ {
+ ++_M_gcount;
+ __c = __sb->snextc();
+ }
+ }
+ if (traits_type::eq_int_type(__c, __eof))
+ __err |= ios_base::eofbit;
+ else if (traits_type::eq_int_type(__c, __delim))
+ {
+ ++_M_gcount;
+ __sb->sbumpc();
+ }
+ }
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ if (__err)
+ this->setstate(__err);
+ }
+ return *this;
+ }
+
+ #ifdef _GLIBCPP_USE_WCHAR_T
+ template<>
+ basic_istream<wchar_t>&
+ basic_istream<wchar_t>::
+ getline(char_type* __s, streamsize __n, char_type __delim)
+ {
+ _M_gcount = 0;
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ try
+ {
+ const int_type __idelim = traits_type::to_int_type(__delim);
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+ int_type __c = __sb->sgetc();
+
+ while (_M_gcount + 1 < __n
+ && !traits_type::eq_int_type(__c, __eof)
+ && !traits_type::eq_int_type(__c, __idelim))
+ {
+ streamsize __size = std::min(streamsize(__sb->egptr()
+ - __sb->gptr()),
+ streamsize(__n - _M_gcount
+ - 1));
+ if (__size > 1)
+ {
+ const char_type* __p = traits_type::find(__sb->gptr(),
+ __size,
+ __delim);
+ if (__p)
+ __size = __p - __sb->gptr();
+ traits_type::copy(__s, __sb->gptr(), __size);
+ __s += __size;
+ __sb->gbump(__size);
+ _M_gcount += __size;
+ __c = __sb->sgetc();
+ }
+ else
+ {
+ *__s++ = traits_type::to_char_type(__c);
+ ++_M_gcount;
+ __c = __sb->snextc();
+ }
+ }
+
+ if (traits_type::eq_int_type(__c, __eof))
+ __err |= ios_base::eofbit;
+ else if (traits_type::eq_int_type(__c, __idelim))
+ {
+ ++_M_gcount;
+ __sb->sbumpc();
+ }
+ else
+ __err |= ios_base::failbit;
+ }
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ }
+ *__s = char_type();
+ if (!_M_gcount)
+ __err |= ios_base::failbit;
+ if (__err)
+ this->setstate(__err);
+ return *this;
+ }
+
+ template<>
+ basic_istream<wchar_t>&
+ basic_istream<wchar_t>::
+ ignore(streamsize __n)
+ {
+ if (__n == 1)
+ return ignore();
+
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb && __n > 0)
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ try
+ {
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+ int_type __c = __sb->sgetc();
+
+ const bool __bound = __n != numeric_limits<streamsize>::max();
+ if (__bound)
+ --__n;
+ while (_M_gcount <= __n
+ && !traits_type::eq_int_type(__c, __eof))
+ {
+ streamsize __size = __sb->egptr() - __sb->gptr();
+ if (__bound)
+ __size = std::min(__size, streamsize(__n - _M_gcount + 1));
+
+ if (__size > 1)
+ {
+ __sb->gbump(__size);
+ _M_gcount += __size;
+ __c = __sb->sgetc();
+ }
+ else
+ {
+ ++_M_gcount;
+ __c = __sb->snextc();
+ }
+ }
+ if (traits_type::eq_int_type(__c, __eof))
+ __err |= ios_base::eofbit;
+ }
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ if (__err)
+ this->setstate(__err);
+ }
+ return *this;
+ }
+
+ template<>
+ basic_istream<wchar_t>&
+ basic_istream<wchar_t>::
+ ignore(streamsize __n, int_type __delim)
+ {
+ if (traits_type::eq_int_type(__delim, traits_type::eof()))
+ return ignore(__n);
+
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb && __n > 0)
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ try
+ {
+ const char_type __cdelim = traits_type::to_char_type(__delim);
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+ int_type __c = __sb->sgetc();
+
+ const bool __bound = __n != numeric_limits<streamsize>::max();
+ if (__bound)
+ --__n;
+ while (_M_gcount <= __n
+ && !traits_type::eq_int_type(__c, __eof)
+ && !traits_type::eq_int_type(__c, __delim))
+ {
+ streamsize __size = __sb->egptr() - __sb->gptr();
+ if (__bound)
+ __size = std::min(__size, streamsize(__n - _M_gcount + 1));
+
+ if (__size > 1)
+ {
+ const char_type* __p = traits_type::find(__sb->gptr(),
+ __size,
+ __cdelim);
+ if (__p)
+ __size = __p - __sb->gptr();
+ __sb->gbump(__size);
+ _M_gcount += __size;
+ __c = __sb->sgetc();
+ }
+ else
+ {
+ ++_M_gcount;
+ __c = __sb->snextc();
+ }
+ }
+ if (traits_type::eq_int_type(__c, __eof))
+ __err |= ios_base::eofbit;
+ else if (traits_type::eq_int_type(__c, __delim))
+ {
+ ++_M_gcount;
+ __sb->sbumpc();
+ }
+ }
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ if (__err)
+ this->setstate(__err);
+ }
+ return *this;
+ }
+ #endif
+ } // namespace std