PR libstdc++/28277 (partial: vstring bits)

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.

From-SVN: r123692
This commit is contained in:
Paolo Carlini 2007-04-10 10:38:50 +00:00 committed by Paolo Carlini
parent 3117d1b509
commit 11202768fe
23 changed files with 482 additions and 319 deletions

View file

@ -1,3 +1,60 @@
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.
2007-04-09 Paolo Carlini <pcarlini@suse.de>
* include/tr1/type_traits_fwd.h (__is_union_or_class): Remove.

View file

@ -694,8 +694,7 @@ GLIBCXX_3.4.9 {
_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;

View file

@ -94,6 +94,7 @@ bits_headers = \
${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 \

View file

@ -328,6 +328,7 @@ bits_headers = \
${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 \

View file

@ -2414,7 +2414,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
// _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());
}
/**

View file

@ -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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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,132 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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;
typedef ctype<_CharT> __ctype_type;
typedef typename __ctype_type::ctype_base __ctype_base;
__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 __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
const __int_type __eof = _Traits::eof();
__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)))
{
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.

View file

@ -785,7 +785,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// 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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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.

View file

@ -93,7 +93,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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.

View file

@ -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 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
{
// [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 @@ _GLIBCXX_END_LDBL_NAMESPACE
// 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 @@ _GLIBCXX_END_LDBL_NAMESPACE
__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 @@ _GLIBCXX_END_LDBL_NAMESPACE
}
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.

View file

@ -279,38 +279,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return *this;
}
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)
@ -338,7 +306,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
try
{
__out._M_insert(__ws, __clen);
__ostream_insert(__out, __ws, __clen);
delete [] __ws;
}
catch(...)
@ -364,6 +332,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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);

View file

@ -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 */

View file

@ -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 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
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"));

View file

@ -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 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
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"));

View file

@ -147,6 +147,18 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
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

View file

@ -2139,11 +2139,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* writing a C string.
*/
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
basic_ostream<_CharT, _Traits>&
template <typename, typename, typename> class _Base>
inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const __gnu_cxx::__versa_string<_CharT, _Traits,
_Alloc, _Base>& __str);
const __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc,
_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.

View file

@ -551,16 +551,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__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 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;
typedef ctype<_CharT> __ctype_type;
typedef typename __ctype_type::ctype_base __ctype_base;
__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)
{
@ -575,12 +576,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
: __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)))
&& !__ct.is(__ctype_base::space,
_Traits::to_char_type(__c)))
{
if (__len == sizeof(__buf) / sizeof(_CharT))
{
@ -589,12 +590,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
__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,50 +603,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// _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;
}
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>&
@ -654,16 +622,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_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 +642,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__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 +655,35 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
__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

View file

@ -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 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
_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

View file

@ -1240,7 +1240,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
{
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 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
{
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 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
__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;

View file

@ -44,6 +44,7 @@
#include <ios>
#include <locale>
#include <bits/ostream_insert.h>
_GLIBCXX_BEGIN_NAMESPACE(std)
@ -74,31 +75,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _ValueT>
__ostream_type&
_M_insert(_ValueT __v);
__ostream_type&
_M_insert(const char_type* __s, streamsize __n);
};
/**
@ -493,7 +452,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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;
}

View file

@ -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

View file

@ -55,6 +55,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
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);

View file

@ -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;
}

View file

@ -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;
}