Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85519 - in trunk: boost libs/rational/test
From: dwalker07_at_[hidden]
Date: 2013-08-29 20:22:01


Author: dlwalker
Date: 2013-08-29 20:22:01 EDT (Thu, 29 Aug 2013)
New Revision: 85519
URL: http://svn.boost.org/trac/boost/changeset/85519

Log:
Started modernizing Boost.Rational I/O (refs #7187)

Text files modified:
   trunk/boost/rational.hpp | 60 ++++++++++++++++++++++++++++------------
   trunk/libs/rational/test/rational_test.cpp | 31 +++++++++++++++++++-
   2 files changed, 71 insertions(+), 20 deletions(-)

Modified: trunk/boost/rational.hpp
==============================================================================
--- trunk/boost/rational.hpp Thu Aug 29 19:05:33 2013 (r85518)
+++ trunk/boost/rational.hpp 2013-08-29 20:22:01 EDT (Thu, 29 Aug 2013) (r85519)
@@ -61,10 +61,13 @@
 
 #include <boost/config.hpp> // for BOOST_NO_STDC_NAMESPACE, BOOST_MSVC, etc
 #ifndef BOOST_NO_IOSTREAM
-#include <ios> // for std::noskipws
+#include <iomanip> // for std::setw
+#include <ios> // for std::noskipws, streamsize
 #include <istream> // for std::istream
 #include <ostream> // for std::ostream
+#include <sstream> // for std::ostringstream
 #endif
+#include <cstddef> // for NULL
 #include <stdexcept> // for std::domain_error
 #include <string> // for std::string implicit constructor
 #include <boost/operators.hpp> // for boost::addable etc
@@ -593,21 +596,23 @@
     char c = 0;
     detail::resetter sentry(is);
 
- is >> n;
- c = is.get();
-
- if (c != '/')
- is.clear(std::istream::badbit); // old GNU c++ lib has no ios_base
-
-#if !defined(__GNUC__) || (defined(__GNUC__) && (__GNUC__ >= 3)) || defined __SGI_STL_PORT
- is >> std::noskipws;
-#else
- is.unsetf(ios::skipws); // compiles, but seems to have no effect.
-#endif
- is >> d;
-
- if (is)
- r.assign(n, d);
+ if ( is >> n )
+ {
+ if ( is.get(c) )
+ {
+ 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 );
+ }
+ else
+ is.setstate( std::ios::failbit );
+ }
+ }
 
     return is;
 }
@@ -616,8 +621,27 @@
 template <typename IntType>
 std::ostream& operator<< (std::ostream& os, const rational<IntType>& r)
 {
- os << r.numerator() << '/' << r.denominator();
- return os;
+ using namespace std;
+
+ // The slash directly preceeds the denominator, which has no prefixes.
+ ostringstream ss;
+
+ ss.copyfmt( os );
+ ss.tie( NULL );
+ ss.exceptions( ios::goodbit );
+ ss.width( 0 );
+ ss << noshowpos << noshowbase << '/' << r.denominator();
+
+ // The numerator holds the showpos, internal, and showbase flags.
+ string const tail = ss.str();
+ streamsize const w = os.width() - static_cast<streamsize>( tail.size() );
+
+ ss.clear();
+ ss.str( "" );
+ ss.flags( os.flags() );
+ ss << setw( w < 0 || (os.flags() & ios::adjustfield) != ios::internal ? 0 :
+ w ) << r.numerator();
+ return os << ss.str() + tail;
 }
 #endif // BOOST_NO_IOSTREAM
 

Modified: trunk/libs/rational/test/rational_test.cpp
==============================================================================
--- trunk/libs/rational/test/rational_test.cpp Thu Aug 29 19:05:33 2013 (r85518)
+++ trunk/libs/rational/test/rational_test.cpp 2013-08-29 20:22:01 EDT (Thu, 29 Aug 2013) (r85519)
@@ -47,6 +47,8 @@
 #include <boost/test/unit_test.hpp>
 
 #include <climits>
+#include <iomanip>
+#include <ios>
 #include <iostream>
 #include <istream>
 #include <ostream>
@@ -810,10 +812,34 @@
 // Output test
 BOOST_AUTO_TEST_CASE_TEMPLATE( rational_output_test, T, all_signed_test_types )
 {
- std::ostringstream oss;
+ using namespace std;
+ typedef boost::rational<T> rational_type;
+
+ // Basic test
+ ostringstream oss;
 
- oss << boost::rational<T>( 44, 14 );
+ oss << rational_type( 44, 14 );
     BOOST_CHECK_EQUAL( oss.str(), "22/7" );
+
+ // Width
+ oss.clear(); oss.str( "" );
+ oss << setw( 5 ) << setfill('*') << rational_type( 1, 2 ) << 'r';
+ BOOST_CHECK_EQUAL( oss.str(), "**1/2r" ); // not "****1/2r"
+
+ // Positive-sign
+ oss.clear(); oss.str( "" );
+ oss << showpos << rational_type( 2, 3 ) << noshowpos;
+ BOOST_CHECK_EQUAL( oss.str(), "+2/3" ); // not "+2/+3"
+
+ // Internal padding
+ oss.clear(); oss.str( "" );
+ oss << setw( 8 ) << internal << rational_type( 36, -15 ) << right << 'r';
+ BOOST_CHECK_EQUAL( oss.str(), "-***12/5r" ); // not "-*****12/5r"
+
+ // Showbase prefix
+ oss.clear(); oss.str( "" );
+ oss << showbase << hex << rational_type( 34, 987 ) << noshowbase << dec;
+ BOOST_CHECK_EQUAL( oss.str(), "0x22/3db" ); // not "0x22/0x3db"
 }
 
 // Input test, failing
@@ -825,6 +851,7 @@
 
     iss >> r;
     BOOST_CHECK( !iss );
+ BOOST_CHECK( !iss.bad() );
 
     iss.clear();
     iss.str( "42" );


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