This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Default constructed stringbufs and stringstreams


Paolo Carlini wrote:

...I gonna show you a patch later today...

I'm attaching it below: besides fixing the problem, it also fixes most of the spurious regressions that happen if we artificially give a non-zero capacity to a default-constructed string (more about these issues soon, of course...)

I like it *so* much and, if you can't spot something wrong with it, I'd
like to commit it later today...

Paolo.

//////////////////
2004-09-29  Paolo Carlini  <pcarlini@suse.de>

	* include/std/std_sstream.h (basic_stringbuf(ios_base::openmode)):
	Don't use _M_stringbuf_init, keep the pointers null, per 27.7.1.1.
	(str()): Slightly tweak, protect from pptr() == 0.
	(_M_update_egptr()): Likewise.
	* include/bits/sstream.tcc (ssekoff, seekpos): In order to check
	for an empty buffer use __beg instead of _M_string.capacity().
	* testsuite/27_io/basic_stringbuf/cons/char/1.cc: New.
	* testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc: Likewise.
diff -prN libstdc++-v3-orig/include/bits/sstream.tcc libstdc++-v3/include/bits/sstream.tcc
*** libstdc++-v3-orig/include/bits/sstream.tcc	Fri Aug 13 00:26:31 2004
--- libstdc++-v3/include/bits/sstream.tcc	Wed Sep 29 14:38:24 2004
*************** namespace std
*** 123,128 ****
--- 123,129 ----
  	{
  	  // Update egptr() to match the actual string end.
  	  _M_update_egptr();
+ 
  	  if (this->gptr() < this->egptr())
  	    __ret = traits_type::to_int_type(*this->gptr());
  	}
*************** namespace std
*** 141,150 ****
        __testin &= !(__mode & ios_base::out);
        __testout &= !(__mode & ios_base::in);
  
!       if (_M_string.capacity() && (__testin || __testout || __testboth))
  	{
- 	  char_type* __beg = __testin ? this->eback() : this->pbase();
- 
  	  _M_update_egptr();
  
  	  off_type __newoffi = __off;
--- 142,150 ----
        __testin &= !(__mode & ios_base::out);
        __testout &= !(__mode & ios_base::in);
  
!       const char_type* __beg = __testin ? this->eback() : this->pbase();
!       if (__beg && (__testin || __testout || __testboth))
  	{
  	  _M_update_egptr();
  
  	  off_type __newoffi = __off;
*************** namespace std
*** 181,195 ****
      seekpos(pos_type __sp, ios_base::openmode __mode)
      {
        pos_type __ret =  pos_type(off_type(-1));
!       if (_M_string.capacity())
! 	{
! 	  off_type __pos (__sp);
! 	  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->eback() : this->pbase();
  
  	  _M_update_egptr();
  
  	  const bool __testpos = 0 <= __pos
  	                         && __pos <=  this->egptr() - __beg;
  	  if ((__testin || __testout) && __testpos)
--- 181,195 ----
      seekpos(pos_type __sp, ios_base::openmode __mode)
      {
        pos_type __ret =  pos_type(off_type(-1));
!       const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
!       const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
  
+       const char_type* __beg = __testin ? this->eback() : this->pbase();
+       if (__beg)
+ 	{
  	  _M_update_egptr();
  
+ 	  off_type __pos(__sp);
  	  const bool __testpos = 0 <= __pos
  	                         && __pos <=  this->egptr() - __beg;
  	  if ((__testin || __testout) && __testpos)
diff -prN libstdc++-v3-orig/include/std/std_sstream.h libstdc++-v3/include/std/std_sstream.h
*** libstdc++-v3-orig/include/std/std_sstream.h	Sun May 23 01:46:33 2004
--- libstdc++-v3/include/std/std_sstream.h	Wed Sep 29 14:19:46 2004
*************** namespace std
*** 111,118 ****
        */
        explicit
        basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
!       : __streambuf_type(), _M_mode(), _M_string()
!       { _M_stringbuf_init(__mode); }
  
        /**
         *  @brief  Starts with an existing string buffer.
--- 111,118 ----
        */
        explicit
        basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
!       : __streambuf_type(), _M_mode(__mode), _M_string()
!       { }
  
        /**
         *  @brief  Starts with an existing string buffer.
*************** namespace std
*** 140,147 ****
        __string_type
        str() const
        {
! 	const bool __testout = this->_M_mode & ios_base::out;
! 	if (__testout)
  	  {
  	    // The current egptr() may not be the actual string end.
  	    if (this->pptr() > this->egptr())
--- 140,146 ----
        __string_type
        str() const
        {
! 	if (this->pptr())
  	  {
  	    // The current egptr() may not be the actual string end.
  	    if (this->pptr() > this->egptr())
*************** namespace std
*** 169,175 ****
        }
  
      protected:
!       // Common initialization code for both ctors goes here.
        /**
         *  @if maint
         *  @doctodo
--- 168,174 ----
        }
  
      protected:
!       // Common initialization code goes here.
        /**
         *  @if maint
         *  @doctodo
*************** namespace std
*** 277,285 ****
        _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
--- 276,283 ----
        _M_update_egptr()
        {
  	const bool __testin = this->_M_mode & ios_base::in;
  
! 	if (this->pptr() && this->pptr() > this->egptr())
  	  if (__testin)
  	    this->setg(this->eback(), this->gptr(), this->pptr());
  	  else
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/char/1.cc libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/char/1.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/1.cc	Wed Sep 29 14:50:45 2004
***************
*** 0 ****
--- 1,74 ----
+ // 2004-09-29  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // 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.
+ 
+ // 27.7.1.1  basic_stringbuf constructors  [lib.stringbuf.cons]
+ 
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ 
+ class my_stringbuf : public std::stringbuf
+ {
+ public:
+   const char_type*
+   pub_eback() const
+   { return eback(); }
+ 
+   const char_type*
+   pub_gptr() const
+   { return gptr(); }
+ 
+   const char_type*
+   pub_egptr() const
+   { return egptr(); }
+ 
+   const char_type*
+   pub_pbase() const
+   { return pbase(); }
+ 
+   const char_type*
+   pub_pptr() const
+   { return pptr(); }
+ 
+   const char_type*
+   pub_epptr() const
+   { return epptr(); }
+ };
+ 
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+   bool test __attribute__((unused)) = true;
+ 
+   my_stringbuf sbuf;
+ 
+   VERIFY( !sbuf.pub_eback() );
+   VERIFY( !sbuf.pub_gptr() );
+   VERIFY( !sbuf.pub_egptr() );
+ 
+   VERIFY( !sbuf.pub_pbase() );
+   VERIFY( !sbuf.pub_pptr() );
+   VERIFY( !sbuf.pub_epptr() );
+ }
+ 
+ int main() 
+ {
+   test01();
+   return 0;
+ }
diff -prN libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc
*** libstdc++-v3-orig/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/1.cc	Wed Sep 29 14:51:27 2004
***************
*** 0 ****
--- 1,74 ----
+ // 2004-09-29  Paolo Carlini  <pcarlini@suse.de>
+ 
+ // 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.
+ 
+ // 27.7.1.1  basic_stringbuf constructors  [lib.stringbuf.cons]
+ 
+ #include <sstream>
+ #include <testsuite_hooks.h>
+ 
+ class my_stringbuf : public std::wstringbuf
+ {
+ public:
+   const char_type*
+   pub_eback() const
+   { return eback(); }
+ 
+   const char_type*
+   pub_gptr() const
+   { return gptr(); }
+ 
+   const char_type*
+   pub_egptr() const
+   { return egptr(); }
+ 
+   const char_type*
+   pub_pbase() const
+   { return pbase(); }
+ 
+   const char_type*
+   pub_pptr() const
+   { return pptr(); }
+ 
+   const char_type*
+   pub_epptr() const
+   { return epptr(); }
+ };
+ 
+ // http://gcc.gnu.org/ml/libstdc++/2004-09/msg00243.html
+ void test01()
+ {
+   bool test __attribute__((unused)) = true;
+ 
+   my_stringbuf sbuf;
+ 
+   VERIFY( !sbuf.pub_eback() );
+   VERIFY( !sbuf.pub_gptr() );
+   VERIFY( !sbuf.pub_egptr() );
+ 
+   VERIFY( !sbuf.pub_pbase() );
+   VERIFY( !sbuf.pub_pptr() );
+   VERIFY( !sbuf.pub_epptr() );
+ }
+ 
+ int main() 
+ {
+   test01();
+   return 0;
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]