|
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