libstdc++: Implement LWG 581 for std:ostream::flush()
LWG 581 changed ostream::flush() to an unformatted output function for C++11, but it was never implemented in libstdc++. libstdc++-v3/ChangeLog: * doc/xml/manual/intro.xml: Document LWG 581 change. * doc/html/manual/bugs.html: Regenerate. * include/bits/basic_ios.tcc: Whitespace. * include/bits/ostream.tcc (basic_ostream::flush()): Construct sentry. * testsuite/27_io/basic_ostream/flush/char/2.cc: Check additional cases. * testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc: Likewise. * testsuite/27_io/basic_ostream/flush/wchar_t/2.cc: Likewise. * testsuite/27_io/basic_ostream/flush/wchar_t/exceptions_badbit_throw.cc: Likewise.
This commit is contained in:
parent
9b6c65c754
commit
f8c5b542f6
|
@ -303,6 +303,9 @@
|
|||
</p></dd><dt><a id="manual.bugs.dr550"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#550" target="_top">550</a>:
|
||||
<span class="emphasis"><em>What should the return type of pow(float,int) be?</em></span>
|
||||
</span></dt><dd><p>In C++11 mode, remove the pow(float,int), etc., signatures.
|
||||
</p></dd><dt><a id="manual.bugs.dr581"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#581" target="_top">581</a>:
|
||||
<span class="emphasis"><em><code class="code">flush()</code> not unformatted function</em></span>
|
||||
</span></dt><dd><p>Change it to be a unformatted output function (i.e. construct a sentry and catch exceptions).
|
||||
</p></dd><dt><a id="manual.bugs.dr586"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#586" target="_top">586</a>:
|
||||
<span class="emphasis"><em>string inserter not a formatted function</em></span>
|
||||
</span></dt><dd><p>Change it to be a formatted output function (i.e. catch exceptions).
|
||||
|
|
|
@ -743,6 +743,12 @@ requirements of the license of GCC.
|
|||
<listitem><para>In C++11 mode, remove the pow(float,int), etc., signatures.
|
||||
</para></listitem></varlistentry>
|
||||
|
||||
<varlistentry xml:id="manual.bugs.dr581"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#581">581</link>:
|
||||
<emphasis><code>flush()</code> not unformatted function</emphasis>
|
||||
</term>
|
||||
<listitem><para>Change it to be a unformatted output function (i.e. construct a sentry and catch exceptions).
|
||||
</para></listitem></varlistentry>
|
||||
|
||||
<varlistentry xml:id="manual.bugs.dr586"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#586">586</link>:
|
||||
<emphasis>string inserter not a formatted function</emphasis>
|
||||
</term>
|
||||
|
|
|
@ -43,7 +43,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
if (this->rdbuf())
|
||||
_M_streambuf_state = __state;
|
||||
else
|
||||
_M_streambuf_state = __state | badbit;
|
||||
_M_streambuf_state = __state | badbit;
|
||||
if (this->exceptions() & this->rdstate())
|
||||
__throw_ios_failure(__N("basic_ios::clear"));
|
||||
}
|
||||
|
|
|
@ -213,21 +213,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 60. What is a formatted input function?
|
||||
// basic_ostream::flush() is *not* an unformatted output function.
|
||||
ios_base::iostate __err = ios_base::goodbit;
|
||||
__try
|
||||
// 581. flush() not unformatted function
|
||||
// basic_ostream::flush() *is* an unformatted output function.
|
||||
if (__streambuf_type* __buf = this->rdbuf())
|
||||
{
|
||||
if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
|
||||
__err |= ios_base::badbit;
|
||||
sentry __cerb(*this);
|
||||
if (__cerb)
|
||||
{
|
||||
ios_base::iostate __err = ios_base::goodbit;
|
||||
__try
|
||||
{
|
||||
if (this->rdbuf()->pubsync() == -1)
|
||||
__err |= ios_base::badbit;
|
||||
}
|
||||
__catch(__cxxabiv1::__forced_unwind&)
|
||||
{
|
||||
this->_M_setstate(ios_base::badbit);
|
||||
__throw_exception_again;
|
||||
}
|
||||
__catch(...)
|
||||
{ this->_M_setstate(ios_base::badbit); }
|
||||
if (__err)
|
||||
this->setstate(__err);
|
||||
}
|
||||
}
|
||||
__catch(__cxxabiv1::__forced_unwind&)
|
||||
{
|
||||
this->_M_setstate(ios_base::badbit);
|
||||
__throw_exception_again;
|
||||
}
|
||||
__catch(...)
|
||||
{ this->_M_setstate(ios_base::badbit); }
|
||||
if (__err)
|
||||
this->setstate(__err);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,42 +22,70 @@
|
|||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 60. What is a formatted input function?
|
||||
// basic_ostream::flush() does not behave as an unformatted output function.
|
||||
// But wait ...
|
||||
// 581. flush() not unformatted function
|
||||
// So now basic_ostream::flush() *is* an unformatted output function.
|
||||
|
||||
#include <ostream>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_io.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
std::ostream os(0);
|
||||
VERIFY( os.bad() );
|
||||
|
||||
// Nothing should happen if os.rdbuf() is null. No sentry is constructed.
|
||||
os.flush();
|
||||
VERIFY( os.rdstate() == std::ios_base::badbit ); // no failbit
|
||||
|
||||
os.exceptions(std::ios_base::failbit);
|
||||
os.flush();
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
__gnu_test::sync_streambuf buf;
|
||||
std::ostream os(&buf);
|
||||
|
||||
|
||||
__gnu_test::sync_streambuf buf_tie;
|
||||
std::ostream os_tie(&buf_tie);
|
||||
|
||||
// No sentry should be constructed so os.tie()->flush() should not be
|
||||
// called.
|
||||
// A sentry should be constructed so os.tie()->flush() should be called.
|
||||
os.tie(&os_tie);
|
||||
|
||||
|
||||
os.flush();
|
||||
|
||||
VERIFY( os.good() );
|
||||
VERIFY( buf.sync_called() );
|
||||
VERIFY( !buf_tie.sync_called() );
|
||||
VERIFY( buf_tie.sync_called() );
|
||||
}
|
||||
|
||||
// os.rdbuf()->pubsync() should be called even if !os.good().
|
||||
void
|
||||
test03()
|
||||
{
|
||||
__gnu_test::sync_streambuf buf;
|
||||
std::ostream os(&buf);
|
||||
|
||||
__gnu_test::sync_streambuf buf_tie;
|
||||
std::ostream os_tie(&buf_tie);
|
||||
|
||||
os.tie(&os_tie);
|
||||
|
||||
// os.rdbuf()->pubsync() should not be called if !os.good().
|
||||
os.setstate(std::ios_base::eofbit);
|
||||
|
||||
os.flush();
|
||||
|
||||
VERIFY( os.rdstate() == std::ios_base::eofbit );
|
||||
VERIFY( buf.sync_called() );
|
||||
VERIFY( os.rdstate() & std::ios_base::eofbit );
|
||||
VERIFY( !buf.sync_called() );
|
||||
VERIFY( !buf_tie.sync_called() );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
return 0;
|
||||
test03();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,21 +28,23 @@ void test01()
|
|||
{
|
||||
__gnu_test::fail_streambuf bib;
|
||||
ostream stream(&bib);
|
||||
|
||||
stream.flush(); // should catch exception and set badbit
|
||||
VERIFY( stream.rdstate() == ios_base::badbit );
|
||||
|
||||
stream.clear();
|
||||
stream.exceptions(ios_base::badbit);
|
||||
|
||||
try
|
||||
{
|
||||
stream.flush();
|
||||
stream.flush(); // should catch exception and set badbit and rethrow
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (const __gnu_test::positioning_error&)
|
||||
catch (const __gnu_test::positioning_error&)
|
||||
{
|
||||
// stream should set badbit and rethrow facet_error.
|
||||
VERIFY( stream.bad() );
|
||||
VERIFY( (stream.rdstate() & ios_base::failbit) == 0 );
|
||||
VERIFY( !stream.eof() );
|
||||
VERIFY( stream.rdstate() == ios_base::badbit );
|
||||
}
|
||||
catch (...)
|
||||
catch (...)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
|
|
|
@ -20,42 +20,70 @@
|
|||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// DR 60. What is a formatted input function?
|
||||
// basic_ostream::flush() does not behave as an unformatted output function.
|
||||
// But wait ...
|
||||
// 581. flush() not unformatted function
|
||||
// So now basic_ostream::flush() *is* an unformatted output function.
|
||||
|
||||
#include <ostream>
|
||||
#include <testsuite_hooks.h>
|
||||
#include <testsuite_io.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
std::wostream os(0);
|
||||
VERIFY( os.bad() );
|
||||
|
||||
// Nothing should happen if os.rdbuf() is null. No sentry is constructed.
|
||||
os.flush();
|
||||
VERIFY( os.rdstate() == std::ios_base::badbit ); // no failbit
|
||||
|
||||
os.exceptions(std::ios_base::failbit);
|
||||
os.flush();
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
__gnu_test::sync_wstreambuf buf;
|
||||
std::wostream os(&buf);
|
||||
|
||||
|
||||
__gnu_test::sync_wstreambuf buf_tie;
|
||||
std::wostream os_tie(&buf_tie);
|
||||
|
||||
// No sentry should be constructed so os.tie()->flush() should not be
|
||||
// called.
|
||||
// A sentry should be constructed so os.tie()->flush() should be called.
|
||||
os.tie(&os_tie);
|
||||
|
||||
|
||||
os.flush();
|
||||
|
||||
VERIFY( os.good() );
|
||||
VERIFY( buf.sync_called() );
|
||||
VERIFY( !buf_tie.sync_called() );
|
||||
VERIFY( buf_tie.sync_called() );
|
||||
}
|
||||
|
||||
// os.rdbuf()->pubsync() should be called even if !os.good().
|
||||
void
|
||||
test03()
|
||||
{
|
||||
__gnu_test::sync_wstreambuf buf;
|
||||
std::wostream os(&buf);
|
||||
|
||||
__gnu_test::sync_wstreambuf buf_tie;
|
||||
std::wostream os_tie(&buf_tie);
|
||||
|
||||
os.tie(&os_tie);
|
||||
|
||||
// os.rdbuf()->pubsync() should not be called if !os.good().
|
||||
os.setstate(std::ios_base::eofbit);
|
||||
|
||||
os.flush();
|
||||
|
||||
VERIFY( os.rdstate() == std::ios_base::eofbit );
|
||||
VERIFY( buf.sync_called() );
|
||||
VERIFY( os.rdstate() & std::ios_base::eofbit );
|
||||
VERIFY( !buf.sync_called() );
|
||||
VERIFY( !buf_tie.sync_called() );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
return 0;
|
||||
test03();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,21 +28,23 @@ void test01()
|
|||
{
|
||||
__gnu_test::fail_wstreambuf bib;
|
||||
wostream stream(&bib);
|
||||
|
||||
stream.flush(); // should catch exception and set badbit
|
||||
VERIFY( stream.rdstate() == ios_base::badbit );
|
||||
|
||||
stream.clear();
|
||||
stream.exceptions(ios_base::badbit);
|
||||
|
||||
try
|
||||
{
|
||||
stream.flush();
|
||||
stream.flush(); // should catch exception and set badbit and rethrow
|
||||
VERIFY( false );
|
||||
}
|
||||
catch (const __gnu_test::positioning_error&)
|
||||
catch (const __gnu_test::positioning_error&)
|
||||
{
|
||||
// stream should set badbit and rethrow facet_error.
|
||||
VERIFY( stream.bad() );
|
||||
VERIFY( (stream.rdstate() & ios_base::failbit) == 0 );
|
||||
VERIFY( !stream.eof() );
|
||||
VERIFY( stream.rdstate() == ios_base::badbit );
|
||||
}
|
||||
catch (...)
|
||||
catch (...)
|
||||
{
|
||||
VERIFY( false );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue