$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r76121 - in sandbox/big_number: boost/multiprecision libs/multiprecision/test
From: john_at_[hidden]
Date: 2011-12-23 12:13:31
Author: johnmaddock
Date: 2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
New Revision: 76121
URL: http://svn.boost.org/trac/boost/changeset/76121
Log:
Fix remaining Boost.Rational support issues and add rational number IO test.
Added:
   sandbox/big_number/libs/multiprecision/test/test_rational_io.cpp   (contents, props changed)
Text files modified: 
   sandbox/big_number/boost/multiprecision/mp_number.hpp           |    42 +++++++                                 
   sandbox/big_number/libs/multiprecision/test/Jamfile.v2          |   228 +++++++++++++++++++++++---------------- 
   sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp |    49 +++++++-                                
   sandbox/big_number/libs/multiprecision/test/test_float_io.cpp   |     2                                         
   4 files changed, 219 insertions(+), 102 deletions(-)
Modified: sandbox/big_number/boost/multiprecision/mp_number.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mp_number.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/mp_number.hpp	2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -1571,6 +1571,46 @@
    a.swap(b);
 }
 
-}} // namespaces
+}  // namespace multipreciion
+
+template <class T>
+class rational;
+
+template <class Backend>
+inline std::istream& operator >> (std::istream& is, rational<multiprecision::mp_number<Backend> >& r)
+{
+   std::string s1;
+   multiprecision::mp_number<Backend> v1, v2;
+   char c;
+   bool have_hex = false;
+
+   while((EOF != (c = is.peek())) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
+   {
+      if(c == 'x' || c == 'X')
+         have_hex = true;
+      s1.append(1, c);
+      is.get();
+   }
+   v1 = s1;
+   s1.erase();
+   if(c == '/')
+   {
+      is.get();
+      while((EOF != (c = is.peek())) && (c == 'x' || c == 'X' || c == '-' || c == '+' || (c >= '0' && c <= '9') || (have_hex && (c >= 'a' && c <= 'f')) || (have_hex && (c >= 'A' && c <= 'F'))))
+      {
+         if(c == 'x' || c == 'X')
+            have_hex = true;
+         s1.append(1, c);
+         is.get();
+      }
+      v2 = s1;
+   }
+   else
+      v2 = 1;
+   r.assign(v1, v2);
+   return is;
+}
+
+} // namespaces
 
 #endif
Modified: sandbox/big_number/libs/multiprecision/test/Jamfile.v2
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/Jamfile.v2	(original)
+++ sandbox/big_number/libs/multiprecision/test/Jamfile.v2	2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -25,6 +25,10 @@
    <toolset>msvc:<runtime-link>static
    ;
 
+local disable-specfun = [ MATCH (--disable-specfun) : [ modules.peek : ARGV ] ] ;
+local disable-concepts = [ MATCH (--disable-concepts) : [ modules.peek : ARGV ] ] ;
+
+
 lib gmp ;
 lib mpfr ;
 
@@ -80,6 +84,14 @@
         : # command line
         : # input files
         : # requirements
+	      <define>TEST_MPZ_BOOST_RATIONAL
+         [ check-target-builds ../config//has_gmp : : <build>no ]
+        : test_arithmetic_mpz_br ;
+
+run test_arithmetic.cpp gmp
+        : # command line
+        : # input files
+        : # requirements
               <define>TEST_MPQ
          [ check-target-builds ../config//has_gmp : : <build>no ]
         : test_arithmetic_mpq ;
@@ -108,6 +120,14 @@
          [ check-target-builds ../config//has_tommath : : <build>no ]
         : test_arithmetic_tommath ;
 
+run test_arithmetic.cpp $(TOMMATH)
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_TOMMATH_BOOST_RATIONAL
+         [ check-target-builds ../config//has_tommath : : <build>no ]
+        : test_arithmetic_tommath_br ;
+
 run test_numeric_limits.cpp
         : # command line
         : # input files
@@ -179,68 +199,6 @@
          [ check-target-builds ../config//has_tommath : : <build>no ]
         : test_numeric_limits_tommath ;
 
-run mp_number_concept_check.cpp  mpfr
-        : # command line
-        : # input files
-        : # requirements
-	      <define>TEST_MPFR_50
-         [ check-target-builds ../config//has_mpfr : : <build>no ]
-        : mp_number_concept_check_mpfr_50 ;
-
-run mp_number_concept_check.cpp  mpfr
-        : # command line
-        : # input files
-        : # requirements
-	      <define>TEST_MPFR_6
-         [ check-target-builds ../config//has_mpfr : : <build>no ]
-        : mp_number_concept_check_mpfr_6 ;
-
-run mp_number_concept_check.cpp  mpfr
-        : # command line
-        : # input files
-        : # requirements
-	      <define>TEST_MPFR_15
-         [ check-target-builds ../config//has_mpfr : : <build>no ]
-        : mp_number_concept_check_mpfr_15 ;
-
-run mp_number_concept_check.cpp  mpfr
-        : # command line
-        : # input files
-        : # requirements
-	      <define>TEST_MPFR_17
-         [ check-target-builds ../config//has_mpfr : : <build>no ]
-        : mp_number_concept_check_mpfr_17 ;
-
-run mp_number_concept_check.cpp  mpfr
-        : # command line
-        : # input files
-        : # requirements
-	      <define>TEST_MPFR_30
-         [ check-target-builds ../config//has_mpfr : : <build>no ]
-        : mp_number_concept_check_mpfr_30 ;
-
-run mp_number_concept_check.cpp  gmp
-        : # command line
-        : # input files
-        : # requirements
-	      <define>TEST_MPF_50
-         [ check-target-builds ../config//has_gmp : : <build>no ]
-        : mp_number_concept_check_mpf50 ;
-
-run mp_number_concept_check.cpp
-        : # command line
-        : # input files
-        : # requirements
-	      <define>TEST_CPP_FLOAT
-        : mp_number_concept_check_cpp_float ;
-
-run mp_number_concept_check.cpp
-        : # command line
-        : # input files
-        : # requirements
-	      <define>TEST_BACKEND
-        : mp_number_concept_check_backend_concept ;
-
 run test_exp.cpp gmp
         : # command line
         : # input files
@@ -609,6 +567,22 @@
          [ check-target-builds ../config//has_gmp : : <build>no ]
         : test_int_io_mpz ;
 
+run test_rational_io.cpp $(TOMMATH)
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_TOMMATH
+         [ check-target-builds ../config//has_tommath : : <build>no ]
+        : test_rational_io_tommath ;
+
+run test_rational_io.cpp gmp
+        : # command line
+        : # input files
+        : # requirements
+	      <define>TEST_MPQ
+         [ check-target-builds ../config//has_gmp : : <build>no ]
+        : test_rational_io_mpz ;
+
 run ../example/gmp_snips.cpp gmp
         : # command line
         : # input files
@@ -630,35 +604,105 @@
          [ check-target-builds ../config//has_tommath : : <build>no ] ;
 
 
-for local source in [ glob math/*.cpp ]
+if ! $(disable-specfun)
 {
-   run $(source) mpfr gmp /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
-        : # command line
-        : # input files
-        : # requirements
-         [ check-target-builds ../config//has_mpfr : : <build>no ] 
-         <define>TEST_MPFR_50
-         <optimization>speed
-         <define>BOOST_ALL_NO_LIB
-         <toolset>msvc:<cxxflags>-bigobj
-        : $(source:B)_mpfr ;
-   run $(source) gmp /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
-        : # command line
-        : # input files
-        : # requirements
-         [ check-target-builds ../config//has_gmp : : <build>no ] 
-         <optimization>speed
-         <define>TEST_MPF_50
-         <define>BOOST_ALL_NO_LIB
-         <toolset>msvc:<cxxflags>-bigobj
-        : $(source:B)_mpf ;
-   run $(source) /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
-        : # command line
-        : # input files
-        : # requirements
-         <define>TEST_CPP_FLOAT
-         <define>BOOST_ALL_NO_LIB
-         <optimization>speed
-         <toolset>msvc:<cxxflags>-bigobj
-        : $(source:B)_cpp_float ;
+
+   for local source in [ glob math/*.cpp ]
+   {
+      run $(source) mpfr gmp /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
+           : # command line
+           : # input files
+           : # requirements
+            [ check-target-builds ../config//has_mpfr : : <build>no ] 
+            <define>TEST_MPFR_50
+            <optimization>speed
+            <define>BOOST_ALL_NO_LIB
+            <toolset>msvc:<cxxflags>-bigobj
+           : $(source:B)_mpfr ;
+      run $(source) gmp /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
+           : # command line
+           : # input files
+           : # requirements
+            [ check-target-builds ../config//has_gmp : : <build>no ] 
+            <optimization>speed
+            <define>TEST_MPF_50
+            <define>BOOST_ALL_NO_LIB
+            <toolset>msvc:<cxxflags>-bigobj
+           : $(source:B)_mpf ;
+      run $(source) /boost/test//boost_test_exec_monitor/<link>static /boost/regex//boost_regex/<link>static
+           : # command line
+           : # input files
+           : # requirements
+            <define>TEST_CPP_FLOAT
+            <define>BOOST_ALL_NO_LIB
+            <optimization>speed
+            <toolset>msvc:<cxxflags>-bigobj
+           : $(source:B)_cpp_float ;
+   }
+}
+
+if ! $(disable-concepts)
+{
+   run mp_number_concept_check.cpp  mpfr
+           : # command line
+           : # input files
+           : # requirements
+	         <define>TEST_MPFR_50
+            [ check-target-builds ../config//has_mpfr : : <build>no ]
+           : mp_number_concept_check_mpfr_50 ;
+
+   run mp_number_concept_check.cpp  mpfr
+           : # command line
+           : # input files
+           : # requirements
+	         <define>TEST_MPFR_6
+            [ check-target-builds ../config//has_mpfr : : <build>no ]
+           : mp_number_concept_check_mpfr_6 ;
+
+   run mp_number_concept_check.cpp  mpfr
+           : # command line
+           : # input files
+           : # requirements
+	         <define>TEST_MPFR_15
+            [ check-target-builds ../config//has_mpfr : : <build>no ]
+           : mp_number_concept_check_mpfr_15 ;
+
+   run mp_number_concept_check.cpp  mpfr
+           : # command line
+           : # input files
+           : # requirements
+	         <define>TEST_MPFR_17
+            [ check-target-builds ../config//has_mpfr : : <build>no ]
+           : mp_number_concept_check_mpfr_17 ;
+
+   run mp_number_concept_check.cpp  mpfr
+           : # command line
+           : # input files
+           : # requirements
+	         <define>TEST_MPFR_30
+            [ check-target-builds ../config//has_mpfr : : <build>no ]
+           : mp_number_concept_check_mpfr_30 ;
+
+   run mp_number_concept_check.cpp  gmp
+           : # command line
+           : # input files
+           : # requirements
+	         <define>TEST_MPF_50
+            [ check-target-builds ../config//has_gmp : : <build>no ]
+           : mp_number_concept_check_mpf50 ;
+
+   run mp_number_concept_check.cpp
+           : # command line
+           : # input files
+           : # requirements
+	         <define>TEST_CPP_FLOAT
+           : mp_number_concept_check_cpp_float ;
+
+   run mp_number_concept_check.cpp
+           : # command line
+           : # input files
+           : # requirements
+	         <define>TEST_BACKEND
+           : mp_number_concept_check_backend_concept ;
+
 }
Modified: sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp	(original)
+++ sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp	2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -10,7 +10,9 @@
 #include <boost/detail/lightweight_test.hpp>
 #include <boost/math/special_functions/pow.hpp>
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && !defined(TEST_TOMMATH)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && \
+   !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) \
+   && !defined(TEST_TOMMATH) && !defined(TEST_TOMMATH_BOOST_RATIONAL) && !defined(TEST_MPZ_BOOST_RATIONAL)
 #  define TEST_MPF_50
 #  define TEST_MPF
 #  define TEST_BACKEND
@@ -30,7 +32,7 @@
 
 #endif
 
-#if defined(TEST_MPF_50) || defined(TEST_MPF) || defined(TEST_MPZ) || defined(TEST_MPQ)
+#if defined(TEST_MPF_50) || defined(TEST_MPF) || defined(TEST_MPZ) || defined(TEST_MPQ) || defined(TEST_MPZ_BOOST_RATIONAL)
 #include <boost/multiprecision/gmp.hpp>
 #endif
 #ifdef TEST_BACKEND
@@ -42,9 +44,28 @@
 #if defined(TEST_MPFR) || defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
-#ifdef TEST_TOMMATH
+#if defined(TEST_TOMMATH) || defined(TEST_TOMMATH_BOOST_RATIONAL)
 #include <boost/multiprecision/tommath.hpp>
 #endif
+#if defined(TEST_TOMMATH_BOOST_RATIONAL) || defined(TEST_MPZ_BOOST_RATIONAL)
+#include <boost/rational.hpp>
+
+#define NO_MIXED_OPS
+
+namespace boost{ namespace multiprecision{
+
+#ifdef TEST_TOMMATH_BOOST_RATIONAL
+template<>
+struct number_category<rational<mp_int> > : public mpl::int_<number_kind_rational> {};
+#endif
+#ifdef TEST_MPZ_BOOST_RATIONAL
+template<>
+struct number_category<rational<mpz_int> > : public mpl::int_<number_kind_rational> {};
+#endif
+
+}}
+
+#endif
 
 #define BOOST_TEST_THROW(x, EX)\
    try { x;  BOOST_ERROR("Expected exception not thrown"); } \
@@ -637,7 +658,9 @@
    BOOST_TEST(ac == 64 * 2);
    ac = a;
    ac = b - ac * a;
+#ifndef NO_MIXED_OPS
    BOOST_TEST(ac == 0);
+#endif
    ac = a;
    ac = b * (ac + a);
    BOOST_TEST(ac == 64 * (16));
@@ -655,7 +678,9 @@
    BOOST_TEST(ac == 8 - 64);
    ac = a;
    ac = a - ac;
+#ifndef NO_MIXED_OPS
    BOOST_TEST(ac == 0);
+#endif
    ac = a;
    ac += a + b;
    BOOST_TEST(ac == 80);
@@ -681,7 +706,9 @@
    BOOST_TEST(ac == 16);
    ac = a;
    ac += -a;
+#ifndef NO_MIXED_OPS
    BOOST_TEST(ac == 0);
+#endif
    ac = a;
    ac += b - a;
    BOOST_TEST(ac == 8 + 64-8);
@@ -691,7 +718,9 @@
    ac = a;
    ac = a;
    ac -= +a;
+#ifndef NO_MIXED_OPS
    BOOST_TEST(ac == 0);
+#endif
    ac = a;
    ac -= -a;
    BOOST_TEST(ac == 16);
@@ -805,6 +834,7 @@
    BOOST_TEST((72 < b+a) == false);
    BOOST_TEST((72 >= b+a) == true);
    BOOST_TEST((72 > b+a) == false);
+#ifndef NO_MIXED_OPS
    //
    // Test sign and zero functions, plus use in boolian context:
    //
@@ -817,6 +847,8 @@
    a = 0;
    BOOST_TEST(a.sign() == 0);
    BOOST_TEST(a.is_zero());
+#endif
+   a = 0;
    if(a)
    {
       BOOST_ERROR("Unexpected non-zero result");
@@ -880,11 +912,6 @@
 #endif
 #ifdef TEST_MPF
    boost::multiprecision::mpf_float::default_precision(1000);
-   /*
-   boost::multiprecision::mpf_float r;
-   r.precision(50);
-   BOOST_TEST(r.precision() >= 50);
-   */
    BOOST_TEST(boost::multiprecision::mpf_float::default_precision() == 1000);
    test<boost::multiprecision::mpf_float>();
 #endif
@@ -906,6 +933,12 @@
 #ifdef TEST_TOMMATH
    test<boost::multiprecision::mp_int>();
 #endif
+#ifdef TEST_TOMMATH_BOOST_RATIONAL
+   test<boost::rational<boost::multiprecision::mp_int> >();
+#endif
+#ifdef TEST_MPZ_BOOST_RATIONAL
+   test<boost::rational<boost::multiprecision::mpz_int> >();
+#endif
    return boost::report_errors();
 }
 
Modified: sandbox/big_number/libs/multiprecision/test/test_float_io.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_float_io.cpp	(original)
+++ sandbox/big_number/libs/multiprecision/test/test_float_io.cpp	2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -50,7 +50,7 @@
 
 bool is_bankers_rounding_error(const std::string& s, const char* expect)
 {
-   // This check isn't foolproof: that would require *much* more sofisticated code!!!
+   // This check isn't foolproof: that would require *much* more sophisticated code!!!
    std::string::size_type l = std::strlen(expect);
    if(l != s.size())
       return false;
Added: sandbox/big_number/libs/multiprecision/test/test_rational_io.cpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/multiprecision/test/test_rational_io.cpp	2011-12-23 12:13:29 EST (Fri, 23 Dec 2011)
@@ -0,0 +1,131 @@
+// Copyright John Maddock 2011.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifdef _MSC_VER
+#  define _SCL_SECURE_NO_WARNINGS
+#endif
+
+#if !defined(TEST_MPQ) && !defined(TEST_TOMMATH)
+#  define TEST_MPQ
+#  define TEST_TOMMATH
+
+#ifdef _MSC_VER
+#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
+#endif
+#ifdef __GNUC__
+#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
+#endif
+
+#endif
+
+#if defined(TEST_MPQ)
+#include <boost/multiprecision/gmp.hpp>
+#endif
+#if defined(TEST_TOMMATH)
+#include <boost/multiprecision/tommath.hpp>
+#endif
+
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/rational.hpp>
+#include "test.hpp"
+#include <iostream>
+#include <iomanip>
+
+template <class T>
+T generate_random()
+{
+   static boost::random::uniform_int_distribution<unsigned> ui(0, 20);
+   static boost::random::mt19937 gen;
+   T val = gen();
+   unsigned lim = ui(gen);
+   for(unsigned i = 0; i < lim; ++i)
+   {
+      val *= (gen.max)();
+      val += gen();
+   }
+   T denom = gen();
+   lim = ui(gen);
+   for(unsigned i = 0; i < lim; ++i)
+   {
+      denom *= (gen.max)();
+      denom += gen();
+   }
+   return val / denom;
+}
+
+template <class T>
+void do_round_trip(const T& val, std::ios_base::fmtflags f, const boost::mpl::true_&)
+{
+   std::stringstream ss;
+   ss << std::setprecision(std::numeric_limits<T>::max_digits10);
+   ss.flags(f);
+   ss << val;
+   T new_val = ss.str();
+   BOOST_CHECK_EQUAL(new_val, val);
+   new_val = val.str(0, f);
+   BOOST_CHECK_EQUAL(new_val, val);
+}
+
+template <class T>
+void do_round_trip(const T& val, std::ios_base::fmtflags f, const boost::mpl::false_&)
+{
+   std::stringstream ss;
+   ss << std::setprecision(std::numeric_limits<T>::max_digits10);
+   ss.flags(f);
+   ss << val;
+   T new_val;
+   ss >> new_val;
+   BOOST_CHECK_EQUAL(new_val, val);
+}
+
+template <class T>
+struct is_mp_number : public boost::mpl::false_{};
+template <class T>
+struct is_mp_number<boost::multiprecision::mp_number<T> > : public boost::mpl::true_{};
+
+template <class T>
+void do_round_trip(const T& val, std::ios_base::fmtflags f)
+{
+   do_round_trip(val, f, is_mp_number<T>());
+}
+
+template <class T>
+void do_round_trip(const T& val)
+{
+   do_round_trip(val, std::ios_base::fmtflags(0));
+   if(val >= 0)
+   {
+      do_round_trip(val, std::ios_base::fmtflags(std::ios_base::showbase|std::ios_base::hex));
+      do_round_trip(val, std::ios_base::fmtflags(std::ios_base::showbase|std::ios_base::oct));
+   }
+}
+
+template <class T>
+void test_round_trip()
+{
+   for(unsigned i = 0; i < 1000; ++i)
+   {
+      T val = generate_random<T>();
+      do_round_trip(val);
+      do_round_trip(T(-val));
+   }
+}
+
+int main()
+{
+#ifdef TEST_MPQ
+   test_round_trip<boost::multiprecision::mpq_rational>();
+   test_round_trip<boost::rational<boost::multiprecision::mpz_int> >();
+#endif
+#ifdef TEST_TOMMATH
+   test_round_trip<boost::rational<boost::multiprecision::mp_int> >();
+#endif
+   return boost::report_errors();
+}
+