[libc++] Fix error flags and exceptions propagated from input stream operations
authorLouis Dionne <ldionne@apple.com>
Fri, 5 Apr 2019 16:33:37 +0000 (16:33 +0000)
committerLouis Dionne <ldionne@apple.com>
Fri, 5 Apr 2019 16:33:37 +0000 (16:33 +0000)
Summary:
This is a re-application of r357533 and r357531. They had been reverted
because we thought the commits broke the LLDB data formatters, but it
turns out this was because only r357531 had been included in the CI
run.

Before this patch, we would only ever throw an exception if the badbit
was set on the stream. The Standard is currently very unclear on how
exceptions should be propagated and what error flags should be set by
the input stream operations. This commit changes libc++ to behave under
a different (but valid) interpretation of the Standard. This interpretation
of the Standard matches what other implementations are doing.

This effectively implements the wording in p1264r0. It hasn't been voted
into the Standard yet, however there is wide agreement that the fix is
correct and it's just a matter of time before the fix is standardized.

PR21586
PR15949
rdar://problem/15347558

Reviewers: mclow.lists, EricWF

Subscribers: christof, dexonsmith, cfe-commits

Differential Revision: https://reviews.llvm.org/D49863

llvm-svn: 357775

42 files changed:
libcxx/include/ios
libcxx/include/istream
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/bool.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/double.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/float.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/int.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_double.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/long_long.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/pointer.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/short.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_int.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_long_long.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream.formatted.arithmetic/unsigned_short.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/chart.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/signed_char_pointer.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/streambuf.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/unsigned_char_pointer.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.formatted/istream_extractors/wchar_t_pointer.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.manip/ws.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_chart.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_streambuf_chart.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/getline_pointer_size_chart.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/ignore.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/peek.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/putback.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/read.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/sync.pass.cpp
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/unget.pass.cpp
libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp
libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp
libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp
libcxx/test/std/utilities/template.bitset/bitset.operators/stream_in.pass.cpp
libcxx/test/std/utilities/template.bitset/bitset.operators/stream_out.pass.cpp

index 96e84eb..ce4e176 100644 (file)
@@ -330,6 +330,15 @@ public:
     void __set_badbit_and_consider_rethrow();
     void __set_failbit_and_consider_rethrow();
 
+    _LIBCPP_INLINE_VISIBILITY
+    void __setstate_nothrow(iostate __state)
+    {
+        if (__rdbuf_)
+            __rdstate_ |= __state;
+        else
+            __rdstate_ |= __state | ios_base::badbit;
+    }
+
 protected:
     _LIBCPP_INLINE_VISIBILITY
     ios_base() {// purposefully does no initialization
index 14a5fe1..d6217bb 100644 (file)
@@ -362,26 +362,31 @@ template <class _Tp, class _CharT, class _Traits>
 _LIBCPP_INLINE_VISIBILITY
 basic_istream<_CharT, _Traits>&
 __input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = ios_base::goodbit;
+    typename basic_istream<_CharT, _Traits>::sentry __s(__is);
+    if (__s)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        typename basic_istream<_CharT, _Traits>::sentry __s(__is);
-        if (__s)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             typedef istreambuf_iterator<_CharT, _Traits> _Ip;
             typedef num_get<_CharT, _Ip> _Fp;
-            ios_base::iostate __err = ios_base::goodbit;
-            use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __err, __n);
-            __is.setstate(__err);
-        }
+            use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __n);
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            __is.__setstate_nothrow(__state);
+            if (__is.exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif
+        __is.setstate(__state);
     }
-    catch (...)
-    {
-        __is.__set_badbit_and_consider_rethrow();
-    }
-#endif  // _LIBCPP_NO_EXCEPTIONS
     return __is;
 }
 
@@ -466,39 +471,46 @@ template <class _Tp, class _CharT, class _Traits>
 _LIBCPP_INLINE_VISIBILITY
 basic_istream<_CharT, _Traits>&
 __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = ios_base::goodbit;
+    typename basic_istream<_CharT, _Traits>::sentry __s(__is);
+    if (__s)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        typename basic_istream<_CharT, _Traits>::sentry __s(__is);
-        if (__s)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             typedef istreambuf_iterator<_CharT, _Traits> _Ip;
             typedef num_get<_CharT, _Ip> _Fp;
-            ios_base::iostate __err = ios_base::goodbit;
             long __temp;
-            use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __err, __temp);
+            use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __temp);
             if (__temp < numeric_limits<_Tp>::min())
             {
-                __err |= ios_base::failbit;
+                __state |= ios_base::failbit;
                 __n = numeric_limits<_Tp>::min();
             }
             else if (__temp > numeric_limits<_Tp>::max())
             {
-                __err |= ios_base::failbit;
+                __state |= ios_base::failbit;
                 __n = numeric_limits<_Tp>::max();
             }
             else
+            {
                 __n = static_cast<_Tp>(__temp);
-            __is.setstate(__err);
-        }
+            }
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        __is.__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            __is.__setstate_nothrow(__state);
+            if (__is.exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        __is.setstate(__state);
+    }
     return __is;
 }
 
@@ -521,22 +533,22 @@ _LIBCPP_INLINE_VISIBILITY
 basic_istream<_CharT, _Traits>&
 __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = ios_base::goodbit;
+    typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif
             _CharT* __s = __p;
             const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
-            ios_base::iostate __err = ios_base::goodbit;
             while (__s != __p + (__n-1))
             {
                 typename _Traits::int_type __i = __is.rdbuf()->sgetc();
                 if (_Traits::eq_int_type(__i, _Traits::eof()))
                 {
-                   __err |= ios_base::eofbit;
+                   __state |= ios_base::eofbit;
                    break;
                 }
                 _CharT __ch = _Traits::to_char_type(__i);
@@ -548,16 +560,21 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n)
             *__s = _CharT();
             __is.width(0);
             if (__s == __p)
-               __err |= ios_base::failbit;
-            __is.setstate(__err);
-        }
+               __state |= ios_base::failbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            __is.__setstate_nothrow(__state);
+            if (__is.exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif
+        __is.setstate(__state);
     }
-    catch (...)
-    {
-        __is.__set_badbit_and_consider_rethrow();
-    }
-#endif  // _LIBCPP_NO_EXCEPTIONS
     return __is;
 }
 
@@ -625,26 +642,33 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = ios_base::goodbit;
+    typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif
             typename _Traits::int_type __i = __is.rdbuf()->sbumpc();
             if (_Traits::eq_int_type(__i, _Traits::eof()))
-                __is.setstate(ios_base::eofbit | ios_base::failbit);
+                __state |= ios_base::eofbit | ios_base::failbit;
             else
                 __c = _Traits::to_char_type(__i);
-        }
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            __is.__setstate_nothrow(__state);
+            if (__is.exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif
+        __is.setstate(__state);
     }
-    catch (...)
-    {
-        __is.__set_badbit_and_consider_rethrow();
-    }
-#endif  // _LIBCPP_NO_EXCEPTIONS
     return __is;
 }
 
@@ -668,58 +692,56 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_type>* __sb)
 {
+    ios_base::iostate __state = ios_base::goodbit;
     __gc_ = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __s(*this, true);
+    if (__s)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __s(*this, true);
-        if (__s)
+        if (__sb)
         {
-            if (__sb)
-            {
 #ifndef _LIBCPP_NO_EXCEPTIONS
-                try
+            try
+            {
+#endif // _LIBCPP_NO_EXCEPTIONS
+                while (true)
                 {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-                    ios_base::iostate __err = ios_base::goodbit;
-                    while (true)
+                    typename traits_type::int_type __i = this->rdbuf()->sgetc();
+                    if (traits_type::eq_int_type(__i, _Traits::eof()))
                     {
-                        typename traits_type::int_type __i = this->rdbuf()->sgetc();
-                        if (traits_type::eq_int_type(__i, _Traits::eof()))
-                        {
-                           __err |= ios_base::eofbit;
-                           break;
-                        }
-                        if (traits_type::eq_int_type(
-                                __sb->sputc(traits_type::to_char_type(__i)),
-                                traits_type::eof()))
-                            break;
-                        ++__gc_;
-                        this->rdbuf()->sbumpc();
+                       __state |= ios_base::eofbit;
+                       break;
                     }
-                    if (__gc_ == 0)
-                       __err |= ios_base::failbit;
-                    this->setstate(__err);
-#ifndef _LIBCPP_NO_EXCEPTIONS
+                    if (traits_type::eq_int_type(
+                            __sb->sputc(traits_type::to_char_type(__i)),
+                            traits_type::eof()))
+                        break;
+                    ++__gc_;
+                    this->rdbuf()->sbumpc();
                 }
-                catch (...)
+                if (__gc_ == 0)
+                   __state |= ios_base::failbit;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            }
+            catch (...)
+            {
+                __state |= ios_base::badbit;
+                if (__gc_ == 0)
+                    __state |= ios_base::failbit;
+
+                this->__setstate_nothrow(__state);
+                if (this->exceptions() & ios_base::failbit || this->exceptions() & ios_base::badbit)
                 {
-                    if (__gc_ == 0)
-                        this->__set_failbit_and_consider_rethrow();
+                    throw;
                 }
-#endif  // _LIBCPP_NO_EXCEPTIONS
             }
-            else
-                this->setstate(ios_base::failbit);
+#endif  // _LIBCPP_NO_EXCEPTIONS
         }
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        this->__set_badbit_and_consider_rethrow();
+        else
+        {
+            __state |= ios_base::failbit;
+        }
+        this->setstate(__state);
     }
-#endif  // _LIBCPP_NO_EXCEPTIONS
     return *this;
 }
 
@@ -727,28 +749,34 @@ template<class _CharT, class _Traits>
 typename basic_istream<_CharT, _Traits>::int_type
 basic_istream<_CharT, _Traits>::get()
 {
+    ios_base::iostate __state = ios_base::goodbit;
     __gc_ = 0;
     int_type __r = traits_type::eof();
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __s(*this, true);
+    if (__s)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __s(*this, true);
-        if (__s)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif
             __r = this->rdbuf()->sbumpc();
             if (traits_type::eq_int_type(__r, traits_type::eof()))
-               this->setstate(ios_base::failbit | ios_base::eofbit);
+               __state |= ios_base::failbit | ios_base::eofbit;
             else
                 __gc_ = 1;
-        }
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            this->__setstate_nothrow(this->rdstate() | ios_base::badbit);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif
+        this->setstate(__state);
     }
-    catch (...)
-    {
-        this->__set_badbit_and_consider_rethrow();
-    }
-#endif  // _LIBCPP_NO_EXCEPTIONS
     return __r;
 }
 
@@ -756,23 +784,23 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __dlm)
 {
+    ios_base::iostate __state = ios_base::goodbit;
     __gc_ = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __sen(*this, true);
-        if (__sen)
+        if (__n > 0)
         {
-            if (__n > 0)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            try
             {
-                ios_base::iostate __err = ios_base::goodbit;
+#endif
                 while (__gc_ < __n-1)
                 {
                     int_type __i = this->rdbuf()->sgetc();
                     if (traits_type::eq_int_type(__i, traits_type::eof()))
                     {
-                       __err |= ios_base::eofbit;
+                       __state |= ios_base::eofbit;
                        break;
                     }
                     char_type __ch = traits_type::to_char_type(__i);
@@ -783,23 +811,33 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __
                      this->rdbuf()->sbumpc();
                 }
                 if (__gc_ == 0)
-                   __err |= ios_base::failbit;
-                this->setstate(__err);
+                   __state |= ios_base::failbit;
+#ifndef _LIBCPP_NO_EXCEPTIONS
             }
-            else
-                this->setstate(ios_base::failbit);
+            catch (...)
+            {
+                __state |= ios_base::badbit;
+                this->__setstate_nothrow(__state);
+                if (this->exceptions() & ios_base::badbit)
+                {
+                    if (__n > 0)
+                        *__s = char_type();
+                    throw;
+                }
+            }
+#endif
         }
+        else
+        {
+            __state |= ios_base::failbit;
+        }
+
         if (__n > 0)
             *__s = char_type();
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        if (__n > 0)
-            *__s = char_type();
-        this->__set_badbit_and_consider_rethrow();
+        this->setstate(__state);
     }
-#endif  // _LIBCPP_NO_EXCEPTIONS
+    if (__n > 0)
+        *__s = char_type();
     return *this;
 }
 
@@ -808,52 +846,43 @@ basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb,
                                     char_type __dlm)
 {
+    ios_base::iostate __state = ios_base::goodbit;
     __gc_ = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __sen(*this, true);
-        if (__sen)
-        {
-            ios_base::iostate __err = ios_base::goodbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
-            try
-            {
+        try
+        {
 #endif  // _LIBCPP_NO_EXCEPTIONS
-                while (true)
+            while (true)
+            {
+                typename traits_type::int_type __i = this->rdbuf()->sgetc();
+                if (traits_type::eq_int_type(__i, traits_type::eof()))
                 {
-                    typename traits_type::int_type __i = this->rdbuf()->sgetc();
-                    if (traits_type::eq_int_type(__i, traits_type::eof()))
-                    {
-                       __err |= ios_base::eofbit;
-                       break;
-                    }
-                    char_type __ch = traits_type::to_char_type(__i);
-                    if (traits_type::eq(__ch, __dlm))
-                        break;
-                    if (traits_type::eq_int_type(__sb.sputc(__ch), traits_type::eof()))
-                        break;
-                    ++__gc_;
-                    this->rdbuf()->sbumpc();
+                   __state |= ios_base::eofbit;
+                   break;
                 }
-#ifndef _LIBCPP_NO_EXCEPTIONS
-            }
-            catch (...)
-            {
+                char_type __ch = traits_type::to_char_type(__i);
+                if (traits_type::eq(__ch, __dlm))
+                    break;
+                if (traits_type::eq_int_type(__sb.sputc(__ch), traits_type::eof()))
+                    break;
+                ++__gc_;
+                this->rdbuf()->sbumpc();
             }
-#endif  // _LIBCPP_NO_EXCEPTIONS
-            if (__gc_ == 0)
-               __err |= ios_base::failbit;
-            this->setstate(__err);
-        }
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        this->__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            // according to the spec, exceptions here are caught but not rethrown
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        if (__gc_ == 0)
+           __state |= ios_base::failbit;
+        this->setstate(__state);
+    }
     return *this;
 }
 
@@ -861,21 +890,21 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_type __dlm)
 {
+    ios_base::iostate __state = ios_base::goodbit;
     __gc_ = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
-            ios_base::iostate __err = ios_base::goodbit;
+#endif  // _LIBCPP_NO_EXCEPTIONS
             while (true)
             {
                 typename traits_type::int_type __i = this->rdbuf()->sgetc();
                 if (traits_type::eq_int_type(__i, traits_type::eof()))
                 {
-                   __err |= ios_base::eofbit;
+                   __state |= ios_base::eofbit;
                    break;
                 }
                 char_type __ch = traits_type::to_char_type(__i);
@@ -887,28 +916,35 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ
                 }
                 if (__gc_ >= __n-1)
                 {
-                    __err |= ios_base::failbit;
+                    __state |= ios_base::failbit;
                     break;
                 }
                 *__s++ = __ch;
                 this->rdbuf()->sbumpc();
                 ++__gc_;
             }
-            if (__gc_ == 0)
-               __err |= ios_base::failbit;
-            this->setstate(__err);
-        }
-        if (__n > 0)
-            *__s = char_type();
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        if (__n > 0)
-            *__s = char_type();
-        this->__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                if (__n > 0)
+                    *__s = char_type();
+                if (__gc_ == 0)
+                    __state |= ios_base::failbit;
+                throw;
+            }
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+    if (__n > 0)
+        *__s = char_type();
+    if (__gc_ == 0)
+        __state |= ios_base::failbit;
+    this->setstate(__state);
     return *this;
 }
 
@@ -916,15 +952,15 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
 {
+    ios_base::iostate __state = ios_base::goodbit;
     __gc_ = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
-            ios_base::iostate __err = ios_base::goodbit;
+#endif  // _LIBCPP_NO_EXCEPTIONS
             if (__n == numeric_limits<streamsize>::max())
             {
                 while (true)
@@ -932,7 +968,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
                     typename traits_type::int_type __i = this->rdbuf()->sbumpc();
                     if (traits_type::eq_int_type(__i, traits_type::eof()))
                     {
-                       __err |= ios_base::eofbit;
+                       __state |= ios_base::eofbit;
                        break;
                     }
                     ++__gc_;
@@ -947,7 +983,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
                     typename traits_type::int_type __i = this->rdbuf()->sbumpc();
                     if (traits_type::eq_int_type(__i, traits_type::eof()))
                     {
-                       __err |= ios_base::eofbit;
+                       __state |= ios_base::eofbit;
                        break;
                     }
                     ++__gc_;
@@ -955,15 +991,20 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
                         break;
                 }
             }
-            this->setstate(__err);
-        }
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        this->__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        this->setstate(__state);
+    }
     return *this;
 }
 
@@ -971,26 +1012,33 @@ template<class _CharT, class _Traits>
 typename basic_istream<_CharT, _Traits>::int_type
 basic_istream<_CharT, _Traits>::peek()
 {
+    ios_base::iostate __state = ios_base::goodbit;
     __gc_ = 0;
     int_type __r = traits_type::eof();
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             __r = this->rdbuf()->sgetc();
             if (traits_type::eq_int_type(__r, traits_type::eof()))
-                this->setstate(ios_base::eofbit);
-        }
+                __state |= ios_base::eofbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        this->__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        this->setstate(__state);
+    }
     return __r;
 }
 
@@ -998,27 +1046,36 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n)
 {
+    ios_base::iostate __state = ios_base::goodbit;
     __gc_ = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             __gc_ = this->rdbuf()->sgetn(__s, __n);
             if (__gc_ != __n)
-                this->setstate(ios_base::failbit | ios_base::eofbit);
-        }
-        else
-            this->setstate(ios_base::failbit);
+                __state |= ios_base::failbit | ios_base::eofbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
     }
-    catch (...)
+    else
     {
-        this->__set_badbit_and_consider_rethrow();
+        __state |= ios_base::failbit;
     }
-#endif  // _LIBCPP_NO_EXCEPTIONS
+    this->setstate(__state);
     return *this;
 }
 
@@ -1026,36 +1083,48 @@ template<class _CharT, class _Traits>
 streamsize
 basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
 {
+    ios_base::iostate __state = ios_base::goodbit;
     __gc_ = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             streamsize __c = this->rdbuf()->in_avail();
             switch (__c)
             {
             case -1:
-                this->setstate(ios_base::eofbit);
+                __state |= ios_base::eofbit;
                 break;
             case 0:
                 break;
             default:
-                read(__s, _VSTD::min(__c, __n));
+                __n = _VSTD::min(__c, __n);
+                __gc_ = this->rdbuf()->sgetn(__s, __n);
+                if (__gc_ != __n)
+                    __state |= ios_base::failbit | ios_base::eofbit;
                 break;
             }
-        }
-        else
-            this->setstate(ios_base::failbit);
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
     }
-    catch (...)
+    else
     {
-        this->__set_badbit_and_consider_rethrow();
+        __state |= ios_base::failbit;
     }
-#endif  // _LIBCPP_NO_EXCEPTIONS
+    this->setstate(__state);
     return __gc_;
 }
 
@@ -1063,27 +1132,36 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::putback(char_type __c)
 {
+    ios_base::iostate __state = this->rdstate() & ~ios_base::eofbit;
     __gc_ = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    this->clear(__state);
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        this->clear(this->rdstate() & ~ios_base::eofbit);
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             if (this->rdbuf() == 0 || this->rdbuf()->sputbackc(__c) == traits_type::eof())
-                this->setstate(ios_base::badbit);
-        }
-        else
-            this->setstate(ios_base::failbit);
+                __state |= ios_base::badbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
     }
-    catch (...)
+    else
     {
-        this->__set_badbit_and_consider_rethrow();
+        __state |= ios_base::failbit;
     }
-#endif  // _LIBCPP_NO_EXCEPTIONS
+    this->setstate(__state);
     return *this;
 }
 
@@ -1091,27 +1169,36 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::unget()
 {
+    ios_base::iostate __state = this->rdstate() & ~ios_base::eofbit;
     __gc_ = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    this->clear(__state);
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        this->clear(this->rdstate() & ~ios_base::eofbit);
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             if (this->rdbuf() == 0 || this->rdbuf()->sungetc() == traits_type::eof())
-                this->setstate(ios_base::badbit);
-        }
-        else
-            this->setstate(ios_base::failbit);
+                __state |= ios_base::badbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
     }
-    catch (...)
+    else
     {
-        this->__set_badbit_and_consider_rethrow();
+        __state |= ios_base::failbit;
     }
-#endif  // _LIBCPP_NO_EXCEPTIONS
+    this->setstate(__state);
     return *this;
 }
 
@@ -1119,29 +1206,36 @@ template<class _CharT, class _Traits>
 int
 basic_istream<_CharT, _Traits>::sync()
 {
+    ios_base::iostate __state = ios_base::goodbit;
     int __r = 0;
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             if (this->rdbuf() == 0)
                 return -1;
             if (this->rdbuf()->pubsync() == -1)
             {
-                this->setstate(ios_base::badbit);
+                __state |= ios_base::badbit;
                 return -1;
             }
-        }
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        this->__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        this->setstate(__state);
+    }
     return __r;
 }
 
@@ -1149,21 +1243,30 @@ template<class _CharT, class _Traits>
 typename basic_istream<_CharT, _Traits>::pos_type
 basic_istream<_CharT, _Traits>::tellg()
 {
+    ios_base::iostate __state = ios_base::goodbit;
     pos_type __r(-1);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    sentry __sen(*this, true);
+    if (__sen)
     {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
 #endif  // _LIBCPP_NO_EXCEPTIONS
-        sentry __sen(*this, true);
-        if (__sen)
-            __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
+        __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        this->__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        this->setstate(__state);
+    }
     return __r;
 }
 
@@ -1171,24 +1274,31 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::seekg(pos_type __pos)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = this->rdstate() & ~ios_base::eofbit;
+    this->clear(__state);
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        this->clear(this->rdstate() & ~ios_base::eofbit);
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1))
-                this->setstate(ios_base::failbit);
-        }
+                __state |= ios_base::failbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        this->__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        this->setstate(__state);
+    }
     return *this;
 }
 
@@ -1196,24 +1306,31 @@ template<class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = this->rdstate() & ~ios_base::eofbit;
+    this->clear(__state);
+    sentry __sen(*this, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        this->clear(this->rdstate() & ~ios_base::eofbit);
-        sentry __sen(*this, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1))
-                this->setstate(ios_base::failbit);
-        }
+                __state |= ios_base::failbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        this->__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            this->__setstate_nothrow(__state);
+            if (this->exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        this->setstate(__state);
+    }
     return *this;
 }
 
@@ -1221,34 +1338,41 @@ template <class _CharT, class _Traits>
 basic_istream<_CharT, _Traits>&
 ws(basic_istream<_CharT, _Traits>& __is)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = ios_base::goodbit;
+    typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif  // _LIBCPP_NO_EXCEPTIONS
             const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
             while (true)
             {
                 typename _Traits::int_type __i = __is.rdbuf()->sgetc();
                 if (_Traits::eq_int_type(__i, _Traits::eof()))
                 {
-                   __is.setstate(ios_base::eofbit);
+                   __state |= ios_base::eofbit;
                    break;
                 }
                 if (!__ct.is(__ct.space, _Traits::to_char_type(__i)))
                     break;
                 __is.rdbuf()->sbumpc();
             }
-        }
 #ifndef _LIBCPP_NO_EXCEPTIONS
-    }
-    catch (...)
-    {
-        __is.__set_badbit_and_consider_rethrow();
-    }
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            __is.__setstate_nothrow(__state);
+            if (__is.exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        __is.setstate(__state);
+    }
     return __is;
 }
 
@@ -1327,13 +1451,14 @@ basic_istream<_CharT, _Traits>&
 operator>>(basic_istream<_CharT, _Traits>& __is,
            basic_string<_CharT, _Traits, _Allocator>& __str)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = ios_base::goodbit;
+    typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif
             __str.clear();
             streamsize __n = __is.width();
             if (__n <= 0)
@@ -1342,13 +1467,12 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
                 __n = numeric_limits<streamsize>::max();
             streamsize __c = 0;
             const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
-            ios_base::iostate __err = ios_base::goodbit;
             while (__c < __n)
             {
                 typename _Traits::int_type __i = __is.rdbuf()->sgetc();
                 if (_Traits::eq_int_type(__i, _Traits::eof()))
                 {
-                   __err |= ios_base::eofbit;
+                   __state |= ios_base::eofbit;
                    break;
                 }
                 _CharT __ch = _Traits::to_char_type(__i);
@@ -1360,18 +1484,21 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
             }
             __is.width(0);
             if (__c == 0)
-               __err |= ios_base::failbit;
-            __is.setstate(__err);
-        }
-        else
-            __is.setstate(ios_base::failbit);
+               __state |= ios_base::failbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            __is.__setstate_nothrow(__state);
+            if (__is.exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif
+        __is.setstate(__state);
     }
-    catch (...)
-    {
-        __is.__set_badbit_and_consider_rethrow();
-    }
-#endif  // _LIBCPP_NO_EXCEPTIONS
     return __is;
 }
 
@@ -1380,22 +1507,22 @@ basic_istream<_CharT, _Traits>&
 getline(basic_istream<_CharT, _Traits>& __is,
         basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = ios_base::goodbit;
+    typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif
             __str.clear();
-            ios_base::iostate __err = ios_base::goodbit;
             streamsize __extr = 0;
             while (true)
             {
                 typename _Traits::int_type __i = __is.rdbuf()->sbumpc();
                 if (_Traits::eq_int_type(__i, _Traits::eof()))
                 {
-                   __err |= ios_base::eofbit;
+                   __state |= ios_base::eofbit;
                    break;
                 }
                 ++__extr;
@@ -1405,21 +1532,26 @@ getline(basic_istream<_CharT, _Traits>& __is,
                 __str.push_back(__ch);
                 if (__str.size() == __str.max_size())
                 {
-                    __err |= ios_base::failbit;
+                    __state |= ios_base::failbit;
                     break;
                 }
             }
             if (__extr == 0)
-               __err |= ios_base::failbit;
-            __is.setstate(__err);
-        }
+               __state |= ios_base::failbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            __is.__setstate_nothrow(__state);
+            if (__is.exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif
+        __is.setstate(__state);
     }
-    catch (...)
-    {
-        __is.__set_badbit_and_consider_rethrow();
-    }
-#endif  // _LIBCPP_NO_EXCEPTIONS
     return __is;
 }
 
@@ -1458,17 +1590,17 @@ template <class _CharT, class _Traits, size_t _Size>
 basic_istream<_CharT, _Traits>&
 operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
 {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    try
+    ios_base::iostate __state = ios_base::goodbit;
+    typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
+    if (__sen)
     {
-#endif  // _LIBCPP_NO_EXCEPTIONS
-        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
-        if (__sen)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
         {
+#endif
             basic_string<_CharT, _Traits> __str;
             const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
             size_t __c = 0;
-            ios_base::iostate __err = ios_base::goodbit;
             _CharT __zero = __ct.widen('0');
             _CharT __one = __ct.widen('1');
             while (__c < _Size)
@@ -1476,7 +1608,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
                 typename _Traits::int_type __i = __is.rdbuf()->sgetc();
                 if (_Traits::eq_int_type(__i, _Traits::eof()))
                 {
-                   __err |= ios_base::eofbit;
+                   __state |= ios_base::eofbit;
                    break;
                 }
                 _CharT __ch = _Traits::to_char_type(__i);
@@ -1488,18 +1620,21 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
             }
             __x = bitset<_Size>(__str);
             if (__c == 0)
-               __err |= ios_base::failbit;
-            __is.setstate(__err);
-        }
-        else
-            __is.setstate(ios_base::failbit);
+               __state |= ios_base::failbit;
 #ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __state |= ios_base::badbit;
+            __is.__setstate_nothrow(__state);
+            if (__is.exceptions() & ios_base::badbit)
+            {
+                throw;
+            }
+        }
+#endif
+        __is.setstate(__state);
     }
-    catch (...)
-    {
-        __is.__set_badbit_and_consider_rethrow();
-    }
-#endif  // _LIBCPP_NO_EXCEPTIONS
     return __is;
 }
 
index 799ec5e..e9df54f 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            bool n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            bool n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 9f9872d..615765c 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            double n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            double n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index c2b937a..72fd7ed 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            float n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            float n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 702287b..d099fa8 100644 (file)
@@ -16,6 +16,7 @@
 #include <istream>
 #include <limits>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -76,6 +77,44 @@ int main(int, char**)
         assert(!is.eof());
         assert( is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            int n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            int n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 9f9118c..a517406 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            long n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            long n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index bdd3019..769e9a3 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            long double n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            long double n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 1612468..dff93d1 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            long long n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            long long n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 0893d8c..f88be1b 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -97,6 +98,44 @@ int main(int, char**)
         assert( is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            void* n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            void* n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index a0d96c3..56ab584 100644 (file)
@@ -16,6 +16,7 @@
 #include <istream>
 #include <limits>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -76,6 +77,44 @@ int main(int, char**)
         assert(!is.eof());
         assert( is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            short n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            short n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 578cfcf..79d3dcb 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            unsigned int n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            unsigned int n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index f1c150d..10e2fab 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            unsigned long n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            unsigned long n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 068d31a..9a73e87 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            unsigned long long n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            unsigned long long n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 9906bbe..c4d95f5 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,44 @@ int main(int, char**)
         assert(!is.eof());
         assert(!is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            unsigned short n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            unsigned short n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index cbb606c..15f26fc 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -83,6 +84,80 @@ int main(int, char**)
         assert(!is.fail());
         assert(c == L'c');
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            char n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            wchar_t n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            char n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            wchar_t n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index bd06de6..d5ae909 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -66,6 +67,44 @@ int main(int, char**)
         assert(!is.fail());
         assert(c == 'c');
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            signed char n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            signed char n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index d512833..64ff48d 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -103,6 +104,46 @@ int main(int, char**)
         assert(std::string((char*)s) == "");
     }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            signed char s[20];
+            is.width(10);
+            is >> s;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            signed char s[20];
+            is.width(10);
+            is >> s;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 9feb826..bf244e1 100644 (file)
 // template <class charT, class traits = char_traits<charT> >
 //   class basic_istream;
 
-// basic_istream<charT,traits>& operator<<(basic_streambuf<charT,traits>* sb);
+// basic_istream<charT,traits>& operator>>(basic_streambuf<charT,traits>* sb);
 
 #include <istream>
 #include <cassert>
 
+#include "test_macros.h"
+
 template <class CharT>
 class testbuf
     : public std::basic_streambuf<CharT>
@@ -65,6 +67,104 @@ int main(int, char**)
         assert(sb2.str() == "testing...");
         assert(is.gcount() == 10);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb(" ");
+        std::basic_istream<char> is(&sb);
+        testbuf<char> sb2;
+        is.exceptions(std::istream::eofbit);
+        bool threw = false;
+        try {
+            is >> &sb2;
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+    {
+        testbuf<wchar_t> sb(L" ");
+        std::basic_istream<wchar_t> is(&sb);
+        testbuf<wchar_t> sb2;
+        is.exceptions(std::istream::eofbit);
+        bool threw = false;
+        try {
+            is >> &sb2;
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        testbuf<char> sb2;
+        is.exceptions(std::istream::failbit);
+        bool threw = false;
+        try {
+            is >> &sb2;
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        testbuf<wchar_t> sb2;
+        is.exceptions(std::istream::failbit);
+        bool threw = false;
+        try {
+            is >> &sb2;
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+    }
+
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::istream::failbit);
+        bool threw = false;
+        try {
+            is >> static_cast<testbuf<char>*>(0);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert(!is.eof());
+        assert( is.fail());
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::istream::failbit);
+        bool threw = false;
+        try {
+            is >> static_cast<testbuf<wchar_t>*>(0);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert(!is.eof());
+        assert( is.fail());
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 3eceaae..8d86d11 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -66,6 +67,44 @@ int main(int, char**)
         assert(!is.fail());
         assert(c == 'c');
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            unsigned char n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            unsigned char n = 0;
+            is >> n;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 14b2993..7e4bf41 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -103,6 +104,46 @@ int main(int, char**)
         assert(std::string((char*)s) == "");
     }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            unsigned char s[20];
+            is.width(10);
+            is >> s;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            unsigned char s[20];
+            is.width(10);
+            is >> s;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index f0a9e07..117a0ba 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -114,6 +115,84 @@ int main(int, char**)
         assert(std::string(s) == "");
     }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            char s[20];
+            is.width(10);
+            is >> s;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::wistream is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        bool threw = false;
+        try {
+            wchar_t s[20];
+            is.width(10);
+            is >> s;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            char s[20];
+            is.width(10);
+            is >> s;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::wistream is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            wchar_t s[20];
+            is.width(10);
+            is >> s;
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 6786ebf..0eaf58b 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -75,6 +76,42 @@ int main(int, char**)
         assert(is.eof());
         assert(is.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb("  ");
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            std::ws(is);
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(!is.fail());
+        assert( is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<wchar_t> sb(L"  ");
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            std::ws(is);
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(!is.fail());
+        assert( is.eof());
+        assert(threw);
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 40a0417..788e215 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -96,6 +97,50 @@ int main(int, char**)
         assert(c == L'c');
         assert(is.gcount() == 1);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb("rrrrrrrrr");
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            while (true) {
+                is.get();
+                if (is.eof())
+                    break;
+            }
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert( is.fail());
+        assert( is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<wchar_t> sb(L"rrrrrrrrr");
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            while (true) {
+                is.get();
+                if (is.eof())
+                    break;
+            }
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert( is.fail());
+        assert( is.eof());
+        assert(threw);
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index ae31c9b..7b5e56d 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -99,6 +100,52 @@ int main(int, char**)
         assert(c == L'c');
         assert(is.gcount() == 1);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb("rrrrrrrrr");
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            while (true) {
+                char c;
+                is.get(c);
+                if (is.eof())
+                    break;
+            }
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert( is.fail());
+        assert( is.eof());
+        assert(threw);
+    }
+    {
+        testbuf<wchar_t> sb(L"rrrrrrrrr");
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        bool threw = false;
+        try {
+            while (true) {
+                wchar_t c;
+                is.get(c);
+                if (is.eof())
+                    break;
+            }
+        } catch (std::ios_base::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert( is.fail());
+        assert( is.eof());
+        assert(threw);
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 149392c..2a88b72 100644 (file)
@@ -84,26 +84,6 @@ int main(int, char**)
         assert(std::string(s) == "");
         assert(is.gcount() == 0);
     }
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    {
-        testbuf<char> sb(" ");
-        std::istream is(&sb);
-        char s[5] = "test";
-        is.exceptions(std::istream::eofbit | std::istream::badbit);
-        try
-        {
-            is.get(s, 5);
-            assert(false);
-        }
-        catch (std::ios_base::failure&)
-        {
-        }
-        assert( is.eof());
-        assert( is.fail());
-        assert(std::string(s) == " ");
-        assert(is.gcount() == 1);
-    }
-#endif
     {
         testbuf<wchar_t> sb(L"  \n    \n ");
         std::wistream is(&sb);
@@ -140,23 +120,78 @@ int main(int, char**)
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
     {
+        testbuf<char> sb(" ");
+        std::basic_istream<char> is(&sb);
+        char s[5] = "test";
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(s, 5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+        assert(threw);
+        assert(std::string(s) == " ");
+        assert(is.gcount() == 1);
+    }
+    {
         testbuf<wchar_t> sb(L" ");
-        std::wistream is(&sb);
+        std::basic_istream<wchar_t> is(&sb);
         wchar_t s[5] = L"test";
-        is.exceptions(std::wistream::eofbit | std::wistream::badbit);
-        try
-        {
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
             is.get(s, 5);
-            assert(false);
-        }
-        catch (std::ios_base::failure&)
-        {
+        } catch (std::ios_base::failure&) {
+            threw = true;
         }
+        assert(!is.bad());
         assert( is.eof());
-        assert( is.fail());
+        assert(!is.fail());
+        assert(threw);
         assert(std::wstring(s) == L" ");
         assert(is.gcount() == 1);
     }
+
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        char s[5] = "test";
+        is.exceptions(std::ios_base::failbit);
+        bool threw = false;
+        try {
+            is.get(s, 5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+        assert(threw);
+        assert(std::basic_string<char>(s) == "");
+        assert(is.gcount() == 0);
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        wchar_t s[5] = L"test";
+        is.exceptions(std::ios_base::failbit);
+        bool threw = false;
+        try {
+            is.get(s, 5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+        assert(threw);
+        assert(std::basic_string<wchar_t>(s) == L"");
+        assert(is.gcount() == 0);
+    }
 #endif
 
   return 0;
index e7c96d6..df8ccc8 100644 (file)
@@ -84,26 +84,6 @@ int main(int, char**)
         assert(std::string(s) == "");
         assert(is.gcount() == 0);
     }
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    {
-        testbuf<char> sb(" ");
-        std::istream is(&sb);
-        char s[5] = "test";
-        is.exceptions(std::istream::eofbit | std::istream::badbit);
-        try
-        {
-            is.get(s, 5, '*');
-            assert(false);
-        }
-        catch (std::ios_base::failure&)
-        {
-        }
-        assert( is.eof());
-        assert( is.fail());
-        assert(std::string(s) == " ");
-        assert(is.gcount() == 1);
-    }
-#endif
     {
         testbuf<wchar_t> sb(L"  *    * ");
         std::wistream is(&sb);
@@ -140,22 +120,77 @@ int main(int, char**)
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
     {
+        testbuf<char> sb(" ");
+        std::basic_istream<char> is(&sb);
+        char s[5] = "test";
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(s, 5, '*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+        assert(threw);
+        assert(std::basic_string<char>(s) == " ");
+        assert(is.gcount() == 1);
+    }
+    {
         testbuf<wchar_t> sb(L" ");
-        std::wistream is(&sb);
+        std::basic_istream<wchar_t> is(&sb);
         wchar_t s[5] = L"test";
-        is.exceptions(std::wistream::eofbit | std::wistream::badbit);
-        try
-        {
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
             is.get(s, 5, L'*');
-            assert(false);
+        } catch (std::ios_base::failure&) {
+            threw = true;
         }
-        catch (std::ios_base::failure&)
-        {
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+        assert(threw);
+        assert(std::basic_string<wchar_t>(s) == L" ");
+        assert(is.gcount() == 1);
+    }
+
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        char s[5] = "test";
+        is.exceptions(std::ios_base::failbit);
+        bool threw = false;
+        try {
+            is.get(s, 5, '*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
         }
+        assert(!is.bad());
         assert( is.eof());
         assert( is.fail());
-        assert(std::wstring(s) == L" ");
-        assert(is.gcount() == 1);
+        assert(threw);
+        assert(std::basic_string<char>(s) == "");
+        assert(is.gcount() == 0);
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        wchar_t s[5] = L"test";
+        is.exceptions(std::ios_base::failbit);
+        bool threw = false;
+        try {
+            is.get(s, 5, L'*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+        assert(threw);
+        assert(std::basic_string<wchar_t>(s) == L"");
+        assert(is.gcount() == 0);
     }
 #endif
 
index dda59d7..f34873c 100644 (file)
@@ -13,6 +13,8 @@
 #include <istream>
 #include <cassert>
 
+#include "test_macros.h"
+
 template <class CharT>
 class testbuf
     : public std::basic_streambuf<CharT>
@@ -84,6 +86,73 @@ int main(int, char**)
         assert(!is.fail());
         assert(is.gcount() == 3);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb(" ");
+        std::basic_istream<char> is(&sb);
+        testbuf<char> sb2;
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(sb2);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+    {
+        testbuf<wchar_t> sb(L" ");
+        std::basic_istream<wchar_t> is(&sb);
+        testbuf<wchar_t> sb2;
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(sb2);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        testbuf<char> sb2;
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(sb2);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        testbuf<wchar_t> sb2;
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(sb2);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index a1e46c2..adef49b 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 class testbuf
@@ -85,6 +86,73 @@ int main(int, char**)
         assert(!is.fail());
         assert(is.gcount() == 3);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb(" ");
+        std::basic_istream<char> is(&sb);
+        testbuf<char> sb2;
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(sb2, '*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+    {
+        testbuf<wchar_t> sb(L" ");
+        std::basic_istream<wchar_t> is(&sb);
+        testbuf<wchar_t> sb2;
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(sb2, L'*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        testbuf<char> sb2;
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(sb2, '*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        testbuf<wchar_t> sb2;
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.get(sb2, L'*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 9c91053..de54bf4 100644 (file)
@@ -76,26 +76,6 @@ int main(int, char**)
         assert(std::string(s) == "");
         assert(is.gcount() == 0);
     }
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    {
-        testbuf<char> sb(" ");
-        std::istream is(&sb);
-        char s[5] = "test";
-        is.exceptions(std::istream::eofbit | std::istream::badbit);
-        try
-        {
-            is.getline(s, 5);
-            assert(false);
-        }
-        catch (std::ios_base::failure&)
-        {
-        }
-        assert( is.eof());
-        assert( is.fail());
-        assert(std::string(s) == " ");
-        assert(is.gcount() == 1);
-    }
-#endif
     {
         testbuf<wchar_t> sb(L"  \n    \n ");
         std::wistream is(&sb);
@@ -124,22 +104,77 @@ int main(int, char**)
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
     {
+        testbuf<char> sb(" ");
+        std::basic_istream<char> is(&sb);
+        char s[5] = "test";
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.getline(s, 5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+        assert(threw);
+        assert(std::basic_string<char>(s) == " ");
+        assert(is.gcount() == 1);
+    }
+    {
         testbuf<wchar_t> sb(L" ");
-        std::wistream is(&sb);
+        std::basic_istream<wchar_t> is(&sb);
         wchar_t s[5] = L"test";
-        is.exceptions(std::wistream::eofbit | std::wistream::badbit);
-        try
-        {
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
             is.getline(s, 5);
-            assert(false);
+        } catch (std::ios_base::failure&) {
+            threw = true;
         }
-        catch (std::ios_base::failure&)
-        {
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+        assert(threw);
+        assert(std::basic_string<wchar_t>(s) == L" ");
+        assert(is.gcount() == 1);
+    }
+
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        char s[5] = "test";
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.getline(s, 5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
         }
+        assert(!is.bad());
         assert( is.eof());
         assert( is.fail());
-        assert(std::wstring(s) == L" ");
-        assert(is.gcount() == 1);
+        assert(threw);
+        assert(std::basic_string<char>(s) == "");
+        assert(is.gcount() == 0);
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        wchar_t s[5] = L"test";
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.getline(s, 5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+        assert(threw);
+        assert(std::basic_string<wchar_t>(s) == L"");
+        assert(is.gcount() == 0);
     }
 #endif
 
index bee1976..de19167 100644 (file)
@@ -76,26 +76,6 @@ int main(int, char**)
         assert(std::string(s) == "");
         assert(is.gcount() == 0);
     }
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    {
-        testbuf<char> sb(" ");
-        std::istream is(&sb);
-        char s[5] = "test";
-        is.exceptions(std::istream::eofbit | std::istream::badbit);
-        try
-        {
-            is.getline(s, 5, '*');
-            assert(false);
-        }
-        catch (std::ios_base::failure&)
-        {
-        }
-        assert( is.eof());
-        assert( is.fail());
-        assert(std::string(s) == " ");
-        assert(is.gcount() == 1);
-    }
-#endif
     {
         testbuf<wchar_t> sb(L"  *    * ");
         std::wistream is(&sb);
@@ -124,22 +104,77 @@ int main(int, char**)
     }
 #ifndef TEST_HAS_NO_EXCEPTIONS
     {
+        testbuf<char> sb(" ");
+        std::basic_istream<char> is(&sb);
+        char s[5] = "test";
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.getline(s, 5, '*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+        assert(threw);
+        assert(std::basic_string<char>(s) == " ");
+        assert(is.gcount() == 1);
+    }
+    {
         testbuf<wchar_t> sb(L" ");
-        std::wistream is(&sb);
+        std::basic_istream<wchar_t> is(&sb);
         wchar_t s[5] = L"test";
-        is.exceptions(std::wistream::eofbit | std::wistream::badbit);
-        try
-        {
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
             is.getline(s, 5, L'*');
-            assert(false);
+        } catch (std::ios_base::failure&) {
+            threw = true;
         }
-        catch (std::ios_base::failure&)
-        {
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+        assert(threw);
+        assert(std::basic_string<wchar_t>(s) == L" ");
+        assert(is.gcount() == 1);
+    }
+
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        char s[5] = "test";
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.getline(s, 5, '*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
         }
+        assert(!is.bad());
         assert( is.eof());
         assert( is.fail());
-        assert(std::wstring(s) == L" ");
-        assert(is.gcount() == 1);
+        assert(threw);
+        assert(std::basic_string<char>(s) == "");
+        assert(is.gcount() == 0);
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        wchar_t s[5] = L"test";
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.getline(s, 5, L'*');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+        assert(threw);
+        assert(std::basic_string<wchar_t>(s) == L"");
+        assert(is.gcount() == 0);
     }
 #endif
 
index 7f6348b..6283162 100644 (file)
@@ -14,6 +14,8 @@
 #include <istream>
 #include <cassert>
 
+#include "test_macros.h"
+
 template <class CharT>
 struct testbuf
     : public std::basic_streambuf<CharT>
@@ -72,6 +74,38 @@ int main(int, char**)
         assert(!is.fail());
         assert(is.gcount() == 6);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb(" ");
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.ignore(5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+    {
+        testbuf<wchar_t> sb(L" ");
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.ignore(5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 1794346..2d09932 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -65,6 +66,38 @@ int main(int, char**)
         assert(!is.fail());
         assert(is.gcount() == 0);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.peek();
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+        bool threw = false;
+        try {
+            is.peek();
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert(!is.fail());
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 4ca3a8c..588c0a6 100644 (file)
@@ -13,6 +13,8 @@
 #include <istream>
 #include <cassert>
 
+#include "test_macros.h"
+
 template <class CharT>
 struct testbuf
     : public std::basic_streambuf<CharT>
@@ -85,6 +87,38 @@ int main(int, char**)
         assert(is.bad());
         assert(is.gcount() == 0);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::badbit);
+        bool threw = false;
+        try {
+            is.putback('x');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert( is.bad());
+        assert(!is.eof());
+        assert( is.fail());
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::badbit);
+        bool threw = false;
+        try {
+            is.putback(L'x');
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert( is.bad());
+        assert(!is.eof());
+        assert( is.fail());
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 9296e0b..0ae8bcf 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <istream>
 #include <cassert>
+#include "test_macros.h"
 
 template <class CharT>
 struct testbuf
@@ -77,6 +78,40 @@ int main(int, char**)
         assert( is.fail());
         assert(is.gcount() == 0);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+        char s[10];
+        bool threw = false;
+        try {
+            is.read(s, 5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+        wchar_t s[10];
+        bool threw = false;
+        try {
+            is.read(s, 5);
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert(!is.bad());
+        assert( is.eof());
+        assert( is.fail());
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 43ddd81..ff22e98 100644 (file)
@@ -13,6 +13,8 @@
 #include <istream>
 #include <cassert>
 
+#include "test_macros.h"
+
 int sync_called = 0;
 
 template <class CharT>
@@ -46,6 +48,41 @@ protected:
     }
 };
 
+#ifndef TEST_HAS_NO_EXCEPTIONS
+struct testbuf_exception { };
+
+template <class CharT>
+struct throwing_testbuf
+    : public std::basic_streambuf<CharT>
+{
+    typedef std::basic_string<CharT> string_type;
+    typedef std::basic_streambuf<CharT> base;
+private:
+    string_type str_;
+public:
+
+    throwing_testbuf() {}
+    throwing_testbuf(const string_type& str)
+        : str_(str)
+    {
+        base::setg(const_cast<CharT*>(str_.data()),
+                   const_cast<CharT*>(str_.data()),
+                   const_cast<CharT*>(str_.data()) + str_.size());
+    }
+
+    CharT* eback() const {return base::eback();}
+    CharT* gptr() const {return base::gptr();}
+    CharT* egptr() const {return base::egptr();}
+
+protected:
+    virtual int sync()
+    {
+        throw testbuf_exception();
+        return 5;
+    }
+};
+#endif // TEST_HAS_NO_EXCEPTIONS
+
 int main(int, char**)
 {
     {
@@ -60,6 +97,36 @@ int main(int, char**)
         assert(is.sync() == 0);
         assert(sync_called == 2);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        throwing_testbuf<char> sb(" 123456789");
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::badbit);
+        bool threw = false;
+        try {
+            is.sync();
+        } catch (testbuf_exception const&) {
+            threw = true;
+        }
+        assert( is.bad());
+        assert(!is.eof());
+        assert( is.fail());
+    }
+    {
+        throwing_testbuf<wchar_t> sb(L" 123456789");
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::badbit);
+        bool threw = false;
+        try {
+            is.sync();
+        } catch (testbuf_exception const&) {
+            threw = true;
+        }
+        assert( is.bad());
+        assert(!is.eof());
+        assert( is.fail());
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index ca00af4..b48ff86 100644 (file)
@@ -13,6 +13,8 @@
 #include <istream>
 #include <cassert>
 
+#include "test_macros.h"
+
 template <class CharT>
 struct testbuf
     : public std::basic_streambuf<CharT>
@@ -77,6 +79,38 @@ int main(int, char**)
         assert(is.bad());
         assert(is.gcount() == 0);
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        testbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::badbit);
+        bool threw = false;
+        try {
+            is.unget();
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert( is.bad());
+        assert(!is.eof());
+        assert( is.fail());
+    }
+    {
+        testbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::badbit);
+        bool threw = false;
+        try {
+            is.unget();
+        } catch (std::ios_base::failure&) {
+            threw = true;
+        }
+        assert(threw);
+        assert( is.bad());
+        assert(!is.eof());
+        assert( is.fail());
+    }
+#endif
 
-  return 0;
+    return 0;
 }
index 8e663cb..6069f8e 100644 (file)
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_macros.h"
 
 int main(int, char**)
 {
@@ -77,6 +78,85 @@ int main(int, char**)
         assert(s == L"   ghij");
     }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        std::basic_stringbuf<char> sb("hello");
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        std::basic_string<char> s;
+        bool threw = false;
+        try {
+            std::getline(is, s);
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(!is.fail());
+        assert( is.eof());
+        assert(threw);
+        assert(s == "hello");
+    }
+    {
+        std::basic_stringbuf<wchar_t> sb(L"hello");
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::eofbit);
+
+        std::basic_string<wchar_t> s;
+        bool threw = false;
+        try {
+            std::getline(is, s);
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(!is.fail());
+        assert( is.eof());
+        assert(threw);
+        assert(s == L"hello");
+    }
+
+    {
+        std::basic_stringbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        std::basic_string<char> s;
+        bool threw = false;
+        try {
+            std::getline(is, s);
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert( is.fail());
+        assert( is.eof());
+        assert(threw);
+        assert(s == "");
+    }
+    {
+        std::basic_stringbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios_base::failbit);
+
+        std::basic_string<wchar_t> s;
+        bool threw = false;
+        try {
+            std::getline(is, s);
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert( is.fail());
+        assert( is.eof());
+        assert(threw);
+        assert(s == L"");
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index b081b55..d7d271b 100644 (file)
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_macros.h"
 
 int main(int, char**)
 {
@@ -89,6 +90,84 @@ int main(int, char**)
         assert(s == L"   ghij");
     }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        std::basic_stringbuf<char> sb("hello");
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios::eofbit);
+
+        std::basic_string<char> s;
+        bool threw = false;
+        try {
+            std::getline(is, s, '\n');
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(!is.fail());
+        assert( is.eof());
+        assert(threw);
+        assert(s == "hello");
+    }
+    {
+        std::basic_stringbuf<wchar_t> sb(L"hello");
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios::eofbit);
+
+        std::basic_string<wchar_t> s;
+        bool threw = false;
+        try {
+            std::getline(is, s, L'\n');
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(!is.fail());
+        assert( is.eof());
+        assert(threw);
+        assert(s == L"hello");
+    }
+    {
+        std::basic_stringbuf<char> sb;
+        std::basic_istream<char> is(&sb);
+        is.exceptions(std::ios::failbit);
+
+        std::basic_string<char> s;
+        bool threw = false;
+        try {
+            std::getline(is, s, '\n');
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert( is.fail());
+        assert( is.eof());
+        assert(threw);
+        assert(s == "");
+    }
+    {
+        std::basic_stringbuf<wchar_t> sb;
+        std::basic_istream<wchar_t> is(&sb);
+        is.exceptions(std::ios::failbit);
+
+        std::basic_string<wchar_t> s;
+        bool threw = false;
+        try {
+            std::getline(is, s, L'\n');
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert( is.fail());
+        assert( is.eof());
+        assert(threw);
+        assert(s == L"");
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 
-  return 0;
+    return 0;
 }
index 389701d..92061e2 100644 (file)
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_macros.h"
 
 int main(int, char**)
 {
@@ -65,6 +66,44 @@ int main(int, char**)
         in >> s;
         assert(in.fail());
     }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        std::stringbuf sb;
+        std::istream is(&sb);
+        is.exceptions(std::ios::failbit);
+
+        bool threw = false;
+        try {
+            std::string s;
+            is >> s;
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        std::stringbuf sb;
+        std::istream is(&sb);
+        is.exceptions(std::ios::eofbit);
+
+        bool threw = false;
+        try {
+            std::string s;
+            is >> s;
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
 #if TEST_STD_VER >= 11
     {
         typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
index 9abe19c..1cb92ea 100644 (file)
@@ -9,19 +9,60 @@
 // test:
 
 // template <class charT, class traits, size_t N>
-// basic_ostream<charT, traits>&
-// operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
+// basic_istream<charT, traits>&
+// operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
 
 #include <bitset>
 #include <sstream>
 #include <cassert>
+#include "test_macros.h"
 
 int main(int, char**)
 {
-    std::istringstream in("01011010");
-    std::bitset<8> b;
-    in >> b;
-    assert(b.to_ulong() == 0x5A);
+    {
+        std::istringstream in("01011010");
+        std::bitset<8> b;
+        in >> b;
+        assert(b.to_ulong() == 0x5A);
+    }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    {
+        std::stringbuf sb;
+        std::istream is(&sb);
+        is.exceptions(std::ios::failbit);
 
-  return 0;
+        bool threw = false;
+        try {
+            std::bitset<8> b;
+            is >> b;
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+    {
+        std::stringbuf sb;
+        std::istream is(&sb);
+        is.exceptions(std::ios::eofbit);
+
+        bool threw = false;
+        try {
+            std::bitset<8> b;
+            is >> b;
+        } catch (std::ios::failure const&) {
+            threw = true;
+        }
+
+        assert(!is.bad());
+        assert(is.fail());
+        assert(is.eof());
+        assert(threw);
+    }
+#endif // TEST_HAS_NO_EXCEPTIONS
+
+    return 0;
 }
index 2c4ce1e..43c20f8 100644 (file)
@@ -9,8 +9,8 @@
 // test:
 
 // template <class charT, class traits, size_t N>
-// basic_istream<charT, traits>&
-// operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
 
 #include <bitset>
 #include <sstream>