Nathan C.
authorPaolo Carlini <paolo@gcc.gnu.org>
Sun, 22 Jun 2003 18:37:10 +0000 (18:37 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sun, 22 Jun 2003 18:37:10 +0000 (18:37 +0000)
2003-06-22  Paolo Carlini  <pcarlini@unitus.it>
    Nathan C. Myers  <ncm-nospam@cantrip.org>

* include/std/std_streambuf.h (_M_move_out_cur): _M_out_lim
is now used only for filebuf, when _M_buf_unified is true.
epgtr() plays the role of _M_out_lim but it's only updated
upon overflow, underflow, uflow, seekoff/pos.
* include/bits/sstream.tcc (_M_underflow): New, implements
stringbuf::underflow and uflow.
(seekoff, seekpos): Tweak, use  _M_update_egptr.
* include/std/std_sstream.h (str): Rewrote, deal correctly
with the new logic, in particular, when pptr() > egptr().
(_M_sync): When __testout && !__testin set all the get area
pointers to the current string end.
(_M_update_egptr): New, internal function updating egptr()
to the actual string end.
(_M_underflow): New, declare.
(underflow): Dispatch to _M_underflow(false).
(uflow): Dispatch to _M_underflow(true).

* include/bits/sstream.tcc (pbackfail, overflow, seekoff,
seekpos): Use only the documented derivation interface to
basic_streambuf (gptr(), setg(), etc.) to work right with
user specializations.
* include/std/std_sstream.h (str, _M_sync): Likewise.

From-SVN: r68347

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/sstream.tcc
libstdc++-v3/include/std/std_sstream.h
libstdc++-v3/include/std/std_streambuf.h

index c9383a5..d2993e4 100644 (file)
@@ -1,21 +1,47 @@
+2003-06-22  Paolo Carlini  <pcarlini@unitus.it>
+           Nathan C. Myers  <ncm-nospam@cantrip.org>
+
+       * include/std/std_streambuf.h (_M_move_out_cur): _M_out_lim
+       is now used only for filebuf, when _M_buf_unified is true.
+       epgtr() plays the role of _M_out_lim but it's only updated
+       upon overflow, underflow, uflow, seekoff/pos.
+       * include/bits/sstream.tcc (_M_underflow): New, implements
+       stringbuf::underflow and uflow.
+       (seekoff, seekpos): Tweak, use  _M_update_egptr.
+       * include/std/std_sstream.h (str): Rewrote, deal correctly
+       with the new logic, in particular, when pptr() > egptr().
+       (_M_sync): When __testout && !__testin set all the get area
+       pointers to the current string end.
+       (_M_update_egptr): New, internal function updating egptr()
+       to the actual string end.
+       (_M_underflow): New, declare.
+       (underflow): Dispatch to _M_underflow(false).
+       (uflow): Dispatch to _M_underflow(true).
+
+       * include/bits/sstream.tcc (pbackfail, overflow, seekoff,
+       seekpos): Use only the documented derivation interface to
+       basic_streambuf (gptr(), setg(), etc.) to work right with
+       user specializations.
+       * include/std/std_sstream.h (str, _M_sync): Likewise.
+
 2003-06-20  Doug Gregor <dgregor@apple.com>
 
-        * testsuite/20_util/auto_ptr.cc: don't dereference NULL auto_ptr
-        * testsuite/21_strings/basic_string/replace/char/4.cc: don't 
-            dereference end iterator.
-        * testsuite/21_strings/basic_string/replace/wchar_t/4.cc: same.
-        * testsuite/22_locale/ctype/narrow/char/1.cc: don't subscript with
-            index equal to the length of a string.
-        * testsuite/22_locale/ctype/narrow/char/2.cc: same.
-        * testsuite/22_locale/ctype/narrow/wchar_t/1.cc: same.
-        * testsuite/22_locale/ctype/narrow/wchar_t/2.cc: same.
-        * testsuite/22_locale/ctype/widen/char/1.cc: same.
-        * testsuite/22_locale/ctype/widen/wchar_t/1.cc: same.
-        * testsuite/23_containers/list_modifiers.cc: don't dereference 
-            singular reverse iterator.
-        * testsuite/23_containers/vector_bool.cc: don't increment singular
-            iterator.
-        * testsuite/24_iterators/rel_ops.cc: don't compare singular iterator.
+       * testsuite/20_util/auto_ptr.cc: Don't dereference NULL auto_ptr
+       * testsuite/21_strings/basic_string/replace/char/4.cc: Don't
+       dereference end iterator.
+       * testsuite/21_strings/basic_string/replace/wchar_t/4.cc: Same.
+       * testsuite/22_locale/ctype/narrow/char/1.cc: Don't subscript with
+       index equal to the length of a string.
+       * testsuite/22_locale/ctype/narrow/char/2.cc: Same.
+       * testsuite/22_locale/ctype/narrow/wchar_t/1.cc: Same.
+       * testsuite/22_locale/ctype/narrow/wchar_t/2.cc: Same.
+       * testsuite/22_locale/ctype/widen/char/1.cc: Same.
+       * testsuite/22_locale/ctype/widen/wchar_t/1.cc: Same.
+       * testsuite/23_containers/list_modifiers.cc: Don't dereference
+       singular reverse iterator.
+       * testsuite/23_containers/vector_bool.cc: Don't increment singular
+       iterator.
+       * testsuite/24_iterators/rel_ops.cc: Don't compare singular iterator.
 
 2003-06-20  Doug Gregor <dgregor@apple.com>
 
index 764e280..f5b4c57 100644 (file)
@@ -49,11 +49,11 @@ namespace std
       int_type __ret = traits_type::eof();
       const bool __testeof = traits_type::eq_int_type(__c, __ret);
       
-      if (this->_M_in_beg < this->_M_in_cur)
+      if (this->eback() < this->gptr())
        {
          const bool __testeq = traits_type::eq(traits_type::to_char_type(__c),
-                                               this->_M_in_cur[-1]);
-         --this->_M_in_cur;
+                                               this->gptr()[-1]);
+         this->gbump(-1);
 
          // Try to put back __c into input sequence in one of three ways.
          // Order these tests done in is unspecified by the standard.
@@ -63,7 +63,7 @@ namespace std
            __ret = traits_type::not_eof(__c);
          else
            {
-             *this->_M_in_cur = traits_type::to_char_type(__c);
+             *this->gptr() = traits_type::to_char_type(__c);
              __ret = __c;
            }
        }
@@ -88,9 +88,9 @@ namespace std
       // experimental value (pronounced "arbitrary" in some of the
       // hipper english-speaking countries), and can be changed to
       // suit particular needs.
-      __size_type __len = std::max(__size_type(_M_string.capacity() + 1),
-                                  __size_type(512));
-      const bool __testput = this->_M_out_cur < this->_M_out_end;
+      const __size_type __len = std::max(__size_type(_M_string.capacity() + 1),
+                                        __size_type(512));
+      const bool __testput = this->pptr() < this->epptr();
       if (__builtin_expect(!__testput && __len > _M_string.max_size(), false))
        return traits_type::eof();
 
@@ -103,19 +103,38 @@ namespace std
          // growth policy builtin into basic_string.
          __string_type __tmp;
          __tmp.reserve(__len);
-         __tmp.assign(_M_string.data(),
-                      this->_M_out_end - this->_M_out_beg);
+         __tmp.assign(_M_string.data(), this->epptr() - this->pbase());
          _M_string.swap(__tmp);
-         // Just to be sure...
-         _M_string.reserve(__len);
          _M_sync(const_cast<char_type*>(_M_string.data()),
-                 this->_M_in_cur - this->_M_in_beg
-                 this->_M_out_cur - this->_M_out_beg);
+                 this->gptr() - this->eback()
+                 this->pptr() - this->pbase());
        }
       return this->sputc(traits_type::to_char_type(__c));
     }
 
   template <class _CharT, class _Traits, class _Alloc>
+    typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type 
+    basic_stringbuf<_CharT, _Traits, _Alloc>::
+    _M_underflow(bool __bump)
+    {
+      int_type __ret = traits_type::eof();
+      const bool __testin = this->_M_mode & ios_base::in;
+      if (__testin)
+       {
+         // Update egptr() to match the actual string end.
+         _M_update_egptr();
+
+         if (this->gptr() < this->egptr())
+           {
+             __ret = traits_type::to_int_type(*this->gptr());
+             if (__bump)
+               this->gbump(1);
+           }
+       }
+      return __ret;
+    }
+
+  template <class _CharT, class _Traits, class _Alloc>
     typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
     basic_stringbuf<_CharT, _Traits, _Alloc>::
     seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
@@ -129,35 +148,32 @@ namespace std
 
       if (_M_string.capacity() && (__testin || __testout || __testboth))
        {
-         char_type* __beg = __testin ? this->_M_in_beg : this->_M_out_beg;
+         char_type* __beg = __testin ? this->eback() : this->pbase();
+
+         _M_update_egptr();
 
          off_type __newoffi = 0;
          off_type __newoffo = 0;
          if (__way == ios_base::cur)
            {
-             __newoffi = this->_M_in_cur - __beg;
-             __newoffo = this->_M_out_cur - __beg;
+             __newoffi = this->gptr() - __beg;
+             __newoffo = this->pptr() - __beg;
            }
          else if (__way == ios_base::end)
-           {
-             __newoffi = this->_M_in_end - __beg;
-             // Due to the resolution of DR169, ios_base::end
-             // is this->_M_out_lim, not _M_out_end.
-             __newoffo = this->_M_out_lim - __beg;
-           }
+           __newoffo = __newoffi = this->egptr() - __beg;
 
          if ((__testin || __testboth)
              && __newoffi + __off >= 0 
-             && this->_M_in_end - __beg >= __newoffi + __off)
+             && this->egptr() - __beg >= __newoffi + __off)
            {
-             this->_M_in_cur = __beg + __newoffi + __off;
+             this->gbump((__beg + __newoffi + __off) - this->gptr());
              __ret = pos_type(__newoffi);
            }
          if ((__testout || __testboth)
              && __newoffo + __off >= 0 
-             && this->_M_out_lim - __beg >= __newoffo + __off)
+             && this->egptr() - __beg >= __newoffo + __off)
            {
-             this->_M_out_cur = __beg + __newoffo + __off;
+             this->pbump((__beg + __newoffo + __off) - this->pptr());
              __ret = pos_type(__newoffo);
            }
        }
@@ -176,23 +192,18 @@ namespace std
          off_type __pos = __sp; // Use streamoff operator to do conversion.
          const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
          const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
-         char_type* __beg = __testin ? this->_M_in_beg : this->_M_out_beg;
+         char_type* __beg = __testin ? this->eback() : this->pbase();
          
-         // NB: Ordered.
-         bool __testposi = false;
-         bool __testposo = false;
-         if (__testin && 0 <= __pos
-             && __pos <=  this->_M_in_end - __beg)
-           __testposi = true;
-         if (__testout && 0 <= __pos
-             && __pos <=  this->_M_out_lim - __beg)
-           __testposo = true;
-         if (__testposi || __testposo)
+         _M_update_egptr();
+
+         const bool __testpos = 0 <= __pos
+                                && __pos <=  this->egptr() - __beg;
+         if ((__testin || __testout) && __testpos)
            {
-             if (__testposi)
-               this->_M_in_cur = __beg + __pos;
-             if (__testposo)
-               this->_M_out_cur = __beg + __pos;
+             if (__testin)
+               this->gbump((__beg + __pos) - this->gptr());
+             if (__testout)
+                this->pbump((__beg + __pos) - this->pptr());
              __ret = pos_type(off_type(__pos));
            }
        }
index 7f3fc64..687e26a 100644 (file)
@@ -133,11 +133,17 @@ namespace std
       __string_type
       str() const
       {
-       __string_type __ret = _M_string;
        const bool __testout = this->_M_mode & ios_base::out;
-       if (__testout && this->_M_out_beg < this->_M_out_lim)
-         __ret = __string_type(this->_M_out_beg, this->_M_out_lim);
-       return __ret;
+       if (__testout)
+         {
+           // The current egptr() may not be the actual string end.
+           if (this->pptr() > this->egptr())
+             return __string_type(this->pbase(), this->pptr());
+           else
+             return __string_type(this->pbase(), this->egptr());
+         }
+       else
+         return _M_string;
       }
 
       /**
@@ -173,18 +179,18 @@ namespace std
        _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
       }
 
-      // Overridden virtual functions:
+      int_type
+      _M_underflow(bool __bump);
+
       // [documentation is inherited]
       virtual int_type
       underflow()
-      {
-       int_type __ret;
-       if (this->_M_in_cur < this->_M_in_end)
-         __ret = traits_type::to_int_type(*this->_M_in_cur);
-       else
-         __ret = traits_type::eof();
-       return __ret;
-      }
+      { return _M_underflow(false); }
+
+      // [documentation is inherited]
+      virtual int_type
+      uflow()
+      { return _M_underflow(true); }
 
       // [documentation is inherited]
       virtual int_type
@@ -250,18 +256,37 @@ namespace std
       {
        const bool __testin = this->_M_mode & ios_base::in;
        const bool __testout = this->_M_mode & ios_base::out;
-       __size_type __len = _M_string.size();
+       const __size_type __len = _M_string.size();
 
        if (__testin)
          this->setg(__base, __base + __i, __base + __len);
        if (__testout)
          {
            this->setp(__base, __base + _M_string.capacity());
-           // _M_out_lim points to the string end.
-           this->_M_out_lim += __len;
-           this->_M_out_cur += __o;
+           this->pbump(__o);
+           // We need a pointer to the string end anyway, even when
+           // !__testin: in that case, however, for the correct
+           // functioning of the streambuf inlines all the get area
+           // pointers must be identical.
+           if (!__testin)
+             this->setg(__base + __len, __base + __len, __base + __len);
          }
       }
+
+      // Internal function for correctly updating egptr() to the actual
+      // string end.
+      void
+      _M_update_egptr()
+      {
+       const bool __testin = this->_M_mode & ios_base::in;
+       const bool __testout = this->_M_mode & ios_base::out;
+
+       if (__testout && this->pptr() > this->egptr())
+         if (__testin)
+           this->setg(this->eback(), this->gptr(), this->pptr());
+         else
+           this->setg(this->pptr(), this->pptr(), this->pptr());
+      }
     };
 
 
index 2092807..fa85bf4 100644 (file)
@@ -238,17 +238,19 @@ namespace std
       void 
       _M_move_out_cur(off_type __n) // argument needs to be +-
       {
-       const bool __testin = _M_in_cur;
-
        _M_out_cur += __n;
-       if (__testin && _M_buf_unified)
-         _M_in_cur += __n;
-       if (_M_out_cur > _M_out_lim)
+       if (__builtin_expect(_M_buf_unified, false))
          {
-           _M_out_lim = _M_out_cur;
-           // NB: in | out buffers drag the _M_in_end pointer along...
+           const bool __testin = _M_in_cur;
            if (__testin)
-             _M_in_end += __n;
+             _M_in_cur += __n;
+           if (_M_out_cur > _M_out_lim)
+             {
+               _M_out_lim = _M_out_cur;
+               // NB: in | out buffers drag the _M_in_end pointer along...
+               if (__testin)
+                 _M_in_end += __n;
+             }
          }
       }