Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85541 - in trunk: boost libs/rational/test
From: dwalker07_at_[hidden]
Date: 2013-09-01 06:54:47


Author: dlwalker
Date: 2013-09-01 06:54:47 EDT (Sun, 01 Sep 2013)
New Revision: 85541
URL: http://svn.boost.org/trac/boost/changeset/85541

Log:
Integrated Boost.Rational's sanity checks during assignment in the input operator, respecting IOStreams' exception policy

Text files modified:
   trunk/boost/rational.hpp | 18 ++++++++++++------
   trunk/libs/rational/test/rational_test.cpp | 24 ++++++++++++++++++++++++
   2 files changed, 36 insertions(+), 6 deletions(-)

Modified: trunk/boost/rational.hpp
==============================================================================
--- trunk/boost/rational.hpp Sun Sep 1 03:25:56 2013 (r85540)
+++ trunk/boost/rational.hpp 2013-09-01 06:54:47 EDT (Sun, 01 Sep 2013) (r85541)
@@ -598,6 +598,8 @@
 template <typename IntType>
 std::istream& operator>> (std::istream& is, rational<IntType>& r)
 {
+ using std::ios;
+
     IntType n = IntType(0), d = IntType(1);
     char c = 0;
     detail::resetter sentry(is);
@@ -609,14 +611,18 @@
             if ( c == '/' )
             {
                 if ( is >> std::noskipws >> d )
- // TODO: check if d is non-zero, fail if not.
- // ("assign" will normalize the value otherwise.)
- // Or: let it throw on normalization fail, but catch the
- // exception and translate it to IOStream error handling.
- r.assign( n, d );
+ try {
+ r.assign( n, d );
+ } catch ( bad_rational & ) { // normalization fail
+ try { is.setstate(ios::failbit); }
+ catch ( ... ) {} // don't throw ios_base::failure...
+ if ( is.exceptions() & ios::failbit )
+ throw; // ...but the original exception instead
+ // ELSE: suppress the exception, use just error flags
+ }
             }
             else
- is.setstate( std::ios::failbit );
+ is.setstate( ios::failbit );
         }
     }
 

Modified: trunk/libs/rational/test/rational_test.cpp
==============================================================================
--- trunk/libs/rational/test/rational_test.cpp Sun Sep 1 03:25:56 2013 (r85540)
+++ trunk/libs/rational/test/rational_test.cpp 2013-09-01 06:54:47 EDT (Sun, 01 Sep 2013) (r85541)
@@ -884,6 +884,30 @@
     iss.str( "1 /2" );
     iss >> r;
     BOOST_CHECK( !iss );
+
+ // Illegal value check(s)
+ typedef std::numeric_limits<T> limits_type;
+
+ iss.clear();
+ iss.str( "3/0" );
+ iss >> r;
+ BOOST_CHECK( !iss );
+
+ if ( limits_type::is_signed && limits_type::is_bounded &&
+ limits_type::min BOOST_PREVENT_MACRO_SUBSTITUTION () +
+ limits_type::max BOOST_PREVENT_MACRO_SUBSTITUTION () < T(0) )
+ {
+ std::ostringstream oss;
+
+ oss << 1 << '/' << limits_type::min BOOST_PREVENT_MACRO_SUBSTITUTION ();
+ iss.clear();
+ iss.str( oss.str() );
+ iss.exceptions( std::ios::failbit );
+ BOOST_CHECK( iss.good() );
+ BOOST_CHECK_THROW( iss >> r, boost::bad_rational );
+ BOOST_CHECK( iss.fail() && !iss.bad() );
+ iss.exceptions( std::ios::goodbit );
+ }
 }
 
 // Input test, passing


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk