public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r12-1843] libstdc++: Implement LWG 415 for std::ws Date: Mon, 28 Jun 2021 13:23:32 +0000 (GMT) [thread overview] Message-ID: <20210628132332.D0D5B3855037@sourceware.org> (raw) https://gcc.gnu.org/g:e5c422b7d8af6f42f8ab230133210742b7ac5661 commit r12-1843-ge5c422b7d8af6f42f8ab230133210742b7ac5661 Author: Jonathan Wakely <jwakely@redhat.com> Date: Fri Jun 25 21:33:02 2021 +0100 libstdc++: Implement LWG 415 for std::ws For C++11 std::ws changed to be an unformatted input function, meaning it constructs a sentry and sets badbit on exceptions. libstdc++-v3/ChangeLog: * doc/xml/manual/intro.xml: Document LWG 415 change. * doc/html/manual/bugs.html: Regenerate. * include/bits/istream.tcc (ws): Create sentry and catch exceptions. * testsuite/27_io/basic_istream/ws/char/lwg415.cc: New test. * testsuite/27_io/basic_istream/ws/wchar_t/lwg415.cc: New test. Diff: --- libstdc++-v3/doc/html/manual/bugs.html | 4 ++ libstdc++-v3/doc/xml/manual/intro.xml | 7 ++ libstdc++-v3/include/bits/istream.tcc | 46 ++++++++++--- .../27_io/basic_istream/ws/char/lwg415.cc | 77 ++++++++++++++++++++++ .../27_io/basic_istream/ws/wchar_t/lwg415.cc | 77 ++++++++++++++++++++++ 5 files changed, 201 insertions(+), 10 deletions(-) diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html index 7b49e4ab87c..38594a9b75a 100644 --- a/libstdc++-v3/doc/html/manual/bugs.html +++ b/libstdc++-v3/doc/html/manual/bugs.html @@ -245,6 +245,10 @@ </p></dd><dt><a id="manual.bugs.dr409"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#409" target="_top">409</a>: <span class="emphasis"><em>Closing an fstream should clear the error state</em></span> </span></dt><dd><p>Have <code class="code">open</code> clear the error flags. + </p></dd><dt><a id="manual.bugs.dr415"></a><span class="term"><a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#415" target="_top">415</a>: + <span class="emphasis"><em>Behavior of std::ws</em></span> + </span></dt><dd><p>Change it to be an unformatted input function + (i.e. construct a sentry and catch exceptions). </p></dd><dt><span class="term"><a class="link" href="../ext/lwg-closed.html#431" target="_top">431</a>: <span class="emphasis"><em>Swapping containers with unequal allocators</em></span> </span></dt><dd><p>Implement Option 3, as per N1599. diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index 45762caa711..86ed6964b6a 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -634,6 +634,13 @@ requirements of the license of GCC. <listitem><para>Have <code>open</code> clear the error flags. </para></listitem></varlistentry> + <varlistentry xml:id="manual.bugs.dr415"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#415">415</link>: + <emphasis>Behavior of std::ws</emphasis> + </term> + <listitem><para>Change it to be an unformatted input function + (i.e. construct a sentry and catch exceptions). + </para></listitem></varlistentry> + <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-closed.html#431">431</link>: <emphasis>Swapping containers with unequal allocators</emphasis> </term> diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc index 1b046bec937..2a153c2e140 100644 --- a/libstdc++-v3/include/bits/istream.tcc +++ b/libstdc++-v3/include/bits/istream.tcc @@ -1057,17 +1057,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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(); - __streambuf_type* __sb = __in.rdbuf(); - __int_type __c = __sb->sgetc(); - - while (!_Traits::eq_int_type(__c, __eof) - && __ct.is(ctype_base::space, _Traits::to_char_type(__c))) - __c = __sb->snextc(); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 451. behavior of std::ws + typename __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + ios_base::iostate __err = ios_base::goodbit; + __try + { + 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(); - if (_Traits::eq_int_type(__c, __eof)) - __in.setstate(ios_base::eofbit); + while (true) + { + if (_Traits::eq_int_type(__c, __eof)) + { + __err = ios_base::eofbit; + break; + } + if (!__ct.is(ctype_base::space, _Traits::to_char_type(__c))) + break; + __c = __sb->snextc(); + } + } + __catch (const __cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + __throw_exception_again; + } + __catch (...) + { + __in._M_setstate(ios_base::badbit); + } + if (__err) + __in.setstate(__err); + } return __in; } diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ws/char/lwg415.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ws/char/lwg415.cc new file mode 100644 index 00000000000..fe6980dff29 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istream/ws/char/lwg415.cc @@ -0,0 +1,77 @@ +#include <istream> + +// C++11 27.7.2.4 Standard basic_istream manipulators [istream.manip] +// +// LWG 415. behavior of std::ws +// std::ws is an unformatted input function. + +#include <istream> +#include <testsuite_hooks.h> +#include <testsuite_io.h> + +void +test01() +{ + std::istream is(0); + VERIFY( is.rdstate() == std::ios_base::badbit ); + + is >> std::ws; // sentry should set failbit + VERIFY( is.rdstate() & std::ios_base::failbit ); +} + +void +test02() +{ + __gnu_test::sync_streambuf buf; + std::istream is(&buf); + + __gnu_test::sync_streambuf buf_tie; + std::ostream os_tie(&buf_tie); + + // A sentry should be constructed so is.tie()->flush() should be called. + // The standard allows the flush to be deferred because the put area of + // is_tie is empty, but libstdc++ doesn't defer it. + is.tie(&os_tie); + + is >> std::ws; + + VERIFY( is.eof() ); + VERIFY( !is.fail() ); + VERIFY( ! buf.sync_called() ); + VERIFY( buf_tie.sync_called() ); +} + +void +test03() +{ + __gnu_test::fail_streambuf buf; + std::istream is(&buf); + + char c; + is >> c >> std::ws; + VERIFY( is.rdstate() == std::ios_base::badbit ); + + is.clear(); + is.exceptions(std::ios_base::badbit); + + try + { + is >> std::ws; + VERIFY( false ); + } + catch (const __gnu_test::underflow_error&) + { + VERIFY( is.rdstate() == std::ios_base::badbit ); + } + catch (...) + { + VERIFY( false ); + } +} + +int main() +{ + test01(); + test02(); + test03(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ws/wchar_t/lwg415.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ws/wchar_t/lwg415.cc new file mode 100644 index 00000000000..fd040098b40 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istream/ws/wchar_t/lwg415.cc @@ -0,0 +1,77 @@ +#include <istream> + +// C++11 27.7.2.4 Standard basic_istream manipulators [istream.manip] +// +// LWG 415. behavior of std::ws +// std::ws is an unformatted input function. + +#include <istream> +#include <testsuite_hooks.h> +#include <testsuite_io.h> + +void +test01() +{ + std::wistream is(0); + VERIFY( is.rdstate() == std::ios_base::badbit ); + + is >> std::ws; // sentry should set failbit + VERIFY( is.rdstate() & std::ios_base::failbit ); +} + +void +test02() +{ + __gnu_test::sync_wstreambuf buf; + std::wistream is(&buf); + + __gnu_test::sync_wstreambuf buf_tie; + std::wostream os_tie(&buf_tie); + + // A sentry should be constructed so is.tie()->flush() should be called. + // The standard allows the flush to be deferred because the put area of + // is_tie is empty, but libstdc++ doesn't defer it. + is.tie(&os_tie); + + is >> std::ws; + + VERIFY( is.eof() ); + VERIFY( !is.fail() ); + VERIFY( ! buf.sync_called() ); + VERIFY( buf_tie.sync_called() ); +} + +void +test03() +{ + __gnu_test::fail_wstreambuf buf; + std::wistream is(&buf); + + wchar_t c; + is >> c >> std::ws; + VERIFY( is.rdstate() == std::ios_base::badbit ); + + is.clear(); + is.exceptions(std::ios_base::badbit); + + try + { + is >> std::ws; + VERIFY( false ); + } + catch (const __gnu_test::underflow_error&) + { + VERIFY( is.rdstate() == std::ios_base::badbit ); + } + catch (...) + { + VERIFY( false ); + } +} + +int main() +{ + test01(); + test02(); + test03(); +}
reply other threads:[~2021-06-28 13:23 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210628132332.D0D5B3855037@sourceware.org \ --to=redi@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).