Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r74545 - in sandbox/big_number: boost/math boost/math/big_number libs/math/test
From: john_at_[hidden]
Date: 2011-09-24 07:08:01


Author: johnmaddock
Date: 2011-09-24 07:07:59 EDT (Sat, 24 Sep 2011)
New Revision: 74545
URL: http://svn.boost.org/trac/boost/changeset/74545

Log:
First cut at removing proto dependency - concept check now builds with msvc and mpfr_real_50.
Text files modified:
   sandbox/big_number/boost/math/big_number.hpp | 909 ++++++++++++++-------------
   sandbox/big_number/boost/math/big_number/big_number_base.hpp | 1283 ++++++++++++++++++++++++---------------
   sandbox/big_number/boost/math/big_number/default_ops.hpp | 286 +++++---
   sandbox/big_number/boost/math/big_number/gmp.hpp | 4
   sandbox/big_number/libs/math/test/big_number_concept_check.cpp | 62 -
   sandbox/big_number/libs/math/test/test_arithmetic.cpp | 44 -
   6 files changed, 1435 insertions(+), 1153 deletions(-)

Modified: sandbox/big_number/boost/math/big_number.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number.hpp (original)
+++ sandbox/big_number/boost/math/big_number.hpp 2011-09-24 07:07:59 EDT (Sat, 24 Sep 2011)
@@ -6,7 +6,6 @@
 #ifndef BOOST_MATH_EXTENDED_REAL_HPP
 #define BOOST_MATH_EXTENDED_REAL_HPP
 
-#include <boost/proto/proto.hpp>
 #include <boost/cstdint.hpp>
 #include <boost/mpl/max.hpp>
 #include <boost/mpl/plus.hpp>
@@ -25,54 +24,33 @@
 namespace boost{ namespace math{
 
 template <class Backend>
-class big_number : public detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type >
+class big_number
 {
- typedef detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type > base_type;
    typedef big_number<Backend> self_type;
 public:
- big_number()
- {
- proto::value(*this) = this;
- BOOST_ASSERT(proto::value(*this) == this);
- }
- big_number(const big_number& e) : m_backend(e.m_backend)
- {
- proto::value(*this) = this;
- BOOST_ASSERT(proto::value(*this) == this);
- }
+ big_number(){}
+ big_number(const big_number& e) : m_backend(e.m_backend){}
    template <class V>
    big_number(V v, typename enable_if<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> > >::type* dummy1 = 0)
    {
- proto::value(*this) = this;
- BOOST_ASSERT(proto::value(*this) == this);
       m_backend = canonical_value(v);
    }
- big_number(const big_number& e, unsigned digits10) : m_backend(e.m_backend, digits10)
- {
- proto::value(*this) = this;
- BOOST_ASSERT(proto::value(*this) == this);
- }
+ big_number(const big_number& e, unsigned digits10) : m_backend(e.m_backend, digits10){}
    template <class V>
    big_number(V v, unsigned digits10, typename enable_if<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> > >::type* dummy1 = 0)
- : base_type(digits10)
    {
- proto::value(*this) = this;
- BOOST_ASSERT(proto::value(*this) == this);
+ m_backend.precision(digits10);
       m_backend = canonical_value(v);
    }
 
    template <class V>
    big_number(V v, typename enable_if<mpl::and_<is_convertible<V, Backend>, mpl::not_<boost::is_arithmetic<V> > > >::type* dummy1 = 0)
- : m_backend(v)
- {
- proto::value(*this) = this;
- BOOST_ASSERT(proto::value(*this) == this);
- }
+ : m_backend(v){}
 
- template <class Exp>
- big_number& operator=(const detail::big_number_exp<Exp>& e)
+ template <class tag, class Arg1, class Arg2, class Arg3>
+ big_number& operator=(const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& e)
    {
- do_assign(e, typename detail::assign_and_eval<Exp>::type());
+ do_assign(e, tag());
       return *this;
    }
 
@@ -90,20 +68,14 @@
       return *this;
    }
 
- template <class Exp>
- big_number(const detail::big_number_exp<Exp>& e)
+ template <class tag, class Arg1, class Arg2, class Arg3>
+ big_number(const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& e)
    {
- proto::value(*this) = this;
- BOOST_ASSERT(proto::value(*this) == this);
- do_assign(e, typename detail::assign_and_eval<Exp>::type());
+ do_assign(e, tag());
    }
 
 #ifndef BOOST_NO_RVALUE_REFERENCES
- big_number(big_number&& r) : m_backend(r.m_backend)
- {
- proto::value(*this) = this;
- BOOST_ASSERT(proto::value(*this) == this);
- }
+ big_number(big_number&& r) : m_backend(r.m_backend){}
    big_number& operator=(big_number&& r)
    {
       m_backend.swap(r.m_backend);
@@ -111,19 +83,25 @@
    }
 #endif
 
- template <class Exp>
- big_number& operator+=(const detail::big_number_exp<Exp>& e)
+ big_number& operator+=(const self_type& val)
+ {
+ do_add(detail::big_number_exp<detail::terminal, self_type>(val), detail::terminal());
+ return *this;
+ }
+
+ template <class tag, class Arg1, class Arg2, class Arg3>
+ big_number& operator+=(const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& e)
    {
       // Create a copy if e contains this, but not if we're just doing a
       // x *= x
       if(contains_self(e) && !is_self(e))
       {
          self_type temp(e);
- do_add(temp, typename proto::tag_of<self_type>::type());
+ do_add(detail::big_number_exp<detail::terminal, self_type>(temp), detail::terminal());
       }
       else
       {
- do_add(e, typename proto::tag_of<Exp>::type());
+ do_add(e, tag());
       }
       return *this;
    }
@@ -137,6 +115,12 @@
       return *this;
    }
 
+ big_number& operator-=(const self_type& val)
+ {
+ do_subtract(detail::big_number_exp<detail::terminal, self_type>(val), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
    big_number& operator-=(const detail::big_number_exp<Exp>& e)
    {
@@ -144,11 +128,11 @@
       if(contains_self(e))
       {
          self_type temp(e);
- do_subtract(temp, typename proto::tag_of<self_type>::type());
+ do_subtract(temp, typename detail_of<self_type>::type());
       }
       else
       {
- do_subtract(e, typename proto::tag_of<Exp>::type());
+ do_subtract(e, typename Exp::tag_type());
       }
       return *this;
    }
@@ -162,6 +146,13 @@
       return *this;
    }
 
+
+ big_number& operator *= (const self_type& e)
+ {
+ do_multiplies(detail::big_number_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
    big_number& operator*=(const detail::big_number_exp<Exp>& e)
    {
@@ -170,11 +161,11 @@
       if(contains_self(e) && !is_self(e))
       {
          self_type temp(e);
- do_multiplies(temp, typename proto::tag_of<self_type>::type());
+ do_multiplies(detail::big_number_exp<detail::terminal, self_type>(temp), detail::terminal());
       }
       else
       {
- do_multiplies(e, typename proto::tag_of<Exp>::type());
+ do_multiplies(e, typename Exp::tag_type());
       }
       return *this;
    }
@@ -188,19 +179,25 @@
       return *this;
    }
 
+ big_number& operator%=(const self_type& e)
+ {
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
+ do_modulus(detail::big_number_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
    template <class Exp>
    big_number& operator%=(const detail::big_number_exp<Exp>& e)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "The modulus operation is only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
       // Create a temporary if the RHS references *this:
       if(contains_self(e))
       {
          self_type temp(e);
- do_modulus(temp, typename proto::tag_of<self_type>::type());
+ do_modulus(temp, typename detail_of<self_type>::type());
       }
       else
       {
- do_modulus(e, typename proto::tag_of<Exp>::type());
+ do_modulus(e, typename Exp::tag_type());
       }
       return *this;
    }
@@ -208,7 +205,7 @@
    typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
       operator%=(const V& v)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "The modulus operation is only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
       using big_num_default_ops::modulus;
       modulus(m_backend, canonical_value(v));
       return *this;
@@ -255,7 +252,7 @@
    template <class V>
    typename enable_if<is_integral<V>, big_number&>::type operator <<= (V val)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "The left-shift operation is only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The left-shift operation is only valid for integer types");
       check_shift_range(val, mpl::bool_<(sizeof(V) > sizeof(std::size_t))>(), is_signed<V>());
       left_shift(m_backend, canonical_value(val));
       return *this;
@@ -264,12 +261,18 @@
    template <class V>
    typename enable_if<is_integral<V>, big_number&>::type operator >>= (V val)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "The right-shift operation is only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The right-shift operation is only valid for integer types");
       check_shift_range(val, mpl::bool_<(sizeof(V) > sizeof(std::size_t))>(), is_signed<V>());
       right_shift(m_backend, canonical_value(val));
       return *this;
    }
 
+ big_number& operator /= (const self_type& e)
+ {
+ do_divide(detail::big_number_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
    big_number& operator/=(const detail::big_number_exp<Exp>& e)
    {
@@ -277,11 +280,11 @@
       if(contains_self(e))
       {
          self_type temp(e);
- do_divide(temp, typename proto::tag_of<self_type>::type());
+ do_divide(detail::big_number_exp<detail::terminal, self_type>(temp), typename detail_of<self_type>::type());
       }
       else
       {
- do_divide(e, typename proto::tag_of<Exp>::type());
+ do_divide(e, typename Exp::tag_type());
       }
       return *this;
    }
@@ -295,6 +298,12 @@
       return *this;
    }
 
+ big_number& operator&=(const self_type& e)
+ {
+ do_bitwise_and(detail::big_number_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
    big_number& operator&=(const detail::big_number_exp<Exp>& e)
    {
@@ -303,11 +312,11 @@
       if(contains_self(e) && !is_self(e))
       {
          self_type temp(e);
- do_bitwise_and(temp, typename proto::tag_of<self_type>::type());
+ do_bitwise_and(temp, typename detail_of<self_type>::type());
       }
       else
       {
- do_bitwise_and(e, typename proto::tag_of<Exp>::type());
+ do_bitwise_and(e, typename Exp::tag_type());
       }
       return *this;
    }
@@ -321,6 +330,12 @@
       return *this;
    }
 
+ big_number& operator|=(const self_type& e)
+ {
+ do_bitwise_or(detail::big_number_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
    big_number& operator|=(const detail::big_number_exp<Exp>& e)
    {
@@ -329,11 +344,11 @@
       if(contains_self(e) && !is_self(e))
       {
          self_type temp(e);
- do_bitwise_or(temp, typename proto::tag_of<self_type>::type());
+ do_bitwise_or(temp, typename detail_of<self_type>::type());
       }
       else
       {
- do_bitwise_or(e, typename proto::tag_of<Exp>::type());
+ do_bitwise_or(e, typename Exp::tag_type());
       }
       return *this;
    }
@@ -347,17 +362,23 @@
       return *this;
    }
 
+ big_number& operator^=(const self_type& e)
+ {
+ do_bitwise_xor(detail::big_number_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
    big_number& operator^=(const detail::big_number_exp<Exp>& e)
    {
       if(contains_self(e))
       {
          self_type temp(e);
- do_bitwise_xor(temp, typename proto::tag_of<self_type>::type());
+ do_bitwise_xor(temp, typename detail_of<self_type>::type());
       }
       else
       {
- do_bitwise_xor(e, typename proto::tag_of<Exp>::type());
+ do_bitwise_xor(e, typename Exp::tag_type());
       }
       return *this;
    }
@@ -370,6 +391,15 @@
       bitwise_xor(m_backend, canonical_value(v));
       return *this;
    }
+ //
+ // Use in boolean context:
+ //
+ typedef bool (self_type::*unmentionable_type)()const;
+
+ operator unmentionable_type()const
+ {
+ return is_zero() ? 0 : &self_type::is_zero;
+ }
 
    //
    // swap:
@@ -381,12 +411,12 @@
    //
    // Zero and sign:
    //
- bool is_zero()
+ bool is_zero()const
    {
       using big_num_default_ops::is_zero;
       return is_zero(m_backend);
    }
- int sign()
+ int sign()const
    {
       using big_num_default_ops::get_sign;
       return get_sign(m_backend);
@@ -435,6 +465,7 @@
    template <class V>
    typename enable_if<is_arithmetic<V>, int>::type compare(const V& o)const
    {
+ using big_num_default_ops::get_sign;
       if(o == 0)
          return get_sign(m_backend);
       return m_backend.compare(canonical_value(o));
@@ -475,114 +506,99 @@
    void do_assign(const Exp& e, const detail::add_immediates&)
    {
       using big_num_default_ops::add;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- add(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ add(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
    }
-
+/*
    template <class Exp>
    void do_assign(const Exp& e, const detail::add_and_negate_immediates&)
    {
       using big_num_default_ops::add;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- add(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ add(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
       m_backend.negate();
    }
-
+*/
    template <class Exp>
    void do_assign(const Exp& e, const detail::subtract_immediates&)
    {
       using big_num_default_ops::subtract;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- subtract(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ subtract(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
    }
-
+ /*
    template <class Exp>
    void do_assign(const Exp& e, const detail::subtract_and_negate_immediates&)
    {
       using big_num_default_ops::subtract;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- subtract(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ subtract(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
       m_backend.negate();
    }
-
+ */
    template <class Exp>
    void do_assign(const Exp& e, const detail::multiply_immediates&)
    {
       using big_num_default_ops::multiply;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- multiply(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ multiply(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
    }
 
    template <class Exp>
- void do_assign(const Exp& e, const detail::multiply_and_negate_immediates&)
+ void do_assign(const Exp& e, const detail::divide_immediates&)
    {
- using big_num_default_ops::multiply;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- multiply(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
- m_backend.negate();
+ using big_num_default_ops::divide;
+ divide(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
    }
 
+#if 0
    template <class Exp>
- void do_assign(const Exp& e, const detail::divide_immediates&)
+ void do_assign(const Exp& e, const detail::multiply_and_negate_immediates&)
    {
- using big_num_default_ops::divide;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- divide(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ using big_num_default_ops::multiply;
+ multiply(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
+ m_backend.negate();
    }
 
    template <class Exp>
    void do_assign(const Exp& e, const detail::divide_and_negate_immediates&)
    {
       using big_num_default_ops::divide;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- divide(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ divide(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
       m_backend.negate();
    }
 
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::unary_plus&)
+ void do_assign(const Exp& e, const detail::unary_plus&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
+ typedef typename Exp::left_type left_type;
+ do_assign(e.left(), typename left_type::tag_type());
    }
 
+#endif
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::negate&)
+ void do_assign(const Exp& e, const detail::negate&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
+ typedef typename Exp::left_type left_type;
+ do_assign(e.left(), typename left_type::tag_type());
       m_backend.negate();
    }
-
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::plus&)
+ void do_assign(const Exp& e, const detail::plus&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
 
- static int const left_depth = boost::result_of<detail::CalcDepth(left_type)>::type::value;
- static int const right_depth = boost::result_of<detail::CalcDepth(right_type)>::type::value;
+ static int const left_depth = left_type::depth;
+ static int const right_depth = right_type::depth;
 
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
+ bool bl = contains_self(e.left());
+ bool br = contains_self(e.right());
 
- if(bl && is_self(proto::left(e)))
+ if(bl && is_self(e.left()))
       {
          // Ignore the left node, it's *this, just add the right:
- do_add(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_add(e.right(), typename right_type::tag_type());
       }
- else if(br && is_self(proto::right(e)))
+ else if(br && is_self(e.right()))
       {
          // Ignore the right node, it's *this, just add the left:
- do_add(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_add(e.left(), typename left_type::tag_type());
       }
       else if(bl || br)
       {
@@ -591,36 +607,36 @@
       }
       else if(left_depth >= right_depth)
       {
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
- do_add(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_assign(e.left(), typename left_type::tag_type());
+ do_add(e.right(), typename right_type::tag_type());
       }
       else
       {
- do_assign(proto::right(e), typename detail::assign_and_eval<right_type>::type());
- do_add(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_assign(e.right(), typename right_type::tag_type());
+ do_add(e.left(), typename left_type::tag_type());
       }
    }
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::minus&)
+ void do_assign(const Exp& e, const detail::minus&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
 
- static int const left_depth = boost::result_of<detail::CalcDepth(left_type)>::type::value;
- static int const right_depth = boost::result_of<detail::CalcDepth(right_type)>::type::value;
+ static int const left_depth = left_type::depth;
+ static int const right_depth = right_type::depth;
 
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
+ bool bl = contains_self(e.left());
+ bool br = contains_self(e.right());
 
- if(bl && is_self(proto::left(e)))
+ if(bl && is_self(e.left()))
       {
          // Ignore the left node, it's *this, just subtract the right:
- do_subtract(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_subtract(e.right(), typename right_type::tag_type());
       }
- else if(br && is_self(proto::right(e)))
+ else if(br && is_self(e.right()))
       {
          // Ignore the right node, it's *this, just subtract the left and negate the result:
- do_subtract(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_subtract(e.left(), typename left_type::tag_type());
          m_backend.negate();
       }
       else if(bl || br)
@@ -630,37 +646,37 @@
       }
       else if(left_depth >= right_depth)
       {
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
- do_subtract(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_assign(e.left(), typename left_type::tag_type());
+ do_subtract(e.right(), typename right_type::tag_type());
       }
       else
       {
- do_assign(proto::right(e), typename detail::assign_and_eval<right_type>::type());
- do_subtract(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_assign(e.right(), typename right_type::tag_type());
+ do_subtract(e.left(), typename left_type::tag_type());
          m_backend.negate();
       }
    }
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::multiplies&)
+ void do_assign(const Exp& e, const detail::multiplies&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
 
- static int const left_depth = boost::result_of<detail::CalcDepth(left_type)>::type::value;
- static int const right_depth = boost::result_of<detail::CalcDepth(right_type)>::type::value;
+ static int const left_depth = left_type::depth;
+ static int const right_depth = right_type::depth;
 
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
+ bool bl = contains_self(e.left());
+ bool br = contains_self(e.right());
 
- if(bl && is_self(proto::left(e)))
+ if(bl && is_self(e.left()))
       {
          // Ignore the left node, it's *this, just add the right:
- do_multiplies(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_multiplies(e.right(), typename right_type::tag_type());
       }
- else if(br && is_self(proto::right(e)))
+ else if(br && is_self(e.right()))
       {
          // Ignore the right node, it's *this, just add the left:
- do_multiplies(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_multiplies(e.left(), typename left_type::tag_type());
       }
       else if(bl || br)
       {
@@ -669,28 +685,28 @@
       }
       else if(left_depth >= right_depth)
       {
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
- do_multiplies(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_assign(e.left(), typename left_type::tag_type());
+ do_multiplies(e.right(), typename right_type::tag_type());
       }
       else
       {
- do_assign(proto::right(e), typename detail::assign_and_eval<right_type>::type());
- do_multiplies(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_assign(e.right(), typename right_type::tag_type());
+ do_multiplies(e.left(), typename left_type::tag_type());
       }
    }
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::divides&)
+ void do_assign(const Exp& e, const detail::divides&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
 
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
+ bool bl = contains_self(e.left());
+ bool br = contains_self(e.right());
 
- if(bl && is_self(proto::left(e)))
+ if(bl && is_self(e.left()))
       {
          // Ignore the left node, it's *this, just add the right:
- do_divide(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_divide(e.right(), typename right_type::tag_type());
       }
       else if(bl || br)
       {
@@ -699,28 +715,28 @@
       }
       else
       {
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
- do_divide(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_assign(e.left(), typename left_type::tag_type());
+ do_divide(e.right(), typename right_type::tag_type());
       }
    }
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::modulus&)
+ void do_assign(const Exp& e, const detail::modulus&)
    {
       //
       // This operation is only valid for integer backends:
       //
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "The modulus operation is only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
 
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
 
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
+ bool bl = contains_self(e.left());
+ bool br = contains_self(e.right());
 
- if(bl && is_self(proto::left(e)))
+ if(bl && is_self(e.left()))
       {
          // Ignore the left node, it's *this, just add the right:
- do_modulus(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_modulus(e.right(), typename right_type::tag_type());
       }
       else if(bl || br)
       {
@@ -729,208 +745,199 @@
       }
       else
       {
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
- do_modulus(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_assign(e.left(), typename left_type::tag_type());
+ do_modulus(e.right(), typename right_type::tag_type());
       }
    }
    template <class Exp>
    void do_assign(const Exp& e, const detail::modulus_immediates&)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "The modulus operation is only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
       using big_num_default_ops::modulus;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- modulus(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ modulus(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
    }
 
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::bitwise_and&)
+ void do_assign(const Exp& e, const detail::bitwise_and&)
    {
       //
       // This operation is only valid for integer backends:
       //
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "Bitwise operations are only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
 
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
 
- static int const left_depth = boost::result_of<detail::CalcDepth(left_type)>::type::value;
- static int const right_depth = boost::result_of<detail::CalcDepth(right_type)>::type::value;
+ static int const left_depth = left_type::depth;
+ static int const right_depth = right_type::depth;
 
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
+ bool bl = contains_self(e.left());
+ bool br = contains_self(e.right());
 
- if(bl && is_self(proto::left(e)))
+ if(bl && is_self(e.left()))
       {
          // Ignore the left node, it's *this, just add the right:
- do_bitwise_and(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_bitwise_and(e.right(), typename right_type::tag_type());
       }
- else if(br && is_self(proto::right(e)))
+ else if(br && is_self(e.right()))
       {
- do_bitwise_and(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_bitwise_and(e.left(), typename left_type::tag_type());
       }
       else if(left_depth >= right_depth)
       {
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
- do_bitwise_and(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_assign(e.left(), typename left_type::tag_type());
+ do_bitwise_and(e.right(), typename right_type::tag_type());
       }
       else
       {
- do_assign(proto::right(e), typename detail::assign_and_eval<right_type>::type());
- do_bitwise_and(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_assign(e.right(), typename right_type::tag_type());
+ do_bitwise_and(e.left(), typename left_type::tag_type());
       }
    }
    template <class Exp>
    void do_assign(const Exp& e, const detail::bitwise_and_immediates&)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "Bitwise operations are only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
       using big_num_default_ops::bitwise_and;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- bitwise_and(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ bitwise_and(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
    }
 
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::bitwise_or&)
+ void do_assign(const Exp& e, const detail::bitwise_or&)
    {
       //
       // This operation is only valid for integer backends:
       //
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "Bitwise operations are only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
 
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
 
- static int const left_depth = boost::result_of<detail::CalcDepth(left_type)>::type::value;
- static int const right_depth = boost::result_of<detail::CalcDepth(right_type)>::type::value;
+ static int const left_depth = left_type::depth;
+ static int const right_depth = right_type::depth;
 
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
+ bool bl = contains_self(e.left());
+ bool br = contains_self(e.right());
 
- if(bl && is_self(proto::left(e)))
+ if(bl && is_self(e.left()))
       {
          // Ignore the left node, it's *this, just add the right:
- do_bitwise_or(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_bitwise_or(e.right(), typename right_type::tag_type());
       }
- else if(br && is_self(proto::right(e)))
+ else if(br && is_self(e.right()))
       {
- do_bitwise_or(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_bitwise_or(e.left(), typename left_type::tag_type());
       }
       else if(left_depth >= right_depth)
       {
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
- do_bitwise_or(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_assign(e.left(), typename left_type::tag_type());
+ do_bitwise_or(e.right(), typename right_type::tag_type());
       }
       else
       {
- do_assign(proto::right(e), typename detail::assign_and_eval<right_type>::type());
- do_bitwise_or(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_assign(e.right(), typename right_type::tag_type());
+ do_bitwise_or(e.left(), typename left_type::tag_type());
       }
    }
    template <class Exp>
    void do_assign(const Exp& e, const detail::bitwise_or_immediates&)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "Bitwise operations are only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
       using big_num_default_ops::bitwise_or;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- bitwise_or(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ bitwise_or(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
    }
 
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::bitwise_xor&)
+ void do_assign(const Exp& e, const detail::bitwise_xor&)
    {
       //
       // This operation is only valid for integer backends:
       //
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "Bitwise operations are only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
 
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
 
- static int const left_depth = boost::result_of<detail::CalcDepth(left_type)>::type::value;
- static int const right_depth = boost::result_of<detail::CalcDepth(right_type)>::type::value;
+ static int const left_depth = left_type::depth;
+ static int const right_depth = right_type::depth;
 
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
+ bool bl = contains_self(e.left());
+ bool br = contains_self(e.right());
 
- if(bl && is_self(proto::left(e)))
+ if(bl && is_self(e.left()))
       {
          // Ignore the left node, it's *this, just add the right:
- do_bitwise_xor(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_bitwise_xor(e.right(), typename right_type::tag_type());
       }
- else if(br && is_self(proto::right(e)))
+ else if(br && is_self(e.right()))
       {
- do_bitwise_xor(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_bitwise_xor(e.left(), typename left_type::tag_type());
       }
       else if(left_depth >= right_depth)
       {
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
- do_bitwise_xor(proto::right(e), typename proto::tag_of<right_type>::type());
+ do_assign(e.left(), typename left_type::tag_type());
+ do_bitwise_xor(e.right(), typename right_type::tag_type());
       }
       else
       {
- do_assign(proto::right(e), typename detail::assign_and_eval<right_type>::type());
- do_bitwise_xor(proto::left(e), typename proto::tag_of<left_type>::type());
+ do_assign(e.right(), typename right_type::tag_type());
+ do_bitwise_xor(e.left(), typename left_type::tag_type());
       }
    }
    template <class Exp>
    void do_assign(const Exp& e, const detail::bitwise_xor_immediates&)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "Bitwise operations are only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "Bitwise operations are only valid for integer types");
       using big_num_default_ops::bitwise_xor;
- typedef typename proto::tag_of<typename proto::result_of::left<Exp>::type>::type left_tag;
- typedef typename proto::tag_of<typename proto::result_of::right<Exp>::type>::type right_tag;
- bitwise_xor(m_backend, canonical_value(underlying_value(proto::left(e), left_tag())), canonical_value(underlying_value(proto::right(e), right_tag())));
+ bitwise_xor(m_backend, canonical_value(e.left().value()), canonical_value(e.right().value()));
    }
-
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::terminal&)
+ void do_assign(const Exp& e, const detail::terminal&)
    {
       if(!is_self(e))
       {
- m_backend = canonical_value(proto::value(e));
+ m_backend = canonical_value(e.value());
       }
    }
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::function&)
+ void do_assign(const Exp& e, const detail::function&)
    {
- typedef typename proto::arity_of<Exp>::type tag_type;
+ typedef typename Exp::arity tag_type;
       do_assign_function(e, tag_type());
    }
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::shift_left&)
+ void do_assign(const Exp& e, const detail::shift_left&)
    {
       // We can only shift by an integer value, not an arbitrary expression:
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::arity_of<right_type>::type right_arity;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ typedef typename right_type::arity right_arity;
       BOOST_STATIC_ASSERT_MSG(right_arity::value == 0, "The left shift operator requires an integer value for the shift operand.");
- typedef typename proto::result_of::value<right_type>::type right_value_type;
+ typedef typename right_type::result_type right_value_type;
       BOOST_STATIC_ASSERT_MSG(is_integral<right_value_type>::value, "The left shift operator requires an integer value for the shift operand.");
- typedef typename proto::tag_of<left_type>::type tag_type;
- do_assign_left_shift(proto::left(e), canonical_value(proto::value(proto::right(e))), tag_type());
+ typedef typename left_type::tag_type tag_type;
+ do_assign_left_shift(e.left(), canonical_value(e.right().value()), tag_type());
    }
 
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::shift_right&)
+ void do_assign(const Exp& e, const detail::shift_right&)
    {
       // We can only shift by an integer value, not an arbitrary expression:
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::arity_of<right_type>::type right_arity;
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ typedef typename right_type::arity right_arity;
       BOOST_STATIC_ASSERT_MSG(right_arity::value == 0, "The left shift operator requires an integer value for the shift operand.");
- typedef typename proto::result_of::value<right_type>::type right_value_type;
+ typedef typename right_type::result_type right_value_type;
       BOOST_STATIC_ASSERT_MSG(is_integral<right_value_type>::value, "The left shift operator requires an integer value for the shift operand.");
- typedef typename proto::tag_of<left_type>::type tag_type;
- do_assign_right_shift(proto::left(e), canonical_value(proto::value(proto::right(e))), tag_type());
+ typedef typename left_type::tag_type tag_type;
+ do_assign_right_shift(e.left(), canonical_value(e.right().value()), tag_type());
    }
 
    template <class Exp>
- void do_assign(const Exp& e, const proto::tag::complement&)
+ void do_assign(const Exp& e, const detail::bitwise_complement&)
    {
       using big_num_default_ops::complement;
- self_type temp(proto::left(e));
+ self_type temp(e.left());
       complement(m_backend, temp.backend());
    }
 
@@ -938,21 +945,21 @@
    void do_assign(const Exp& e, const detail::complement_immediates&)
    {
       using big_num_default_ops::complement;
- complement(m_backend, canonical_value(proto::left(e)));
+ complement(m_backend, canonical_value(e.left().value()));
    }
 
    template <class Exp, class Val>
- void do_assign_right_shift(const Exp& e, const Val& val, const proto::tag::terminal&)
+ void do_assign_right_shift(const Exp& e, const Val& val, const detail::terminal&)
    {
       using big_num_default_ops::right_shift;
- right_shift(m_backend, canonical_value(proto::value(e)), val);
+ right_shift(m_backend, canonical_value(e.value()), val);
    }
 
    template <class Exp, class Val>
- void do_assign_left_shift(const Exp& e, const Val& val, const proto::tag::terminal&)
+ void do_assign_left_shift(const Exp& e, const Val& val, const detail::terminal&)
    {
       using big_num_default_ops::left_shift;
- left_shift(m_backend, canonical_value(proto::value(e)), val);
+ left_shift(m_backend, canonical_value(e.value()), val);
    }
 
    template <class Exp, class Val, class Tag>
@@ -972,21 +979,21 @@
    }
 
    template <class Exp>
- void do_assign_function(const Exp& e, const mpl::long_<1>&)
+ void do_assign_function(const Exp& e, const mpl::int_<1>&)
    {
- proto::value(proto::left(e))(&m_backend);
+ e.left().value()(&m_backend);
    }
    template <class Exp>
- void do_assign_function(const Exp& e, const mpl::long_<2>&)
+ void do_assign_function(const Exp& e, const mpl::int_<2>&)
    {
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<right_type>::type tag_type;
- do_assign_function_1(proto::value(proto::left(e)), proto::right(e), tag_type());
+ 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());
    }
    template <class F, class Exp>
- void do_assign_function_1(const F& f, const Exp& val, const proto::tag::terminal&)
+ void do_assign_function_1(const F& f, const Exp& val, const detail::terminal&)
    {
- f(m_backend, canonical_value(proto::value(val)));
+ f(m_backend, canonical_value(val.value()));
    }
    template <class F, class Exp, class Tag>
    void do_assign_function_1(const F& f, const Exp& val, const Tag&)
@@ -995,30 +1002,30 @@
       f(m_backend, t.backend());
    }
    template <class Exp>
- void do_assign_function(const Exp& e, const mpl::long_<3>&)
+ void do_assign_function(const Exp& e, const mpl::int_<3>&)
    {
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<right_type>::type tag_type;
- typedef typename proto::result_of::child_c<Exp, 2>::type end_type;
- typedef typename proto::tag_of<end_type>::type end_tag;
- do_assign_function_2(proto::value(proto::left(e)), proto::right(e), proto::child_c<2>(e), tag_type(), end_tag());
+ typedef typename Exp::middle_type middle_type;
+ 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());
    }
    template <class F, class Exp1, class Exp2>
- void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const proto::tag::terminal&, const proto::tag::terminal&)
+ void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const detail::terminal&, const detail::terminal&)
    {
- f(m_backend, canonical_value(proto::value(val1)), canonical_value(proto::value(val2)));
+ f(m_backend, canonical_value(val1.value()), canonical_value(val2.value()));
    }
    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 proto::tag::terminal&)
+ 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(), canonical_value(proto::value(val2)));
+ f(m_backend, temp1.backend(), canonical_value(val2.value()));
    }
    template <class F, class Exp1, class Exp2, class Tag2>
- void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const proto::tag::terminal&, const 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, canonical_value(proto::value(val1)), temp2.backend());
+ f(m_backend, canonical_value(val1.value()), 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&)
@@ -1029,137 +1036,160 @@
    }
 
    template <class Exp>
- void do_add(const Exp& e, const proto::tag::terminal&)
+ void do_add(const Exp& e, const detail::terminal&)
    {
       using big_num_default_ops::add;
- add(m_backend, canonical_value(proto::value(e)));
- }
-
- template <class Exp>
- void do_add(const Exp& e, const proto::tag::unary_plus&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_add(proto::left(e), typename proto::tag_of<left_type>::type());
+ add(m_backend, canonical_value(e.value()));
    }
 
    template <class Exp>
- void do_add(const Exp& e, const proto::tag::negate&)
+ void do_add(const Exp& e, const detail::negate&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_subtract(proto::left(e), typename proto::tag_of<left_type>::type());
+ typedef typename Exp::left_type left_type;
+ do_subtract(e.left(), typename left_type::tag_type());
    }
 
    template <class Exp>
- void do_add(const Exp& e, const proto::tag::plus&)
+ void do_add(const Exp& e, const detail::plus&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_add(proto::left(e), typename proto::tag_of<left_type>::type());
- do_add(proto::right(e), typename proto::tag_of<right_type>::type());
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_add(e.left(), typename left_type::tag_type());
+ do_add(e.right(), typename right_type::tag_type());
    }
 
    template <class Exp>
- void do_add(const Exp& e, const proto::tag::minus&)
+ void do_add(const Exp& e, const detail::minus&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_add(proto::left(e), typename proto::tag_of<left_type>::type());
- do_subtract(proto::right(e), typename proto::tag_of<right_type>::type());
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_add(e.left(), typename left_type::tag_type());
+ do_subtract(e.right(), typename right_type::tag_type());
    }
 
    template <class Exp, class unknown>
    void do_add(const Exp& e, const unknown&)
    {
       self_type temp(e);
- do_add(temp, proto::tag::terminal());
+ do_add(detail::big_number_exp<detail::terminal, self_type>(temp), detail::terminal());
    }
 
    template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::terminal&)
+ void do_add(const Exp& e, const detail::add_immediates&)
    {
+ using big_num_default_ops::add;
+ add(m_backend, canonical_value(e.left().value()));
+ add(m_backend, canonical_value(e.right().value()));
+ }
+ template <class Exp>
+ void do_add(const Exp& e, const detail::subtract_immediates&)
+ {
+ using big_num_default_ops::add;
       using big_num_default_ops::subtract;
- subtract(m_backend, canonical_value(proto::value(e)));
+ add(m_backend, canonical_value(e.left().value()));
+ subtract(m_backend, canonical_value(e.right().value()));
    }
-
    template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::unary_plus&)
+ void do_subtract(const Exp& e, const detail::terminal&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_subtract(proto::left(e), typename proto::tag_of<left_type>::type());
+ using big_num_default_ops::subtract;
+ subtract(m_backend, canonical_value(e.value()));
    }
 
    template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::negate&)
+ void do_subtract(const Exp& e, const detail::negate&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_add(proto::left(e), typename proto::tag_of<left_type>::type());
+ typedef typename Exp::left_type left_type;
+ do_add(e.left(), typename left_type::tag_type());
    }
 
    template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::plus&)
+ void do_subtract(const Exp& e, const detail::plus&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_subtract(proto::left(e), typename proto::tag_of<left_type>::type());
- do_subtract(proto::right(e), typename proto::tag_of<right_type>::type());
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_subtract(e.left(), typename left_type::tag_type());
+ do_subtract(e.right(), typename right_type::tag_type());
    }
 
    template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::minus&)
+ void do_subtract(const Exp& e, const detail::minus&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_subtract(proto::left(e), typename proto::tag_of<left_type>::type());
- do_add(proto::right(e), typename proto::tag_of<right_type>::type());
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_subtract(e.left(), typename left_type::tag_type());
+ do_add(e.right(), typename right_type::tag_type());
+ }
+ template <class Exp>
+ void do_subtract(const Exp& e, const detail::add_immediates&)
+ {
+ using big_num_default_ops::subtract;
+ subtract(m_backend, canonical_value(e.left().value()));
+ subtract(m_backend, canonical_value(e.right().value()));
+ }
+ template <class Exp>
+ void do_subtract(const Exp& e, const detail::subtract_immediates&)
+ {
+ using big_num_default_ops::add;
+ using big_num_default_ops::subtract;
+ subtract(m_backend, canonical_value(e.left().value()));
+ add(m_backend, canonical_value(e.right().value()));
    }
-
    template <class Exp, class unknown>
    void do_subtract(const Exp& e, const unknown&)
    {
       self_type temp(e);
- do_subtract(temp, proto::tag::terminal());
+ do_subtract(detail::big_number_exp<detail::terminal, self_type>(temp), detail::terminal());
    }
 
    template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::terminal&)
+ void do_multiplies(const Exp& e, const detail::terminal&)
    {
       using big_num_default_ops::multiply;
- multiply(m_backend, canonical_value(proto::value(e)));
+ multiply(m_backend, canonical_value(e.value()));
    }
 
    template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::unary_plus&)
+ void do_multiplies(const Exp& e, const detail::negate&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_multiplies(proto::left(e), typename proto::tag_of<left_type>::type());
+ typedef typename Exp::left_type left_type;
+ do_multiplies(e.left(), typename left_type::tag_type());
+ m_backend.negate();
    }
 
    template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::negate&)
+ void do_multiplies(const Exp& e, const detail::multiplies&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_multiplies(proto::left(e), typename proto::tag_of<left_type>::type());
- m_backend.negate();
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_multiplies(e.left(), typename left_type::tag_type());
+ do_multiplies(e.right(), typename right_type::tag_type());
    }
 
    template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::multiplies&)
+ void do_multiplies(const Exp& e, const detail::divides&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_multiplies(proto::left(e), typename proto::tag_of<left_type>::type());
- do_multiplies(proto::right(e), typename proto::tag_of<right_type>::type());
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_multiplies(e.left(), typename left_type::tag_type());
+ do_divide(e.right(), typename right_type::tag_type());
    }
 
    template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::divides&)
+ void do_multiplies(const Exp& e, const detail::multiply_immediates&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_multiplies(proto::left(e), typename proto::tag_of<left_type>::type());
- do_divide(proto::right(e), typename proto::tag_of<right_type>::type());
+ using big_num_default_ops::multiply;
+ multiply(m_backend, canonical_value(e.left().value()));
+ multiply(m_backend, canonical_value(e.right().value()));
+ }
+ template <class Exp>
+ void do_multiplies(const Exp& e, const detail::divide_immediates&)
+ {
+ using big_num_default_ops::multiply;
+ using big_num_default_ops::divide;
+ multiply(m_backend, canonical_value(e.left().value()));
+ divide(m_backend, canonical_value(e.right().value()));
    }
-
    template <class Exp, class unknown>
    void do_multiplies(const Exp& e, const unknown&)
    {
@@ -1169,43 +1199,52 @@
    }
 
    template <class Exp>
- void do_divide(const Exp& e, const proto::tag::terminal&)
+ void do_divide(const Exp& e, const detail::terminal&)
    {
       using big_num_default_ops::divide;
- divide(m_backend, canonical_value(proto::value(e)));
+ divide(m_backend, canonical_value(e.value()));
    }
 
    template <class Exp>
- void do_divide(const Exp& e, const proto::tag::unary_plus&)
+ void do_divide(const Exp& e, const detail::negate&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_divide(proto::left(e), typename proto::tag_of<left_type>::type());
+ typedef typename Exp::left_type left_type;
+ do_divide(e.left(), typename left_type::tag_type());
+ m_backend.negate();
    }
 
    template <class Exp>
- void do_divide(const Exp& e, const proto::tag::negate&)
+ void do_divide(const Exp& e, const detail::multiplies&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_divide(proto::left(e), typename proto::tag_of<left_type>::type());
- m_backend.negate();
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_divide(e.left(), typename left_type::tag_type());
+ do_divide(e.right(), typename right_type::tag_type());
    }
 
    template <class Exp>
- void do_divide(const Exp& e, const proto::tag::multiplies&)
+ void do_divide(const Exp& e, const detail::divides&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_divide(proto::left(e), typename proto::tag_of<left_type>::type());
- do_divide(proto::right(e), typename proto::tag_of<right_type>::type());
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_divide(e.left(), typename left_type::tag_type());
+ do_multiplies(e.right(), typename right_type::tag_type());
    }
 
    template <class Exp>
- void do_divide(const Exp& e, const proto::tag::divides&)
+ void do_divides(const Exp& e, const detail::multiply_immediates&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_divide(proto::left(e), typename proto::tag_of<left_type>::type());
- do_multiplies(proto::right(e), typename proto::tag_of<right_type>::type());
+ using big_num_default_ops::divide;
+ divide(m_backend, canonical_value(e.left().value()));
+ divide(m_backend, canonical_value(e.right().value()));
+ }
+ template <class Exp>
+ void do_divides(const Exp& e, const detail::divide_immediates&)
+ {
+ using big_num_default_ops::multiply;
+ using big_num_default_ops::divide;
+ divide(m_backend, canonical_value(e.left().value()));
+ mutiply(m_backend, canonical_value(e.right().value()));
    }
 
    template <class Exp, class unknown>
@@ -1217,35 +1256,35 @@
    }
 
    template <class Exp>
- void do_modulus(const Exp& e, const proto::tag::terminal&)
+ void do_modulus(const Exp& e, const detail::terminal&)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "The modulus operation is only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
       using big_num_default_ops::modulus;
- modulus(m_backend, canonical_value(proto::value(e)));
+ modulus(m_backend, canonical_value(e.value()));
    }
 
    template <class Exp, class Unknown>
    void do_modulus(const Exp& e, const Unknown&)
    {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "The modulus operation is only valid for integer types");
+ BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_integer, "The modulus operation is only valid for integer types");
       using big_num_default_ops::modulus;
       self_type temp(e);
- modulus(m_backend, canonical_value(proto::value(temp)));
+ modulus(m_backend, canonical_value(temp));
    }
 
    template <class Exp>
- void do_bitwise_and(const Exp& e, const proto::tag::terminal&)
+ void do_bitwise_and(const Exp& e, const detail::terminal&)
    {
       using big_num_default_ops::bitwise_and;
- bitwise_and(m_backend, canonical_value(proto::value(e)));
+ bitwise_and(m_backend, canonical_value(e.value()));
    }
    template <class Exp>
- void do_bitwise_and(const Exp& e, const proto::tag::bitwise_and&)
+ void do_bitwise_and(const Exp& e, const detail::bitwise_and&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_bitwise_and(proto::left(e), typename proto::tag_of<left_type>::type());
- do_bitwise_and(proto::right(e), typename proto::tag_of<right_type>::type());
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_bitwise_and(e.left(), typename left_type::tag_type());
+ do_bitwise_and(e.right(), typename right_type::tag_type());
    }
    template <class Exp, class unknown>
    void do_bitwise_and(const Exp& e, const unknown&)
@@ -1256,18 +1295,18 @@
    }
 
    template <class Exp>
- void do_bitwise_or(const Exp& e, const proto::tag::terminal&)
+ void do_bitwise_or(const Exp& e, const detail::terminal&)
    {
       using big_num_default_ops::bitwise_or;
- bitwise_or(m_backend, canonical_value(proto::value(e)));
+ bitwise_or(m_backend, canonical_value(e.value()));
    }
    template <class Exp>
- void do_bitwise_or(const Exp& e, const proto::tag::bitwise_or&)
+ void do_bitwise_or(const Exp& e, const detail::bitwise_or&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_bitwise_or(proto::left(e), typename proto::tag_of<left_type>::type());
- do_bitwise_or(proto::right(e), typename proto::tag_of<right_type>::type());
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_bitwise_or(e.left(), typename left_type::tag_type());
+ do_bitwise_or(e.right(), typename right_type::tag_type());
    }
    template <class Exp, class unknown>
    void do_bitwise_or(const Exp& e, const unknown&)
@@ -1278,18 +1317,18 @@
    }
 
    template <class Exp>
- void do_bitwise_xor(const Exp& e, const proto::tag::terminal&)
+ void do_bitwise_xor(const Exp& e, const detail::terminal&)
    {
       using big_num_default_ops::bitwise_xor;
- bitwise_xor(m_backend, canonical_value(proto::value(e)));
+ bitwise_xor(m_backend, canonical_value(e.value()));
    }
    template <class Exp>
- void do_bitwise_xor(const Exp& e, const proto::tag::bitwise_xor&)
+ void do_bitwise_xor(const Exp& e, const detail::bitwise_xor&)
    {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- do_bitwise_xor(proto::left(e), typename proto::tag_of<left_type>::type());
- do_bitwise_xor(proto::right(e), typename proto::tag_of<right_type>::type());
+ typedef typename Exp::left_type left_type;
+ typedef typename Exp::right_type right_type;
+ do_bitwise_xor(e.left(), typename left_type::tag_type());
+ do_bitwise_xor(e.right(), typename right_type::tag_type());
    }
    template <class Exp, class unknown>
    void do_bitwise_xor(const Exp& e, const unknown&)
@@ -1303,47 +1342,48 @@
    template <class Exp>
    bool contains_self(const Exp& e)const
    {
- return contains_self(e, mpl::int_<proto::arity_of<Exp>::value>());
+ return contains_self(e, typename Exp::arity());
    }
    template <class Exp>
    bool contains_self(const Exp& e, mpl::int_<0> const&)const
    {
- return is_really_self(proto::value(e));
+ return is_really_self(e.value());
    }
    template <class Exp>
    bool contains_self(const Exp& e, mpl::int_<1> const&)const
    {
- typedef typename proto::result_of::child_c<Exp, 0>::type child_type;
- return contains_self(proto::child_c<0>(e), mpl::int_<proto::arity_of<child_type>::value>());
+ typedef typename Exp::left_type child_type;
+ return contains_self(e.left(), typename child_type::arity());
    }
    template <class Exp>
    bool contains_self(const Exp& e, mpl::int_<2> const&)const
    {
- typedef typename proto::result_of::child_c<Exp, 0>::type child0_type;
- typedef typename proto::result_of::child_c<Exp, 1>::type child1_type;
- return contains_self(proto::child_c<0>(e), mpl::int_<proto::arity_of<child0_type>::value>()) || contains_self(proto::child_c<1>(e), mpl::int_<proto::arity_of<child1_type>::value>());
+ typedef typename Exp::left_type child0_type;
+ typedef typename Exp::right_type child1_type;
+ return contains_self(e.left(), typename child0_type::arity())
+ || contains_self(e.right(), typename child1_type::arity());
    }
    template <class Exp>
    bool contains_self(const Exp& e, mpl::int_<3> const&)const
    {
- typedef typename proto::result_of::child_c<Exp, 0>::type child0_type;
- typedef typename proto::result_of::child_c<Exp, 1>::type child1_type;
- typedef typename proto::result_of::child_c<Exp, 2>::type child2_type;
- return contains_self(proto::child_c<0>(e), mpl::int_<proto::arity_of<child0_type>::value>())
- || contains_self(proto::child_c<1>(e), mpl::int_<proto::arity_of<child1_type>::value>())
- || contains_self(proto::child_c<2>(e), mpl::int_<proto::arity_of<child2_type>::value>());
+ typedef typename Exp::left_type child0_type;
+ typedef typename Exp::middle_type child1_type;
+ typedef typename Exp::right_type child2_type;
+ return contains_self(e.left(), typename child0_type::arity())
+ || contains_self(e.middle(), typename child1_type::arity())
+ || contains_self(e.right(), typename child2_type::arity());
    }
 
    // Test if the expression is a reference to *this:
    template <class Exp>
    bool is_self(const Exp& e)const
    {
- return is_self(e, mpl::int_<proto::arity_of<Exp>::value>());
+ return is_self(e, typename Exp::arity());
    }
    template <class Exp>
    bool is_self(const Exp& e, mpl::int_<0> const&)const
    {
- return is_really_self(proto::value(e));
+ return is_really_self(e.value());
    }
    template <class Exp, int v>
    bool is_self(const Exp& e, mpl::int_<v> const&)const
@@ -1353,36 +1393,15 @@
 
    template <class Val>
    bool is_really_self(const Val&)const { return false; }
- bool is_really_self(const self_type* v)const
- {
- return v == this;
- }
- bool is_really_self(self_type* v)const
- {
- return v == this;
- }
- template <class Exp>
- static typename detail::underlying_result<Exp>::type underlying_value(const detail::big_number_exp<Exp>& e, const proto::tag::terminal&)
- {
- return proto::value(e);
- }
- template <class Exp, class tag>
- static typename detail::underlying_result<Exp>::type
- underlying_value(const detail::big_number_exp<Exp>& e, const tag&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::tag_of<left_type>::type tag_type;
- return underlying_value(proto::left(e), tag_type());
- }
+ bool is_really_self(const self_type& v)const { return &v == this; }
 
    static const Backend& canonical_value(const self_type& v){ return v.m_backend; }
- static const Backend& canonical_value(const self_type* v){ return v->m_backend; }
- static const Backend& canonical_value(self_type* v){ return v->m_backend; }
- static const Backend& canonical_value(self_type& v){ return v.m_backend; }
+ //static const Backend& canonical_value(const self_type* v){ return v->m_backend; }
+ //static const Backend& canonical_value(self_type* v){ return v->m_backend; }
+ //static const Backend& canonical_value(self_type& v){ return v.m_backend; }
    template <class V>
    static typename detail::canonical<V, Backend>::type canonical_value(const V& v){ return v; }
    static typename detail::canonical<std::string, Backend>::type canonical_value(const std::string& v){ return v.c_str(); }
-
    Backend m_backend;
 };
 
@@ -1395,14 +1414,14 @@
    return a.compare(b);
 }
 
-template <class Backend, class Exp>
-inline int big_number_compare(const big_number<Backend>& a, const big_number_exp<Exp>& b)
+template <class Backend, class tag, class A1, class A2, class A3>
+inline int big_number_compare(const big_number<Backend>& a, const big_number_exp<tag, A1, A2, A3>& b)
 {
    return a.compare(big_number<Backend>(b));
 }
 
-template <class Exp, class Backend>
-inline int big_number_compare(const big_number_exp<Exp>& a, const big_number<Backend>& b)
+template <class tag, class A1, class A2, class A3, class Backend>
+inline int big_number_compare(const big_number_exp<tag, A1, A2, A3>& a, const big_number<Backend>& b)
 {
    return -b.compare(big_number<Backend>(a));
 }
@@ -1419,26 +1438,26 @@
    return -b.compare(a);
 }
 
-template <class Exp1, class Exp2>
-inline int big_number_compare(const big_number_exp<Exp1>& a, const big_number_exp<Exp2>& b)
+template <class tag, class A1, class A2, class A3, class tag2, class A1b, class A2b, class A3b>
+inline int big_number_compare(const big_number_exp<tag, A1, A2, A3>& a, const big_number_exp<tag2, A1b, A2b, A3b>& b)
 {
- typedef typename expression_type<Exp1>::type real1;
- typedef typename expression_type<Exp2>::type real2;
+ typedef typename big_number_exp<tag, A1, A2, A3>::result_type real1;
+ typedef typename big_number_exp<tag2, A1b, A2b, A3b>::result_type real2;
    return real1(a).compare(real2(b));
 }
 
-template <class Exp, class Val>
-inline typename enable_if<is_arithmetic<Val>, int>::type big_number_compare(const big_number_exp<Exp>& a, const Val b)
+template <class tag, class A1, class A2, class A3, class Val>
+inline typename enable_if<is_arithmetic<Val>, int>::type big_number_compare(const big_number_exp<tag, A1, A2, A3>& a, const Val b)
 {
- typedef typename expression_type<Exp>::type real;
+ typedef typename big_number_exp<tag, A1, A2, A3>::result_type real;
    real t(a);
    return t.compare(b);
 }
 
-template <class Val, class Exp>
-inline typename enable_if<is_arithmetic<Val>, int>::type big_number_compare(const Val a, const big_number_exp<Exp>& b)
+template <class Val, class tag, class A1, class A2, class A3>
+inline typename enable_if<is_arithmetic<Val>, int>::type big_number_compare(const Val a, const big_number_exp<tag, A1, A2, A3>& b)
 {
- typedef typename expression_type<Exp>::type real;
+ typedef typename big_number_exp<tag, A1, A2, A3>::result_type real;
    return -real(b).compare(a);
 }
 
@@ -1527,10 +1546,10 @@
 
 namespace detail{
 
-template <class Exp>
-inline std::ostream& operator << (std::ostream& os, const big_number_exp<Exp>& r)
+template <class tag, class A1, class A2, class A3>
+inline std::ostream& operator << (std::ostream& os, const big_number_exp<tag, A1, A2, A3>& r)
 {
- typedef typename expression_type<detail::big_number_exp<Exp> >::type value_type;
+ typedef typename big_number_exp<tag, A1, A2, A3>::result_type value_type;
    value_type temp(r);
    return os << temp;
 }

Modified: sandbox/big_number/boost/math/big_number/big_number_base.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/big_number_base.hpp (original)
+++ sandbox/big_number/boost/math/big_number/big_number_base.hpp 2011-09-24 07:07:59 EDT (Sat, 24 Sep 2011)
@@ -7,6 +7,8 @@
 #define BOOST_MATH_BIG_NUM_BASE_HPP
 
 #include <limits>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
 
 namespace boost{ namespace math{
 
@@ -16,145 +18,8 @@
 namespace detail{
 
 // Forward-declare an expression wrapper
-template<typename Expr>
+template<class tag, class Arg1 = void, class Arg2 = void, class Arg3 = void>
 struct big_number_exp;
-//
-// Declare our grammars:
-//
-struct integer_terminal : public
-proto::and_<
- proto::terminal< proto::_ >,
- proto::if_ < boost::is_integral< proto::_value >() >
- >
-{};
-
-struct big_number_grammar;
-
-template<typename T>
-struct is_big_number_ptr : mpl::false_ {};
-
-template<typename Backend>
-struct is_big_number_ptr<big_number<Backend>*> : mpl::true_ {};
-
-
-struct big_number_grammar_cases
-{
- // The primary template matches nothing:
- template<typename Tag>
- struct case_
- : proto::not_<proto::_>
- {};
-};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::terminal>
- : proto::and_<
- proto::terminal<proto::_ >,
- proto::or_<
- proto::if_ < is_big_number_ptr< proto::_value >() >,
- proto::if_ < is_arithmetic< proto::_value >() >,
- proto::if_ < is_same< proto::_value, std::string>() >,
- proto::if_ < is_convertible< proto::_value, const char*>() >
- >
- >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::plus>
- : proto::plus< big_number_grammar, big_number_grammar >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::multiplies>
- : proto::multiplies< big_number_grammar, big_number_grammar >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::minus>
- : proto::minus< big_number_grammar, big_number_grammar >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::divides>
- : proto::divides< big_number_grammar, big_number_grammar >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::unary_plus>
- : proto::unary_plus< big_number_grammar>
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::negate>
- : proto::negate< big_number_grammar>
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::modulus>
- : proto::modulus< big_number_grammar, big_number_grammar >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::bitwise_and>
- : proto::bitwise_and< big_number_grammar, big_number_grammar >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::bitwise_or>
- : proto::bitwise_or< big_number_grammar, big_number_grammar >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::bitwise_xor>
- : proto::bitwise_xor< big_number_grammar, big_number_grammar >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::shift_left>
- : proto::shift_left< big_number_grammar, integer_terminal >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::shift_right>
- : proto::shift_right< big_number_grammar, integer_terminal >
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::complement>
- : proto::complement<big_number_grammar>
-{};
-
-template<>
-struct big_number_grammar_cases::case_<proto::tag::function>
- : proto::or_<
- proto::function< proto::_, big_number_grammar >,
- proto::function< proto::_, big_number_grammar, proto::_ >
- >
-{};
-
-struct big_number_grammar : proto::switch_<big_number_grammar_cases>{};
-
-// Define a calculator domain. Expression within
-// the calculator domain will be wrapped in the
-// calculator<> expression wrapper.
-struct big_number_domain
- : proto::domain< proto::generator<big_number_exp>, big_number_grammar>
-{};
-
-struct CalcDepth
- : proto::or_<
- proto::when< proto::terminal<proto::_>,
- mpl::int_<0>()
- >
- , proto::when< proto::unary_expr<proto::_, CalcDepth>,
- CalcDepth(proto::_child)
- >
- , proto::when< proto::binary_expr<proto::_, CalcDepth, CalcDepth>,
- mpl::plus<mpl::max<CalcDepth(proto::_left),
- CalcDepth(proto::_right)>, mpl::int_<1> >()
- >
- >
-{};
 
 template <int b>
 struct has_enough_bits
@@ -231,429 +96,869 @@
    typedef typename canonical_imp<Val, Backend, tag_type>::type type;
 };
 
-template <class Exp, class tag>
-struct assign_and_eval_imp
-{
- typedef tag type;
-};
-
+struct terminal{};
+struct negate{};
+struct plus{};
+struct minus{};
+struct multiplies{};
+struct divides{};
+struct modulus{};
+struct shift_left{};
+struct shift_right{};
+struct bitwise_and{};
+struct bitwise_or{};
+struct bitwise_xor{};
+struct bitwise_complement{};
 struct add_immediates{};
-struct add_and_negate_immediates{};
 struct subtract_immediates{};
-struct subtract_and_negate_immediates{};
 struct multiply_immediates{};
-struct multiply_and_negate_immediates{};
 struct divide_immediates{};
-struct divide_and_negate_immediates{};
 struct modulus_immediates{};
 struct bitwise_and_immediates{};
 struct bitwise_or_immediates{};
 struct bitwise_xor_immediates{};
 struct complement_immediates{};
+struct function{};
 
-struct immediate{};
-struct negative_immediate{};
+template <class T>
+struct backend_type;
 
-template <class Exp, class tag>
-struct immediate_type
-{
- typedef tag type;
-};
-template <class Exp>
-struct immediate_type<Exp, proto::tag::terminal>
+template <class T>
+struct backend_type<big_number<T> >
 {
- typedef immediate type;
+ typedef T type;
 };
-template <class Exp>
-struct immediate_type<Exp, proto::tag::unary_plus>
+
+template <class tag, class A1, class A2, class A3>
+struct backend_type<big_number_exp<tag, A1, A2, A3> >
 {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename mpl::if_<
- is_same<left_tag, proto::tag::terminal>,
- immediate,
- left_tag
- >::type type;
-};
-template <class Exp>
-struct immediate_type<Exp, proto::tag::negate>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename immediate_type<left_type, left_tag>::type tag;
- typedef typename mpl::if_<
- is_same<immediate, tag>,
- negative_immediate,
- tag
- >::type type;
+ typedef typename backend_type<typename big_number_exp<tag, A1, A2, A3>::result_type>::type type;
 };
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::plus>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename proto::tag_of<right_type>::type right_tag;
- typedef typename immediate_type<left_type, left_tag>::type left_imm;
- typedef typename immediate_type<right_type, right_tag>::type right_imm;
- typedef typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, immediate> >,
- add_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, negative_immediate> >,
- subtract_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, negative_immediate>, is_same<right_imm, immediate> >,
- subtract_and_negate_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, negative_immediate>, is_same<right_imm, negative_immediate> >,
- add_and_negate_immediates,
- proto::tag::plus
- >::type
- >::type
- >::type
- >::type type;
-};
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::minus>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename proto::tag_of<right_type>::type right_tag;
- typedef typename immediate_type<left_type, left_tag>::type left_imm;
- typedef typename immediate_type<right_type, right_tag>::type right_imm;
- typedef typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, immediate> >,
- subtract_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, negative_immediate> >,
- add_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, negative_immediate>, is_same<right_imm, immediate> >,
- add_and_negate_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, negative_immediate>, is_same<right_imm, negative_immediate> >,
- subtract_and_negate_immediates,
- proto::tag::minus
- >::type
- >::type
- >::type
- >::type type;
-};
+template <class T>
+struct is_big_number : public mpl::false_{};
+template <class T>
+struct is_big_number<boost::math::big_number<T> > : public mpl::true_{};
+template <class T>
+struct is_big_number_exp : public mpl::false_{};
+template <class Tag, class Arg1, class Arg2, class Arg3>
+struct is_big_number_exp<boost::math::detail::big_number_exp<Tag, Arg1, Arg2, Arg3> > : public mpl::true_{};
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::multiplies>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename proto::tag_of<right_type>::type right_tag;
- typedef typename immediate_type<left_type, left_tag>::type left_imm;
- typedef typename immediate_type<right_type, right_tag>::type right_imm;
- typedef typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, immediate> >,
- multiply_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, negative_immediate> >,
- multiply_and_negate_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, negative_immediate>, is_same<right_imm, immediate> >,
- multiply_and_negate_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, negative_immediate>, is_same<right_imm, negative_immediate> >,
- multiply_immediates,
- proto::tag::multiplies
- >::type
- >::type
- >::type
- >::type type;
-};
+template <class T1, class T2>
+struct combine_expression;
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::divides>
+template <class T1, class T2>
+struct combine_expression<big_number<T1>, T2>
 {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename proto::tag_of<right_type>::type right_tag;
- typedef typename immediate_type<left_type, left_tag>::type left_imm;
- typedef typename immediate_type<right_type, right_tag>::type right_imm;
- typedef typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, immediate> >,
- divide_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, negative_immediate> >,
- divide_and_negate_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, negative_immediate>, is_same<right_imm, immediate> >,
- divide_and_negate_immediates,
- typename mpl::if_<
- mpl::and_<is_same<left_imm, negative_immediate>, is_same<right_imm, negative_immediate> >,
- divide_immediates,
- proto::tag::divides
- >::type
- >::type
- >::type
- >::type type;
+ typedef big_number<T1> type;
 };
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::modulus>
+template <class T1, class T2>
+struct combine_expression<T1, big_number<T2> >
 {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename proto::tag_of<right_type>::type right_tag;
- typedef typename immediate_type<left_type, left_tag>::type left_imm;
- typedef typename immediate_type<right_type, right_tag>::type right_imm;
- typedef typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, immediate> >,
- modulus_immediates,
- proto::tag::modulus
- >::type type;
+ typedef big_number<T2> type;
 };
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::bitwise_and>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename proto::tag_of<right_type>::type right_tag;
- typedef typename immediate_type<left_type, left_tag>::type left_imm;
- typedef typename immediate_type<right_type, right_tag>::type right_imm;
- typedef typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, immediate> >,
- bitwise_and_immediates,
- proto::tag::bitwise_and
- >::type type;
+template <class T>
+struct combine_expression<big_number<T>, big_number<T> >
+{
+ typedef big_number<T> type;
 };
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::bitwise_or>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename proto::tag_of<right_type>::type right_tag;
- typedef typename immediate_type<left_type, left_tag>::type left_imm;
- typedef typename immediate_type<right_type, right_tag>::type right_imm;
- typedef typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, immediate> >,
- bitwise_or_immediates,
- proto::tag::bitwise_or
- >::type type;
+template <class T>
+struct arg_type
+{
+ typedef big_number_exp<terminal, T> type;
 };
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::bitwise_xor>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename proto::tag_of<right_type>::type right_tag;
- typedef typename immediate_type<left_type, left_tag>::type left_imm;
- typedef typename immediate_type<right_type, right_tag>::type right_imm;
- typedef typename mpl::if_<
- mpl::and_<is_same<left_imm, immediate>, is_same<right_imm, immediate> >,
- bitwise_xor_immediates,
- proto::tag::bitwise_xor
- >::type type;
+template <class Tag, class Arg1, class Arg2, class Arg3>
+struct arg_type<big_number_exp<Tag, Arg1, Arg2, Arg3> >
+{
+ typedef big_number_exp<Tag, Arg1, Arg2, Arg3> type;
 };
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::complement>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::tag_of<left_type>::type left_tag;
- typedef typename immediate_type<left_type, left_tag>::type left_imm;
- typedef typename mpl::if_<
- is_same<left_imm, immediate>,
- complement_immediates,
- proto::tag::complement
- >::type type;
-};
+template <class T>
+void unmentionable_proc(){}
 
-template <class Exp>
-struct assign_and_eval
-{
- typedef typename proto::tag_of<Exp>::type tag_type;
- typedef typename assign_and_eval_imp<Exp, tag_type>::type type;
-};
+typedef void (*unmentionable_type)();
 
-template <class Exp, class tag>
-struct underlying_result_imp
+template <class T>
+struct big_number_exp_storage
 {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::tag_of<left_type>::type tag_type;
- typedef typename underlying_result_imp<left_type, tag_type>::type type;
+ typedef const T& type;
 };
 
-template <class Exp>
-struct underlying_result_imp<Exp, proto::tag::terminal>
+template <class T>
+struct big_number_exp_storage<T*>
 {
- typedef typename proto::result_of::value<Exp const &>::type type;
+ typedef T* type;
 };
 
-template <class Exp>
-struct underlying_result
+template <class T>
+struct big_number_exp_storage<const T*>
 {
- typedef typename proto::tag_of<Exp>::type tag_type;
- typedef typename underlying_result_imp<Exp, tag_type>::type type;
+ typedef const T* type;
 };
 
-template <class Exp1, class Exp2>
-struct combine_expression_type
+template <class tag, class A1, class A2, class A3>
+struct big_number_exp_storage<big_number_exp<tag, A1, A2, A3> >
 {
- typedef void type;
+ typedef big_number_exp<tag, A1, A2, A3> type;
 };
 
-template <class Backend>
-struct combine_expression_type<boost::math::big_number<Backend>, boost::math::big_number<Backend> >
+template<class tag, class Arg1>
+struct big_number_exp<tag, Arg1, void, void>
 {
- typedef boost::math::big_number<Backend> type;
-};
+ typedef mpl::int_<1> arity;
+ typedef typename arg_type<Arg1>::type left_type;
+ typedef typename left_type::result_type result_type;
+ typedef tag tag_type;
 
-template <class Backend, class Exp>
-struct combine_expression_type<boost::math::big_number<Backend>, Exp>
-{
- typedef boost::math::big_number<Backend> type;
-};
+ big_number_exp(const Arg1& a) : arg(a) {}
 
-template <class Backend, class Exp>
-struct combine_expression_type<Exp, boost::math::big_number<Backend> >
-{
- typedef boost::math::big_number<Backend> type;
-};
+ left_type left()const { return arg; }
 
-template <class T>
-struct is_big_number : public mpl::false_{};
-template <class T>
-struct is_big_number<boost::math::big_number<T> > : public mpl::true_{};
-template <class T>
-struct is_big_number_exp : public mpl::false_{};
-template <class T>
-struct is_big_number_exp<boost::math::detail::big_number_exp<T> > : public mpl::true_{};
+ const Arg1& left_ref()const{ return arg; }
 
+ static const unsigned depth = left_type::depth + 1;
 
-template <class Exp, int arity>
-struct expression_type_imp;
+ operator unmentionable_type()const
+ {
+ result_type r(*this);
+ return r ? unmentionable_proc<void> : 0;
+ }
 
-template <class Exp>
-struct expression_type_imp<Exp, 0>
-{
- typedef typename remove_pointer<typename proto::result_of::value<Exp>::type>::type type;
+private:
+ typename big_number_exp_storage<Arg1>::type arg;
 };
 
-template <class Exp>
-struct expression_type_imp<Exp, 1>
+template<class Arg1>
+struct big_number_exp<terminal, Arg1, void, void>
 {
- typedef typename proto::result_of::left<Exp>::type nested_type;
- typedef typename expression_type_imp<nested_type, proto::arity_of<nested_type>::value>::type type;
-};
+ typedef mpl::int_<0> arity;
+ typedef Arg1 result_type;
+ typedef terminal tag_type;
 
-template <class Exp>
-struct expression_type_imp<Exp, 2>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename expression_type_imp<left_type, proto::arity_of<left_type>::value>::type left_result;
- typedef typename expression_type_imp<right_type, proto::arity_of<right_type>::value>::type right_result;
- typedef typename combine_expression_type<left_result, right_result>::type type;
-};
+ big_number_exp(const Arg1& a) : arg(a) {}
 
-template <class Exp>
-struct expression_type_imp<Exp, 3>
-{
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
- typedef typename proto::result_of::child_c<Exp, 2>::type end_type;
- typedef typename expression_type_imp<left_type, proto::arity_of<left_type>::value>::type left_result;
- typedef typename expression_type_imp<right_type, proto::arity_of<right_type>::value>::type right_result;
- typedef typename expression_type_imp<end_type, proto::arity_of<end_type>::value>::type end_result;
- typedef typename combine_expression_type<left_result, typename combine_expression_type<right_result, end_type>::type>::type type;
-};
+ const Arg1& value()const { return arg; }
 
-template <class Exp>
-struct expression_type
-{
- typedef typename expression_type_imp<Exp, proto::arity_of<Exp>::value>::type type;
-};
+ static const unsigned depth = 0;
 
-template <class Exp>
-struct backend_type
-{
- typedef typename expression_type<Exp>::type num_type;
- typedef typename backend_type<num_type>::type type;
+ operator unmentionable_type()const
+ {
+ return arg ? unmentionable_proc<void> : 0;
+ }
+
+private:
+ typename big_number_exp_storage<Arg1>::type arg;
 };
 
-template <class Backend>
-struct backend_type<boost::math::big_number<Backend> >
+template <class tag, class Arg1, class Arg2>
+struct big_number_exp<tag, Arg1, Arg2, void>
 {
- typedef Backend type;
+ typedef mpl::int_<2> arity;
+ typedef typename arg_type<Arg1>::type left_type;
+ typedef typename arg_type<Arg2>::type right_type;
+ typedef typename left_type::result_type left_result_type;
+ typedef typename right_type::result_type right_result_type;
+ typedef typename combine_expression<left_result_type, right_result_type>::type result_type;
+ typedef tag tag_type;
+
+ big_number_exp(const Arg1& a1, const Arg2& a2) : arg1(a1), arg2(a2) {}
+
+ left_type left()const { return arg1; }
+ right_type right()const { return arg2; }
+ const Arg1& left_ref()const{ return arg1; }
+ const Arg2& right_ref()const{ return arg2; }
+
+ operator unmentionable_type()const
+ {
+ result_type r(*this);
+ return r ? unmentionable_proc<void> : 0;
+ }
+
+ static const unsigned left_depth = left_type::depth + 1;
+ static const unsigned right_depth = right_type::depth + 1;
+ static const unsigned depth = left_depth > right_depth ? left_depth : right_depth;
+private:
+ typename big_number_exp_storage<Arg1>::type arg1;
+ typename big_number_exp_storage<Arg2>::type arg2;
 };
 
-template<typename Expr>
+template <class tag, class Arg1, class Arg2, class Arg3>
 struct big_number_exp
- : proto::extends<Expr, big_number_exp<Expr>, big_number_domain>
 {
+ typedef mpl::int_<3> arity;
+ typedef typename arg_type<Arg1>::type left_type;
+ typedef typename arg_type<Arg2>::type middle_type;
+ typedef typename arg_type<Arg3>::type right_type;
+ typedef typename left_type::result_type left_result_type;
+ typedef typename middle_type::result_type middle_result_type;
+ typedef typename right_type::result_type right_result_type;
+ typedef typename combine_expression<
+ left_result_type,
+ typename combine_expression<right_result_type, middle_result_type>::type
+ >::type result_type;
+ typedef tag tag_type;
+
+ big_number_exp(const Arg1& a1, const Arg2& a2, const Arg3& a3) : arg1(a1), arg2(a2), arg3(a3) {}
+
+ left_type left()const { return arg1; }
+ middle_type middle()const { return arg2; }
+ right_type right()const { return arg3; }
+ const Arg1& left_ref()const{ return arg1; }
+ const Arg2& middle_ref()const{ return arg2; }
+ const Arg3& right_ref()const{ return arg3; }
+
+ operator unmentionable_type()const
+ {
+ result_type r(*this);
+ return r ? unmentionable_proc<void> : 0;
+ }
+
+ static const unsigned left_depth = left_type::depth + 1;
+ static const unsigned middle_depth = middle_type::depth + 1;
+ static const unsigned right_depth = right_type::depth + 1;
+ static const unsigned depth = left_depth > right_depth ? (left_depth > middle_depth ? left_depth : middle_depth) : (right_depth > middle_depth ? right_depth : middle_depth);
 private:
- typedef proto::extends<Expr, big_number_exp<Expr>, big_number_domain> base_type;
- typedef big_number_exp<Expr> self_type;
- typedef typename remove_reference<typename expression_type<self_type>::type>::type number_type;
- typedef void (self_type::*unmentionable_type)();
- void unmentionable_proc(){}
- unmentionable_type boolean_context_from_terminal(const number_type* pval)const
- {
- return pval->is_zero() ? 0 : &self_type::unmentionable_proc;
- }
- unmentionable_type boolean_context_from_terminal(number_type* pval)const
- {
- return pval->is_zero() ? 0 : &self_type::unmentionable_proc;
- }
- template <class Terminal>
- unmentionable_type boolean_context_from_terminal(const Terminal& val)const
- {
- return val ? 0 : &self_type::unmentionable_proc;
- }
- unmentionable_type boolean_context(const proto::tag::terminal&)const
- {
- return boolean_context_from_terminal(proto::value(*this));
- }
- template <class Tag>
- unmentionable_type boolean_context(const Tag&)const
- {
- // we have to evaluate the expression template:
- number_type result(*this);
- return result.is_zero() ? 0 : &self_type::unmentionable_proc;
- }
-public:
- big_number_exp(Expr const &expr = Expr())
- : base_type(expr)
- {}
- template <class Other>
- big_number_exp(const Other& o, typename enable_if<is_convertible<Other, base_type> >::type const* = 0)
- : base_type(o)
- {}
-
- operator unmentionable_type()const
- {
- return boolean_context(typename proto::tag_of<self_type>::type());
- }
+ typename big_number_exp_storage<Arg1>::type arg1;
+ typename big_number_exp_storage<Arg2>::type arg2;
+ typename big_number_exp_storage<Arg3>::type arg3;
 };
 
 } // namespace detail
 
 //
-// Traits class, lets us know whether a backend is an integer type, otherwise assumed to be a real number type:
+// Non-member operators for big_number:
+//
+// Unary operators first:
+//
+template <class B>
+inline const big_number<B>& operator + (const big_number<B>& v) { return v; }
+template <class tag, class Arg1, class Arg2, class Arg3>
+inline const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& operator + (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
+template <class B>
+inline detail::big_number_exp<detail::negate, big_number<B> > operator - (const big_number<B>& v) { return v; }
+template <class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::negate, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > operator - (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
+template <class B>
+inline detail::big_number_exp<detail::complement_immediates, big_number<B> > operator ~ (const big_number<B>& v) { return v; }
+template <class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::bitwise_complement, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > operator ~ (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
+//
+// Then addition:
+//
+template <class B>
+inline detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >
+ operator + (const big_number<B>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::add_immediates, big_number<B>, V > >::type
+ operator + (const big_number<B>& a, const V& b)
+{
+ return detail::big_number_exp<detail::add_immediates, big_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::add_immediates, V, big_number<B> > >::type
+ operator + (const V& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::add_immediates, V, big_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::plus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
+ operator + (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::plus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
+ operator + (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator + (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator + (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+}
+template <class V, class tag, class Arg1, class Arg2, class Arg3>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::plus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator + (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::plus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(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::big_number_exp<detail::minus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
+ operator + (const big_number<B>& a, const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::minus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
+}
+template <class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::minus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
+ operator + (const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::minus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
+}
+template <class B>
+inline detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >
+ operator + (const big_number<B>& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
+{
+ return detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
+}
+template <class B>
+inline detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >
+ operator + (const detail::big_number_exp<detail::negate, big_number<B> >& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >(b, a.left_ref());
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::subtract_immediates, big_number<B>, V > >::type
+ operator + (const detail::big_number_exp<detail::negate, big_number<B> >& a, const V& b)
+{
+ return detail::big_number_exp<detail::subtract_immediates, V, big_number<B> >(b, a.left_ref());
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::subtract_immediates, V, big_number<B> > >::type
+ operator + (const V& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
+{
+ return detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
+}
+//
+// Subtraction:
+//
+template <class B>
+inline detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >
+ operator - (const big_number<B>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::subtract_immediates, big_number<B>, V > >::type
+ operator - (const big_number<B>& a, const V& b)
+{
+ return detail::big_number_exp<detail::subtract_immediates, big_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::subtract_immediates, V, big_number<B> > >::type
+ operator - (const V& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::subtract_immediates, V, big_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::minus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
+ operator - (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::minus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
+ operator - (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator - (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator - (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+}
+template <class V, class tag, class Arg1, class Arg2, class Arg3>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::minus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator - (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::minus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(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::big_number_exp<detail::plus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
+ operator - (const big_number<B>& a, const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::plus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
+}
+template <class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::plus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
+ operator - (const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::plus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
+}
+template <class B>
+inline detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >
+ operator - (const big_number<B>& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
+{
+ return detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
+}
+template <class B>
+inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> > >
+ operator - (const detail::big_number_exp<detail::negate, big_number<B> >& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >(b, a.left_ref());
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::add_immediates, big_number<B>, V > > >::type
+ operator - (const detail::big_number_exp<detail::negate, big_number<B> >& a, const V& b)
+{
+ return detail::big_number_exp<detail::add_immediates, V, big_number<B> >(b, a.left_ref());
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::add_immediates, V, big_number<B> > >::type
+ operator - (const V& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
+{
+ return detail::big_number_exp<detail::add_immediates, V, big_number<B> >(a, b.left_ref());
+}
+//
+// Multiplication:
+//
+template <class B>
+inline detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> >
+ operator * (const big_number<B>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::multiply_immediates, big_number<B>, V > >::type
+ operator * (const big_number<B>& a, const V& b)
+{
+ return detail::big_number_exp<detail::multiply_immediates, big_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::multiply_immediates, V, big_number<B> > >::type
+ operator * (const V& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::multiply_immediates, V, big_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::multiplies, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
+ operator * (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::multiplies, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
+ operator * (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator * (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator * (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+}
+template <class V, class tag, class Arg1, class Arg2, class Arg3>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::multiplies, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator * (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::multiplies, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(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::big_number_exp<detail::negate, detail::big_number_exp<detail::multiplies, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
+ operator * (const big_number<B>& a, const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::multiplies, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > (a, b.left_ref());
+}
+template <class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiplies, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
+ operator * (const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::multiplies, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
+}
+template <class B>
+inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> > >
+ operator * (const big_number<B>& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
+{
+ return detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
+}
+template <class B>
+inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> > >
+ operator * (const detail::big_number_exp<detail::negate, big_number<B> >& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> >(b, a.left_ref());
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiply_immediates, big_number<B>, V > > >::type
+ operator * (const detail::big_number_exp<detail::negate, big_number<B> >& a, const V& b)
+{
+ return detail::big_number_exp<detail::multiply_immediates, big_number<B>, V >(a.left_ref(), b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiply_immediates, big_number<B>, V > > >::type
+ operator * (const V& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
+{
+ return detail::big_number_exp<detail::multiply_immediates, big_number<B>, V >(b.left_ref(), a);
+}
+//
+// Division:
+//
+template <class B>
+inline detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> >
+ operator / (const big_number<B>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::divide_immediates, big_number<B>, V > >::type
+ operator / (const big_number<B>& a, const V& b)
+{
+ return detail::big_number_exp<detail::divide_immediates, big_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::divide_immediates, V, big_number<B> > >::type
+ operator / (const V& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::divide_immediates, V, big_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::divides, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
+ operator / (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::divides, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
+ operator / (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator / (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator / (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+}
+template <class V, class tag, class Arg1, class Arg2, class Arg3>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::divides, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator / (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::divides, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(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::big_number_exp<detail::negate, detail::big_number_exp<detail::divides, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
+ operator / (const big_number<B>& a, const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::divides, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
+}
+template <class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divides, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type, big_number<B> > >
+ operator / (const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::divides, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type, big_number<B> >(a.left_ref(), b);
+}
+template <class B>
+inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> > >
+ operator / (const big_number<B>& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
+{
+ return detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
+}
+template <class B>
+inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> > >
+ operator / (const detail::big_number_exp<detail::negate, big_number<B> >& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> >(a.left_ref(), b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divide_immediates, big_number<B>, V > > >::type
+ operator / (const detail::big_number_exp<detail::negate, big_number<B> >& a, const V& b)
+{
+ return detail::big_number_exp<detail::divide_immediates, big_number<B>, V>(a.left_ref(), b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divide_immediates, V, big_number<B> > > >::type
+ operator / (const V& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
+{
+ return detail::big_number_exp<detail::divide_immediates, V, big_number<B> >(a, b.left_ref());
+}
+//
+// Modulus:
+//
+template <class B>
+inline detail::big_number_exp<detail::modulus_immediates, big_number<B>, big_number<B> >
+ operator % (const big_number<B>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::modulus_immediates, big_number<B>, big_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::modulus_immediates, big_number<B>, V > >::type
+ operator % (const big_number<B>& a, const V& b)
+{
+ return detail::big_number_exp<detail::modulus_immediates, big_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::modulus_immediates, V, big_number<B> > >::type
+ operator % (const V& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::modulus_immediates, V, big_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::modulus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
+ operator % (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::modulus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
+ operator % (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator % (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator % (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+}
+template <class V, class tag, class Arg1, class Arg2, class Arg3>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::modulus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator % (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::modulus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+//
+// Left shift:
+//
+template <class B, class I>
+inline typename enable_if<is_integral<I>, detail::big_number_exp<detail::shift_left, big_number<B>, I > >::type
+ operator << (const big_number<B>& a, const I& b)
+{
+ return detail::big_number_exp<detail::shift_left, big_number<B>, I>(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class I>
+inline typename enable_if<is_integral<I>, detail::big_number_exp<detail::shift_left, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, I> >::type
+ operator << (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const I& b)
+{
+ return detail::big_number_exp<detail::shift_left, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, I>(a, b);
+}
+//
+// Right shift:
+//
+template <class B, class I>
+inline typename enable_if<is_integral<I>, detail::big_number_exp<detail::shift_right, big_number<B>, I > >::type
+ operator >> (const big_number<B>& a, const I& b)
+{
+ return detail::big_number_exp<detail::shift_right, big_number<B>, I>(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class I>
+inline typename enable_if<is_integral<I>, detail::big_number_exp<detail::shift_right, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, I> >::type
+ operator >> (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const I& b)
+{
+ return detail::big_number_exp<detail::shift_right, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, I>(a, b);
+}
+//
+// Bitwise AND:
+//
+template <class B>
+inline detail::big_number_exp<detail::bitwise_and_immediates, big_number<B>, big_number<B> >
+ operator & (const big_number<B>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::bitwise_and_immediates, big_number<B>, big_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_and_immediates, big_number<B>, V > >::type
+ operator & (const big_number<B>& a, const V& b)
+{
+ return detail::big_number_exp<detail::bitwise_and_immediates, big_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_and_immediates, V, big_number<B> > >::type
+ operator & (const V& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::bitwise_and_immediates, V, big_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::bitwise_and, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
+ operator & (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::bitwise_and, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
+ operator & (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator & (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator & (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+}
+template <class V, class tag, class Arg1, class Arg2, class Arg3>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_and, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator & (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::bitwise_and, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+//
+// Bitwise OR:
+//
+template <class B>
+inline detail::big_number_exp<detail::bitwise_or_immediates, big_number<B>, big_number<B> >
+ operator| (const big_number<B>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::bitwise_or_immediates, big_number<B>, big_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_or_immediates, big_number<B>, V > >::type
+ operator| (const big_number<B>& a, const V& b)
+{
+ return detail::big_number_exp<detail::bitwise_or_immediates, big_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_or_immediates, V, big_number<B> > >::type
+ operator| (const V& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::bitwise_or_immediates, V, big_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::bitwise_or, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
+ operator| (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::bitwise_or, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
+ operator| (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator| (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator| (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+}
+template <class V, class tag, class Arg1, class Arg2, class Arg3>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_or, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator| (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::bitwise_or, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+//
+// Bitwise XOR:
+//
+template <class B>
+inline detail::big_number_exp<detail::bitwise_xor_immediates, big_number<B>, big_number<B> >
+ operator^ (const big_number<B>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::bitwise_xor_immediates, big_number<B>, big_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_xor_immediates, big_number<B>, V > >::type
+ operator^ (const big_number<B>& a, const V& b)
+{
+ return detail::big_number_exp<detail::bitwise_xor_immediates, big_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_xor_immediates, V, big_number<B> > >::type
+ operator^ (const V& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::bitwise_xor_immediates, V, big_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::big_number_exp<detail::bitwise_xor, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
+ operator^ (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::bitwise_xor, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
+ operator^ (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
+{
+ return detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator^ (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class V>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator^ (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
+}
+template <class V, class tag, class Arg1, class Arg2, class Arg3>
+inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_xor, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator^ (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::big_number_exp<detail::bitwise_xor, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+
+//
+// Traits class, lets us know what kind of number we have, defaults to a floating point type:
 //
+enum number_category_type
+{
+ number_kind_integer = 0,
+ number_kind_floating_point = 1,
+ number_kind_rational = 2,
+ number_kind_fixed_point = 3
+};
+
 template <class Num>
-struct is_extended_integer : public mpl::false_ {};
+struct number_category : public mpl::int_<number_kind_floating_point> {};
 template <class Backend>
-struct is_extended_integer<big_number<Backend> > : public is_extended_integer<Backend>{};
+struct number_category<big_number<Backend> > : public number_category<Backend>{};
+template <class tag, class A1, class A2, class A3>
+struct number_category<detail::big_number_exp<tag, A1, A2, A3> > : public number_category<typename detail::big_number_exp<tag, A1, A2, A3>::result_type>{};
 
 }} // namespaces
 
@@ -662,10 +967,10 @@
 template <class T>
 struct promote_arg;
 
-template <class Exp>
-struct promote_arg<boost::math::detail::big_number_exp<Exp> >
+template <class tag, class A1, class A2, class A3>
+struct promote_arg<boost::math::detail::big_number_exp<tag, A1, A2, A3> >
 {
- typedef typename boost::math::detail::expression_type<Exp>::type type;
+ typedef typename boost::math::detail::big_number_exp<tag, A1, A2, A3>::result_type type;
 };
 
 }}}

Modified: sandbox/big_number/boost/math/big_number/default_ops.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/default_ops.hpp (original)
+++ sandbox/big_number/boost/math/big_number/default_ops.hpp 2011-09-24 07:07:59 EDT (Sat, 24 Sep 2011)
@@ -10,6 +10,8 @@
 #include <boost/math/big_number/big_number_base.hpp>
 #include <boost/math/special_functions/fpclassify.hpp>
 #include <boost/lexical_cast.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/front.hpp>
 
 namespace boost{ namespace math{ namespace big_num_default_ops{
 
@@ -418,17 +420,9 @@
 
 }
 
-
 template <class Backend>
 class big_number;
 
-namespace detail{
-
-template<typename Expr>
-struct big_number_exp;
-
-}
-
 //
 // Default versions of floating point classification routines:
 //
@@ -438,10 +432,10 @@
    using big_num_default_ops::eval_fpclassify;
    return eval_fpclassify(arg.backend());
 }
-template <class Exp>
-inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+template <class tag, class A1, class A2, class A3>
+inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
    return fpclassify(value_type(arg));
 }
 template <class Backend>
@@ -450,10 +444,10 @@
    int v = fpclassify(arg);
    return (v != FP_INFINITE) && (v != FP_NAN);
 }
-template <class Exp>
-inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+template <class tag, class A1, class A2, class A3>
+inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
    return isfinite(value_type(arg));
 }
 template <class Backend>
@@ -461,10 +455,10 @@
 {
    return fpclassify(arg) == FP_NAN;
 }
-template <class Exp>
-inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+template <class tag, class A1, class A2, class A3>
+inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
    return isnan(value_type(arg));
 }
 template <class Backend>
@@ -472,10 +466,10 @@
 {
    return fpclassify(arg) == FP_INFINITE;
 }
-template <class Exp>
-inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+template <class tag, class A1, class A2, class A3>
+inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
    return isinf(value_type(arg));
 }
 template <class Backend>
@@ -483,17 +477,17 @@
 {
    return fpclassify(arg) == FP_NORMAL;
 }
-template <class Exp>
-inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+template <class tag, class A1, class A2, class A3>
+inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
    return isnormal(value_type(arg));
 }
 
-template <class Exp, class Policy>
-inline int itrunc(const detail::big_number_exp<Exp>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class Policy>
+inline int itrunc(const detail::big_number_exp<tag, A1, A2, A3>& v, const Policy& pol)
 {
- typedef typename detail::expression_type<Exp>::type number_type;
+ typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type number_type;
    number_type r = trunc(v, pol);
    if(fabs(r) > (std::numeric_limits<int>::max)())
       return policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
@@ -641,30 +635,38 @@
 \
 }\
 \
-template <class Exp> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<Exp>::type> \
- , detail::big_number_exp<Exp> \
->::type const \
-func(const detail::big_number_exp<Exp>& arg)\
-{\
- return proto::make_expr<proto::tag::function>(\
- detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<Exp>::type>() \
+template <class tag, class A1, class A2, class A3> \
+detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+> \
+func(const detail::big_number_exp<tag, A1, A2, A3>& arg)\
+{\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+> (\
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type>() \
       , arg \
     );\
 }\
 template <class Backend> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
+detail::big_number_exp<\
+ detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
- , detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type> \
->::type const \
+ , big_number<Backend>\
+> \
 func(const big_number<Backend>& arg)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , big_number<Backend>\
+ >(\
         detail::BOOST_JOIN(func, _funct)<Backend>() \
- , static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(arg) \
+ , arg \
     );\
 }
 
@@ -688,61 +690,81 @@
 \
 }\
 template <class Backend> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
+detail::big_number_exp<\
+ detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
- , detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type> \
- , detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type> \
->::type const \
+ , big_number<Backend> \
+ , big_number<Backend> \
+> \
 func(const big_number<Backend>& arg, const big_number<Backend>& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , big_number<Backend> \
+ , big_number<Backend> \
+ >(\
         detail::BOOST_JOIN(func, _funct)<Backend>() \
- , static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(arg),\
- static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(a)\
+ , arg,\
+ a\
     );\
 }\
-template <class Backend, class Exp> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
- , detail::BOOST_JOIN(func, _funct)<Backend> \
- , detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type> \
- , detail::big_number_exp<Exp> \
->::type const \
-func(const big_number<Backend>& arg, const detail::big_number_exp<Exp>& a)\
+template <class Backend, class tag, class A1, class A2, class A3> \
+detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , big_number<Backend> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+> \
+func(const big_number<Backend>& arg, const detail::big_number_exp<tag, A1, A2, A3>& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , big_number<Backend> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+ >(\
         detail::BOOST_JOIN(func, _funct)<Backend>() \
- , static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(arg),\
+ , arg,\
       a\
     );\
 }\
-template <class Exp, class Backend> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
- , detail::BOOST_JOIN(func, _funct)<Backend> \
- , detail::big_number_exp<Exp> \
- , detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type > \
->::type const \
-func(const detail::big_number_exp<Exp>& arg, const big_number<Backend>& a)\
+template <class tag, class A1, class A2, class A3, class Backend> \
+detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+ , big_number<Backend>\
+>\
+func(const detail::big_number_exp<tag, A1, A2, A3>& arg, const big_number<Backend>& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+ , big_number<Backend>\
+ >(\
         detail::BOOST_JOIN(func, _funct)<Backend>() \
       , arg,\
- static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(a)\
+ a\
     );\
 }\
-template <class Exp1, class Exp2> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<Exp1>::type> \
- , detail::big_number_exp<Exp1> \
- , detail::big_number_exp<Exp2> \
->::type const \
-func(const detail::big_number_exp<Exp1>& arg, const detail::big_number_exp<Exp2>& a)\
-{\
- return proto::make_expr<proto::tag::function>(\
- detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<Exp1>::type>() \
+template <class tag, class A1, class A2, class A3, class tagb, class A1b, class A2b, class A3b> \
+detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+ , detail::big_number_exp<tagb, A1b, A2b, A3b> \
+>\
+func(const detail::big_number_exp<tag, A1, A2, A3>& arg, const detail::big_number_exp<tagb, A1b, A2b, A3b>& a)\
+{\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+ , detail::big_number_exp<tagb, A1b, A2b, A3b> \
+ >(\
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type>() \
       , arg,\
       a\
     );\
@@ -750,35 +772,47 @@
 template <class Backend, class Arithmetic> \
 typename enable_if<\
    is_arithmetic<Arithmetic>,\
- typename proto::result_of::make_expr<\
- proto::tag::function\
+ detail::big_number_exp<\
+ detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
- , detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type> \
- , typename proto::result_of::as_child<const Arithmetic&>::type\
->::type>::type const \
+ , big_number<Backend>\
+ , Arithmetic\
+ > \
+>::type \
 func(const big_number<Backend>& arg, const Arithmetic& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , big_number<Backend>\
+ , Arithmetic\
+ >(\
         detail::BOOST_JOIN(func, _funct)<Backend>() \
- , static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(arg),\
- proto::as_child(a)\
+ , arg,\
+ a\
     );\
 }\
-template <class Exp, class Arithmetic> \
+template <class tag, class A1, class A2, class A3, class Arithmetic> \
 typename enable_if<\
    is_arithmetic<Arithmetic>,\
- typename proto::result_of::make_expr<\
- proto::tag::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<Exp>::type> \
- , detail::big_number_exp<Exp> \
- , typename proto::result_of::as_child<const Arithmetic&>::type\
->::type>::type const \
-func(const detail::big_number_exp<Exp>& arg, const Arithmetic& a)\
-{\
- return proto::make_expr<proto::tag::function>(\
- detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<Exp>::type>() \
+ detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+ , Arithmetic\
+ > \
+>::type \
+func(const detail::big_number_exp<tag, A1, A2, A3>& arg, const Arithmetic& a)\
+{\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+ , Arithmetic\
+ >(\
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type>() \
       , arg,\
- proto::as_child(a)\
+ a\
     );\
 }\
 
@@ -797,33 +831,43 @@
 \
 }\
 \
-template <class Exp> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
- , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<Exp>::type> \
- , detail::big_number_exp<Exp> \
- , typename proto::result_of::as_child<Arg2>::type \
->::type const \
-func(const detail::big_number_exp<Exp>& arg, Arg2 const& a)\
-{\
- return proto::make_expr<proto::tag::function>(\
- detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<Exp>::type>() \
- , arg, proto::as_child(a) \
+template <class tag, class A1, class A2, class A3> \
+detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+ , Arg2\
+>\
+func(const detail::big_number_exp<tag, A1, A2, A3>& arg, Arg2 const& a)\
+{\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
+ , detail::big_number_exp<tag, A1, A2, A3> \
+ , Arg2\
+ >(\
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type>() \
+ , arg, a \
     );\
 }\
 template <class Backend> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
+detail::big_number_exp<\
+ detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
- , detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type> \
- , typename proto::result_of::as_child<Arg2 const>::type \
->::type const \
+ , big_number<Backend>\
+ , Arg2\
+>\
 func(const big_number<Backend>& arg, Arg2 const& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::big_number_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , big_number<Backend>\
+ , Arg2\
+ >(\
         detail::BOOST_JOIN(func, _funct)<Backend>() \
- , static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(arg),\
- proto::as_child(a)\
+ , arg,\
+ a\
     );\
 }\
 

Modified: sandbox/big_number/boost/math/big_number/gmp.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/gmp.hpp (original)
+++ sandbox/big_number/boost/math/big_number/gmp.hpp 2011-09-24 07:07:59 EDT (Sat, 24 Sep 2011)
@@ -1305,7 +1305,9 @@
 }
 
 template<>
-struct is_extended_integer<gmp_int> : public mpl::true_ {};
+struct number_category<gmp_int> : public mpl::int_<number_kind_integer>{};
+template<>
+struct number_category<gmp_rational> : public mpl::int_<number_kind_rational>{};
 
 typedef big_number<gmp_real<50> > mpf_real_50;
 typedef big_number<gmp_real<100> > mpf_real_100;

Modified: sandbox/big_number/libs/math/test/big_number_concept_check.cpp
==============================================================================
--- sandbox/big_number/libs/math/test/big_number_concept_check.cpp (original)
+++ sandbox/big_number/libs/math/test/big_number_concept_check.cpp 2011-09-24 07:07:59 EDT (Sat, 24 Sep 2011)
@@ -54,68 +54,6 @@
 #include <boost/math/concepts/real_type_concept.hpp>
 #include "libs/math/test/compile_test/instantiate.hpp"
 
-void a()
-{
- using namespace boost;
- using namespace boost::math;
- using namespace boost::math::concepts;
-
- function_requires<DistributionConcept<bernoulli_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<beta_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<binomial_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<cauchy_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<chi_squared_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<exponential_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<extreme_value_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<fisher_f_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<gamma_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<geometric_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<hypergeometric_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<inverse_chi_squared_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<inverse_gamma_distribution<boost::math::mpfr_real_50> > >();
-}
-
-void b()
-{
- using namespace boost;
- using namespace boost::math;
- using namespace boost::math::concepts;
-
- function_requires<DistributionConcept<inverse_gaussian_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<laplace_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<logistic_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<lognormal_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<negative_binomial_distribution<boost::math::mpfr_real_50> > >();
-}
-
-void c()
-{
- using namespace boost;
- using namespace boost::math;
- using namespace boost::math::concepts;
-
- function_requires<DistributionConcept<non_central_chi_squared_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<non_central_beta_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<non_central_f_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<non_central_t_distribution<boost::math::mpfr_real_50> > >();
-}
-
-void d()
-{
- using namespace boost;
- using namespace boost::math;
- using namespace boost::math::concepts;
-
- function_requires<DistributionConcept<normal_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<pareto_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<poisson_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<rayleigh_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<students_t_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<triangular_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<uniform_distribution<boost::math::mpfr_real_50> > >();
- function_requires<DistributionConcept<weibull_distribution<boost::math::mpfr_real_50> > >();
-}
-
 void foo()
 {
 #ifdef TEST_BACKEND

Modified: sandbox/big_number/libs/math/test/test_arithmetic.cpp
==============================================================================
--- sandbox/big_number/libs/math/test/test_arithmetic.cpp (original)
+++ sandbox/big_number/libs/math/test/test_arithmetic.cpp 2011-09-24 07:07:59 EDT (Sat, 24 Sep 2011)
@@ -53,11 +53,11 @@
       BOOST_LIGHTWEIGHT_TEST_OSTREAM << e.what() << std::endl;\
    }
 
-template <class Real>
-void test_integer_ops(const boost::mpl::false_&){}
+template <class Real, unsigned N>
+void test_integer_ops(const boost::mpl::int_<N>&){}
 
 template <class Real>
-void test_integer_ops(const boost::mpl::true_&)
+void test_integer_ops(const boost::mpl::int_<boost::math::number_kind_integer>&)
 {
    Real a(20);
    Real b(7);
@@ -236,7 +236,6 @@
    BOOST_TEST(c == (i & ~j));
    c = ~(a | b);
    BOOST_TEST(c == ~(i | j));
-
    //
    // Non-member functions:
    //
@@ -250,11 +249,11 @@
    BOOST_TEST(abs(+a) == 20);
 }
 
-template <class Real>
-void test_real_ops(const boost::mpl::false_&){}
+template <class Real, unsigned N>
+void test_real_ops(const boost::mpl::int_<N>&){}
 
 template <class Real>
-void test_real_ops(const boost::mpl::true_&)
+void test_real_ops(const boost::mpl::int_<boost::math::number_kind_floating_point>&)
 {
 #if defined(TEST_MPF) || defined(TEST_MPF_50) || defined(TEST_BACKEND) || defined(TEST_MPFR)
    BOOST_TEST(abs(Real(2)) == 2);
@@ -501,7 +500,6 @@
    BOOST_TEST(Real(r / n5) == n1 / n5);
    r /= n5;
    BOOST_TEST(r == n1 / n5);
-
    //
    // special cases for full coverage:
    //
@@ -513,7 +511,6 @@
    BOOST_TEST(r == n4 * n5);
    r = (4 * n4) / Real(4);
    BOOST_TEST(r == n4);
-
    test_negative_mixed<Real, Num>(boost::mpl::bool_<std::numeric_limits<Num>::is_signed>());
 }
 
@@ -541,11 +538,11 @@
    //
    // Integer only functions:
    //
- test_integer_ops<Real>(boost::math::is_extended_integer<Real>());
+ test_integer_ops<Real>(boost::math::number_category<Real>());
    //
    // Real number only functions:
    //
- test_real_ops<Real>(boost::mpl::bool_<false == boost::math::is_extended_integer<Real>::value >());
+ test_real_ops<Real>(boost::math::number_category<Real>());
    //
    // Test basic arithmetic:
    //
@@ -565,14 +562,12 @@
    BOOST_TEST(a / b == 8);
    a /= b;
    BOOST_TEST(a == 8);
-
    Real ac(a);
    BOOST_TEST(ac == a);
    BOOST_TEST(-a == -8);
-
    ac = a * c;
    BOOST_TEST(ac == 8*500L);
-
+ ac = 8*500L;
    ac = ac + b + c;
    BOOST_TEST(ac == 8*500L+64+500);
    ac = a;
@@ -639,10 +634,6 @@
    ac = a * ac;
    BOOST_TEST(ac == 8*8);
    ac = a;
-#ifndef TEST_E_FLOAT
- ac = ac + "8";
- BOOST_TEST(ac == 16);
-#endif
    ac = a;
    ac += +a;
    BOOST_TEST(ac == 16);
@@ -656,10 +647,6 @@
    ac += b*c;
    BOOST_TEST(ac == 8 + 64 * 500);
    ac = a;
-#ifndef TEST_E_FLOAT
- ac = ac - "8";
- BOOST_TEST(ac == 0);
-#endif
    ac = a;
    ac -= +a;
    BOOST_TEST(ac == 0);
@@ -678,12 +665,7 @@
    ac = a;
    ac -= ac * b;
    BOOST_TEST(ac == 8 - 8 * 64);
-#ifndef TEST_E_FLOAT
- ac = a * "8";
- BOOST_TEST(ac == 64);
-#else
    ac = a * 8;
-#endif
    ac *= +a;
    BOOST_TEST(ac == 64 * 8);
    ac = a;
@@ -698,10 +680,6 @@
    ac = a;
    ac *= b + c;
    BOOST_TEST(ac == 8 * (64 + 500));
-#ifndef TEST_E_FLOAT
- ac = b / "8";
- BOOST_TEST(ac == 8);
-#endif
    ac = b;
    ac /= +a;
    BOOST_TEST(ac == 8);
@@ -714,10 +692,6 @@
    ac = b;
    ac /= a + Real(0);
    BOOST_TEST(ac == 8);
-#ifndef TEST_E_FLOAT
- ac = a + std::string("8");
- BOOST_TEST(ac == 16);
-#endif
    //
    // simple tests with immediate values, these calls can be optimised in many backends:
    //


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