summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog14
-rw-r--r--libstdc++-v3/include/bits/istream.tcc123
-rw-r--r--libstdc++-v3/include/std/std_istream.h15
3 files changed, 144 insertions, 8 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 3b579d73496..7e0b5e7c1bf 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,17 @@
+2004-06-22 Paolo Carlini <pcarlini@suse.de>
+
+ * include/std/std_istream.h (ignore(streamsize __n = 1,
+ int_type __delim = traits_type::eof())): Split into...
+ (ignore(), ignore(streamsize __n), ignore(streamsize __n,
+ int_type __delim)): The first two can be much more simpler
+ and efficient than the fully general case; also, the last
+ two can take advantage of the same mechanism already used
+ for getline.
+ * include/bits/istream.tcc (ignore(streamsize __n = 1,
+ int_type __delim = traits_type::eof()): Remove.
+ (ignore(), ignore(streamsize __n), ignore(streamsize __n,
+ int_type __delim)): New.
+
2004-06-21 Loren J. Rittle <ljrittle@acm.org>
* config/linker-map.gnu: Use wildcards for
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc
index c8861b651ef..59a44de10dd 100644
--- a/libstdc++-v3/include/bits/istream.tcc
+++ b/libstdc++-v3/include/bits/istream.tcc
@@ -641,11 +641,97 @@ namespace std
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)
@@ -653,21 +739,46 @@ namespace std
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 = __eof;
+ int_type __c = __sb->sgetc();
- if (__n != numeric_limits<streamsize>::max())
+ const bool __bound = __n != numeric_limits<streamsize>::max();
+ if (__bound)
--__n;
while (_M_gcount <= __n
- && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof))
+ && !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); }
diff --git a/libstdc++-v3/include/std/std_istream.h b/libstdc++-v3/include/std/std_istream.h
index a3a53ba73f6..65f9e6c3034 100644
--- a/libstdc++-v3/include/std/std_istream.h
+++ b/libstdc++-v3/include/std/std_istream.h
@@ -1,6 +1,6 @@
// Input streams -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -412,9 +412,20 @@ namespace std
* - the next character equals @a delim (in this case, the character
* is extracted); note that this condition will never occur if
* @a delim equals @c traits::eof().
+ *
+ * NB: Provide three overloads, instead of the single function
+ * (with defaults) mandated by the Standard: this leads to a
+ * better performing implementation, while still conforming to
+ * the Standard.
*/
__istream_type&
- ignore(streamsize __n = 1, int_type __delim = traits_type::eof());
+ ignore();
+
+ __istream_type&
+ ignore(streamsize __n);
+
+ __istream_type&
+ ignore(streamsize __n, int_type __delim);
/**
* @brief Looking ahead in the stream
OpenPOWER on IntegriCloud