diff mbox

PR libstdc++/81381 support stateful allocators in basic_stringbuf

Message ID 20170710180729.GA30095@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely July 10, 2017, 6:07 p.m. UTC
This allows using non-DefaultConstructible and stateful allocators
with basic_stringbuf, by copying the allocator from the basic_string.

	PR libstdc++/81381
	* include/bits/sstream.tcc (basic_stringbuf::overflow)
	(basic_stringbuf::basic_stringbuf(const __string_type&, ios::mode))
	(basic_stringbuf::str()): Construct new strings with an allocator.
	* testsuite/27_io/basic_stringbuf/cons/81381.cc: New.

Tested powerpc64le-linux, committed to trunk.
commit 19703301e40c1e44055a951c29565fb0bd1018e6
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Jul 10 17:16:14 2017 +0100

    PR libstdc++/81381 support stateful allocators in basic_stringbuf
    
    	PR libstdc++/81381
    	* include/bits/sstream.tcc (basic_stringbuf::overflow)
    	(basic_stringbuf::basic_stringbuf(const __string_type&, ios::mode))
    	(basic_stringbuf::str()): Construct new strings with an allocator.
    	* testsuite/27_io/basic_stringbuf/cons/81381.cc: New.
diff mbox

Patch

diff --git a/libstdc++-v3/include/bits/sstream.tcc b/libstdc++-v3/include/bits/sstream.tcc
index fc2fcb8..56c53bc 100644
--- a/libstdc++-v3/include/bits/sstream.tcc
+++ b/libstdc++-v3/include/bits/sstream.tcc
@@ -129,7 +129,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  const __size_type __opt_len = std::max(__size_type(2 * __capacity),
 						 __size_type(512));
 	  const __size_type __len = std::min(__opt_len, __max_size);
-	  __string_type __tmp;
+	  __string_type __tmp(_M_string.get_allocator());
 	  __tmp.reserve(__len);
 	  if (this->pbase())
 	    __tmp.assign(this->pbase(), this->epptr() - this->pbase());
diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream
index 7690252..e84b60c 100644
--- a/libstdc++-v3/include/std/sstream
+++ b/libstdc++-v3/include/std/sstream
@@ -112,7 +112,8 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
       explicit
       basic_stringbuf(const __string_type& __str,
 		      ios_base::openmode __mode = ios_base::in | ios_base::out)
-      : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size())
+      : __streambuf_type(), _M_mode(),
+	_M_string(__str.data(), __str.size(), __str.get_allocator())
       { _M_stringbuf_init(__mode); }
 
 #if __cplusplus >= 201103L
@@ -165,14 +166,14 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
       __string_type
       str() const
       {
-	__string_type __ret;
+	__string_type __ret(_M_string.get_allocator());
 	if (this->pptr())
 	  {
 	    // The current egptr() may not be the actual string end.
 	    if (this->pptr() > this->egptr())
-	      __ret = __string_type(this->pbase(), this->pptr());
+	      __ret.assign(this->pbase(), this->pptr());
 	    else
- 	      __ret = __string_type(this->pbase(), this->egptr());
+	      __ret.assign(this->pbase(), this->egptr());
 	  }
 	else
 	  __ret = _M_string;
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/81381.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/81381.cc
new file mode 100644
index 0000000..865449d
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/81381.cc
@@ -0,0 +1,42 @@ 
+// Copyright (C) 2017 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+// PR libstdc++/81381
+
+#include <memory>
+#include <sstream>
+#include <testsuite_allocator.h>
+
+using Alloc = __gnu_test::uneq_allocator<char>;
+using String = std::basic_string<char, std::char_traits<char>, Alloc>;
+
+struct SB : std::basic_stringbuf<char, std::char_traits<char>, Alloc>
+{
+  SB(const String& s) : basic_stringbuf(s) { }
+
+  using basic_stringbuf::overflow;
+};
+
+int main()
+{
+  String s(Alloc(23));
+  SB b(s);
+  b.overflow('a');
+  VERIFY( b.str().get_allocator() == s.get_allocator() );
+}