istream.tcc (getline(char_type*, streamsize, char_type), [...]): Restore a generic...
authorPaolo Carlini <pcarlini@suse.de>
Mon, 8 Nov 2004 15:46:28 +0000 (15:46 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 8 Nov 2004 15:46:28 +0000 (15:46 +0000)
2004-11-08  Paolo Carlini  <pcarlini@suse.de>

* include/bits/istream.tcc (getline(char_type*, streamsize,
char_type), 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.

From-SVN: r90268

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/istream.tcc
libstdc++-v3/include/std/std_istream.h
libstdc++-v3/src/Makefile.am
libstdc++-v3/src/Makefile.in
libstdc++-v3/src/istream.cc [new file with mode: 0644]

index 6ad6a596f800be1202e7085d519c3e3bad74934c..62f996c11d964301ae1ba222ccddfe48ab88dd87 100644 (file)
@@ -1,3 +1,16 @@
+2004-11-08  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/bits/istream.tcc (getline(char_type*, streamsize,
+       char_type), 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.
+
 2004-11-07  Paolo Carlini  <pcarlini@suse.de>
 
        * testsuite/performance/27_io/ifstream_getline-2.cc: New.
index 2399b8b1e35843afd556131a7bd6b738fb4ea180..b467376b78981551be8c0fff845ffa89f1f3e4f4 100644 (file)
@@ -584,61 +584,43 @@ namespace std
       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); }
-       }
+            {
+              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;
+        __err |= ios_base::failbit;
       if (__err)
-       this->setstate(__err);
+        this->setstate(__err);
       return *this;
     }
 
@@ -680,48 +662,31 @@ namespace std
     {
       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();
-                   }             
-               }
+        {
+          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);
-       }
+                __err |= ios_base::eofbit;
+            }
+          catch(...)
+            { this->_M_setstate(ios_base::badbit); }
+          if (__err)
+            this->setstate(__err);
+        }
       return *this;
     }
 
@@ -736,56 +701,31 @@ namespace std
       _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);
-       }
+        {
+          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;
     }
 
index 65f9e6c30345466f51083456e02e892f3952344b..28b0fdd5c6005a487393b0ccba80001d48f42772 100644 (file)
@@ -574,7 +574,40 @@ namespace std
       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 _GLIBCXX_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.
    *
@@ -693,13 +726,13 @@ namespace std
     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s);
   
   template<class _Traits>
-    basic_istream<char,_Traits>&
-    operator>>(basic_istream<char,_Traits>& __in, unsigned char* __s)
+    basic_istream<char, _Traits>&
+    operator>>(basic_istream<char, _Traits>& __in, unsigned char* __s)
     { return (__in >> reinterpret_cast<char*>(__s)); }
 
   template<class _Traits>
-    basic_istream<char,_Traits>&
-    operator>>(basic_istream<char,_Traits>& __in, signed char* __s)
+    basic_istream<char, _Traits>&
+    operator>>(basic_istream<char, _Traits>& __in, signed char* __s)
     { return (__in >> reinterpret_cast<char*>(__s)); }
   //@}
 
index b2ca5f6201d4d1f204663b7f9037485ed17c3630..67e17cf78790d8fb5ea741d0df983e92a7b18c84 100644 (file)
@@ -126,6 +126,7 @@ sources = \
        ext-inst.cc \
        io-inst.cc \
        istream-inst.cc \
+       istream.cc \
        locale-inst.cc \
        locale-misc-inst.cc \
        misc-inst.cc \
index eb0b0c68f5a1402ca679abe8792c32fdee7760a7..e49698c903e413fd4fa6c846469d3556ab61b415 100644 (file)
@@ -71,8 +71,8 @@ am__objects_3 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
        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 \
+       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)
@@ -336,6 +336,7 @@ sources = \
        ext-inst.cc \
        io-inst.cc \
        istream-inst.cc \
+       istream.cc \
        locale-inst.cc \
        locale-misc-inst.cc \
        misc-inst.cc \
diff --git a/libstdc++-v3/src/istream.cc b/libstdc++-v3/src/istream.cc
new file mode 100644 (file)
index 0000000..7725ab4
--- /dev/null
@@ -0,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 _GLIBCXX_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