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]

[Patch] vstring bits of libstdc++/28277, reduce <ext/vstring.h>, etc.


Hi,

this rather large patch started by implementing the vstring bits of 28277, thus fixing the testcase in the PR. Then I noticed that I had to fix a recent mistake of mine, when I added _M_insert(const char_type*, streamsize) to basic_ostream and used it in the free-standing inserters: that strategy creates problem when we have a specialization of basic_ostream: it makes unnecessarily impossible using the default free-standing inserters with it. Thus I removed it and added a free-standing __ostream_insert, which is used in the ostream inserters for chars, basic_string and vstring.

Additionally, the patch includes a tweak to the <ext/vstring.h> includes (and surrounding adjustments) cutting its preprocessed size to half and fixes the various extractors to not refer to non-standard types of istream for the same reasons mentioned above. Also, we want the string inserters and extractors together with the string class itself (not in <istream>/<ostream>) according to the letter of the standard: that enable using, say <ios> + an istream/ostream specialization + <string>, without the full <istream>/<ostream>.

There are also minor additional tweaks, like commonizing __is_null_pointer.

One long-standing issue that the patch does *not* fix, is that the ostream free-standing inserters and the istream free-standing extractors use the non-standard _M_setstate, from basic_ios: that means that the above breaks if the stream specialization doesn't use basic_ios from <ios> and uses its own specialization. But this is really for another time: due to the export bits, we want to have a minimal version of the present patch also in 4_2-branch and testing takes time if we want to be safe.

Regtested x86/x86_64-linux, without PCHs too.

Paolo.

////////////////////
2007-04-10  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/28277 (partial: vstring bits)
	* include/bits/ostream_insert.h: New.
	* include/Makefile.am: Add.
	* include/ext/vstring.h (operator<<(basic_ostream<>&,
	const __versa_string<>&): Forward to __ostream_insert.
	* include/bits/basic_string.h (operator<<(basic_ostream<>&,
	const string<>&)): Likewise.
	* include/std/ostream (operator<<(basic_ostream<>&, _CharT),
	operator<<(basic_ostream<char,>&, char), operator<<(basic_ostream<>&,
	const _CharT*), operator<<(basic_ostream<char,>&, const char*)):
	Likewise.
	* include/ext/vstring.tcc (operator<<(basic_ostream<>&,
	const __versa_string<>&)): Remove.
	(class basic_ostream): Remove friend declarations.
	(basic_ostream<>::_M_write(char_type, streamsize),
	_M_insert(const char_type*, streamsize)): Remove.
	* include/bits/ostream.tcc (_M_insert(const char_type*, streamsize)):
	Remove definition.
	(operator<<(basic_ostream<>&, const char*)): Use __ostream_insert.
	* config/abi/pre/gnu.ver: Adjust.
	* src/ostream-inst.cc: Add __ostream_insert instantiations.
	* include/bits/locale_facets.h (__pad<>::_S_pad): Remove __num
	parameter.
	* include/bits/locale_facets.tcc (__pad<>::_S_pad): Adjust.
	(num_put<>::_M_pad(_CharT, streamsize, ios_base&, _CharT*,
	const _CharT*, int&)): Likewise.
	* include/Makefile.in: Rebuild.
	* testsuite/ext/vstring/inserters_extractors/char/28277.cc: New.
	* testsuite/ext/vstring/inserters_extractors/wchar_t/28277.cc: New.

	* include/ext/vstring_util.h: Do not include the whole <locale>.
	* include/ext/vstring.tcc (operator>>(basic_istream<>&,
	__versa_string<>&, getline(basic_istream<>&, __versa_string<>&,
	_CharT)): Tweak to refer to ios_base as a base of istream; do not
	refer to non-standard types of istream.
	* include/bits/istream.tcc (operator>>(basic_istream<>&, _CharT*),
	ws(basic_istream<>&)): Do not refer to non-standard types of istream.
	* include/std/bitset (operator>>(std::basic_istream<>&, bitset<>&)):
	Avoid using basic_streambuf<>*.

	* include/bits/istream.tcc (operator>>(basic_istream<>&,
	basic_string<>&), getline(basic_istream<>&, basic_string<>&, _CharT)):
	Move...
	* include/bits/basic_string.tcc: ... here; tweak to refer to ios_base
	as a base of istream; do not refer to non-standard types of istream.
	* include/std/string: Tweak includes.

	* include/ext/type_traits.h (__is_null_pointer): Add.
	* include/ext/rc_string_base.h: Use it.
	* include/ext/sso_string_base.h: Likewise.
	* include/bits/basic_string.tcc (__is_null_pointer): Remove, use
	the above.
	* include/ext/vstring_util.h (__vstring_utility<>::_S_is_null_pointer):
	Remove.
Index: src/ostream-inst.cc
===================================================================
--- src/ostream-inst.cc	(revision 123675)
+++ src/ostream-inst.cc	(working copy)
@@ -55,6 +55,7 @@
   template ostream& operator<<(ostream&, _Setbase);
   template ostream& operator<<(ostream&, _Setprecision);
   template ostream& operator<<(ostream&, _Setw);
+  template ostream& __ostream_insert(ostream&, const char*, streamsize);
 
   template ostream& ostream::_M_insert(long);
   template ostream& ostream::_M_insert(unsigned long);
@@ -83,6 +84,7 @@
   template wostream& operator<<(wostream&, _Setbase);
   template wostream& operator<<(wostream&, _Setprecision);
   template wostream& operator<<(wostream&, _Setw);
+  template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize);
 
   template wostream& wostream::_M_insert(long);
   template wostream& wostream::_M_insert(unsigned long);
Index: include/ext/vstring_util.h
===================================================================
--- include/ext/vstring_util.h	(revision 123675)
+++ include/ext/vstring_util.h	(working copy)
@@ -42,7 +42,8 @@
 #include <debug/debug.h>
 #include <bits/stl_function.h>  // For less
 #include <bits/functexcept.h>
-#include <locale>
+#include <bits/localefwd.h>
+#include <bits/ostream_insert.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
 
@@ -94,17 +95,6 @@
 	  _CharT*  _M_p; // The actual data.
 	};
 
-      // For use in _M_construct (_S_construct) forward_iterator_tag.
-      template<typename _Type>
-        static bool
-        _S_is_null_pointer(_Type* __ptr)
-        { return __ptr == 0; }
-
-      template<typename _Type>
-        static bool
-        _S_is_null_pointer(_Type)
-        { return false; }
-
       // When __n = 1 way faster than the general multichar
       // traits_type::copy/move/assign.
       static void
Index: include/ext/vstring.h
===================================================================
--- include/ext/vstring.h	(revision 123675)
+++ include/ext/vstring.h	(working copy)
@@ -2138,13 +2138,30 @@
    *  Output characters of @a str into os following the same rules as for
    *  writing a C string.
    */
-  template<typename _CharT, typename _Traits, typename _Alloc,
-           template <typename, typename, typename> class _Base>
-    basic_ostream<_CharT, _Traits>&
+
+  // NB: Two separate overloads as a workaround for c++/29236.
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    inline basic_ostream<_CharT, _Traits>&
     operator<<(basic_ostream<_CharT, _Traits>& __os,
 	       const __gnu_cxx::__versa_string<_CharT, _Traits,
-	                                       _Alloc, _Base>& __str);
+	       _Alloc>& __str)
+    {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 586. string inserter not a formatted function
+      return __ostream_insert(__os, __str.data(), __str.size());
+    }
 
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    inline basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+	       const __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc,
+	       __gnu_cxx::__rc_string_base>& __str)
+    {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 586. string inserter not a formatted function
+      return __ostream_insert(__os, __str.data(), __str.size());
+    }
+
   /**
    *  @brief  Read a line from stream into a string.
    *  @param is  Input stream.
Index: include/ext/rc_string_base.h
===================================================================
--- include/ext/rc_string_base.h	(revision 123675)
+++ include/ext/rc_string_base.h	(working copy)
@@ -1,6 +1,6 @@
 // Reference-counted versatile string base -*- C++ -*-
 
-// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2007 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
@@ -545,7 +545,7 @@
 	  return _S_empty_rep._M_refcopy();
 
 	// NB: Not required, but considered best practice.
-	if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0))
+	if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0))
 	  std::__throw_logic_error(__N("__rc_string_base::"
 				       "_S_construct NULL not valid"));
 
Index: include/ext/type_traits.h
===================================================================
--- include/ext/type_traits.h	(revision 123675)
+++ include/ext/type_traits.h	(working copy)
@@ -147,6 +147,18 @@
   template<>
     struct __remove_unsigned<wchar_t>;
 
+
+  // For use in string and vstring.
+  template<typename _Type>
+    inline bool
+    __is_null_pointer(_Type* __ptr)
+    { return __ptr == 0; }
+
+  template<typename _Type>
+    inline bool
+    __is_null_pointer(_Type)
+    { return false; }
+
 _GLIBCXX_END_NAMESPACE
 
 #endif 
Index: include/ext/vstring.tcc
===================================================================
--- include/ext/vstring.tcc	(revision 123675)
+++ include/ext/vstring.tcc	(working copy)
@@ -551,16 +551,15 @@
 	       __gnu_cxx::__versa_string<_CharT, _Traits,
 	                                 _Alloc, _Base>& __str)
     {
-      typedef basic_istream<_CharT, _Traits>	        __istream_type;
-      typedef typename __istream_type::int_type		__int_type;
-      typedef typename __istream_type::__streambuf_type __streambuf_type;
-      typedef typename __istream_type::__ctype_type	__ctype_type;
+      typedef std::basic_istream<_CharT, _Traits>       __istream_type;
+      typedef typename __istream_type::ios_base         __ios_base;
       typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
 	                                                __string_type;
+      typedef typename __istream_type::int_type		__int_type;
       typedef typename __string_type::size_type		__size_type;
 
       __size_type __extracted = 0;
-      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      typename __ios_base::iostate __err = __ios_base::goodbit;
       typename __istream_type::sentry __cerb(__in, false);
       if (__cerb)
 	{
@@ -573,14 +572,12 @@
 	      const streamsize __w = __in.width();
 	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
 		                              : __str.max_size();
-	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
 	      const __int_type __eof = _Traits::eof();
-	      __streambuf_type* __sb = __in.rdbuf();
-	      __int_type __c = __sb->sgetc();
+	      __int_type __c = __in.rdbuf()->sgetc();
 
 	      while (__extracted < __n
 		     && !_Traits::eq_int_type(__c, __eof)
-		     && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
+		     && !isspace(_Traits::to_char_type(__c), __in.getloc()))
 		{
 		  if (__len == sizeof(__buf) / sizeof(_CharT))
 		    {
@@ -589,12 +586,12 @@
 		    }
 		  __buf[__len++] = _Traits::to_char_type(__c);
 		  ++__extracted;
-		  __c = __sb->snextc();
+		  __c = __in.rdbuf()->snextc();
 		}
 	      __str.append(__buf, __len);
 
 	      if (_Traits::eq_int_type(__c, __eof))
-		__err |= ios_base::eofbit;
+		__err |= __ios_base::eofbit;
 	      __in.width(0);
 	    }
 	  catch(...)
@@ -602,12 +599,12 @@
 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
 	      // 91. Description of operator>> and getline() for string<>
 	      // might cause endless loop
-	      __in._M_setstate(ios_base::badbit);
+	      __in._M_setstate(__ios_base::badbit);
 	    }
 	}
       // 211.  operator>>(istream&, string&) doesn't set failbit
       if (!__extracted)
-	__err |= ios_base::failbit;
+	__err |= __ios_base::failbit;
       if (__err)
 	__in.setstate(__err);
       return __in;
@@ -615,55 +612,21 @@
 
   template<typename _CharT, typename _Traits, typename _Alloc,
            template <typename, typename, typename> class _Base>
-    basic_ostream<_CharT, _Traits>&
-    operator<<(basic_ostream<_CharT, _Traits>& __out,
-	       const __gnu_cxx::__versa_string<_CharT, _Traits,
-	                                       _Alloc, _Base>& __str)
-    {
-      typedef basic_ostream<_CharT, _Traits>            __ostream_type;
-
-      typename __ostream_type::sentry __cerb(__out);
-      if (__cerb)
-	{
-	  const streamsize __w = __out.width();
-	  streamsize __len = static_cast<streamsize>(__str.size());
-	  const _CharT* __s = __str.data();
-
-	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
-	  // 25. String operator<< uses width() value wrong
-	  if (__w > __len)
-	    {
-	      _CharT* __cs = (static_cast<
-			      _CharT*>(__builtin_alloca(sizeof(_CharT) * __w)));
-	      __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
-					     __s, __w, __len, false);
-	      __s = __cs;
-	      __len = __w;
-	    }
-	  __out._M_write(__s, __len);
-	  __out.width(0);
-	}
-      return __out;
-    }
-
-  template<typename _CharT, typename _Traits, typename _Alloc,
-           template <typename, typename, typename> class _Base>
     basic_istream<_CharT, _Traits>&
     getline(basic_istream<_CharT, _Traits>& __in,
 	    __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
 	    _CharT __delim)
     {
       typedef basic_istream<_CharT, _Traits>	        __istream_type;
-      typedef typename __istream_type::int_type		__int_type;
-      typedef typename __istream_type::__streambuf_type __streambuf_type;
-      typedef typename __istream_type::__ctype_type	__ctype_type;
+      typedef typename __istream_type::ios_base         __ios_base;
       typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>
 	                                                __string_type;
+      typedef typename __istream_type::int_type		__int_type;
       typedef typename __string_type::size_type		__size_type;
 
       __size_type __extracted = 0;
       const __size_type __n = __str.max_size();
-      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+      typename __ios_base::iostate __err = __ios_base::goodbit;
       typename __istream_type::sentry __cerb(__in, true);
       if (__cerb)
 	{
@@ -675,8 +638,7 @@
 	      __size_type __len = 0;
 	      const __int_type __idelim = _Traits::to_int_type(__delim);
 	      const __int_type __eof = _Traits::eof();
-	      __streambuf_type* __sb = __in.rdbuf();
-	      __int_type __c = __sb->sgetc();
+	      __int_type __c = __in.rdbuf()->sgetc();
 
 	      while (__extracted < __n
 		     && !_Traits::eq_int_type(__c, __eof)
@@ -689,35 +651,35 @@
 		    }
 		  __buf[__len++] = _Traits::to_char_type(__c);
 		  ++__extracted;
-		  __c = __sb->snextc();
+		  __c = __in.rdbuf()->snextc();
 		}
 	      __str.append(__buf, __len);
 
 	      if (_Traits::eq_int_type(__c, __eof))
-		__err |= ios_base::eofbit;
+		__err |= __ios_base::eofbit;
 	      else if (_Traits::eq_int_type(__c, __idelim))
 		{
 		  ++__extracted;		  
-		  __sb->sbumpc();
+		  __in.rdbuf()->sbumpc();
 		}
 	      else
-		__err |= ios_base::failbit;
+		__err |= __ios_base::failbit;
 	    }
 	  catch(...)
 	    {
 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
 	      // 91. Description of operator>> and getline() for string<>
 	      // might cause endless loop
-	      __in._M_setstate(ios_base::badbit);
+	      __in._M_setstate(__ios_base::badbit);
 	    }
 	}
       if (!__extracted)
-	__err |= ios_base::failbit;
+	__err |= __ios_base::failbit;
       if (__err)
 	__in.setstate(__err);
       return __in;
     }      
-  
+
 _GLIBCXX_END_NAMESPACE
 
 #endif // _VSTRING_TCC
Index: include/ext/sso_string_base.h
===================================================================
--- include/ext/sso_string_base.h	(revision 123675)
+++ include/ext/sso_string_base.h	(working copy)
@@ -1,6 +1,6 @@
 // Short-string-optimized versatile string base -*- C++ -*-
 
-// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2007 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
@@ -405,7 +405,7 @@
 		   std::forward_iterator_tag)
       {
 	// NB: Not required, but considered best practice.
-	if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0))
+	if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0))
 	  std::__throw_logic_error(__N("__sso_string_base::"
 				       "_M_construct NULL not valid"));
 
Index: include/bits/locale_facets.tcc
===================================================================
--- include/bits/locale_facets.tcc	(revision 123675)
+++ include/bits/locale_facets.tcc	(working copy)
@@ -1,6 +1,7 @@
 // Locale support -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+// 2006, 2007
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -910,8 +911,8 @@
     {
       // [22.2.2.2.2] Stage 3.
       // If necessary, pad.
-      __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs,
-						  __w, __len, true);
+      __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new,
+						  __cs, __w, __len);
       __len = static_cast<int>(__w);
     }
 
@@ -2503,10 +2504,6 @@
   // Assumes
   // __newlen > __oldlen
   // __news is allocated for __newlen size
-  // Used by both num_put and ostream inserters: if __num,
-  // internal-adjusted objects are padded according to the rules below
-  // concerning 0[xX] and +-, otherwise, exactly as right-adjusted
-  // ones are.
 
   // NB: Of the two parameters, _CharT can be deduced from the
   // function arguments. The other (_Traits) has to be explicitly specified.
@@ -2515,7 +2512,7 @@
     __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill,
 				   _CharT* __news, const _CharT* __olds,
 				   const streamsize __newlen,
-				   const streamsize __oldlen, const bool __num)
+				   const streamsize __oldlen)
     {
       const size_t __plen = static_cast<size_t>(__newlen - __oldlen);
       const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield;
@@ -2529,7 +2526,7 @@
 	}
 
       size_t __mod = 0;
-      if (__adjust == ios_base::internal && __num)
+      if (__adjust == ios_base::internal)
 	{
 	  // Pad after the sign, if there is one.
 	  // Pad after 0[xX], if there is one.
Index: include/bits/locale_facets.h
===================================================================
--- include/bits/locale_facets.h	(revision 123675)
+++ include/bits/locale_facets.h	(working copy)
@@ -93,7 +93,7 @@
       static void
       _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
 	     const _CharT* __olds, const streamsize __newlen,
-	     const streamsize __oldlen, const bool __num);
+	     const streamsize __oldlen);
     };
 
   // Used by both numeric and monetary facets.
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h	(revision 123675)
+++ include/bits/basic_string.h	(working copy)
@@ -2414,7 +2414,7 @@
     {
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 586. string inserter not a formatted function
-      return __os._M_insert(__str.data(), __str.size());
+      return __ostream_insert(__os, __str.data(), __str.size());
     }
 
   /**
Index: include/bits/istream.tcc
===================================================================
--- include/bits/istream.tcc	(revision 123675)
+++ include/bits/istream.tcc	(working copy)
@@ -785,7 +785,7 @@
     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
     {
       typedef basic_istream<_CharT, _Traits>		__istream_type;
-      typedef typename __istream_type::__streambuf_type __streambuf_type;
+      typedef basic_streambuf<_CharT, _Traits>          __streambuf_type;
       typedef typename _Traits::int_type		int_type;
       typedef _CharT					char_type;
       typedef ctype<_CharT>				__ctype_type;
@@ -837,13 +837,13 @@
 
   // 27.6.1.4 Standard basic_istream manipulators
   template<typename _CharT, typename _Traits>
-    basic_istream<_CharT,_Traits>&
-    ws(basic_istream<_CharT,_Traits>& __in)
+    basic_istream<_CharT, _Traits>&
+    ws(basic_istream<_CharT, _Traits>& __in)
     {
       typedef basic_istream<_CharT, _Traits>		__istream_type;
-      typedef typename __istream_type::__streambuf_type __streambuf_type;
-      typedef typename __istream_type::__ctype_type	__ctype_type;
+      typedef basic_streambuf<_CharT, _Traits>          __streambuf_type;
       typedef typename __istream_type::int_type		__int_type;
+      typedef ctype<_CharT>				__ctype_type;
 
       const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
       const __int_type __eof = _Traits::eof();
@@ -859,133 +859,6 @@
       return __in;
     }
 
-  // 21.3.7.9 basic_string::getline and operators
-  template<typename _CharT, typename _Traits, typename _Alloc>
-    basic_istream<_CharT, _Traits>&
-    operator>>(basic_istream<_CharT, _Traits>& __in,
-	       basic_string<_CharT, _Traits, _Alloc>& __str)
-    {
-      typedef basic_istream<_CharT, _Traits>		__istream_type;
-      typedef typename __istream_type::int_type		__int_type;
-      typedef typename __istream_type::__streambuf_type __streambuf_type;
-      typedef typename __istream_type::__ctype_type	__ctype_type;
-      typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
-      typedef typename __string_type::size_type		__size_type;
-
-      __size_type __extracted = 0;
-      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-      typename __istream_type::sentry __cerb(__in, false);
-      if (__cerb)
-	{
-	  try
-	    {
-	      // Avoid reallocation for common case.
-	      __str.erase();
-	      _CharT __buf[128];
-	      __size_type __len = 0;	      
-	      const streamsize __w = __in.width();
-	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
-		                              : __str.max_size();
-	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
-	      const __int_type __eof = _Traits::eof();
-	      __streambuf_type* __sb = __in.rdbuf();
-	      __int_type __c = __sb->sgetc();
-
-	      while (__extracted < __n
-		     && !_Traits::eq_int_type(__c, __eof)
-		     && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
-		{
-		  if (__len == sizeof(__buf) / sizeof(_CharT))
-		    {
-		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
-		      __len = 0;
-		    }
-		  __buf[__len++] = _Traits::to_char_type(__c);
-		  ++__extracted;
-		  __c = __sb->snextc();
-		}
-	      __str.append(__buf, __len);
-
-	      if (_Traits::eq_int_type(__c, __eof))
-		__err |= ios_base::eofbit;
-	      __in.width(0);
-	    }
-	  catch(...)
-	    {
-	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-	      // 91. Description of operator>> and getline() for string<>
-	      // might cause endless loop
-	      __in._M_setstate(ios_base::badbit);
-	    }
-	}
-      // 211.  operator>>(istream&, string&) doesn't set failbit
-      if (!__extracted)
-	__err |= ios_base::failbit;
-      if (__err)
-	__in.setstate(__err);
-      return __in;
-    }
-
-  template<typename _CharT, typename _Traits, typename _Alloc>
-    basic_istream<_CharT, _Traits>&
-    getline(basic_istream<_CharT, _Traits>& __in,
-	    basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
-    {
-      typedef basic_istream<_CharT, _Traits>		__istream_type;
-      typedef typename __istream_type::int_type		__int_type;
-      typedef typename __istream_type::__streambuf_type __streambuf_type;
-      typedef typename __istream_type::__ctype_type	__ctype_type;
-      typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
-      typedef typename __string_type::size_type		__size_type;
-
-      __size_type __extracted = 0;
-      const __size_type __n = __str.max_size();
-      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
-      typename __istream_type::sentry __cerb(__in, true);
-      if (__cerb)
-	{
-	  try
-	    {
-	      __str.erase();
-	      const __int_type __idelim = _Traits::to_int_type(__delim);
-	      const __int_type __eof = _Traits::eof();
-	      __streambuf_type* __sb = __in.rdbuf();
-	      __int_type __c = __sb->sgetc();
-
-	      while (__extracted < __n
-		     && !_Traits::eq_int_type(__c, __eof)
-		     && !_Traits::eq_int_type(__c, __idelim))
-		{
-		  __str += _Traits::to_char_type(__c);
-		  ++__extracted;
-		  __c = __sb->snextc();
-		}
-
-	      if (_Traits::eq_int_type(__c, __eof))
-		__err |= ios_base::eofbit;
-	      else if (_Traits::eq_int_type(__c, __idelim))
-		{
-		  ++__extracted;		  
-		  __sb->sbumpc();
-		}
-	      else
-		__err |= ios_base::failbit;
-	    }
-	  catch(...)
-	    {
-	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-	      // 91. Description of operator>> and getline() for string<>
-	      // might cause endless loop
-	      __in._M_setstate(ios_base::badbit);
-	    }
-	}
-      if (!__extracted)
-	__err |= ios_base::failbit;
-      if (__err)
-	__in.setstate(__err);
-      return __in;
-    }
-
   // Inhibit implicit instantiations for required instantiations,
   // which are defined via explicit instantiations elsewhere.
   // NB:  This syntax is a GNU extension.
Index: include/bits/ostream.tcc
===================================================================
--- include/bits/ostream.tcc	(revision 123675)
+++ include/bits/ostream.tcc	(working copy)
@@ -281,38 +281,6 @@
 
   template<typename _CharT, typename _Traits>
     basic_ostream<_CharT, _Traits>&
-    basic_ostream<_CharT, _Traits>::
-    _M_insert(const char_type* __s, streamsize __n)
-    {
-      sentry __cerb(*this);
-      if (__cerb)
-	{
-	  try
-	    {
-	      const streamsize __w = this->width();
-	      if (__w > __n)
-		{
-		  const bool __left = ((this->flags() & ios_base::adjustfield)
-				       == ios_base::left);
-		  if (!__left)
-		    _M_write(this->fill(), __w - __n);
-		  if (this->good())
-		    _M_write(__s, __n);
-		  if (__left && this->good())
-		    _M_write(this->fill(), __w - __n);
-		}
-	      else
-		_M_write(__s, __n);
-	      this->width(0);
-	    }
-	  catch(...)
-	    { this->_M_setstate(ios_base::badbit); }
-	}
-      return *this;
-    }
-
-  template<typename _CharT, typename _Traits>
-    basic_ostream<_CharT, _Traits>&
     operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
     {
       if (!__s)
@@ -338,7 +306,7 @@
 
 	  try
 	    {
-	      __out._M_insert(__ws, __clen);
+	      __ostream_insert(__out, __ws, __clen);
 	      delete [] __ws;
 	    }
 	  catch(...)
@@ -364,6 +332,7 @@
   extern template ostream& operator<<(ostream&, const char*);
   extern template ostream& operator<<(ostream&, const unsigned char*);
   extern template ostream& operator<<(ostream&, const signed char*);
+  extern template ostream& __ostream_insert(ostream&, const char*, streamsize);
 
   extern template ostream& ostream::_M_insert(long);
   extern template ostream& ostream::_M_insert(unsigned long);
@@ -385,6 +354,8 @@
   extern template wostream& operator<<(wostream&, char);
   extern template wostream& operator<<(wostream&, const wchar_t*);
   extern template wostream& operator<<(wostream&, const char*);
+  extern template wostream& __ostream_insert(wostream&, const wchar_t*,
+					     streamsize);
 
   extern template wostream& wostream::_M_insert(long);
   extern template wostream& wostream::_M_insert(unsigned long);
Index: include/bits/basic_string.tcc
===================================================================
--- include/bits/basic_string.tcc	(revision 123675)
+++ include/bits/basic_string.tcc	(working copy)
@@ -48,16 +48,6 @@
 
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
-  template<typename _Type>
-    inline bool
-    __is_null_pointer(_Type* __ptr)
-    { return __ptr == 0; }
-
-  template<typename _Type>
-    inline bool
-    __is_null_pointer(_Type)
-    { return false; }
-
   template<typename _CharT, typename _Traits, typename _Alloc>
     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
     basic_string<_CharT, _Traits, _Alloc>::
@@ -142,7 +132,8 @@
 	  return _S_empty_rep()._M_refdata();
 #endif
 	// NB: Not required, but considered best practice.
-	if (__builtin_expect(__is_null_pointer(__beg) && __beg != __end, 0))
+	if (__builtin_expect(__gnu_cxx::__is_null_pointer(__beg)
+			     && __beg != __end, 0))
 	  __throw_logic_error(__N("basic_string::_S_construct NULL not valid"));
 
 	const size_type __dnew = static_cast<size_type>(std::distance(__beg,
@@ -972,6 +963,128 @@
       return __r;
     }
 
+  // 21.3.7.9 basic_string::getline and operators
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __in,
+	       basic_string<_CharT, _Traits, _Alloc>& __str)
+    {
+      typedef basic_istream<_CharT, _Traits>		__istream_type;
+      typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
+      typedef typename __istream_type::ios_base         __ios_base;
+      typedef typename __istream_type::int_type		__int_type;
+      typedef typename __string_type::size_type		__size_type;
+
+      __size_type __extracted = 0;
+      typename __ios_base::iostate __err = __ios_base::goodbit;
+      typename __istream_type::sentry __cerb(__in, false);
+      if (__cerb)
+	{
+	  try
+	    {
+	      // Avoid reallocation for common case.
+	      __str.erase();
+	      _CharT __buf[128];
+	      __size_type __len = 0;	      
+	      const streamsize __w = __in.width();
+	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
+		                              : __str.max_size();
+	      const __int_type __eof = _Traits::eof();
+	      __int_type __c = __in.rdbuf()->sgetc();
+
+	      while (__extracted < __n
+		     && !_Traits::eq_int_type(__c, __eof)
+		     && !isspace(_Traits::to_char_type(__c), __in.getloc()))
+		{
+		  if (__len == sizeof(__buf) / sizeof(_CharT))
+		    {
+		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
+		      __len = 0;
+		    }
+		  __buf[__len++] = _Traits::to_char_type(__c);
+		  ++__extracted;
+		  __c = __in.rdbuf()->snextc();
+		}
+	      __str.append(__buf, __len);
+
+	      if (_Traits::eq_int_type(__c, __eof))
+		__err |= __ios_base::eofbit;
+	      __in.width(0);
+	    }
+	  catch(...)
+	    {
+	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+	      // 91. Description of operator>> and getline() for string<>
+	      // might cause endless loop
+	      __in._M_setstate(__ios_base::badbit);
+	    }
+	}
+      // 211.  operator>>(istream&, string&) doesn't set failbit
+      if (!__extracted)
+	__err |= __ios_base::failbit;
+      if (__err)
+	__in.setstate(__err);
+      return __in;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    basic_istream<_CharT, _Traits>&
+    getline(basic_istream<_CharT, _Traits>& __in,
+	    basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
+    {
+      typedef basic_istream<_CharT, _Traits>		__istream_type;
+      typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
+      typedef typename __istream_type::ios_base         __ios_base;
+      typedef typename __istream_type::int_type		__int_type;
+      typedef typename __string_type::size_type		__size_type;
+
+      __size_type __extracted = 0;
+      const __size_type __n = __str.max_size();
+      typename __ios_base::iostate __err = __ios_base::goodbit;
+      typename __istream_type::sentry __cerb(__in, true);
+      if (__cerb)
+	{
+	  try
+	    {
+	      __str.erase();
+	      const __int_type __idelim = _Traits::to_int_type(__delim);
+	      const __int_type __eof = _Traits::eof();
+	      __int_type __c = __in.rdbuf()->sgetc();
+
+	      while (__extracted < __n
+		     && !_Traits::eq_int_type(__c, __eof)
+		     && !_Traits::eq_int_type(__c, __idelim))
+		{
+		  __str += _Traits::to_char_type(__c);
+		  ++__extracted;
+		  __c = __in.rdbuf()->snextc();
+		}
+
+	      if (_Traits::eq_int_type(__c, __eof))
+		__err |= __ios_base::eofbit;
+	      else if (_Traits::eq_int_type(__c, __idelim))
+		{
+		  ++__extracted;		  
+		  __in.rdbuf()->sbumpc();
+		}
+	      else
+		__err |= __ios_base::failbit;
+	    }
+	  catch(...)
+	    {
+	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+	      // 91. Description of operator>> and getline() for string<>
+	      // might cause endless loop
+	      __in._M_setstate(__ios_base::badbit);
+	    }
+	}
+      if (!__extracted)
+	__err |= __ios_base::failbit;
+      if (__err)
+	__in.setstate(__err);
+      return __in;
+    }
+
   // Inhibit implicit instantiations for required instantiations,
   // which are defined via explicit instantiations elsewhere.
   // NB: This syntax is a GNU extension.
Index: include/bits/ostream_insert.h
===================================================================
--- include/bits/ostream_insert.h	(revision 0)
+++ include/bits/ostream_insert.h	(revision 0)
@@ -0,0 +1,114 @@
+// Helpers for ostream inserters -*- C++ -*-
+
+// Copyright (C) 2007 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.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file ostream_insert.h
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _OSTREAM_INSERT_H
+#define _OSTREAM_INSERT_H 1
+
+#pragma GCC system_header
+
+#include <iosfwd>
+
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
+  template<typename _CharT, typename _Traits>
+    inline void
+    __ostream_write(basic_ostream<_CharT, _Traits>& __out,
+		    const _CharT* __s, streamsize __n)
+    {
+      typedef basic_ostream<_CharT, _Traits>       __ostream_type;      
+      typedef typename __ostream_type::ios_base    __ios_base;
+
+      const streamsize __put = __out.rdbuf()->sputn(__s, __n);
+      if (__put != __n)
+	__out.setstate(__ios_base::badbit);
+    }
+
+  template<typename _CharT, typename _Traits>
+    inline void
+    __ostream_fill(basic_ostream<_CharT, _Traits>& __out, streamsize __n)
+    {
+      typedef basic_ostream<_CharT, _Traits>       __ostream_type;      
+      typedef typename __ostream_type::ios_base    __ios_base;
+
+      const _CharT __c = __out.fill();
+      for (; __n > 0; --__n)
+	{
+	  const typename _Traits::int_type __put = __out.rdbuf()->sputc(__c);
+	  if (_Traits::eq_int_type(__put, _Traits::eof()))
+	    {
+	      __out.setstate(__ios_base::badbit);
+	      break;
+	    }
+	}
+    }
+
+  template<typename _CharT, typename _Traits>
+    basic_ostream<_CharT, _Traits>&
+    __ostream_insert(basic_ostream<_CharT, _Traits>& __out,
+		     const _CharT* __s, streamsize __n)
+    {
+      typedef basic_ostream<_CharT, _Traits>       __ostream_type;
+      typedef typename __ostream_type::ios_base    __ios_base;
+
+      typename __ostream_type::sentry __cerb(__out);
+      if (__cerb)
+	{
+	  try
+	    {
+	      const streamsize __w = __out.width();
+	      if (__w > __n)
+		{
+		  const bool __left = ((__out.flags()
+					& __ios_base::adjustfield)
+				       == __ios_base::left);
+		  if (!__left)
+		    __ostream_fill(__out, __w - __n);
+		  if (__out.good())
+		    __ostream_write(__out, __s, __n);
+		  if (__left && __out.good())
+		    __ostream_fill(__out, __w - __n);
+		}
+	      else
+		__ostream_write(__out, __s, __n);
+	      __out.width(0);
+	    }
+	  catch(...)
+	    { __out._M_setstate(__ios_base::badbit); }
+	}
+      return __out;
+    }
+
+_GLIBCXX_END_NAMESPACE
+
+#endif /* _OSTREAM_INSERT_H */
Index: include/Makefile.in
===================================================================
--- include/Makefile.in	(revision 123675)
+++ include/Makefile.in	(working copy)
@@ -328,6 +328,7 @@
 	${bits_srcdir}/localefwd.h \
 	${bits_srcdir}/mask_array.h \
 	${bits_srcdir}/ostream.tcc \
+	${bits_srcdir}/ostream_insert.h \
 	${bits_srcdir}/postypes.h \
 	${bits_srcdir}/stream_iterator.h \
 	${bits_srcdir}/streambuf_iterator.h \
Index: include/Makefile.am
===================================================================
--- include/Makefile.am	(revision 123675)
+++ include/Makefile.am	(working copy)
@@ -94,6 +94,7 @@
 	${bits_srcdir}/localefwd.h \
 	${bits_srcdir}/mask_array.h \
 	${bits_srcdir}/ostream.tcc \
+	${bits_srcdir}/ostream_insert.h \
 	${bits_srcdir}/postypes.h \
 	${bits_srcdir}/stream_iterator.h \
 	${bits_srcdir}/streambuf_iterator.h \
Index: include/std/bitset
===================================================================
--- include/std/bitset	(revision 123675)
+++ include/std/bitset	(working copy)
@@ -1240,7 +1240,6 @@
 	{
 	  try
 	    {
-	      basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
 	      // 303. Bitset input operator underspecified
 	      const char_type __zero = __is.widen('0');
@@ -1249,7 +1248,7 @@
 		{
 		  static typename _Traits::int_type __eof = _Traits::eof();
 		  
-		  typename _Traits::int_type __c1 = __buf->sbumpc();
+		  typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc();
 		  if (_Traits::eq_int_type(__c1, __eof))
 		    {
 		      __state |= __ios_base::eofbit;
@@ -1262,8 +1261,9 @@
 			__tmp.push_back('0');
 		      else if (__c2 == __one)
 			__tmp.push_back('1');
-		      else if (_Traits::eq_int_type(__buf->sputbackc(__c2),
-						    __eof))
+		      else if (_Traits::
+			       eq_int_type(__is.rdbuf()->sputbackc(__c2),
+					   __eof))
 			{
 			  __state |= __ios_base::failbit;
 			  break;
Index: include/std/string
===================================================================
--- include/std/string	(revision 123675)
+++ include/std/string	(working copy)
@@ -47,9 +47,10 @@
 #include <bits/char_traits.h>  // NB: In turn includes stl_algobase.h
 #include <bits/allocator.h>
 #include <bits/cpp_type_traits.h>
-#include <iosfwd> 	// For operators >>, <<, and getline decls.
+#include <bits/localefwd.h>    // For operators >>, <<, and getline.
+#include <bits/ostream_insert.h>
 #include <bits/stl_iterator.h>
-#include <bits/stl_function.h>  // For less
+#include <bits/stl_function.h> // For less
 #include <bits/basic_string.h>
 
 #ifndef _GLIBCXX_EXPORT_TEMPLATE
Index: include/std/ostream
===================================================================
--- include/std/ostream	(revision 123675)
+++ include/std/ostream	(working copy)
@@ -44,6 +44,7 @@
 
 #include <ios>
 #include <locale>
+#include <bits/ostream_insert.h>
 
 _GLIBCXX_BEGIN_NAMESPACE(std)
 
@@ -74,31 +75,6 @@
       							__num_put_type;
       typedef ctype<_CharT>           			__ctype_type;
 
-      template<typename _CharT2, typename _Traits2>
-        friend basic_ostream<_CharT2, _Traits2>&
-        operator<<(basic_ostream<_CharT2, _Traits2>&, _CharT2);
- 
-      template<typename _Traits2>
-        friend basic_ostream<char, _Traits2>&
-        operator<<(basic_ostream<char, _Traits2>&, char);
- 
-      template<typename _CharT2, typename _Traits2>
-        friend basic_ostream<_CharT2, _Traits2>&
-        operator<<(basic_ostream<_CharT2, _Traits2>&, const _CharT2*);
- 
-      template<typename _Traits2>
-        friend basic_ostream<char, _Traits2>&
-        operator<<(basic_ostream<char, _Traits2>&, const char*);
- 
-      template<typename _CharT2, typename _Traits2>
-        friend basic_ostream<_CharT2, _Traits2>&
-        operator<<(basic_ostream<_CharT2, _Traits2>&, const char*);
-
-      template<typename _CharT2, typename _Traits2, typename _Alloc>
-        friend basic_ostream<_CharT2, _Traits2>&
-        operator<<(basic_ostream<_CharT2, _Traits2>&,
-		   const basic_string<_CharT2, _Traits2, _Alloc>&);
-
       // [27.6.2.2] constructor/destructor
       /**
        *  @brief  Base constructor.
@@ -320,20 +296,6 @@
 	  this->setstate(ios_base::badbit);
       }
 
-      void
-      _M_write(char_type __c, streamsize __n)
-      {
-	for (; __n > 0; --__n)
-	  {
-	    const int_type __put = this->rdbuf()->sputc(__c);
-	    if (traits_type::eq_int_type(__put, traits_type::eof()))
-	      {
-		this->setstate(ios_base::badbit);
-		break;
-	      }
-	  }
-      }
-
       /**
        *  @brief  Character string insertion.
        *  @param  s  The array to insert.
@@ -407,9 +369,6 @@
       template<typename _ValueT>
         __ostream_type&
         _M_insert(_ValueT __v);
-
-      __ostream_type&
-      _M_insert(const char_type* __s, streamsize __n);
     };
 
   /**
@@ -493,7 +452,7 @@
   template<typename _CharT, typename _Traits>
     inline basic_ostream<_CharT, _Traits>&
     operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
-    { return __out._M_insert(&__c, 1); }
+    { return __ostream_insert(__out, &__c, 1); }
 
   template<typename _CharT, typename _Traits>
     inline basic_ostream<_CharT, _Traits>&
@@ -504,7 +463,7 @@
   template <class _Traits> 
     inline basic_ostream<char, _Traits>&
     operator<<(basic_ostream<char, _Traits>& __out, char __c)
-    { return __out._M_insert(&__c, 1); }
+    { return __ostream_insert(__out, &__c, 1); }
 
   // Signed and unsigned
   template<class _Traits>
@@ -539,7 +498,8 @@
       if (!__s)
 	__out.setstate(ios_base::badbit);
       else
-	__out._M_insert(__s, static_cast<streamsize>(_Traits::length(__s)));
+	__ostream_insert(__out, __s,
+			 static_cast<streamsize>(_Traits::length(__s)));
       return __out;
     }
 
@@ -555,7 +515,8 @@
       if (!__s)
 	__out.setstate(ios_base::badbit);
       else
-	__out._M_insert(__s, static_cast<streamsize>(_Traits::length(__s)));
+	__ostream_insert(__out, __s,
+			 static_cast<streamsize>(_Traits::length(__s)));
       return __out;
     }
 
Index: testsuite/ext/vstring/inserters_extractors/wchar_t/28277.cc
===================================================================
--- testsuite/ext/vstring/inserters_extractors/wchar_t/28277.cc	(revision 0)
+++ testsuite/ext/vstring/inserters_extractors/wchar_t/28277.cc	(revision 0)
@@ -0,0 +1,48 @@
+// 2007-04-09  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// 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.
+
+#include <ostream>
+#include <sstream>
+#include <ext/vstring.h>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  wostringstream oss_01;
+  const __gnu_cxx::__wvstring str_01(50, L'a');
+
+  oss_01.width(5000000);
+  const streamsize width = oss_01.width();
+
+  oss_01 << str_01;
+
+  VERIFY( oss_01.good() );
+  VERIFY( oss_01.str().size() == width );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/ext/vstring/inserters_extractors/char/28277.cc
===================================================================
--- testsuite/ext/vstring/inserters_extractors/char/28277.cc	(revision 0)
+++ testsuite/ext/vstring/inserters_extractors/char/28277.cc	(revision 0)
@@ -0,0 +1,48 @@
+// 2007-04-09  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// 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.
+
+#include <ostream>
+#include <sstream>
+#include <ext/vstring.h>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+  using namespace std;
+  bool test __attribute__((unused)) = true;
+
+  ostringstream oss_01;
+  const __gnu_cxx::__vstring str_01(50, 'a');
+
+  oss_01.width(20000000);
+  const streamsize width = oss_01.width();
+
+  oss_01 << str_01;
+
+  VERIFY( oss_01.good() );
+  VERIFY( oss_01.str().size() == width );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: config/abi/pre/gnu.ver
===================================================================
--- config/abi/pre/gnu.ver	(revision 123675)
+++ config/abi/pre/gnu.ver	(working copy)
@@ -694,8 +694,7 @@
 
     _ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EE[il]PSt15basic_streambuf*;
 
-    _ZNSo9_M_insertEPKc[il];
-    _ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertEPKw[il];
+    _ZSt16__ostream_insert*;
 
     _ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv;
     _ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb;

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