</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.
<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>
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;
}
--- /dev/null
+#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();
+}
--- /dev/null
+#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();
+}