This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[v3] libstdc++/26250


Hi,

tested x86-linux, committed to mainline.

Paolo.

/////////////////////
2006-02-17  Paolo Carlini  <pcarlini@suse.de>
	    Howard Hinnant  <hhinnant@apple.com>

	PR libstdc++/26250
	* include/bits/sstream.tcc (basic_stringbuf<>::overflow): Tweak
	to leave epgtr() just past the new write position, as per the
	relevant bits of 27.7.1.3/8 (not changed by DR 432).
	* testsuite/27_io/basic_stringbuf/overflow/char/26250.cc: New.
	* testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc: Same.

	* docs/html/ext/howto.html: Add entries for DR 169 and DR 432.

	* include/std/std_sstream.h (basic_stringbuf<>::_M_sync): Move out
	of line...
	* include/bits/sstream.tcc: ... here.
Index: include/bits/sstream.tcc
===================================================================
--- include/bits/sstream.tcc	(revision 110911)
+++ include/bits/sstream.tcc	(working copy)
@@ -1,6 +1,6 @@
 // String based streams -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -101,14 +101,18 @@
 
       // Try to append __c into output sequence in one of two ways.
       // Order these tests done in is unspecified by the standard.
+      const char_type __conv = traits_type::to_char_type(__c);
       if (!__testput)
 	{
-	  // NB: Start ostringstream buffers at 512 chars. This is an
+	  // NB: Start ostringstream buffers at 512 chars.  This is an
 	  // experimental value (pronounced "arbitrary" in some of the
 	  // hipper english-speaking countries), and can be changed to
 	  // suit particular needs.
-	  // Then, in virtue of DR 169 (TC) we are allowed to grow more
-	  // than one char.
+	  //
+	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+	  // 169. Bad efficiency of overflow() mandated
+	  // 432. stringbuf::overflow() makes only one write position
+	  //      available
 	  const __size_type __opt_len = std::max(__size_type(2 * __capacity),
 						 __size_type(512));
 	  const __size_type __len = std::min(__opt_len, __max_size);
@@ -116,11 +120,15 @@
 	  __tmp.reserve(__len);
 	  if (this->pbase())
 	    __tmp.assign(this->pbase(), this->epptr() - this->pbase());
+	  __tmp.push_back(__conv);
 	  _M_string.swap(__tmp);
 	  _M_sync(const_cast<char_type*>(_M_string.data()),
 		  this->gptr() - this->eback(), this->pptr() - this->pbase());
 	}
-      return this->sputc(traits_type::to_char_type(__c));
+      else
+	*this->pptr() = __conv;
+      this->pbump(1);
+      return __c;
     }
 
   template <class _CharT, class _Traits, class _Alloc>
@@ -203,8 +211,8 @@
 	  _M_update_egptr();
 
 	  const off_type __pos(__sp);
-	  const bool __testpos = 0 <= __pos
-	                         && __pos <=  this->egptr() - __beg;
+	  const bool __testpos = (0 <= __pos
+				  && __pos <= this->egptr() - __beg);
 	  if (__testpos)
 	    {
 	      if (__testin)
@@ -217,6 +225,38 @@
       return __ret;
     }
 
+  // Assumes: contents of _M_string and internal buffer match exactly.
+  // __i == _M_in_cur - _M_in_beg
+  // __o == _M_out_cur - _M_out_beg
+  template <class _CharT, class _Traits, class _Alloc>
+    void
+    basic_stringbuf<_CharT, _Traits, _Alloc>::
+    _M_sync(char_type* __base, __size_type __i, __size_type __o)
+    {
+      const bool __testin = _M_mode & ios_base::in;
+      const bool __testout = _M_mode & ios_base::out;
+      char_type* __end = __base + _M_string.size();
+      
+      if (__testin)
+	this->setg(__base, __base + __i, __end);
+      if (__testout)
+	{
+	  // If __base comes from setbuf we cannot trust capacity()
+	  // to match the size of the buffer area:  in general, after
+	  // Step 1 in setbuf, _M_string.capacity() >= __n.
+	  if (__base == _M_string.data())
+	    this->setp(__base, __base + _M_string.capacity());
+	  else
+	    this->setp(__base, __end);
+	  this->pbump(__o);
+	  // egptr() always tracks the string end.  When !__testin,
+	  // for the correct functioning of the streambuf inlines
+	  // the other get area pointers are identical.
+	  if (!__testin)
+	    this->setg(__end, __end, __end);
+	}
+    }
+
   // Inhibit implicit instantiations for required instantiations,
   // which are defined via explicit instantiations elsewhere.
   // NB:  This syntax is a GNU extension.
Index: include/std/std_sstream.h
===================================================================
--- include/std/std_sstream.h	(revision 110891)
+++ include/std/std_sstream.h	(working copy)
@@ -1,6 +1,6 @@
 // String based streams -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004, 2005
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -228,38 +228,11 @@
 	      ios_base::openmode __mode = ios_base::in | ios_base::out);
 
       // Internal function for correctly updating the internal buffer
-      // for a particular _M_string, due to initialization or
-      // re-sizing of an existing _M_string.
-      // Assumes: contents of _M_string and internal buffer match exactly.
-      // __i == _M_in_cur - _M_in_beg
-      // __o == _M_out_cur - _M_out_beg
+      // for a particular _M_string, due to initialization or re-sizing
+      // of an existing _M_string.
       void
-      _M_sync(char_type* __base, __size_type __i, __size_type __o)
-      {
-	const bool __testin = _M_mode & ios_base::in;
-	const bool __testout = _M_mode & ios_base::out;
-	char_type* __end = __base + _M_string.size();
+      _M_sync(char_type* __base, __size_type __i, __size_type __o);
 
-	if (__testin)
-	  this->setg(__base, __base + __i, __end);
-	if (__testout)
-	  {
-	    // If __base comes from setbuf we cannot trust capacity()
-	    // to match the size of the buffer area: in general, after
-	    // Step 1 above, _M_string.capacity() >= __n.
-	    if (__base == _M_string.data())
-	      this->setp(__base, __base + _M_string.capacity());
-	    else
-	      this->setp(__base, __end);
-	    this->pbump(__o);
-	    // egptr() always tracks the string end. When !__testin,
-	    // for the correct functioning of the streambuf inlines
-	    // the other get area pointers are identical.
-	    if (!__testin)
-	      this->setg(__end, __end, __end);
-	  }
-      }
-
       // Internal function for correctly updating egptr() to the actual
       // string end.
       void
Index: docs/html/ext/howto.html
===================================================================
--- docs/html/ext/howto.html	(revision 110891)
+++ docs/html/ext/howto.html	(working copy)
@@ -358,6 +358,12 @@
         calculating an incorrect number of characters to write.
     </dd>
 
+    <dt><a href="lwg-defects.html#169">169</a>:
+        <em>Bad efficiency of overflow() mandated</em>
+    </dt>
+    <dd>Grow efficiently the internal array object.
+    </dd>
+
     <dt><a href="lwg-defects.html#171">171</a>:
         <em>Strange seekpos() semantics due to joint position</em>
     </dt>
@@ -536,6 +542,13 @@
     <dd>Implement Option 3, as per N1599.
     </dd>
 
+    <dt><a href="lwg-defects.html#432">432</a>:
+        <em>432. stringbuf::overflow() makes only one write position
+	    available</em>
+    </dt>
+    <dd>Implement the resolution, beyond DR 169.
+    </dd>
+
     <dt><a href="lwg-defects.html#434">434</a>:
         <em>bitset::to_string() hard to use</em>
     </dt>
Index: testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc
===================================================================
--- testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc	(revision 0)
+++ testsuite/27_io/basic_stringbuf/overflow/wchar_t/26250.cc	(revision 0)
@@ -0,0 +1,58 @@
+// Copyright (C) 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <sstream>
+#include <testsuite_hooks.h>
+
+struct pubbuf
+: std::wstringbuf
+{
+  using std::wstringbuf::eback;
+  using std::wstringbuf::egptr;
+  using std::wstringbuf::pbase;
+  using std::wstringbuf::pptr;
+  using std::wstringbuf::epptr;
+  using std::wstringbuf::overflow;
+};
+
+// libstdc++/26250
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  pubbuf buf;
+
+  VERIFY( buf.overflow(L'x') == L'x' );
+  VERIFY( buf.pptr() - buf.pbase() == 1 );
+ 
+  // not required but good for efficiency
+  // NB: we are implementing DR 169 and DR 432
+  const int write_positions = buf.epptr() - buf.pbase();
+  VERIFY( write_positions > 1 );
+
+  // 27.7.1.3, p8:
+  VERIFY( buf.egptr() - buf.eback() == 1 );
+}
+
+int main() 
+{
+  test01();
+  return 0;
+}
Index: testsuite/27_io/basic_stringbuf/overflow/char/26250.cc
===================================================================
--- testsuite/27_io/basic_stringbuf/overflow/char/26250.cc	(revision 0)
+++ testsuite/27_io/basic_stringbuf/overflow/char/26250.cc	(revision 0)
@@ -0,0 +1,58 @@
+// Copyright (C) 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <sstream>
+#include <testsuite_hooks.h>
+
+struct pubbuf
+: std::stringbuf
+{
+  using std::stringbuf::eback;
+  using std::stringbuf::egptr;
+  using std::stringbuf::pbase;
+  using std::stringbuf::pptr;
+  using std::stringbuf::epptr;
+  using std::stringbuf::overflow;
+};
+
+// libstdc++/26250
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  pubbuf buf;
+
+  VERIFY( buf.overflow('x') == 'x' );
+  VERIFY( buf.pptr() - buf.pbase() == 1 );
+ 
+  // not required but good for efficiency
+  // NB: we are implementing DR 169 and DR 432
+  const int write_positions = buf.epptr() - buf.pbase();
+  VERIFY( write_positions > 1 );
+
+  // 27.7.1.3, p8:
+  VERIFY( buf.egptr() - buf.eback() == 1 );
+}
+
+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]