re PR libstdc++/12593 (Resolution of DR 91 (WP) still unimplemented)

2003-11-22  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/12593
	* include/bits/istream.tcc (operator>>(basic_string<>&),
	getline(basic_string<>&)): Implement resolution of DR 91 [WP];
	fix some minor issues with the exit conditions.
	* docs/html/ext/howto.html: Add an entry for DR 91.

From-SVN: r73835
This commit is contained in:
Paolo Carlini 2003-11-22 09:54:25 +00:00 committed by Paolo Carlini
parent 13418b4003
commit 1a311979dd
3 changed files with 81 additions and 37 deletions

View File

@ -1,3 +1,11 @@
2003-11-22 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/12593
* include/bits/istream.tcc (operator>>(basic_string<>&),
getline(basic_string<>&)): Implement resolution of DR 91 [WP];
fix some minor issues with the exit conditions.
* docs/html/ext/howto.html: Add an entry for DR 91.
2003-11-21 Paolo Carlini <pcarlini@suse.de>
* config/locale/gnu/monetary_members.cc

View File

@ -526,6 +526,15 @@
replaced by <code>isspace(c,is.getloc())</code>.
</dd>
<dt><a href="lwg-defects.html#91">91</a>:
<em>Description of operator&gt;&gt; and getline() for string&lt;&gt;
might cause endless loop</em>
</dt>
<dd>They behave as a formatted input function and as an unformatted
input function, respectively (except that <code>getline</code> is
not required to set <code>gcount</code>).
</dd>
<dt><a href="lwg-defects.html#109">109</a>:
<em>Missing binders for non-const sequence elements</em>
</dt>

View File

@ -1102,32 +1102,46 @@ namespace std
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;
__size_type __extracted = 0;
typename __istream_type::sentry __cerb(__in, false);
if (__cerb)
{
__str.erase();
streamsize __w = __in.width();
__size_type __n;
__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)))
try
{
__str += _Traits::to_char_type(__c);
++__extracted;
__c = __sb->snextc();
__str.erase();
streamsize __w = __in.width();
__size_type __n;
__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)))
{
__str += _Traits::to_char_type(__c);
++__extracted;
__c = __sb->snextc();
}
if (_Traits::eq_int_type(__c, __eof))
__in.setstate(ios_base::eofbit);
__in.width(0);
}
catch(...)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 91. Description of operator>> and getline() for string<>
// might cause endless loop
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
__in.setstate(ios_base::badbit);
if ((__in.exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
if (_Traits::eq_int_type(__c, __eof))
__in.setstate(ios_base::eofbit);
__in.width(0);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 211. operator>>(istream&, string&) doesn't set failbit
@ -1149,31 +1163,44 @@ namespace std
typedef typename __string_type::size_type __size_type;
__size_type __extracted = 0;
const __size_type __n = __str.max_size();
bool __testdelim = false;
typename __istream_type::sentry __cerb(__in, true);
if (__cerb)
{
__str.erase();
__size_type __n = __str.max_size();
__int_type __idelim = _Traits::to_int_type(__delim);
__streambuf_type* __sb = __in.rdbuf();
__int_type __c = __sb->sbumpc();
const __int_type __eof = _Traits::eof();
__testdelim = _Traits::eq_int_type(__c, __idelim);
while (__extracted <= __n && !_Traits::eq_int_type(__c, __eof)
&& !__testdelim)
try
{
__str += _Traits::to_char_type(__c);
++__extracted;
__c = __sb->sbumpc();
__str.erase();
__int_type __idelim = _Traits::to_int_type(__delim);
__streambuf_type* __sb = __in.rdbuf();
__int_type __c = __sb->sbumpc();
const __int_type __eof = _Traits::eof();
__testdelim = _Traits::eq_int_type(__c, __idelim);
while (!_Traits::eq_int_type(__c, __eof) && !__testdelim
&& __extracted < __n)
{
__str += _Traits::to_char_type(__c);
++__extracted;
__c = __sb->sbumpc();
__testdelim = _Traits::eq_int_type(__c, __idelim);
}
if (_Traits::eq_int_type(__c, __eof))
__in.setstate(ios_base::eofbit);
}
catch(...)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 91. Description of operator>> and getline() for string<>
// might cause endless loop
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
__in.setstate(ios_base::badbit);
if ((__in.exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
if (_Traits::eq_int_type(__c, __eof))
__in.setstate(ios_base::eofbit);
}
if (!__extracted && !__testdelim)
if ((!__extracted && !__testdelim) || __extracted == __n)
__in.setstate(ios_base::failbit);
return __in;
}