This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
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;
+ }