{
template<typename _CharT, typename _Traits>
basic_istream<_CharT, _Traits>::sentry::
- sentry(basic_istream<_CharT, _Traits>& __in, bool __noskipws)
+ sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false)
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
if (__in.good())
{
if (__in.tie())
__in.tie()->flush();
- if (!__noskipws && (__in.flags() & ios_base::skipws))
+ if (!__noskip && (__in.flags() & ios_base::skipws))
{
const __int_type __eof = traits_type::eof();
__streambuf_type* __sb = __in.rdbuf();
const __ctype_type& __ct = __check_facet(__in._M_ctype);
while (!traits_type::eq_int_type(__c, __eof)
- && __ct.is(ctype_base::space,
+ && __ct.is(ctype_base::space,
traits_type::to_char_type(__c)))
__c = __sb->snextc();
_M_ok = true;
else
{
- _M_ok = false;
__err |= ios_base::failbit;
__in.setstate(__err);
}
{
try
{
- int_type __cb = this->rdbuf()->sbumpc();
+ const int_type __cb = this->rdbuf()->sbumpc();
// 27.6.1.1 paragraph 3
if (!traits_type::eq_int_type(__cb, traits_type::eof()))
{
&& !traits_type::eq_int_type(__c, __idelim))
{
*__s++ = traits_type::to_char_type(__c);
- __c = __sb->snextc();
++_M_gcount;
+ __c = __sb->snextc();
}
if (traits_type::eq_int_type(__c, __eof))
__err |= ios_base::eofbit;
const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sgetc();
- --__n;
- while (_M_gcount < __n
+ 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()),
- __n - _M_gcount);
+ streamsize(__n - _M_gcount
+ - 1));
if (__size > 1)
{
const char_type* __p = traits_type::find(__sb->gptr(),
else
{
*__s++ = traits_type::to_char_type(__c);
- __c = __sb->snextc();
++_M_gcount;
+ __c = __sb->snextc();
}
}
__err |= ios_base::eofbit;
else if (traits_type::eq_int_type(__c, __idelim))
{
+ ++_M_gcount;
__sb->sbumpc();
- ++_M_gcount;
}
else
__err |= ios_base::failbit;
return *this;
}
+ // We provide three overloads, since the first two are much simpler
+ // than the general case. Also, the latter two can thus adopt the
+ // same "batchy" strategy used by getline above.
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ ignore(void)
+ {
+ _M_gcount = 0;
+ sentry __cerb(*this, true);
+ if (__cerb)
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ try
+ {
+ const int_type __eof = traits_type::eof();
+ __streambuf_type* __sb = this->rdbuf();
+
+ if (traits_type::eq_int_type(__sb->sbumpc(), __eof))
+ __err |= ios_base::eofbit;
+ else
+ _M_gcount = 1;
+ }
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ if (__err)
+ this->setstate(__err);
+ }
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_istream<_CharT, _Traits>&
+ basic_istream<_CharT, _Traits>::
+ 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<typename _CharT, typename _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::
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;
+ int_type __c = __sb->sgetc();
- __n = std::min(__n, numeric_limits<streamsize>::max());
- while (_M_gcount < __n
- && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof))
+ 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))
{
- ++_M_gcount;
- if (traits_type::eq_int_type(__c, __delim))
- break;
+ 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); }
try
{
// Cannot compare int_type with streamsize generically.
- streamsize __num = this->rdbuf()->in_avail();
- if (__num >= 0)
- {
- __num = std::min(__num, __n);
- if (__num)
- _M_gcount = this->rdbuf()->sgetn(__s, __num);
- }
- else
+ const streamsize __num = this->rdbuf()->in_avail();
+ if (__num > 0)
+ _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n));
+ else if (__num == -1)
__err |= ios_base::eofbit;
}
catch(...)
if (!this->fail())
{
// 136. seekp, seekg setting wrong streams?
- pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::in);
+ const pos_type __p = this->rdbuf()->pubseekpos(__pos,
+ ios_base::in);
// 129. Need error indication from seekp() and seekg()
if (__p == pos_type(off_type(-1)))
if (!this->fail())
{
// 136. seekp, seekg setting wrong streams?
- pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
- ios_base::in);
+ const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
+ ios_base::in);
// 129. Need error indication from seekp() and seekg()
if (__p == pos_type(off_type(-1)))
operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c)
{
typedef basic_istream<_CharT, _Traits> __istream_type;
+ typedef typename __istream_type::int_type __int_type;
+
typename __istream_type::sentry __cerb(__in, false);
if (__cerb)
{
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
- typename __istream_type::int_type __cb = __in.rdbuf()->sbumpc();
+ const __int_type __cb = __in.rdbuf()->sbumpc();
if (!_Traits::eq_int_type(__cb, _Traits::eof()))
__c = _Traits::to_char_type(__cb);
else
{
try
{
+ // Avoid reallocation for common case.
__str.erase();
- streamsize __w = __in.width();
- __size_type __n;
- __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size();
-
+ _CharT __buf[128];
+ __size_type __len = 0;
+ const streamsize __w = __in.width();
+ const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
+ : __str.max_size();
const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
const __int_type __eof = _Traits::eof();
__streambuf_type* __sb = __in.rdbuf();
&& !_Traits::eq_int_type(__c, __eof)
&& !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
{
- __str += _Traits::to_char_type(__c);
+ if (__len == sizeof(__buf) / sizeof(_CharT))
+ {
+ __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
+ __len = 0;
+ }
+ __buf[__len++] = _Traits::to_char_type(__c);
++__extracted;
__c = __sb->snextc();
}
+ __str.append(__buf, __len);
+
if (_Traits::eq_int_type(__c, __eof))
__err |= ios_base::eofbit;
__in.width(0);
__size_type __extracted = 0;
const __size_type __n = __str.max_size();
- bool __testdelim = false;
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
typename __istream_type::sentry __cerb(__in, true);
if (__cerb)
{
try
{
- // Avoid reallocation for common case.
+ // Avoid reallocation for common case.
__str.erase();
_CharT __buf[128];
__size_type __len = 0;
__err |= ios_base::eofbit;
else if (_Traits::eq_int_type(__c, __idelim))
{
+ ++__extracted;
__sb->sbumpc();
- ++__extracted;
}
else
__err |= ios_base::failbit;