Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78401 - in sandbox/big_number: boost/multiprecision boost/multiprecision/detail boost/multiprecision/detail/functions libs/multiprecision/doc libs/multiprecision/doc/html libs/multiprecision/doc/html/boost_multiprecision/indexes libs/multiprecision/doc/html/boost_multiprecision/ref libs/multiprecision/test
From: john_at_[hidden]
Date: 2012-05-10 05:20:31


Author: johnmaddock
Date: 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
New Revision: 78401
URL: http://svn.boost.org/trac/boost/changeset/78401

Log:
Change non-member functions to be protected by enable_if based on the type of the number.
Extend expression templates to 4 arguments.
Add pow and powm functions for integer types.
Update docs to match.
Text files modified:
   sandbox/big_number/boost/multiprecision/cpp_dec_float.hpp | 2
   sandbox/big_number/boost/multiprecision/cpp_int.hpp | 7
   sandbox/big_number/boost/multiprecision/detail/default_ops.hpp | 306 +++++++++------------
   sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp | 67 +++-
   sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp | 26 +
   sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp | 551 ++++++++++++++++++++++-----------------
   sandbox/big_number/boost/multiprecision/gmp.hpp | 23 +
   sandbox/big_number/boost/multiprecision/integer_ops.hpp | 180 +++++++++++-
   sandbox/big_number/boost/multiprecision/miller_rabin.hpp | 12
   sandbox/big_number/boost/multiprecision/mp_number.hpp | 117 ++++++--
   sandbox/big_number/boost/multiprecision/mpfr.hpp | 17 +
   sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s01.html | 14
   sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s02.html | 4
   sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s03.html | 4
   sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s04.html | 9
   sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/ref/mp_number.html | 17 +
   sandbox/big_number/libs/multiprecision/doc/html/index.html | 2
   sandbox/big_number/libs/multiprecision/doc/multiprecision.qbk | 13
   sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp | 27 +
   19 files changed, 879 insertions(+), 519 deletions(-)

Modified: sandbox/big_number/boost/multiprecision/cpp_dec_float.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_dec_float.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_dec_float.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -334,7 +334,7 @@
    {
       exp = f.exp;
       neg = f.neg;
- fpclass = static_cast<fpclass_type>(static_cast<int>(f.fpclass));
+ fpclass = static_cast<enum_fpclass_type>(static_cast<int>(f.fpclass));
       std::copy(f.data.begin(), f.data.begin() + (std::min)(f.prec_elem, prec_elem), data.begin());
       precision((std::min)(f.prec_elem, prec_elem));
       return *this;

Modified: sandbox/big_number/boost/multiprecision/cpp_int.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_int.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_int.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -1082,10 +1082,13 @@
       for(unsigned j = 0; j < inner_limit; ++j)
       {
          BOOST_ASSERT(i+j < result.size());
+ BOOST_ASSERT((std::numeric_limits<double_limb_type>::max)() - carry > static_cast<double_limb_type>(cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value) * static_cast<double_limb_type>(cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value));
          carry += static_cast<double_limb_type>(pa[i]) * static_cast<double_limb_type>(pb[j]);
+ BOOST_ASSERT((std::numeric_limits<double_limb_type>::max)() - carry >= pr[i+j]);
          carry += pr[i + j];
          pr[i + j] = static_cast<limb_type>(carry);
          carry >>= cpp_int_backend<MinBits, Signed, Allocator>::limb_bits;
+ BOOST_ASSERT(carry <= (cpp_int_backend<MinBits, Signed, Allocator>::max_limb_value));
       }
       if(cpp_int_backend<MinBits, Signed, Allocator>::variable || (i + bs < result.size()))
          pr[i + bs] = static_cast<limb_type>(carry);
@@ -1529,6 +1532,8 @@
          {
             --r_order; // No remainder, division was exact.
             r.resize(r.size() - 1);
+ if(result)
+ pres[r_order] = static_cast<limb_type>(0u);
          }
       }
       else
@@ -1540,6 +1545,8 @@
          {
             --r_order; // No remainder, division was exact.
             r.resize(r.size() - 1);
+ if(result)
+ pres[r_order] = static_cast<limb_type>(0u);
          }
       }
    }

Modified: sandbox/big_number/boost/multiprecision/detail/default_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/default_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/default_ops.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -445,6 +445,26 @@
    eval_multiply(n, b);
    eval_subtract(result, a, n);
 }
+template<class T, class A>
+inline typename enable_if<is_arithmetic<A>, void>::type eval_fmod(T& result, const T& x, const A& a)
+{
+ typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+ typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+ cast_type c;
+ c = a;
+ eval_fmod(result, x, c);
+}
+
+template<class T, class A>
+inline typename enable_if<is_arithmetic<A>, void>::type eval_fmod(T& result, const A& x, const T& a)
+{
+ typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+ typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+ cast_type c;
+ c = x;
+ eval_fmod(result, c, a);
+}
+
 template <class T>
 inline void eval_trunc(T& result, const T& a)
 {
@@ -484,68 +504,6 @@
    }
 }
 
-template<class T, class A>
-inline typename enable_if<is_floating_point<A>, void>::type eval_pow(T& result, const T& x, const A& a)
-{
- // Note this one is resticted to float arguments since pow.hpp already has a version for
- // integer powers....
- typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
- typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
- cast_type c;
- c = a;
- eval_pow(result, x, c);
-}
-
-template<class T, class A>
-inline typename enable_if<is_arithmetic<A>, void>::type eval_pow(T& result, const A& x, const T& a)
-{
- typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
- typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
- cast_type c;
- c = x;
- eval_pow(result, c, a);
-}
-
-template<class T, class A>
-inline typename enable_if<is_arithmetic<A>, void>::type eval_fmod(T& result, const T& x, const A& a)
-{
- typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
- typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
- cast_type c;
- c = a;
- eval_fmod(result, x, c);
-}
-
-template<class T, class A>
-inline typename enable_if<is_arithmetic<A>, void>::type eval_fmod(T& result, const A& x, const T& a)
-{
- typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
- typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
- cast_type c;
- c = x;
- eval_fmod(result, c, a);
-}
-
-template<class T, class A>
-inline typename enable_if<is_arithmetic<A>, void>::type eval_atan2(T& result, const T& x, const A& a)
-{
- typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
- typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
- cast_type c;
- c = a;
- eval_atan2(result, x, c);
-}
-
-template<class T, class A>
-inline typename enable_if<is_arithmetic<A>, void>::type eval_atan2(T& result, const A& x, const T& a)
-{
- typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
- typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
- cast_type c;
- c = x;
- eval_atan2(result, c, a);
-}
-
 template <class T, class Arithmetic>
 inline typename enable_if<is_integral<Arithmetic> >::type eval_gcd(T& result, const T& a, const Arithmetic& b)
 {
@@ -670,10 +628,10 @@
    using multiprecision::default_ops::eval_fpclassify;
    return eval_fpclassify(arg.backend());
 }
-template <class tag, class A1, class A2, class A3>
-inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& arg)
+template <class tag, class A1, class A2, class A3, class A4>
+inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& arg)
 {
- typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type value_type;
+ typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type value_type;
    return fpclassify(value_type(arg));
 }
 template <class Backend, bool ExpressionTemplates>
@@ -682,10 +640,10 @@
    int v = fpclassify(arg);
    return (v != FP_INFINITE) && (v != FP_NAN);
 }
-template <class tag, class A1, class A2, class A3>
-inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& arg)
+template <class tag, class A1, class A2, class A3, class A4>
+inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& arg)
 {
- typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type value_type;
+ typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type value_type;
    return isfinite(value_type(arg));
 }
 template <class Backend, bool ExpressionTemplates>
@@ -693,10 +651,10 @@
 {
    return fpclassify(arg) == FP_NAN;
 }
-template <class tag, class A1, class A2, class A3>
-inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& arg)
+template <class tag, class A1, class A2, class A3, class A4>
+inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& arg)
 {
- typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type value_type;
+ typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type value_type;
    return isnan(value_type(arg));
 }
 template <class Backend, bool ExpressionTemplates>
@@ -704,10 +662,10 @@
 {
    return fpclassify(arg) == FP_INFINITE;
 }
-template <class tag, class A1, class A2, class A3>
-inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& arg)
+template <class tag, class A1, class A2, class A3, class A4>
+inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& arg)
 {
- typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type value_type;
+ typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type value_type;
    return isinf(value_type(arg));
 }
 template <class Backend, bool ExpressionTemplates>
@@ -715,20 +673,20 @@
 {
    return fpclassify(arg) == FP_NORMAL;
 }
-template <class tag, class A1, class A2, class A3>
-inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& arg)
+template <class tag, class A1, class A2, class A3, class A4>
+inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& arg)
 {
- typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type value_type;
+ typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type value_type;
    return isnormal(value_type(arg));
 }
 
 } // namespace math
 namespace multiprecision{
 
-template <class tag, class A1, class A2, class A3, class Policy>
-inline typename detail::mp_exp<tag, A1, A2, A3>::result_type trunc(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class A4, class Policy>
+inline typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type trunc(const detail::mp_exp<tag, A1, A2, A3, A4>& v, const Policy& pol)
 {
- typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    return trunc(number_type(v), pol);
 }
 
@@ -741,17 +699,17 @@
    return result;
 }
 
-template <class tag, class A1, class A2, class A3, class Policy>
-inline int itrunc(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class A4, class Policy>
+inline int itrunc(const detail::mp_exp<tag, A1, A2, A3, A4>& v, const Policy& pol)
 {
- typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = trunc(v, pol);
    if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !boost::math::isfinite(v))
       return boost::math::policies::raise_rounding_error("boost::multiprecision::itrunc<%1%>(%1%)", 0, number_type(v), 0, pol).template convert_to<int>();
    return r.template convert_to<int>();
 }
-template <class tag, class A1, class A2, class A3>
-inline int itrunc(const detail::mp_exp<tag, A1, A2, A3>& v)
+template <class tag, class A1, class A2, class A3, class A4>
+inline int itrunc(const detail::mp_exp<tag, A1, A2, A3, A4>& v)
 {
    return itrunc(v, boost::math::policies::policy<>());
 }
@@ -768,17 +726,17 @@
 {
    return itrunc(v, boost::math::policies::policy<>());
 }
-template <class tag, class A1, class A2, class A3, class Policy>
-inline long ltrunc(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class A4, class Policy>
+inline long ltrunc(const detail::mp_exp<tag, A1, A2, A3, A4>& v, const Policy& pol)
 {
- typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = trunc(v, pol);
    if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !boost::math::isfinite(v))
       return boost::math::policies::raise_rounding_error("boost::multiprecision::ltrunc<%1%>(%1%)", 0, number_type(v), 0L, pol).template convert_to<long>();
    return r.template convert_to<long>();
 }
-template <class tag, class A1, class A2, class A3>
-inline long ltrunc(const detail::mp_exp<tag, A1, A2, A3>& v)
+template <class tag, class A1, class A2, class A3, class A4>
+inline long ltrunc(const detail::mp_exp<tag, A1, A2, A3, A4>& v)
 {
    return ltrunc(v, boost::math::policies::policy<>());
 }
@@ -796,17 +754,17 @@
    return ltrunc(v, boost::math::policies::policy<>());
 }
 #ifndef BOOST_NO_LONG_LONG
-template <class tag, class A1, class A2, class A3, class Policy>
-inline long long lltrunc(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class A4, class Policy>
+inline long long lltrunc(const detail::mp_exp<tag, A1, A2, A3, A4>& v, const Policy& pol)
 {
- typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = trunc(v, pol);
    if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !boost::math::isfinite(v))
       return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, number_type(v), 0LL, pol).template convert_to<long long>();
    return r.template convert_to<long long>();
 }
-template <class tag, class A1, class A2, class A3>
-inline long long lltrunc(const detail::mp_exp<tag, A1, A2, A3>& v)
+template <class tag, class A1, class A2, class A3, class A4>
+inline long long lltrunc(const detail::mp_exp<tag, A1, A2, A3, A4>& v)
 {
    return lltrunc(v, boost::math::policies::policy<>());
 }
@@ -824,10 +782,10 @@
    return lltrunc(v, boost::math::policies::policy<>());
 }
 #endif
-template <class tag, class A1, class A2, class A3, class Policy>
-inline typename detail::mp_exp<tag, A1, A2, A3>::result_type round(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class A4, class Policy>
+inline typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type round(const detail::mp_exp<tag, A1, A2, A3, A4>& v, const Policy& pol)
 {
- typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    return round(static_cast<number_type>(v), pol);
 }
 template <class T, bool ExpressionTemplates, class Policy>
@@ -839,17 +797,17 @@
    return result;
 }
 
-template <class tag, class A1, class A2, class A3, class Policy>
-inline int iround(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class A4, class Policy>
+inline int iround(const detail::mp_exp<tag, A1, A2, A3, A4>& v, const Policy& pol)
 {
- typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = round(v, pol);
    if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !boost::math::isfinite(v))
       return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0, pol).template convert_to<int>();
    return r.template convert_to<int>();
 }
-template <class tag, class A1, class A2, class A3>
-inline int iround(const detail::mp_exp<tag, A1, A2, A3>& v)
+template <class tag, class A1, class A2, class A3, class A4>
+inline int iround(const detail::mp_exp<tag, A1, A2, A3, A4>& v)
 {
    return iround(v, boost::math::policies::policy<>());
 }
@@ -866,17 +824,17 @@
 {
    return iround(v, boost::math::policies::policy<>());
 }
-template <class tag, class A1, class A2, class A3, class Policy>
-inline long lround(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class A4, class Policy>
+inline long lround(const detail::mp_exp<tag, A1, A2, A3, A4>& v, const Policy& pol)
 {
- typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = round(v, pol);
    if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !boost::math::isfinite(v))
       return boost::math::policies::raise_rounding_error("boost::multiprecision::lround<%1%>(%1%)", 0, number_type(v), 0L, pol).template convert_to<long>();
    return r.template convert_to<long>();
 }
-template <class tag, class A1, class A2, class A3>
-inline long lround(const detail::mp_exp<tag, A1, A2, A3>& v)
+template <class tag, class A1, class A2, class A3, class A4>
+inline long lround(const detail::mp_exp<tag, A1, A2, A3, A4>& v)
 {
    return lround(v, boost::math::policies::policy<>());
 }
@@ -894,17 +852,17 @@
    return lround(v, boost::math::policies::policy<>());
 }
 #ifndef BOOST_NO_LONG_LONG
-template <class tag, class A1, class A2, class A3, class Policy>
-inline long long llround(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class A4, class Policy>
+inline long long llround(const detail::mp_exp<tag, A1, A2, A3, A4>& v, const Policy& pol)
 {
- typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = round(v, pol);
    if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !boost::math::isfinite(v))
       return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0LL, pol).template convert_to<long long>();
    return r.template convert_to<long long>();
 }
-template <class tag, class A1, class A2, class A3>
-inline long long llround(const detail::mp_exp<tag, A1, A2, A3>& v)
+template <class tag, class A1, class A2, class A3, class A4>
+inline long long llround(const detail::mp_exp<tag, A1, A2, A3, A4>& v)
 {
    return llround(v, boost::math::policies::policy<>());
 }
@@ -937,21 +895,21 @@
 \
 }\
 \
-template <class tag, class A1, class A2, class A3> \
-inline typename enable_if_c<number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category,\
+template <class tag, class A1, class A2, class A3, class A4> \
+inline typename enable_if_c<number_category<detail::mp_exp<tag, A1, A2, A3, A4> >::value == category,\
    detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
- , detail::mp_exp<tag, A1, A2, A3> >\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> > \
>::type \
-func(const detail::mp_exp<tag, A1, A2, A3>& arg)\
+func(const detail::mp_exp<tag, A1, A2, A3, A4>& arg)\
 {\
     return detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
> (\
- detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>() \
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type>() \
       , arg \
     );\
 }\
@@ -960,7 +918,7 @@
    detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
- , mp_number<Backend> >\
+ , mp_number<Backend> > \
>::type \
 func(const mp_number<Backend>& arg)\
 {\
@@ -1031,43 +989,43 @@
       a\
     );\
 }\
-template <class Backend, class tag, class A1, class A2, class A3> \
+template <class Backend, class tag, class A1, class A2, class A3, class A4> \
 inline typename enable_if_c<\
- (number_category<Backend>::value == category) && (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
+ (number_category<Backend>::value == category) && (number_category<detail::mp_exp<tag, A1, A2, A3, A4> >::value == category),\
    detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
   , mp_number<Backend> \
- , detail::mp_exp<tag, A1, A2, A3> > \
+ , detail::mp_exp<tag, A1, A2, A3, A4> > \
>::type \
-func(const mp_number<Backend>& arg, const detail::mp_exp<tag, A1, A2, A3>& a)\
+func(const mp_number<Backend>& arg, const detail::mp_exp<tag, A1, A2, A3, A4>& a)\
 {\
     return detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
   , mp_number<Backend> \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
>(\
         detail::BOOST_JOIN(func, _funct)<Backend>() \
       , arg,\
       a\
     );\
 }\
-template <class tag, class A1, class A2, class A3, class Backend> \
+template <class tag, class A1, class A2, class A3, class A4, class Backend> \
 inline typename enable_if_c<\
- (number_category<Backend>::value == category) && (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
+ (number_category<Backend>::value == category) && (number_category<detail::mp_exp<tag, A1, A2, A3, A4> >::value == category),\
    detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
   , mp_number<Backend> > \
>::type \
-func(const detail::mp_exp<tag, A1, A2, A3>& arg, const mp_number<Backend>& a)\
+func(const detail::mp_exp<tag, A1, A2, A3, A4>& arg, const mp_number<Backend>& a)\
 {\
     return detail::mp_exp<\
     detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
   , mp_number<Backend> \
>(\
         detail::BOOST_JOIN(func, _funct)<Backend>() \
@@ -1075,24 +1033,24 @@
       a\
     );\
 }\
-template <class tag, class A1, class A2, class A3, class tagb, class A1b, class A2b, class A3b> \
+template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b> \
 inline typename enable_if_c<\
- (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category) && (number_category<detail::mp_exp<tagb, A1b, A2b, A3b> >::value == category),\
+ (number_category<detail::mp_exp<tag, A1, A2, A3, A4> >::value == category) && (number_category<detail::mp_exp<tagb, A1b, A2b, A3b, A4b> >::value == category),\
    detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
- , detail::mp_exp<tag, A1, A2, A3> \
- , detail::mp_exp<tagb, A1b, A2b, A3b> > \
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
+ , detail::mp_exp<tagb, A1b, A2b, A3b, A4b> > \
>::type \
-func(const detail::mp_exp<tag, A1, A2, A3>& arg, const detail::mp_exp<tagb, A1b, A2b, A3b>& a)\
+func(const detail::mp_exp<tag, A1, A2, A3, A4>& arg, const detail::mp_exp<tagb, A1b, A2b, A3b, A4b>& a)\
 {\
     return detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
- , detail::mp_exp<tag, A1, A2, A3> \
- , detail::mp_exp<tagb, A1b, A2b, A3b> \
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
+ , detail::mp_exp<tagb, A1b, A2b, A3b, A4b> \
>(\
- detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>() \
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type>() \
       , arg,\
       a\
     );\
@@ -1120,25 +1078,25 @@
       a\
     );\
 }\
-template <class tag, class A1, class A2, class A3, class Arithmetic> \
+template <class tag, class A1, class A2, class A3, class A4, class Arithmetic> \
 inline typename enable_if_c<\
- is_arithmetic<Arithmetic>::value && (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
+ is_arithmetic<Arithmetic>::value && (number_category<detail::mp_exp<tag, A1, A2, A3, A4> >::value == category),\
    detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
   , Arithmetic\
> \
>::type \
-func(const detail::mp_exp<tag, A1, A2, A3>& arg, const Arithmetic& a)\
+func(const detail::mp_exp<tag, A1, A2, A3, A4>& arg, const Arithmetic& a)\
 {\
     return detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
   , Arithmetic\
>(\
- detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>() \
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type>() \
       , arg,\
       a\
     );\
@@ -1166,25 +1124,25 @@
       a\
     );\
 }\
-template <class tag, class A1, class A2, class A3, class Arithmetic> \
+template <class tag, class A1, class A2, class A3, class A4, class Arithmetic> \
 inline typename enable_if_c<\
- is_arithmetic<Arithmetic>::value && (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
+ is_arithmetic<Arithmetic>::value && (number_category<detail::mp_exp<tag, A1, A2, A3, A4> >::value == category),\
    detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
   , Arithmetic \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
> \
>::type \
-func(const Arithmetic& arg, const detail::mp_exp<tag, A1, A2, A3>& a)\
+func(const Arithmetic& arg, const detail::mp_exp<tag, A1, A2, A3, A4>& a)\
 {\
     return detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
   , Arithmetic \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
>(\
- detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>() \
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type>() \
       , arg,\
       a\
     );\
@@ -1228,24 +1186,24 @@
 
 
 #define HETERO_BINARY_OP_FUNCTOR_B(func, Arg2, category)\
-template <class tag, class A1, class A2, class A3> \
+template <class tag, class A1, class A2, class A3, class A4> \
 inline typename enable_if_c<\
- (number_category<detail::mp_exp<tag, A1, A2, A3> >::value == category),\
+ (number_category<detail::mp_exp<tag, A1, A2, A3, A4> >::value == category),\
    detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
   , Arg2> \
>::type \
-func(const detail::mp_exp<tag, A1, A2, A3>& arg, Arg2 const& a)\
+func(const detail::mp_exp<tag, A1, A2, A3, A4>& arg, Arg2 const& a)\
 {\
     return detail::mp_exp<\
     detail::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
- , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3, A4> \
   , Arg2\
>(\
- detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>() \
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type>() \
       , arg, a \
     );\
 }\
@@ -1313,19 +1271,19 @@
 
 }
 
-template <class tag, class A1, class A2, class A3>
+template <class tag, class A1, class A2, class A3, class A4>
 inline detail::mp_exp<
     detail::function
- , detail::abs_funct<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>
- , detail::mp_exp<tag, A1, A2, A3> >
-abs(const detail::mp_exp<tag, A1, A2, A3>& arg)
+ , detail::abs_funct<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type>
+ , detail::mp_exp<tag, A1, A2, A3, A4> >
+abs(const detail::mp_exp<tag, A1, A2, A3, A4>& arg)
 {
     return detail::mp_exp<
     detail::function
- , detail::abs_funct<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>
- , detail::mp_exp<tag, A1, A2, A3>
+ , detail::abs_funct<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type>
+ , detail::mp_exp<tag, A1, A2, A3, A4>
> (
- detail::abs_funct<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>()
+ detail::abs_funct<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3, A4> >::type>()
       , arg
     );
 }
@@ -1389,7 +1347,7 @@
 //
 BINARY_OP_FUNCTOR(gcd, number_kind_integer)
 BINARY_OP_FUNCTOR(lcm, number_kind_integer)
-
+HETERO_BINARY_OP_FUNCTOR_B(pow, unsigned, number_kind_integer)
 
 #undef BINARY_OP_FUNCTOR
 #undef UNARY_OP_FUNCTOR

Modified: sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -15,30 +15,11 @@
 namespace detail{
 
 template<typename T, typename U>
-inline T pow_imp(T& result, const T& t, const U& p, const mpl::false_&)
-{
- T temp(p);
- eval_pow(result, t, p);
-}
-
-template<typename T, typename U>
-inline void pow_imp(T& result, const T& t, const U& p, const mpl::true_&)
+inline void pow_imp(T& result, const T& t, const U& p, const mpl::false_&)
 {
    // Compute the pure power of typename T t^p. Binary splitting of the power is
    // used. The resulting computational complexity has the order of log2[abs(p)].
-
- typedef typename mpl::front<typename T::signed_types>::type int_type;
-
- if(p < 0)
- {
- T temp;
- temp = static_cast<int_type>(1);
- T denom;
- pow_imp(denom, t, -p, mpl::true_());
- eval_divide(result, temp, denom);
- return;
- }
-
+ typedef typename boost::multiprecision::detail::canonical<U, T>::type int_type;
    switch(p)
    {
    case 0:
@@ -74,19 +55,37 @@
          if(p_minus_n)
          {
             T temp;
- pow_imp(temp, t, p_minus_n, mpl::true_());
+ pow_imp(temp, t, p_minus_n, mpl::false_());
             eval_multiply(result, temp);
          }
       }
    }
 }
 
+template<typename T, typename U>
+inline void pow_imp(T& result, const T& t, const U& p, const mpl::true_&)
+{
+ // Signed integer power, just take care of the sign then call the unsigned version:
+ typedef typename boost::multiprecision::detail::canonical<U, T>::type int_type;
+
+ if(p < 0)
+ {
+ T temp;
+ temp = static_cast<int_type>(1);
+ T denom;
+ pow_imp(denom, t, -p, mpl::false_());
+ eval_divide(result, temp, denom);
+ return;
+ }
+ pow_imp(result, t, p, mpl::false_());
+}
+
 } // namespace detail
 
 template<typename T, typename U>
 inline typename enable_if<is_integral<U> >::type eval_pow(T& result, const T& t, const U& p)
 {
- detail::pow_imp(result, t, p, mpl::true_());
+ detail::pow_imp(result, t, p, boost::is_signed<U>());
 }
 
 template <class T>
@@ -545,6 +544,28 @@
    }
 }
 
+template<class T, class A>
+inline typename enable_if<is_floating_point<A>, void>::type eval_pow(T& result, const T& x, const A& a)
+{
+ // Note this one is resticted to float arguments since pow.hpp already has a version for
+ // integer powers....
+ typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+ typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+ cast_type c;
+ c = a;
+ eval_pow(result, x, c);
+}
+
+template<class T, class A>
+inline typename enable_if<is_arithmetic<A>, void>::type eval_pow(T& result, const A& x, const T& a)
+{
+ typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+ typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+ cast_type c;
+ c = x;
+ eval_pow(result, c, a);
+}
+
 namespace detail{
 
    template <class T>

Modified: sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/functions/trig.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -766,13 +766,23 @@
          eval_add(result, get_constant_pi<T>());
    }
 }
-/*
-template <class T, class Arithmetic>
-typename disable_if<is_same<T, Arithmetic> >::type eval_atan2(T& result, const T& a, const Arithmetic& b)
+template<class T, class A>
+inline typename enable_if<is_arithmetic<A>, void>::type eval_atan2(T& result, const T& x, const A& a)
 {
- BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The atan2 function is only valid for floating point types.");
- T x;
- x = static_cast<typename boost::multiprecision::detail::canonical<Arithmetic, T>::type>(b);
- eval_atan2(result, a, x);
+ typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+ typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+ cast_type c;
+ c = a;
+ eval_atan2(result, x, c);
 }
-*/
+
+template<class T, class A>
+inline typename enable_if<is_arithmetic<A>, void>::type eval_atan2(T& result, const A& x, const T& a)
+{
+ typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
+ typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
+ cast_type c;
+ c = x;
+ eval_atan2(result, c, a);
+}
+

Modified: sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -22,12 +22,28 @@
 template <class Backend, bool ExpressionTemplates = true>
 class mp_number;
 
+template <class T>
+struct is_mp_number : public mpl::false_ {};
+
+template <class Backend, bool ExpressionTemplates>
+struct is_mp_number<mp_number<Backend, ExpressionTemplates> > : public mpl::true_ {};
+
 namespace detail{
 
 // Forward-declare an expression wrapper
-template<class tag, class Arg1 = void, class Arg2 = void, class Arg3 = void>
+template<class tag, class Arg1 = void, class Arg2 = void, class Arg3 = void, class Arg4 = void>
 struct mp_exp;
 
+} // namespace detail
+
+template <class T>
+struct is_mp_number_expression : public mpl::false_ {};
+
+template<class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+struct is_mp_number_expression<detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > : public mpl::true_ {};
+
+namespace detail{
+
 template <class T>
 typename boost::enable_if<is_arithmetic<T>, T>::type abs(const T& t)
 {
@@ -144,10 +160,10 @@
    typedef T type;
 };
 
-template <class tag, class A1, class A2, class A3>
-struct backend_type<mp_exp<tag, A1, A2, A3> >
+template <class tag, class A1, class A2, class A3, class A4>
+struct backend_type<mp_exp<tag, A1, A2, A3, A4> >
 {
- typedef typename backend_type<typename mp_exp<tag, A1, A2, A3>::result_type>::type type;
+ typedef typename backend_type<typename mp_exp<tag, A1, A2, A3, A4>::result_type>::type type;
 };
 
 
@@ -157,8 +173,8 @@
 struct is_mp_number<boost::multiprecision::mp_number<T, ExpressionTemplates> > : public mpl::true_{};
 template <class T>
 struct is_mp_number_exp : public mpl::false_{};
-template <class Tag, class Arg1, class Arg2, class Arg3>
-struct is_mp_number_exp<boost::multiprecision::detail::mp_exp<Tag, Arg1, Arg2, Arg3> > : public mpl::true_{};
+template <class Tag, class Arg1, class Arg2, class Arg3, class Arg4>
+struct is_mp_number_exp<boost::multiprecision::detail::mp_exp<Tag, Arg1, Arg2, Arg3, Arg4> > : public mpl::true_{};
 
 template <class T1, class T2>
 struct combine_expression;
@@ -187,10 +203,10 @@
    typedef mp_exp<terminal, T> type;
 };
 
-template <class Tag, class Arg1, class Arg2, class Arg3>
-struct arg_type<mp_exp<Tag, Arg1, Arg2, Arg3> >
+template <class Tag, class Arg1, class Arg2, class Arg3, class Arg4>
+struct arg_type<mp_exp<Tag, Arg1, Arg2, Arg3, Arg4> >
 {
- typedef mp_exp<Tag, Arg1, Arg2, Arg3> type;
+ typedef mp_exp<Tag, Arg1, Arg2, Arg3, Arg4> type;
 };
 
 template <class T>
@@ -219,14 +235,14 @@
    typedef const T* type;
 };
 
-template <class tag, class A1, class A2, class A3>
-struct mp_exp_storage<mp_exp<tag, A1, A2, A3> >
+template <class tag, class A1, class A2, class A3, class A4>
+struct mp_exp_storage<mp_exp<tag, A1, A2, A3, A4> >
 {
- typedef mp_exp<tag, A1, A2, A3> type;
+ typedef mp_exp<tag, A1, A2, A3, A4> type;
 };
 
 template<class tag, class Arg1>
-struct mp_exp<tag, Arg1, void, void>
+struct mp_exp<tag, Arg1, void, void, void>
 {
    typedef mpl::int_<1> arity;
    typedef typename arg_type<Arg1>::type left_type;
@@ -253,7 +269,7 @@
 };
 
 template<class Arg1>
-struct mp_exp<terminal, Arg1, void, void>
+struct mp_exp<terminal, Arg1, void, void, void>
 {
    typedef mpl::int_<0> arity;
    typedef Arg1 result_type;
@@ -276,7 +292,7 @@
 };
 
 template <class tag, class Arg1, class Arg2>
-struct mp_exp<tag, Arg1, Arg2, void>
+struct mp_exp<tag, Arg1, Arg2, void, void>
 {
    typedef mpl::int_<2> arity;
    typedef typename arg_type<Arg1>::type left_type;
@@ -309,7 +325,7 @@
 };
 
 template <class tag, class Arg1, class Arg2, class Arg3>
-struct mp_exp
+struct mp_exp<tag, Arg1, Arg2, Arg3, void>
 {
    typedef mpl::int_<3> arity;
    typedef typename arg_type<Arg1>::type left_type;
@@ -350,6 +366,61 @@
    mp_exp& operator=(const mp_exp&);
 };
 
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+struct mp_exp
+{
+ typedef mpl::int_<4> arity;
+ typedef typename arg_type<Arg1>::type left_type;
+ typedef typename arg_type<Arg2>::type left_middle_type;
+ typedef typename arg_type<Arg3>::type right_middle_type;
+ typedef typename arg_type<Arg4>::type right_type;
+ typedef typename left_type::result_type left_result_type;
+ typedef typename left_middle_type::result_type left_middle_result_type;
+ typedef typename right_middle_type::result_type right_middle_result_type;
+ typedef typename right_type::result_type right_result_type;
+ typedef typename combine_expression<
+ typename combine_expression<
+ typename combine_expression<left_result_type, left_middle_result_type>::type,
+ right_middle_result_type
+ >::type,
+ right_result_type
+ >::type result_type;
+ typedef tag tag_type;
+
+ mp_exp(const Arg1& a1, const Arg2& a2, const Arg3& a3, const Arg4& a4) : arg1(a1), arg2(a2), arg3(a3), arg4(a4) {}
+
+ left_type left()const { return left_type(arg1); }
+ left_middle_type left_middle()const { return left_middle_type(arg2); }
+ right_middle_type right_middle()const { return right_middle_type(arg3); }
+ right_type right()const { return right_type(arg4); }
+ const Arg1& left_ref()const{ return arg1; }
+ const Arg2& left_middle_ref()const{ return arg2; }
+ const Arg3& right_middle_ref()const{ return arg3; }
+ const Arg4& right_ref()const{ return arg4; }
+
+ operator unmentionable_type()const
+ {
+ result_type r(*this);
+ return r ? &unmentionable<void>::proc : 0;
+ }
+
+ static const unsigned left_depth = left_type::depth + 1;
+ static const unsigned left_middle_depth = left_middle_type::depth + 1;
+ static const unsigned right_middle_depth = right_middle_type::depth + 1;
+ static const unsigned right_depth = right_type::depth + 1;
+
+ static const unsigned left_max_depth = left_depth > left_middle_depth ? left_depth : left_middle_depth;
+ static const unsigned right_max_depth = right_depth > right_middle_depth ? right_depth : right_middle_depth;
+
+ static const unsigned depth = left_max_depth > right_max_depth ? left_max_depth : right_max_depth;
+private:
+ typename mp_exp_storage<Arg1>::type arg1;
+ typename mp_exp_storage<Arg2>::type arg2;
+ typename mp_exp_storage<Arg3>::type arg3;
+ typename mp_exp_storage<Arg4>::type arg4;
+ mp_exp& operator=(const mp_exp&);
+};
+
 template <class T>
 struct digits2
 {
@@ -506,16 +577,16 @@
 //
 template <class B, bool ExpressionTemplates>
 inline const mp_number<B, ExpressionTemplates>& operator + (const mp_number<B, ExpressionTemplates>& v) { return v; }
-template <class tag, class Arg1, class Arg2, class Arg3>
-inline const detail::mp_exp<tag, Arg1, Arg2, Arg3>& operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& v) { return v; }
 template <class B>
 inline detail::mp_exp<detail::negate, mp_number<B, true> > operator - (const mp_number<B, true>& v) { return detail::mp_exp<detail::negate, mp_number<B, true> >(v); }
-template <class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::negate, detail::mp_exp<tag, Arg1, Arg2, Arg3> > operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return detail::mp_exp<detail::negate, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(v); }
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::negate, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& v) { return detail::mp_exp<detail::negate, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(v); }
 template <class B>
 inline detail::mp_exp<detail::complement_immediates, mp_number<B, true> > operator ~ (const mp_number<B, true>& v) { return detail::mp_exp<detail::complement_immediates, mp_number<B, true> >(v); }
-template <class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::bitwise_complement, detail::mp_exp<tag, Arg1, Arg2, Arg3> > operator ~ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return detail::mp_exp<detail::bitwise_complement, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(v); }
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::bitwise_complement, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > operator ~ (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& v) { return detail::mp_exp<detail::bitwise_complement, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(v); }
 //
 // Then addition:
 //
@@ -537,50 +608,50 @@
 {
    return detail::mp_exp<detail::add_immediates, V, mp_number<B, true> >(a, b);
 }
-template <class B, class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::plus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
- operator + (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::plus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >
+ operator + (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::plus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::plus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >
- operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >
+ operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >(a, b);
+ return detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
-inline detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
- operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
+inline detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
+ operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
 {
- return detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+ return detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class V>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
- operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
+ operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
 {
- return detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+ return detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
 }
-template <class V, class tag, class Arg1, class Arg2, class Arg3>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::plus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
- operator + (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::plus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > >::type
+ operator + (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::plus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::plus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
 //
 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
 //
-template <class B, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::minus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
- operator + (const mp_number<B, true>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& b)
+template <class B, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::minus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type >
+ operator + (const mp_number<B, true>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::minus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
+ return detail::mp_exp<detail::minus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type >(a, b.left_ref());
 }
-template <class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::minus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
- operator + (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::minus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type >
+ operator + (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::minus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
+ return detail::mp_exp<detail::minus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type >(b, a.left_ref());
 }
 template <class B>
 inline detail::mp_exp<detail::subtract_immediates, mp_number<B, true>, mp_number<B, true> >
@@ -627,51 +698,51 @@
 {
    return detail::mp_exp<detail::subtract_immediates, V, mp_number<B, true> >(a, b);
 }
-template <class B, class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::minus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
- operator - (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::minus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >
+ operator - (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::minus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::minus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >
- operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >
+ operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >(a, b);
+ return detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
-inline detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
- operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
+inline detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
+ operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
 {
- return detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+ return detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class V>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
- operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
+ operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
 {
- return detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+ return detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
 }
-template <class V, class tag, class Arg1, class Arg2, class Arg3>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::minus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
- operator - (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::minus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > >::type
+ operator - (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::minus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::minus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
 //
 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
 //
-template <class B, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
- operator - (const mp_number<B, true>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& b)
-{
- return detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
-}
-template <class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::negate, detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
- operator - (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class B, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type >
+ operator - (const mp_number<B, true>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
+{
+ return detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type >(a, b.left_ref());
+}
+template <class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type > >
+ operator - (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::negate, detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >(
- detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref()));
+ return detail::mp_exp<detail::negate, detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type > >(
+ detail::mp_exp<detail::plus, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type >(b, a.left_ref()));
 }
 template <class B>
 inline detail::mp_exp<detail::add_immediates, mp_number<B, true>, mp_number<B, true> >
@@ -719,52 +790,52 @@
 {
    return detail::mp_exp<detail::multiply_immediates, V, mp_number<B, true> >(a, b);
 }
-template <class B, class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::multiplies, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
- operator * (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::multiplies, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >
+ operator * (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::multiplies, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::multiplies, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >
- operator * (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >
+ operator * (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >(a, b);
+ return detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
-inline detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
- operator * (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
+inline detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
+ operator * (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
 {
- return detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+ return detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class V>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
- operator * (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
+ operator * (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
 {
- return detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+ return detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
 }
-template <class V, class tag, class Arg1, class Arg2, class Arg3>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::multiplies, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
- operator * (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::multiplies, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > >::type
+ operator * (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::multiplies, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::multiplies, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
 //
 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
 //
-template <class B, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
- operator * (const mp_number<B, true>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& b)
-{
- return detail::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >(
- detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > (a, b.left_ref()));
-}
-template <class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
- operator * (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class B, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type > >
+ operator * (const mp_number<B, true>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
+{
+ return detail::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type > >(
+ detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type > (a, b.left_ref()));
+}
+template <class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type > >
+ operator * (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >(
- detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref()));
+ return detail::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type > >(
+ detail::mp_exp<detail::multiplies, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type >(b, a.left_ref()));
 }
 template <class B>
 inline detail::mp_exp<detail::negate, detail::mp_exp<detail::multiply_immediates, mp_number<B, true>, mp_number<B, true> > >
@@ -815,52 +886,52 @@
 {
    return detail::mp_exp<detail::divide_immediates, V, mp_number<B, true> >(a, b);
 }
-template <class B, class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::divides, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
- operator / (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::divides, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >
+ operator / (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::divides, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::divides, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >
- operator / (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >
+ operator / (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >(a, b);
+ return detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
-inline detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
- operator / (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
+inline detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
+ operator / (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
 {
- return detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+ return detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class V>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
- operator / (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
+ operator / (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
 {
- return detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+ return detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
 }
-template <class V, class tag, class Arg1, class Arg2, class Arg3>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::divides, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
- operator / (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::divides, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > >::type
+ operator / (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::divides, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::divides, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
 //
 // Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
 //
-template <class B, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::negate, detail::mp_exp<detail::divides, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
- operator / (const mp_number<B, true>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& b)
-{
- return detail::mp_exp<detail::negate, detail::mp_exp<detail::divides, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >(
- detail::mp_exp<detail::divides, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref()));
-}
-template <class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::negate, detail::mp_exp<detail::divides, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type, mp_number<B, true> > >
- operator / (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class B, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::divides, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type > >
+ operator / (const mp_number<B, true>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>& b)
+{
+ return detail::mp_exp<detail::negate, detail::mp_exp<detail::divides, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type > >(
+ detail::mp_exp<detail::divides, mp_number<B, true>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type >(a, b.left_ref()));
+}
+template <class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::divides, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type, mp_number<B, true> > >
+ operator / (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::negate, detail::mp_exp<detail::divides, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type, mp_number<B, true> > >(
- detail::mp_exp<detail::divides, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type, mp_number<B, true> >(a.left_ref(), b));
+ return detail::mp_exp<detail::negate, detail::mp_exp<detail::divides, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type, mp_number<B, true> > >(
+ detail::mp_exp<detail::divides, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3, Arg4>::left_type, mp_number<B, true> >(a.left_ref(), b));
 }
 template <class B>
 inline detail::mp_exp<detail::negate, detail::mp_exp<detail::divide_immediates, mp_number<B, true>, mp_number<B, true> > >
@@ -911,35 +982,35 @@
 {
    return detail::mp_exp<detail::modulus_immediates, V, mp_number<B, true> >(a, b);
 }
-template <class B, class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::modulus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
- operator % (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::modulus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >
+ operator % (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::modulus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::modulus, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >
- operator % (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >
+ operator % (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >(a, b);
+ return detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
-inline detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
- operator % (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
+inline detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
+ operator % (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
 {
- return detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+ return detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class V>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
- operator % (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
+ operator % (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
 {
- return detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+ return detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
 }
-template <class V, class tag, class Arg1, class Arg2, class Arg3>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::modulus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
- operator % (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::modulus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > >::type
+ operator % (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::modulus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::modulus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
 //
 // Left shift:
@@ -950,11 +1021,11 @@
 {
    return detail::mp_exp<detail::shift_left, mp_number<B, true>, I>(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class I>
-inline typename enable_if<is_integral<I>, detail::mp_exp<detail::shift_left, detail::mp_exp<tag, Arg1, Arg2, Arg3>, I> >::type
- operator << (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const I& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
+inline typename enable_if<is_integral<I>, detail::mp_exp<detail::shift_left, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type
+ operator << (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
 {
- return detail::mp_exp<detail::shift_left, detail::mp_exp<tag, Arg1, Arg2, Arg3>, I>(a, b);
+ return detail::mp_exp<detail::shift_left, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b);
 }
 //
 // Right shift:
@@ -965,11 +1036,11 @@
 {
    return detail::mp_exp<detail::shift_right, mp_number<B, true>, I>(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class I>
-inline typename enable_if<is_integral<I>, detail::mp_exp<detail::shift_right, detail::mp_exp<tag, Arg1, Arg2, Arg3>, I> >::type
- operator >> (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const I& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class I>
+inline typename enable_if<is_integral<I>, detail::mp_exp<detail::shift_right, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, I> >::type
+ operator >> (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const I& b)
 {
- return detail::mp_exp<detail::shift_right, detail::mp_exp<tag, Arg1, Arg2, Arg3>, I>(a, b);
+ return detail::mp_exp<detail::shift_right, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, I>(a, b);
 }
 //
 // Bitwise AND:
@@ -992,35 +1063,35 @@
 {
    return detail::mp_exp<detail::bitwise_and_immediates, V, mp_number<B, true> >(a, b);
 }
-template <class B, class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::bitwise_and, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
- operator & (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::bitwise_and, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >
+ operator & (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::bitwise_and, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::bitwise_and, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >
- operator & (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >
+ operator & (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >(a, b);
+ return detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
-inline detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
- operator & (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
+inline detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
+ operator & (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
 {
- return detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+ return detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class V>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
- operator & (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
+ operator & (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
 {
- return detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+ return detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
 }
-template <class V, class tag, class Arg1, class Arg2, class Arg3>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_and, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
- operator & (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_and, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > >::type
+ operator & (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::bitwise_and, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::bitwise_and, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
 //
 // Bitwise OR:
@@ -1043,35 +1114,35 @@
 {
    return detail::mp_exp<detail::bitwise_or_immediates, V, mp_number<B, true> >(a, b);
 }
-template <class B, class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::bitwise_or, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
- operator| (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::bitwise_or, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >
+ operator| (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::bitwise_or, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::bitwise_or, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >
- operator| (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >
+ operator| (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >(a, b);
+ return detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
-inline detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
- operator| (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
+inline detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
+ operator| (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
 {
- return detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+ return detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class V>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
- operator| (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
+ operator| (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
 {
- return detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+ return detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
 }
-template <class V, class tag, class Arg1, class Arg2, class Arg3>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_or, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
- operator| (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_or, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > >::type
+ operator| (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::bitwise_or, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::bitwise_or, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
 //
 // Bitwise XOR:
@@ -1094,35 +1165,35 @@
 {
    return detail::mp_exp<detail::bitwise_xor_immediates, V, mp_number<B, true> >(a, b);
 }
-template <class B, class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::bitwise_xor, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
- operator^ (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class B, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline detail::mp_exp<detail::bitwise_xor, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >
+ operator^ (const mp_number<B, true>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::bitwise_xor, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::bitwise_xor, mp_number<B, true>, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class B>
-inline detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >
- operator^ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B, true>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class B>
+inline detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >
+ operator^ (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const mp_number<B, true>& b)
 {
- return detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B, true> >(a, b);
+ return detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, mp_number<B, true> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
-inline detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
- operator^ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class tag2, class Arg1b, class Arg2b, class Arg3b, class Arg4b>
+inline detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >
+ operator^ (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b>& b)
 {
- return detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+ return detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b, Arg4b> >(a, b);
 }
-template <class tag, class Arg1, class Arg2, class Arg3, class V>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
- operator^ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V > >::type
+ operator^ (const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& a, const V& b)
 {
- return detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+ return detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>, V >(a, b);
 }
-template <class V, class tag, class Arg1, class Arg2, class Arg3>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_xor, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
- operator^ (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+template <class V, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_xor, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> > >::type
+ operator^ (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& b)
 {
- return detail::mp_exp<detail::bitwise_xor, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+ return detail::mp_exp<detail::bitwise_xor, V, detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> >(a, b);
 }
 
 //
@@ -1140,15 +1211,15 @@
 struct number_category : public mpl::int_<number_kind_floating_point> {};
 template <class Backend, bool ExpressionTemplates>
 struct number_category<mp_number<Backend, ExpressionTemplates> > : public number_category<Backend>{};
-template <class tag, class A1, class A2, class A3>
-struct number_category<detail::mp_exp<tag, A1, A2, A3> > : public number_category<typename detail::mp_exp<tag, A1, A2, A3>::result_type>{};
+template <class tag, class A1, class A2, class A3, class A4>
+struct number_category<detail::mp_exp<tag, A1, A2, A3, A4> > : public number_category<typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type>{};
 
 template <class T>
 struct component_type;
 template <class T, bool ExpressionTemplates>
 struct component_type<mp_number<T, ExpressionTemplates> > : public component_type<T>{};
-template <class tag, class A1, class A2, class A3>
-struct component_type<detail::mp_exp<tag, A1, A2, A3> > : public component_type<typename detail::mp_exp<tag, A1, A2, A3>::result_type>{};
+template <class tag, class A1, class A2, class A3, class A4>
+struct component_type<detail::mp_exp<tag, A1, A2, A3, A4> > : public component_type<typename detail::mp_exp<tag, A1, A2, A3, A4>::result_type>{};
 
 }} // namespaces
 
@@ -1157,10 +1228,10 @@
 template <class T>
 struct promote_arg;
 
-template <class tag, class A1, class A2, class A3>
-struct promote_arg<boost::multiprecision::detail::mp_exp<tag, A1, A2, A3> >
+template <class tag, class A1, class A2, class A3, class A4>
+struct promote_arg<boost::multiprecision::detail::mp_exp<tag, A1, A2, A3, A4> >
 {
- typedef typename boost::multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type type;
+ typedef typename boost::multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type type;
 };
 
 }}}

Modified: sandbox/big_number/boost/multiprecision/gmp.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/gmp.hpp (original)
+++ sandbox/big_number/boost/multiprecision/gmp.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -1412,6 +1412,29 @@
    typedef typename make_unsigned<Integer>::type unsigned_type;
    return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val)));
 }
+inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m)
+{
+ if(eval_get_sign(p) < 0)
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
+ }
+ mpz_powm(result.data(), base.data(), p.data(), m.data());
+}
+
+template <class Integer>
+inline typename enable_if<
+ mpl::and_<
+ is_unsigned<Integer>,
+ mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)>
+ >
+>::type eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
+{
+ if(p < 0)
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
+ }
+ mpz_powm_ui(result.data(), base.data(), p, m.data());
+}
 
 struct gmp_rational;
 void eval_add(gmp_rational& t, const gmp_rational& o);

Modified: sandbox/big_number/boost/multiprecision/integer_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/integer_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/integer_ops.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -49,25 +49,25 @@
    eval_qr(x.backend(), y.backend(), q.backend(), r.backend());
 }
 
-template <class Backend, bool ExpressionTemplates, class tag, class A1, class A2, class A3>
+template <class Backend, bool ExpressionTemplates, class tag, class A1, class A2, class A3, class A4>
 inline typename enable_if_c<number_category<Backend>::value == number_kind_integer>::type
- divide_qr(const mp_number<Backend, ExpressionTemplates>& x, const multiprecision::detail::mp_exp<tag, A1, A2, A3>& y,
+ divide_qr(const mp_number<Backend, ExpressionTemplates>& x, const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& y,
    mp_number<Backend, ExpressionTemplates>& q, mp_number<Backend, ExpressionTemplates>& r)
 {
    divide_qr(x, mp_number<Backend, ExpressionTemplates>(y), q, r);
 }
 
-template <class tag, class A1, class A2, class A3, class Backend, bool ExpressionTemplates>
+template <class tag, class A1, class A2, class A3, class A4, class Backend, bool ExpressionTemplates>
 inline typename enable_if_c<number_category<Backend>::value == number_kind_integer>::type
- divide_qr(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& x, const mp_number<Backend, ExpressionTemplates>& y,
+ divide_qr(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& x, const mp_number<Backend, ExpressionTemplates>& y,
    mp_number<Backend, ExpressionTemplates>& q, mp_number<Backend, ExpressionTemplates>& r)
 {
    divide_qr(mp_number<Backend, ExpressionTemplates>(x), y, q, r);
 }
 
-template <class tag, class A1, class A2, class A3, class tagb, class A1b, class A2b, class A3b, class Backend, bool ExpressionTemplates>
+template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b, class Backend, bool ExpressionTemplates>
 inline typename enable_if_c<number_category<Backend>::value == number_kind_integer>::type
- divide_qr(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& x, const multiprecision::detail::mp_exp<tagb, A1b, A2b, A3b>& y,
+ divide_qr(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& x, const multiprecision::detail::mp_exp<tagb, A1b, A2b, A3b, A4b>& y,
    mp_number<Backend, ExpressionTemplates>& q, mp_number<Backend, ExpressionTemplates>& r)
 {
    divide_qr(mp_number<Backend, ExpressionTemplates>(x), mp_number<Backend, ExpressionTemplates>(y), q, r);
@@ -81,11 +81,11 @@
    return eval_integer_modulus(x.backend(), val);
 }
 
-template <class tag, class A1, class A2, class A3, class Integer>
-inline typename enable_if<mpl::and_<is_integral<Integer>, mpl::bool_<number_category<typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type>::value == number_kind_integer> >, Integer>::type
- integer_modulus(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& x, Integer val)
+template <class tag, class A1, class A2, class A3, class A4, class Integer>
+inline typename enable_if<mpl::and_<is_integral<Integer>, mpl::bool_<number_category<typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type>::value == number_kind_integer> >, Integer>::type
+ integer_modulus(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& x, Integer val)
 {
- typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type result_type;
+ typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type result_type;
    return integer_modulus(result_type(x), val);
 }
 
@@ -97,11 +97,11 @@
    return eval_lsb(x.backend());
 }
 
-template <class tag, class A1, class A2, class A3>
-inline typename enable_if_c<number_category<typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type>::value == number_kind_integer, unsigned>::type
- lsb(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& x)
+template <class tag, class A1, class A2, class A3, class A4>
+inline typename enable_if_c<number_category<typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type>::value == number_kind_integer, unsigned>::type
+ lsb(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& x)
 {
- typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    number_type n(x);
    using default_ops::eval_lsb;
    return eval_lsb(n.backend());
@@ -115,11 +115,11 @@
    return eval_bit_test(x.backend(), index);
 }
 
-template <class tag, class A1, class A2, class A3>
-inline typename enable_if_c<number_category<typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type>::value == number_kind_integer, bool>::type
- bit_test(const multiprecision::detail::mp_exp<tag, A1, A2, A3>& x, unsigned index)
+template <class tag, class A1, class A2, class A3, class A4>
+inline typename enable_if_c<number_category<typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type>::value == number_kind_integer, bool>::type
+ bit_test(const multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>& x, unsigned index)
 {
- typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3>::result_type number_type;
+ typedef typename multiprecision::detail::mp_exp<tag, A1, A2, A3, A4>::result_type number_type;
    number_type n(x);
    using default_ops::eval_bit_test;
    return eval_bit_test(n.backend(), index);
@@ -152,6 +152,150 @@
    return x;
 }
 
+namespace detail{
+
+//
+// Calculate (a^p)%c:
+//
+template <class Backend>
+void eval_powm(Backend& result, const Backend& a, const Backend& p, const Backend& c)
+{
+ typedef typename canonical<unsigned char, Backend>::type ui_type;
+ Backend x, y(a), b(p);
+ x = ui_type(1u);
+ while(eval_get_sign(b) > 0)
+ {
+ if(eval_bit_test(b, 0))
+ {
+ eval_multiply(result, x, y);
+ eval_modulus(x, result, c);
+ }
+ eval_multiply(result, y, y);
+ eval_modulus(y, result, c);
+ eval_right_shift(b, ui_type(1));
+ }
+ eval_modulus(result, x, c);
+}
+
+template <class Backend, class Integer>
+void eval_powm(Backend& result, const Backend& a, const Backend& p, Integer c)
+{
+ typedef typename canonical<unsigned char, Backend>::type ui_type;
+ typedef typename canonical<Integer, Backend>::type i_type;
+
+ if(eval_get_sign(p) < 0)
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
+ }
+
+ Backend x, y(a), b(p);
+ x = ui_type(1u);
+ while(eval_get_sign(b) > 0)
+ {
+ if(eval_bit_test(b, 0))
+ {
+ eval_multiply(result, x, y);
+ eval_modulus(x, result, static_cast<i_type>(c));
+ }
+ eval_multiply(result, y, y);
+ eval_modulus(y, result, static_cast<i_type>(c));
+ eval_right_shift(b, ui_type(1));
+ }
+ eval_modulus(result, x, static_cast<i_type>(c));
+}
+
+template <class Backend, class Integer>
+void eval_powm(Backend& result, const Backend& a, Integer b, const Backend& c)
+{
+ typedef typename canonical<unsigned char, Backend>::type ui_type;
+ typedef typename canonical<Integer, Backend>::type i_type;
+
+ if(b < 0)
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
+ }
+
+ Backend x, y(a);
+ x = ui_type(1u);
+ while(b > 0)
+ {
+ if(b & 1)
+ {
+ eval_multiply(result, x, y);
+ eval_modulus(x, result, c);
+ }
+ eval_multiply(result, y, y);
+ eval_modulus(y, result, c);
+ b >>= 1;
+ }
+ eval_modulus(result, x, c);
+}
+
+template <class Backend, class Integer1, class Integer2>
+void eval_powm(Backend& result, const Backend& a, Integer1 b, Integer2 c)
+{
+ typedef typename canonical<unsigned char, Backend>::type ui_type;
+ typedef typename canonical<Integer1, Backend>::type i1_type;
+ typedef typename canonical<Integer2, Backend>::type i2_type;
+
+ if(b < 0)
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
+ }
+
+ Backend x, y(a);
+ x = ui_type(1u);
+ while(b > 0)
+ {
+ if(b & 1)
+ {
+ eval_multiply(result, x, y);
+ eval_modulus(x, result, static_cast<i2_type>(c));
+ }
+ eval_multiply(result, y, y);
+ eval_modulus(y, result, static_cast<i2_type>(c));
+ b >>= 1;
+ }
+ eval_modulus(result, x, static_cast<i2_type>(c));
+}
+
+struct powm_func
+{
+ template <class T, class U, class V>
+ void operator()(T& result, const T& b, const U& p, const V& m)const
+ {
+ eval_powm(result, b, p, m);
+ }
+};
+
+}
+
+template <class T, class U, class V>
+inline typename enable_if<
+ mpl::and_<
+ mpl::bool_<number_category<T>::value == number_kind_integer>,
+ mpl::or_<
+ is_mp_number<T>,
+ is_mp_number_expression<T>
+ >,
+ mpl::or_<
+ is_mp_number<U>,
+ is_mp_number_expression<U>,
+ is_integral<U>
+ >,
+ mpl::or_<
+ is_mp_number<V>,
+ is_mp_number_expression<V>,
+ is_integral<V>
+ >
+ >,
+ detail::mp_exp<detail::function, detail::powm_func, T, U, V> >::type
+ powm(const T& b, const U& p, const V& mod)
+{
+ return detail::mp_exp<detail::function, detail::powm_func, T, U, V>(
+ detail::powm_func(), b, p, mod);
+}
+
 }} //namespaces
 
 #endif

Modified: sandbox/big_number/boost/multiprecision/miller_rabin.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/miller_rabin.hpp (original)
+++ sandbox/big_number/boost/multiprecision/miller_rabin.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -197,17 +197,17 @@
    return miller_rabin_test(x, trials, gen);
 }
 
-template <class tag, class Arg1, class Arg2, class Arg3, class Engine>
-bool miller_rabin_test(const detail::mp_exp<tag, Arg1, Arg2, Arg3> & n, unsigned trials, Engine& gen)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class Engine>
+bool miller_rabin_test(const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> & n, unsigned trials, Engine& gen)
 {
- typedef typename detail::mp_exp<tag, Arg1, Arg2, Arg3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>::result_type number_type;
    return miller_rabin_test(number_type(n), trials, gen);
 }
 
-template <class tag, class Arg1, class Arg2, class Arg3>
-bool miller_rabin_test(const detail::mp_exp<tag, Arg1, Arg2, Arg3> & n, unsigned trials)
+template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+bool miller_rabin_test(const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4> & n, unsigned trials)
 {
- typedef typename detail::mp_exp<tag, Arg1, Arg2, Arg3>::result_type number_type;
+ typedef typename detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>::result_type number_type;
    return miller_rabin_test(number_type(n), trials);
 }
 

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 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -88,10 +88,10 @@
    mp_number(V v, typename enable_if<mpl::and_<is_convertible<V, Backend>, mpl::not_<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> > > > >::type* = 0)
       : m_backend(v){}
 
- template <class tag, class Arg1, class Arg2, class Arg3>
- mp_number& operator=(const detail::mp_exp<tag, Arg1, Arg2, Arg3>& e)
+ template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+ mp_number& operator=(const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& e)
    {
- typedef typename is_same<mp_number, typename detail::mp_exp<tag, Arg1, Arg2, Arg3>::result_type>::type tag_type;
+ typedef typename is_same<mp_number, typename detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>::result_type>::type tag_type;
       do_assign(e, tag_type());
       return *this;
    }
@@ -144,8 +144,8 @@
       return *this;
    }
 
- template <class tag, class Arg1, class Arg2, class Arg3>
- mp_number(const detail::mp_exp<tag, Arg1, Arg2, Arg3>& e)
+ template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+ mp_number(const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& e)
    {
       *this = e;
    }
@@ -165,8 +165,8 @@
       return *this;
    }
 
- template <class tag, class Arg1, class Arg2, class Arg3>
- mp_number& operator+=(const detail::mp_exp<tag, Arg1, Arg2, Arg3>& e)
+ template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+ mp_number& operator+=(const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& e)
    {
       // Create a copy if e contains this, but not if we're just doing a
       // x *= x
@@ -564,17 +564,17 @@
       return m_backend;
    }
 private:
- template <class tag, class Arg1, class Arg2, class Arg3>
- void do_assign(const detail::mp_exp<tag, Arg1, Arg2, Arg3>& e, const mpl::true_&)
+ template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+ void do_assign(const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& e, const mpl::true_&)
    {
       do_assign(e, tag());
    }
- template <class tag, class Arg1, class Arg2, class Arg3>
- void do_assign(const detail::mp_exp<tag, Arg1, Arg2, Arg3>& e, const mpl::false_&)
+ template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
+ void do_assign(const detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>& e, const mpl::false_&)
    {
       // The result of the expression isn't the same type as this -
       // create a temporary result and assign it to *this:
- typedef typename detail::mp_exp<tag, Arg1, Arg2, Arg3>::result_type temp_type;
+ typedef typename detail::mp_exp<tag, Arg1, Arg2, Arg3, Arg4>::result_type temp_type;
       temp_type t(e);
       *this = t;
    }
@@ -1061,12 +1061,12 @@
    {
       typedef typename Exp::right_type right_type;
       typedef typename right_type::tag_type tag_type;
- do_assign_function_1(e.left().value(), e.right(), tag_type());
+ do_assign_function_1(e.left().value(), e.right_ref(), tag_type());
    }
    template <class F, class Exp>
    void do_assign_function_1(const F& f, const Exp& val, const detail::terminal&)
    {
- f(m_backend, function_arg_value(val.value()));
+ f(m_backend, function_arg_value(val));
    }
    template <class F, class Exp, class Tag>
    void do_assign_function_1(const F& f, const Exp& val, const Tag&)
@@ -1081,24 +1081,24 @@
       typedef typename middle_type::tag_type tag_type;
       typedef typename Exp::right_type end_type;
       typedef typename end_type::tag_type end_tag;
- do_assign_function_2(e.left().value(), e.middle(), e.right(), tag_type(), end_tag());
+ do_assign_function_2(e.left().value(), e.middle_ref(), e.right_ref(), tag_type(), end_tag());
    }
    template <class F, class Exp1, class Exp2>
    void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const detail::terminal&, const detail::terminal&)
    {
- f(m_backend, function_arg_value(val1.value()), function_arg_value(val2.value()));
+ f(m_backend, function_arg_value(val1), function_arg_value(val2));
    }
    template <class F, class Exp1, class Exp2, class Tag1>
    void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const Tag1&, const detail::terminal&)
    {
       self_type temp1(val1);
- f(m_backend, temp1.backend(), function_arg_value(val2.value()));
+ f(m_backend, temp1.backend(), function_arg_value(val2));
    }
    template <class F, class Exp1, class Exp2, class Tag2>
    void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const detail::terminal&, const Tag2&)
    {
       self_type temp2(val2);
- f(m_backend, function_arg_value(val1.value()), temp2.backend());
+ f(m_backend, function_arg_value(val1), temp2.backend());
    }
    template <class F, class Exp1, class Exp2, class Tag1, class Tag2>
    void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const Tag1&, const Tag2&)
@@ -1109,6 +1109,51 @@
    }
 
    template <class Exp>
+ void do_assign_function(const Exp& e, const mpl::int_<4>&)
+ {
+ typedef typename Exp::left_middle_type left_type;
+ typedef typename left_type::tag_type left_tag_type;
+ typedef typename Exp::right_middle_type middle_type;
+ typedef typename middle_type::tag_type middle_tag_type;
+ typedef typename Exp::right_type right_type;
+ typedef typename right_type::tag_type right_tag_type;
+ do_assign_function_3a(e.left().value(), e.left_middle_ref(), e.right_middle_ref(), e.right_ref(), left_tag_type(), middle_tag_type(), right_tag_type());
+ }
+ template <class F, class Exp1, class Exp2, class Exp3, class Tag2, class Tag3>
+ void do_assign_function_3a(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const detail::terminal&, const Tag2& t2, const Tag3& t3)
+ {
+ do_assign_function_3b(f, val1, val2, val3, t2, t3);
+ }
+ template <class F, class Exp1, class Exp2, class Exp3, class Tag1, class Tag2, class Tag3>
+ void do_assign_function_3a(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const Tag1&, const Tag2& t2, const Tag3& t3)
+ {
+ mp_number t(val1);
+ do_assign_function_3b(f, t, val2, val3, t2, t3);
+ }
+ template <class F, class Exp1, class Exp2, class Exp3, class Tag3>
+ void do_assign_function_3b(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const detail::terminal&, const Tag3& t3)
+ {
+ do_assign_function_3c(f, val1, val2, val3, t3);
+ }
+ template <class F, class Exp1, class Exp2, class Exp3, class Tag2, class Tag3>
+ void do_assign_function_3b(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const Tag2& t2, const Tag3& t3)
+ {
+ mp_number t(val2);
+ do_assign_function_3c(f, val1, t, val3, t3);
+ }
+ template <class F, class Exp1, class Exp2, class Exp3>
+ void do_assign_function_3c(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const detail::terminal&)
+ {
+ f(m_backend, function_arg_value(val1), function_arg_value(val2), function_arg_value(val3));
+ }
+ template <class F, class Exp1, class Exp2, class Exp3, class Tag3>
+ void do_assign_function_3c(const F& f, const Exp1& val1, const Exp2& val2, const Exp3& val3, const Tag3& t3)
+ {
+ mp_number t(val3);
+ do_assign_function_3c(f, val1, val2, t, detail::terminal());
+ }
+
+ template <class Exp>
    void do_add(const Exp& e, const detail::terminal&)
    {
       using default_ops::eval_add;
@@ -1485,6 +1530,10 @@
    static const Backend& function_arg_value(const self_type& v) { return v.backend(); }
    template <class V>
    static const V& function_arg_value(const V& v) { return v; }
+ template <class A1, class A2, class A3, class A4>
+ static const A1& function_arg_value(const detail::mp_exp<detail::terminal, A1, A2, A3, A4>& exp) { return exp.value(); }
+ template <class A2, class A3, class A4>
+ static const Backend& function_arg_value(const detail::mp_exp<detail::terminal, mp_number<Backend>, A2, A3, A4>& exp) { return exp.value().backend(); }
    Backend m_backend;
 };
 
@@ -1497,14 +1546,14 @@
    return a.compare(b);
 }
 
-template <class Backend, bool ExpressionTemplates, class tag, class A1, class A2, class A3>
-inline int mp_number_compare(const mp_number<Backend, ExpressionTemplates>& a, const mp_exp<tag, A1, A2, A3>& b)
+template <class Backend, bool ExpressionTemplates, class tag, class A1, class A2, class A3, class A4>
+inline int mp_number_compare(const mp_number<Backend, ExpressionTemplates>& a, const mp_exp<tag, A1, A2, A3, A4>& b)
 {
    return a.compare(mp_number<Backend, ExpressionTemplates>(b));
 }
 
-template <class tag, class A1, class A2, class A3, class Backend, bool ExpressionTemplates>
-inline int mp_number_compare(const mp_exp<tag, A1, A2, A3>& a, const mp_number<Backend, ExpressionTemplates>& b)
+template <class tag, class A1, class A2, class A3, class A4, class Backend, bool ExpressionTemplates>
+inline int mp_number_compare(const mp_exp<tag, A1, A2, A3, A4>& a, const mp_number<Backend, ExpressionTemplates>& b)
 {
    return -b.compare(mp_number<Backend, ExpressionTemplates>(a));
 }
@@ -1521,26 +1570,26 @@
    return -b.compare(a);
 }
 
-template <class tag, class A1, class A2, class A3, class tag2, class A1b, class A2b, class A3b>
-inline int mp_number_compare(const mp_exp<tag, A1, A2, A3>& a, const mp_exp<tag2, A1b, A2b, A3b>& b)
+template <class tag, class A1, class A2, class A3, class A4, class tag2, class A1b, class A2b, class A3b>
+inline int mp_number_compare(const mp_exp<tag, A1, A2, A3, A4>& a, const mp_exp<tag2, A1b, A2b, A3b>& b)
 {
- typedef typename mp_exp<tag, A1, A2, A3>::result_type real1;
+ typedef typename mp_exp<tag, A1, A2, A3, A4>::result_type real1;
    typedef typename mp_exp<tag2, A1b, A2b, A3b>::result_type real2;
    return real1(a).compare(real2(b));
 }
 
-template <class tag, class A1, class A2, class A3, class Val>
-inline typename enable_if<is_arithmetic<Val>, int>::type mp_number_compare(const mp_exp<tag, A1, A2, A3>& a, const Val b)
+template <class tag, class A1, class A2, class A3, class A4, class Val>
+inline typename enable_if<is_arithmetic<Val>, int>::type mp_number_compare(const mp_exp<tag, A1, A2, A3, A4>& a, const Val b)
 {
- typedef typename mp_exp<tag, A1, A2, A3>::result_type real;
+ typedef typename mp_exp<tag, A1, A2, A3, A4>::result_type real;
    real t(a);
    return t.compare(b);
 }
 
-template <class Val, class tag, class A1, class A2, class A3>
-inline typename enable_if<is_arithmetic<Val>, int>::type mp_number_compare(const Val a, const mp_exp<tag, A1, A2, A3>& b)
+template <class Val, class tag, class A1, class A2, class A3, class A4>
+inline typename enable_if<is_arithmetic<Val>, int>::type mp_number_compare(const Val a, const mp_exp<tag, A1, A2, A3, A4>& b)
 {
- typedef typename mp_exp<tag, A1, A2, A3>::result_type real;
+ typedef typename mp_exp<tag, A1, A2, A3, A4>::result_type real;
    return -real(b).compare(a);
 }
 
@@ -1640,10 +1689,10 @@
 
 namespace detail{
 
-template <class tag, class A1, class A2, class A3>
-inline std::ostream& operator << (std::ostream& os, const mp_exp<tag, A1, A2, A3>& r)
+template <class tag, class A1, class A2, class A3, class A4>
+inline std::ostream& operator << (std::ostream& os, const mp_exp<tag, A1, A2, A3, A4>& r)
 {
- typedef typename mp_exp<tag, A1, A2, A3>::result_type value_type;
+ typedef typename mp_exp<tag, A1, A2, A3, A4>::result_type value_type;
    value_type temp(r);
    return os << temp;
 }

Modified: sandbox/big_number/boost/multiprecision/mpfr.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mpfr.hpp (original)
+++ sandbox/big_number/boost/multiprecision/mpfr.hpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -900,18 +900,31 @@
    mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
 }
 
+#ifdef BOOST_MSVC
+//
+// The enable_if usage below doesn't work with msvc - but only when
+// certain other enable_if usages are defined first. It's a capricious
+// and rather annoying compiler bug in other words....
+//
+# define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10) &&
+#else
+#define BOOST_MP_ENABLE_IF_WORKAROUND
+#endif
+
 template <unsigned Digits10, class Integer>
-inline typename enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<sizeof(Integer) <= sizeof(long)> > >::type eval_pow(mpfr_float_backend<Digits10>& result, const mpfr_float_backend<Digits10>& b, const Integer& e)
+inline typename enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type eval_pow(mpfr_float_backend<Digits10>& result, const mpfr_float_backend<Digits10>& b, const Integer& e)
 {
    mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
 }
 
 template <unsigned Digits10, class Integer>
-inline typename enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<sizeof(Integer) <= sizeof(long)> > >::type eval_pow(mpfr_float_backend<Digits10>& result, const mpfr_float_backend<Digits10>& b, const Integer& e)
+inline typename enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type eval_pow(mpfr_float_backend<Digits10>& result, const mpfr_float_backend<Digits10>& b, const Integer& e)
 {
    mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
 }
 
+#undef BOOST_MP_ENABLE_IF_WORKAROUND
+
 template <unsigned Digits10>
 inline void eval_exp(mpfr_float_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
 {

Modified: sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s01.html
==============================================================================
--- sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s01.html (original)
+++ sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s01.html 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -13,9 +13,9 @@
 <div class="spirit-nav">
 <a accesskey="p" href="../indexes.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../indexes.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s02.html"><img src="../../images/next.png" alt="Next"></a>
 </div>
-<div class="section id1100765">
+<div class="section id904139">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id1100765"></a>Function Index</h3></div></div></div>
+<a name="id904139"></a>Function Index</h3></div></div></div>
 <p><a class="link" href="s01.html#idx_id_0">A</a> <a class="link" href="s01.html#idx_id_1">B</a> <a class="link" href="s01.html#idx_id_2">C</a> <a class="link" href="s01.html#idx_id_3">D</a> <a class="link" href="s01.html#idx_id_4">E</a> <a class="link" href="s01.html#idx_id_5">F</a> <a class="link" href="s01.html#idx_id_7">I</a> <a class="link" href="s01.html#idx_id_8">L</a> <a class="link" href="s01.html#idx_id_9">M</a> <a class="link" href="s01.html#idx_id_12">P</a> <a class="link" href="s01.html#idx_id_13">R</a> <a class="link" href="s01.html#idx_id_14">S</a> <a class="link" href="s01.html#idx_id_15">T</a> <a class="link" href="s01.html#idx_id_16">Z</a></p>
 <div class="variablelist"><dl>
 <dt>
@@ -168,13 +168,19 @@
 <dt>
 <a name="idx_id_12"></a><span class="term">P</span>
 </dt>
-<dd><div class="index"><ul class="index" type="none" compact><li class="listitem" style="list-style-type: none">
+<dd><div class="index"><ul class="index" type="none" compact>
+<li class="listitem" style="list-style-type: none">
+<p><span class="index-entry-level-0">powm</span></p>
+<div class="index"><ul class="index" type="none" compact><li class="listitem" style="list-style-type: none"><p><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">mp_number</span></a></p></li></ul></div>
+</li>
+<li class="listitem" style="list-style-type: none">
 <p><span class="index-entry-level-0">precision</span></p>
 <div class="index"><ul class="index" type="none" compact>
 <li class="listitem" style="list-style-type: none"><p><a class="link" href="../intro.html" title="Introduction"><span class="index-entry-level-1">Introduction</span></a></p></li>
 <li class="listitem" style="list-style-type: none"><p><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">mp_number</span></a></p></li>
 </ul></div>
-</li></ul></div></dd>
+</li>
+</ul></div></dd>
 <dt>
 <a name="idx_id_13"></a><span class="term">R</span>
 </dt>

Modified: sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s02.html
==============================================================================
--- sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s02.html (original)
+++ sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s02.html 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -13,9 +13,9 @@
 <div class="spirit-nav">
 <a accesskey="p" href="s01.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../indexes.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s03.html"><img src="../../images/next.png" alt="Next"></a>
 </div>
-<div class="section id1101718">
+<div class="section id905111">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id1101718"></a>Class Index</h3></div></div></div>
+<a name="id905111"></a>Class Index</h3></div></div></div>
 <p><a class="link" href="s02.html#idx_id_19">C</a> <a class="link" href="s02.html#idx_id_23">G</a> <a class="link" href="s02.html#idx_id_26">M</a> <a class="link" href="s02.html#idx_id_27">N</a> <a class="link" href="s02.html#idx_id_32">T</a></p>
 <div class="variablelist"><dl>
 <dt>

Modified: sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s03.html
==============================================================================
--- sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s03.html (original)
+++ sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s03.html 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -13,9 +13,9 @@
 <div class="spirit-nav">
 <a accesskey="p" href="s02.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../indexes.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="s04.html"><img src="../../images/next.png" alt="Next"></a>
 </div>
-<div class="section id1101951">
+<div class="section id905344">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id1101951"></a>Typedef Index</h3></div></div></div>
+<a name="id905344"></a>Typedef Index</h3></div></div></div>
 <p><a class="link" href="s03.html#idx_id_36">C</a> <a class="link" href="s03.html#idx_id_41">I</a> <a class="link" href="s03.html#idx_id_42">L</a> <a class="link" href="s03.html#idx_id_43">M</a> <a class="link" href="s03.html#idx_id_49">T</a></p>
 <div class="variablelist"><dl>
 <dt>

Modified: sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s04.html
==============================================================================
--- sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s04.html (original)
+++ sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/indexes/s04.html 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -12,9 +12,9 @@
 <div class="spirit-nav">
 <a accesskey="p" href="s03.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../indexes.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a>
 </div>
-<div class="section id1104317">
+<div class="section id908786">
 <div class="titlepage"><div><div><h3 class="title">
-<a name="id1104317"></a>Index</h3></div></div></div>
+<a name="id908786"></a>Index</h3></div></div></div>
 <p><a class="link" href="s04.html#idx_id_51">A</a> <a class="link" href="s04.html#idx_id_52">B</a> <a class="link" href="s04.html#idx_id_53">C</a> <a class="link" href="s04.html#idx_id_54">D</a> <a class="link" href="s04.html#idx_id_55">E</a> <a class="link" href="s04.html#idx_id_56">F</a> <a class="link" href="s04.html#idx_id_57">G</a> <a class="link" href="s04.html#idx_id_58">I</a> <a class="link" href="s04.html#idx_id_59">L</a> <a class="link" href="s04.html#idx_id_60">M</a> <a class="link" href="s04.html#idx_id_61">N</a> <a class="link" href="s04.html#idx_id_62">O</a> <a class="link" href="s04.html#idx_id_63">P</a> <a class="link" href="s04.html#idx_id_64">R</a> <a class="link" href="s04.html#idx_id_65">S</a> <a class="link" href="s04.html#idx_id_66">T</a> <a class="link" href="s04.html#idx_id_67">Z</a></p>
 <div class="variablelist"><dl>
 <dt>
@@ -400,6 +400,7 @@
 <li class="listitem" style="list-style-type: none"><p><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">miller_rabin_test</span></a></p></li>
 <li class="listitem" style="list-style-type: none"><p><span class="bold"><strong><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">mp_number</span></a></strong></span></p></li>
 <li class="listitem" style="list-style-type: none"><p><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">number_category</span></a></p></li>
+<li class="listitem" style="list-style-type: none"><p><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">powm</span></a></p></li>
 <li class="listitem" style="list-style-type: none"><p><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">precision</span></a></p></li>
 <li class="listitem" style="list-style-type: none"><p><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">round</span></a></p></li>
 <li class="listitem" style="list-style-type: none"><p><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">sign</span></a></p></li>
@@ -444,6 +445,10 @@
 </dt>
 <dd><div class="index"><ul class="index" type="none" compact>
 <li class="listitem" style="list-style-type: none">
+<p><span class="index-entry-level-0">powm</span></p>
+<div class="index"><ul class="index" type="none" compact><li class="listitem" style="list-style-type: none"><p><a class="link" href="../ref/mp_number.html" title="mp_number"><span class="index-entry-level-1">mp_number</span></a></p></li></ul></div>
+</li>
+<li class="listitem" style="list-style-type: none">
 <p><span class="index-entry-level-0">precision</span></p>
 <div class="index"><ul class="index" type="none" compact>
 <li class="listitem" style="list-style-type: none"><p><a class="link" href="../intro.html" title="Introduction"><span class="index-entry-level-1">Introduction</span></a></p></li>

Modified: sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/ref/mp_number.html
==============================================================================
--- sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/ref/mp_number.html (original)
+++ sandbox/big_number/libs/multiprecision/doc/html/boost_multiprecision/ref/mp_number.html 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -144,8 +144,10 @@
 <span class="keyword">struct</span> <span class="identifier">number_category</span><span class="special">;</span>
 
 <span class="comment">// Integer specific functions:</span>
+<span class="emphasis"><em>unmentionable-expression-template-type</em></span> <span class="identifier">pow</span><span class="special">(</span><span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;,</span> <span class="keyword">unsigned</span><span class="special">);</span>
+<span class="emphasis"><em>unmentionable-expression-template-type</em></span> <span class="identifier">powm</span><span class="special">(</span><span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">m</span><span class="special">);</span>
 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Backend</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">ExpressionTemplates</span><span class="special">&gt;</span>
-<span class="keyword">bool</span> <span class="identifier">divide_qr</span><span class="special">(</span><span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span>
+<span class="keyword">void</span> <span class="identifier">divide_qr</span><span class="special">(</span><span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span>
                <span class="identifier">mp_number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">,</span> <span class="identifier">ExpressionTemplates</span><span class="special">&gt;&amp;</span> <span class="identifier">q</span><span class="special">,</span> <span class="identifier">mp_number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">,</span> <span class="identifier">ExpressionTemplates</span><span class="special">&gt;&amp;</span> <span class="identifier">r</span><span class="special">);</span>
 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Integer</span><span class="special">&gt;</span>
 <span class="identifier">Integer</span> <span class="identifier">integer_modulus</span><span class="special">(</span><span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">Integer</span> <span class="identifier">val</span><span class="special">);</span>
@@ -558,6 +560,19 @@
 <a name="boost_multiprecision.ref.mp_number.h7"></a>
         <span><a name="boost_multiprecision.ref.mp_number.integer_functions"></a></span><a class="link" href="mp_number.html#boost_multiprecision.ref.mp_number.integer_functions">Integer functions</a>
       </h5>
+<pre class="programlisting"><span class="emphasis"><em>unmentionable-expression-template-type</em></span> <span class="identifier">pow</span><span class="special">(</span><span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">p</span><span class="special">);</span>
+</pre>
+<p>
+ Returns <span class="emphasis"><em>b<sup>p</sup></em></span> as an expression template. Note that this
+ function should be used with extreme care as the result can grow so large
+ as to take "effectively forever" to compute, or else simply run
+ the host machine out of memory.
+ </p>
+<pre class="programlisting"><span class="emphasis"><em>unmentionable-expression-template-type</em></span> <span class="identifier">powm</span><span class="special">(</span><span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">,</span> <span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">m</span><span class="special">);</span>
+</pre>
+<p>
+ Returns <span class="emphasis"><em>b<sup>p</sup> mod m</em></span> as an expression template.
+ </p>
 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Backend</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">ExpressionTemplates</span><span class="special">&gt;</span>
 <span class="keyword">bool</span> <span class="identifier">divide_qr</span><span class="special">(</span><span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">const</span> <span class="emphasis"><em>mp_number-or-expression-template-type</em></span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">,</span>
                <span class="identifier">mp_number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">,</span> <span class="identifier">ExpressionTemplates</span><span class="special">&gt;&amp;</span> <span class="identifier">q</span><span class="special">,</span> <span class="identifier">mp_number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">,</span> <span class="identifier">ExpressionTemplates</span><span class="special">&gt;&amp;</span> <span class="identifier">r</span><span class="special">);</span>

Modified: sandbox/big_number/libs/multiprecision/doc/html/index.html
==============================================================================
--- sandbox/big_number/libs/multiprecision/doc/html/index.html (original)
+++ sandbox/big_number/libs/multiprecision/doc/html/index.html 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -117,7 +117,7 @@
 </div>
 </div>
 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
-<td align="left"><p><small>Last revised: April 15, 2012 at 17:36:47 GMT</small></p></td>
+<td align="left"><p><small>Last revised: May 09, 2012 at 18:07:25 GMT</small></p></td>
 <td align="right"><div class="copyright-footer"></div></td>
 </tr></table>
 <hr>

Modified: sandbox/big_number/libs/multiprecision/doc/multiprecision.qbk
==============================================================================
--- sandbox/big_number/libs/multiprecision/doc/multiprecision.qbk (original)
+++ sandbox/big_number/libs/multiprecision/doc/multiprecision.qbk 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -1052,8 +1052,10 @@
    struct number_category;
 
    // Integer specific functions:
+ ``['unmentionable-expression-template-type]`` pow(const ``['mp_number-or-expression-template-type]``&, unsigned);
+ ``['unmentionable-expression-template-type]`` powm(const ``['mp_number-or-expression-template-type]``& b, const ``['mp_number-or-expression-template-type]``& p, const ``['mp_number-or-expression-template-type]``& m);
    template <class Backend, bool ExpressionTemplates>
- bool divide_qr(const ``['mp_number-or-expression-template-type]``& x, const ``['mp_number-or-expression-template-type]``& y,
+ void divide_qr(const ``['mp_number-or-expression-template-type]``& x, const ``['mp_number-or-expression-template-type]``& y,
                   mp_number<Backend, ExpressionTemplates>& q, mp_number<Backend, ExpressionTemplates>& r);
    template <class Integer>
    Integer integer_modulus(const ``['mp_number-or-expression-template-type]``& x, Integer val);
@@ -1336,6 +1338,15 @@
 
 [h4 Integer functions]
 
+ ``['unmentionable-expression-template-type]`` pow(const ``['mp_number-or-expression-template-type]``& b, unsigned p);
+
+Returns ['b[super p]] as an expression template. Note that this function should be used with extreme care as the result can grow so
+large as to take "effectively forever" to compute, or else simply run the host machine out of memory.
+
+ ``['unmentionable-expression-template-type]`` powm(const ``['mp_number-or-expression-template-type]``& b, const ``['mp_number-or-expression-template-type]``& p, const ``['mp_number-or-expression-template-type]``& m);
+
+Returns ['b[super p] mod m] as an expression template.
+
    template <class Backend, bool ExpressionTemplates>
    bool divide_qr(const ``['mp_number-or-expression-template-type]``& x, const ``['mp_number-or-expression-template-type]``& y,
                   mp_number<Backend, ExpressionTemplates>& q, mp_number<Backend, ExpressionTemplates>& r);

Modified: sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_cpp_int.cpp 2012-05-10 05:20:26 EDT (Thu, 10 May 2012)
@@ -257,6 +257,33 @@
          BOOST_CHECK_EQUAL(t.str(), t1.str());
       }
 
+ //
+ // Now integer functions:
+ //
+ mpz_int z1, z2;
+ test_type t1, t2;
+ divide_qr(a, b, z1, z2);
+ divide_qr(a1, b1, t1, t2);
+ BOOST_CHECK_EQUAL(z1.str(), t1.str());
+ BOOST_CHECK_EQUAL(z2.str(), t2.str());
+ BOOST_CHECK_EQUAL(integer_modulus(a, si), integer_modulus(a1, si));
+ BOOST_CHECK_EQUAL(lsb(a), lsb(a1));
+
+ for(unsigned i = 0; i < 1000; i += 13)
+ {
+ BOOST_CHECK_EQUAL(bit_test(a, i), bit_test(a1, i));
+ }
+ if(!std::numeric_limits<test_type>::is_modulo)
+ {
+ // We have to take care that our powers don't grow too large, otherwise this takes "forever",
+ // also don't test for modulo types, as these may give a diffferent result from arbitrary
+ // precision types:
+ BOOST_CHECK_EQUAL(mpz_int(pow(d, ui % 19)).str(), test_type(pow(d1, ui % 19)).str());
+ BOOST_CHECK_EQUAL(mpz_int(powm(a, b, c)).str(), test_type(powm(a, b, c)).str());
+ BOOST_CHECK_EQUAL(mpz_int(powm(a, b, ui)).str(), test_type(powm(a, b, ui)).str());
+ BOOST_CHECK_EQUAL(mpz_int(powm(a, ui, c)).str(), test_type(powm(a, ui, c)).str());
+ }
+
       if(last_error_count != boost::detail::test_errors())
       {
          last_error_count = boost::detail::test_errors();


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