Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r74578 - in sandbox/big_number/boost: math/big_number/functions multiprecision multiprecision/backends multiprecision/backends/functions multiprecision/big_number multiprecision/concepts multiprecision/detail
From: john_at_[hidden]
Date: 2011-09-26 12:29:48


Author: johnmaddock
Date: 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
New Revision: 74578
URL: http://svn.boost.org/trac/boost/changeset/74578

Log:
Giant file and directory rename: changed directory name from math to multiprecision and updated code to match.
Added:
   sandbox/big_number/boost/math/big_number/functions/
   sandbox/big_number/boost/multiprecision/
      - copied from r74479, /sandbox/big_number/boost/math/
   sandbox/big_number/boost/multiprecision/arithmetic_backend.hpp
      - copied, changed from r74479, /sandbox/big_number/boost/math/big_number/arithmetic_backend.hpp
   sandbox/big_number/boost/multiprecision/backends/
      - copied from r74479, /sandbox/big_number/boost/math/big_number/
   sandbox/big_number/boost/multiprecision/backends/functions/
   sandbox/big_number/boost/multiprecision/backends/functions/pow.hpp (contents, props changed)
   sandbox/big_number/boost/multiprecision/detail/
   sandbox/big_number/boost/multiprecision/detail/big_number_base.hpp
      - copied, changed from r74479, /sandbox/big_number/boost/math/big_number/big_number_base.hpp
   sandbox/big_number/boost/multiprecision/detail/default_ops.hpp
      - copied, changed from r74479, /sandbox/big_number/boost/math/big_number/default_ops.hpp
   sandbox/big_number/boost/multiprecision/e_float.hpp
      - copied, changed from r74479, /sandbox/big_number/boost/math/big_number/e_float.hpp
   sandbox/big_number/boost/multiprecision/gmp.hpp
      - copied, changed from r74479, /sandbox/big_number/boost/math/big_number/gmp.hpp
   sandbox/big_number/boost/multiprecision/mp_number.hpp
      - copied, changed from r74479, /sandbox/big_number/boost/math/big_number.hpp
   sandbox/big_number/boost/multiprecision/mpfr.hpp
      - copied, changed from r74479, /sandbox/big_number/boost/math/big_number/mpfr.hpp
Removed:
   sandbox/big_number/boost/multiprecision/backends/arithmetic_backend.hpp
   sandbox/big_number/boost/multiprecision/backends/big_number_base.hpp
   sandbox/big_number/boost/multiprecision/backends/default_ops.hpp
   sandbox/big_number/boost/multiprecision/backends/e_float.hpp
   sandbox/big_number/boost/multiprecision/backends/gmp.hpp
   sandbox/big_number/boost/multiprecision/backends/mpfr.hpp
   sandbox/big_number/boost/multiprecision/big_number/
   sandbox/big_number/boost/multiprecision/big_number.hpp
Text files modified:
   sandbox/big_number/boost/multiprecision/arithmetic_backend.hpp | 6
   sandbox/big_number/boost/multiprecision/concepts/big_number_architypes.hpp | 4
   sandbox/big_number/boost/multiprecision/detail/big_number_base.hpp | 1290 ++++++++++++++++++++++++---------------
   sandbox/big_number/boost/multiprecision/detail/default_ops.hpp | 374 ++++++-----
   sandbox/big_number/boost/multiprecision/e_float.hpp | 4
   sandbox/big_number/boost/multiprecision/gmp.hpp | 38
   sandbox/big_number/boost/multiprecision/mp_number.hpp | 985 +++++++++++++++--------------
   sandbox/big_number/boost/multiprecision/mpfr.hpp | 40
   8 files changed, 1555 insertions(+), 1186 deletions(-)

Copied: sandbox/big_number/boost/multiprecision/arithmetic_backend.hpp (from r74479, /sandbox/big_number/boost/math/big_number/arithmetic_backend.hpp)
==============================================================================
--- /sandbox/big_number/boost/math/big_number/arithmetic_backend.hpp (original)
+++ sandbox/big_number/boost/multiprecision/arithmetic_backend.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
@@ -10,7 +10,7 @@
 #include <iomanip>
 #include <boost/cstdint.hpp>
 #include <boost/lexical_cast.hpp>
-#include <boost/math/big_number.hpp>
+#include <boost/multiprecision/mp_number.hpp>
 
 namespace boost{
 namespace math{
@@ -122,10 +122,10 @@
 #endif
 
 template <class Arithmetic>
-class numeric_limits<boost::math::big_number<boost::math::arithmetic_backend<Arithmetic> > > : public std::numeric_limits<Arithmetic>
+class numeric_limits<boost::math::mp_number<boost::math::arithmetic_backend<Arithmetic> > > : public std::numeric_limits<Arithmetic>
 {
    typedef std::numeric_limits<Arithmetic> base_type;
- typedef boost::math::big_number<boost::math::arithmetic_backend<Arithmetic> > number_type;
+ typedef boost::math::mp_number<boost::math::arithmetic_backend<Arithmetic> > number_type;
 public:
    BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return (base_type::min)(); }
    BOOST_STATIC_CONSTEXPR number_type (max)() noexcept { return (base_type::max)(); }

Deleted: /sandbox/big_number/boost/math/big_number/arithmetic_backend.hpp
==============================================================================
--- /sandbox/big_number/boost/math/big_number/arithmetic_backend.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
+++ (empty file)
@@ -1,147 +0,0 @@
-///////////////////////////////////////////////////////////////
-// Copyright 2011 John Maddock. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
-
-#ifndef BOOST_MATH_ARITH_BACKEND_HPP
-#define BOOST_MATH_ARITH_BACKEND_HPP
-
-#include <iostream>
-#include <iomanip>
-#include <boost/cstdint.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/math/big_number.hpp>
-
-namespace boost{
-namespace math{
-
-template <class Arithmetic>
-struct arithmetic_backend
-{
- typedef mpl::list<long long> signed_types;
- typedef mpl::list<unsigned long long> unsigned_types;
- typedef mpl::list<long double> real_types;
-
- arithmetic_backend(){}
- arithmetic_backend(const arithmetic_backend& o)
- {
- m_value = o.m_value;
- }
- arithmetic_backend(const Arithmetic& o) : m_value(o) {}
-#ifndef BOOST_NO_RVALUE_REFERENCES
- arithmetic_backend(arithmetic_backend&& o) : m_value(o.m_value) {}
- arithmetic_backend(Arithmetic&& o) : m_value(o) {}
-#endif
- arithmetic_backend& operator = (const arithmetic_backend& o)
- {
- m_value = o.m_value;
- return *this;
- }
- arithmetic_backend& operator = (boost::uintmax_t i)
- {
- m_value = i;
- return *this;
- }
- arithmetic_backend& operator = (boost::intmax_t i)
- {
- m_value = i;
- return *this;
- }
- arithmetic_backend& operator = (long double d)
- {
- m_value = d;
- return *this;
- }
- arithmetic_backend& operator = (const char* s)
- {
- m_value = boost::lexical_cast<double>(s);
- return *this;
- }
- void swap(arithmetic_backend& o)
- {
- std::swap(m_value, o.m_value);
- }
- std::string str(unsigned digits, bool scientific)const
- {
- return boost::lexical_cast<std::string>(m_value);
- }
- void negate()
- {
- m_value = -m_value;
- }
- int compare(const arithmetic_backend& o)const
- {
- return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0);
- }
- int compare(boost::intmax_t i)const
- {
- return m_value > i ? 1 : (m_value < i ? -1 : 0);
- }
- int compare(boost::uintmax_t i)const
- {
- return m_value > i ? 1 : (m_value < i ? -1 : 0);
- }
- int compare(long double d)const
- {
- return m_value > d ? 1 : (m_value < d ? -1 : 0);
- }
- Arithmetic& data() { return m_value; }
- const Arithmetic& data()const { return m_value; }
-private:
- Arithmetic m_value;
-};
-
-template <class Arithmetic>
-inline void add(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
-{
- result.data() += o.data();
-}
-template <class Arithmetic>
-inline void subtract(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
-{
- result.data() -= o.data();
-}
-template <class Arithmetic>
-inline void multiply(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
-{
- result.data() *= o.data();
-}
-template <class Arithmetic>
-inline void divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
-{
- result.data() /= o.data();
-}
-
-}} // namespaces
-
-
-namespace std{
-
-#ifdef BOOST_NO_NOEXCEPT
-# define noexcept
-#endif
-
-template <class Arithmetic>
-class numeric_limits<boost::math::big_number<boost::math::arithmetic_backend<Arithmetic> > > : public std::numeric_limits<Arithmetic>
-{
- typedef std::numeric_limits<Arithmetic> base_type;
- typedef boost::math::big_number<boost::math::arithmetic_backend<Arithmetic> > number_type;
-public:
- BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return (base_type::min)(); }
- BOOST_STATIC_CONSTEXPR number_type (max)() noexcept { return (base_type::max)(); }
- BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { return -(max)(); }
- BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept { return base_type::epsilon(); }
- BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { return epsilon() / 2; }
- BOOST_STATIC_CONSTEXPR number_type infinity() noexcept { return base_type::infinity(); }
- BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return base_type::quiet_NaN(); }
- BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return base_type::signaling_NaN(); }
- BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return base_type::denorm_min(); }
-};
-
-#ifdef BOOST_NO_NOEXCEPT
-# undef noexcept
-#endif
-
-}
-
-#endif

Deleted: /sandbox/big_number/boost/math/big_number/big_number_base.hpp
==============================================================================
--- /sandbox/big_number/boost/math/big_number/big_number_base.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
+++ (empty file)
@@ -1,675 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright 2011 John Maddock. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_MATH_BIG_NUM_BASE_HPP
-#define BOOST_MATH_BIG_NUM_BASE_HPP
-
-#include <limits>
-
-namespace boost{ namespace math{
-
-template <class Backend>
-class big_number;
-
-namespace detail{
-
-// Forward-declare an expression wrapper
-template<typename Expr>
-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
-{
- template <class T>
- struct type : public mpl::bool_<std::numeric_limits<T>::digits >= b>{};
-};
-
-template <class Val, class Backend, class Tag>
-struct canonical_imp
-{
- typedef Val type;
-};
-template <class Val, class Backend>
-struct canonical_imp<Val, Backend, mpl::int_<0> >
-{
- typedef typename has_enough_bits<std::numeric_limits<Val>::digits>::template type<mpl::_> pred_type;
- typedef typename mpl::find_if<
- typename Backend::signed_types,
- pred_type
- >::type iter_type;
- typedef typename mpl::deref<iter_type>::type type;
-};
-template <class Val, class Backend>
-struct canonical_imp<Val, Backend, mpl::int_<1> >
-{
- typedef typename has_enough_bits<std::numeric_limits<Val>::digits>::template type<mpl::_> pred_type;
- typedef typename mpl::find_if<
- typename Backend::unsigned_types,
- pred_type
- >::type iter_type;
- typedef typename mpl::deref<iter_type>::type type;
-};
-template <class Val, class Backend>
-struct canonical_imp<Val, Backend, mpl::int_<2> >
-{
- typedef typename has_enough_bits<std::numeric_limits<Val>::digits>::template type<mpl::_> pred_type;
- typedef typename mpl::find_if<
- typename Backend::real_types,
- pred_type
- >::type iter_type;
- typedef typename mpl::deref<iter_type>::type type;
-};
-template <class Val, class Backend>
-struct canonical_imp<Val, Backend, mpl::int_<3> >
-{
- typedef const char* type;
-};
-
-template <class Val, class Backend>
-struct canonical
-{
- typedef typename mpl::if_<
- is_signed<Val>,
- mpl::int_<0>,
- typename mpl::if_<
- is_unsigned<Val>,
- mpl::int_<1>,
- typename mpl::if_<
- is_floating_point<Val>,
- mpl::int_<2>,
- typename mpl::if_<
- mpl::or_<
- is_convertible<Val, const char*>,
- is_same<Val, std::string>
- >,
- mpl::int_<3>,
- mpl::int_<4>
- >::type
- >::type
- >::type
- >::type tag_type;
-
- typedef typename canonical_imp<Val, Backend, tag_type>::type type;
-};
-
-template <class Exp, class tag>
-struct assign_and_eval_imp
-{
- typedef tag type;
-};
-
-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 immediate{};
-struct negative_immediate{};
-
-template <class Exp, class tag>
-struct immediate_type
-{
- typedef tag type;
-};
-template <class Exp>
-struct immediate_type<Exp, proto::tag::terminal>
-{
- typedef immediate type;
-};
-template <class Exp>
-struct immediate_type<Exp, proto::tag::unary_plus>
-{
- 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;
-};
-
-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 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 Exp>
-struct assign_and_eval_imp<Exp, proto::tag::divides>
-{
- 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;
-};
-
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::modulus>
-{
- 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;
-};
-
-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 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 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 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 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;
-};
-
-template <class Exp, class tag>
-struct underlying_result_imp
-{
- 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;
-};
-
-template <class Exp>
-struct underlying_result_imp<Exp, proto::tag::terminal>
-{
- typedef typename proto::result_of::value<Exp const &>::type type;
-};
-
-template <class Exp>
-struct underlying_result
-{
- typedef typename proto::tag_of<Exp>::type tag_type;
- typedef typename underlying_result_imp<Exp, tag_type>::type type;
-};
-
-template <class Exp1, class Exp2>
-struct combine_expression_type
-{
- typedef void type;
-};
-
-template <class Backend>
-struct combine_expression_type<boost::math::big_number<Backend>, boost::math::big_number<Backend> >
-{
- typedef boost::math::big_number<Backend> type;
-};
-
-template <class Backend, class Exp>
-struct combine_expression_type<boost::math::big_number<Backend>, Exp>
-{
- typedef boost::math::big_number<Backend> type;
-};
-
-template <class Backend, class Exp>
-struct combine_expression_type<Exp, boost::math::big_number<Backend> >
-{
- typedef boost::math::big_number<Backend> 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 T>
-struct is_big_number_exp<boost::math::detail::big_number_exp<T> > : public mpl::true_{};
-
-
-template <class Exp, int arity>
-struct expression_type_imp;
-
-template <class Exp>
-struct expression_type_imp<Exp, 0>
-{
- typedef typename remove_pointer<typename proto::result_of::value<Exp>::type>::type type;
-};
-
-template <class Exp>
-struct expression_type_imp<Exp, 1>
-{
- 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;
-};
-
-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;
-};
-
-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;
-};
-
-template <class Exp>
-struct expression_type
-{
- typedef typename expression_type_imp<Exp, proto::arity_of<Exp>::value>::type type;
-};
-
-template <class Exp>
-struct backend_type
-{
- typedef typename expression_type<Exp>::type num_type;
- typedef typename backend_type<num_type>::type type;
-};
-
-template <class Backend>
-struct backend_type<boost::math::big_number<Backend> >
-{
- typedef Backend type;
-};
-
-template<typename Expr>
-struct big_number_exp
- : proto::extends<Expr, big_number_exp<Expr>, big_number_domain>
-{
-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());
- }
-};
-
-} // namespace detail
-
-//
-// Traits class, lets us know whether a backend is an integer type, otherwise assumed to be a real number type:
-//
-template <class Num>
-struct is_extended_integer : public mpl::false_ {};
-template <class Backend>
-struct is_extended_integer<big_number<Backend> > : public is_extended_integer<Backend>{};
-
-}} // namespaces
-
-namespace boost{ namespace math{ namespace tools{
-
-template <class T>
-struct promote_arg;
-
-template <class Exp>
-struct promote_arg<boost::math::detail::big_number_exp<Exp> >
-{
- typedef typename boost::math::detail::expression_type<Exp>::type type;
-};
-
-}}}
-
-#endif // BOOST_MATH_BIG_NUM_BASE_HPP
-
-

Deleted: /sandbox/big_number/boost/math/big_number/default_ops.hpp
==============================================================================
--- /sandbox/big_number/boost/math/big_number/default_ops.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
+++ (empty file)
@@ -1,859 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright 2011 John Maddock. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_MATH_BIG_NUM_DEF_OPS
-#define BOOST_MATH_BIG_NUM_DEF_OPS
-
-#include <boost/math/policies/error_handling.hpp>
-#include <boost/math/big_number/big_number_base.hpp>
-#include <boost/math/special_functions/fpclassify.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace boost{ namespace math{ namespace big_num_default_ops{
-
-//
-// Default versions of mixed arithmetic, these just construct a temporary
-// from the arithmetic value and then do the arithmetic on that:
-//
-template <class T, class V>
-inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
- add(T& result, V const& v)
-{
- T t;
- t = v;
- add(result, t);
-}
-template <class T, class V>
-inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
- subtract(T& result, V const& v)
-{
- T t;
- t = v;
- subtract(result, t);
-}
-template <class T, class V>
-inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
- multiply(T& result, V const& v)
-{
- T t;
- t = v;
- multiply(result, t);
-}
-template <class T, class V>
-inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
- divide(T& result, V const& v)
-{
- T t;
- t = v;
- divide(result, t);
-}
-template <class T, class V>
-inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
- modulus(T& result, V const& v)
-{
- T t;
- t = v;
- modulus(result, t);
-}
-template <class T, class V>
-inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
- bitwise_and(T& result, V const& v)
-{
- T t;
- t = v;
- bitwise_and(result, t);
-}
-template <class T, class V>
-inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
- bitwise_or(T& result, V const& v)
-{
- T t;
- t = v;
- bitwise_or(result, t);
-}
-template <class T, class V>
-inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
- bitwise_xor(T& result, V const& v)
-{
- T t;
- t = v;
- bitwise_xor(result, t);
-}
-
-template <class T, class V>
-inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
- complement(T& result, V const& v)
-{
- T t;
- t = v;
- complement(result, t);
-}
-
-template <class T>
-inline bool is_same_object(const T& u, const T&v)
-{ return &u == &v; }
-template <class T, class U>
-inline bool is_same_object(const T& u, const U&v)
-{ return false; }
-
-//
-// Default versions of 3-arg arithmetic functions, these just forward to the 2 arg versions:
-//
-template <class T, class U, class V>
-inline void add(T& t, const U& u, const V& v)
-{
- if(is_same_object(t, v))
- {
- add(t, u);
- }
- else if(is_same_object(t, u))
- {
- add(t, v);
- }
- else
- {
- t = u;
- add(t, v);
- }
-}
-template <class T, class U, class V>
-inline void subtract(T& t, const U& u, const V& v)
-{
- if(is_same_object(t, u))
- subtract(t, v);
- else if(is_same_object(t, v))
- {
- subtract(t, u);
- t.negate();
- }
- else
- {
- t = u;
- subtract(t, v);
- }
-}
-template <class T, class U, class V>
-inline void multiply(T& t, const U& u, const V& v)
-{
- if(is_same_object(t, u))
- multiply(t, v);
- else if(is_same_object(t, v))
- multiply(t, u);
- else
- {
- t = u;
- multiply(t, v);
- }
-}
-template <class T, class U, class V>
-inline void divide(T& t, const U& u, const V& v)
-{
- if(is_same_object(t, u))
- divide(t, v);
- else if(is_same_object(t, v))
- {
- T temp = t;
- divide(temp, u, v);
- temp.swap(t);
- }
- else
- {
- t = u;
- divide(t, v);
- }
-}
-template <class T, class U, class V>
-inline void modulus(T& t, const U& u, const V& v)
-{
- if(is_same_object(t, u))
- modulus(t, v);
- else if(is_same_object(t, v))
- {
- T temp;
- modulus(temp, u, v);
- temp.swap(t);
- }
- else
- {
- t = u;
- modulus(t, v);
- }
-}
-template <class T, class U, class V>
-inline void bitwise_and(T& t, const U& u, const V& v)
-{
- if(is_same_object(t, u))
- bitwise_and(t, v);
- else if(is_same_object(t, v))
- bitwise_and(t, u);
- else
- {
- t = u;
- bitwise_and(t, v);
- }
-}
-
-template <class T, class U, class V>
-inline void bitwise_or(T& t, const U& u, const V& v)
-{
- if(is_same_object(t, u))
- bitwise_or(t, v);
- else if(is_same_object(t, v))
- bitwise_or(t, u);
- else
- {
- t = u;
- bitwise_or(t, v);
- }
-}
-
-template <class T, class U, class V>
-inline void bitwise_xor(T& t, const U& u, const V& v)
-{
- if(is_same_object(t, u))
- bitwise_xor(t, v);
- else if(is_same_object(t, v))
- bitwise_xor(t, u);
- else
- {
- t = u;
- bitwise_xor(t, v);
- }
-}
-
-template <class T>
-inline void increment(T& val)
-{
- typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
- add(val, static_cast<ui_type>(1u));
-}
-
-template <class T>
-inline void decrement(T& val)
-{
- typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
- subtract(val, static_cast<ui_type>(1u));
-}
-
-template <class T, class V>
-inline void left_shift(T& result, const T& arg, const V val)
-{
- result = arg;
- left_shift(result, val);
-}
-
-template <class T, class V>
-inline void right_shift(T& result, const T& arg, const V val)
-{
- result = arg;
- right_shift(result, val);
-}
-
-template <class T>
-inline bool is_zero(const T& val)
-{
- typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
- return val.compare(static_cast<ui_type>(0)) == 0;
-}
-template <class T>
-inline int get_sign(const T& val)
-{
- typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
- return val.compare(static_cast<ui_type>(0));
-}
-
-template <class R, int b>
-struct has_enough_bits
-{
- template <class T>
- struct type : public mpl::and_<mpl::not_<is_same<R, T> >, mpl::bool_<std::numeric_limits<T>::digits >= b> >{};
-};
-
-template <class R>
-struct terminal
-{
- terminal(const R& v) : value(v){}
- terminal(){}
- terminal& operator = (R val) { value = val; }
- R value;
- operator R()const { return value; }
-};
-
-template<class R, class B>
-struct calculate_next_larger_type
-{
- typedef typename mpl::if_<
- is_signed<R>,
- typename B::signed_types,
- typename mpl::if_<
- is_unsigned<R>,
- typename B::unsigned_types,
- typename B::real_types
- >::type
- >::type list_type;
- typedef typename has_enough_bits<R, std::numeric_limits<R>::digits>::template type<mpl::_> pred_type;
- typedef typename mpl::find_if<
- list_type,
- pred_type
- >::type iter_type;
- typedef typename mpl::eval_if<
- is_same<typename mpl::end<list_type>::type, iter_type>,
- mpl::identity<terminal<R> >,
- mpl::deref<iter_type>
- >::type type;
-};
-
-template <class R, class B>
-inline void convert_to(R* result, const B& backend)
-{
- typedef typename calculate_next_larger_type<R, B>::type next_type;
- next_type n;
- convert_to(&n, backend);
- *result = static_cast<R>(n);
-}
-
-template <class R, class B>
-inline void convert_to(terminal<R>* result, const B& backend)
-{
- //
- // We ran out of types to try for the convertion, try
- // a lexical_cast and hope for the best:
- //
- result->value = boost::lexical_cast<R>(backend.str(0, false));
-}
-
-//
-// Functions:
-//
-template <class T>
-void eval_abs(T& result, const T& arg)
-{
- typedef typename T::signed_types type_list;
- typedef typename mpl::front<type_list>::type front;
- *result = arg;
- if(arg.compare(front(0)) < 0)
- result->negate();
-}
-template <class T>
-void eval_fabs(T& result, const T& arg)
-{
- typedef typename T::signed_types type_list;
- typedef typename mpl::front<type_list>::type front;
- *result = arg;
- if(arg.compare(front(0)) < 0)
- result->negate();
-}
-
-template <class Backend>
-inline int eval_fpclassify(const Backend& arg)
-{
- return is_zero(arg) ? FP_ZERO : FP_NORMAL;
-}
-
-template <class T>
-inline void eval_fmod(T& result, const T& a, const T& b)
-{
- if((&result == &a) || (&result == &b))
- {
- T temp;
- eval_fmod(temp, a, b);
- result = temp;
- }
- T n;
- divide(result, a, b);
- if(get_sign(a) < 0)
- eval_ceil(n, result);
- else
- eval_floor(n, result);
- multiply(n, b);
- subtract(result, a, n);
-}
-
-//
-// These have to implemented by the backend, declared here so that our macro generated code compiles OK.
-//
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_floor();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_ceil();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_trunc();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_sqrt();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_ldexp();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_frexp();
-//
-// TODO: implement default versions of these:
-//
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_exp();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_log();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_sin();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_cos();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_tan();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_asin();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_acos();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_atan();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_sinh();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_cosh();
-template <class T>
-typename enable_if_c<sizeof(T) == 0>::type eval_tanh();
-//
-// These functions are implemented in separate files, but expanded inline here:
-//
-#include <boost/math/big_number/functions/pow.hpp>
-
-}
-
-
-template <class Backend>
-class big_number;
-
-namespace detail{
-
-template<typename Expr>
-struct big_number_exp;
-
-}
-
-//
-// Default versions of floating point classification routines:
-//
-template <class Backend>
-inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
-{
- 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)
-{
- typedef typename detail::expression_type<Exp>::type value_type;
- return fpclassify(value_type(arg));
-}
-template <class Backend>
-inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
-{
- 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)
-{
- typedef typename detail::expression_type<Exp>::type value_type;
- return isfinite(value_type(arg));
-}
-template <class Backend>
-inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
-{
- return fpclassify(arg) == FP_NAN;
-}
-template <class Exp>
-inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
-{
- typedef typename detail::expression_type<Exp>::type value_type;
- return isnan(value_type(arg));
-}
-template <class Backend>
-inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
-{
- return fpclassify(arg) == FP_INFINITE;
-}
-template <class Exp>
-inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
-{
- typedef typename detail::expression_type<Exp>::type value_type;
- return isinf(value_type(arg));
-}
-template <class Backend>
-inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
-{
- return fpclassify(arg) == FP_NORMAL;
-}
-template <class Exp>
-inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
-{
- typedef typename detail::expression_type<Exp>::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)
-{
- typedef typename detail::expression_type<Exp>::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>();
- return r.template convert_to<int>();
-}
-template <class Backend, class Policy>
-inline int itrunc(const big_number<Backend>& v, const Policy& pol)
-{
- big_number<Backend> 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>();
- return r.template convert_to<int>();
-}
-template <class T, class Policy>
-inline long ltrunc(const detail::big_number_exp<T>& v, const Policy& pol)
-{
- typedef typename detail::expression_type<T>::type number_type;
- number_type r = trunc(v, pol);
- if(fabs(r) > (std::numeric_limits<long>::max)())
- return policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
- return r.template convert_to<long>();
-}
-template <class T, class Policy>
-inline long ltrunc(const big_number<T>& v, const Policy& pol)
-{
- big_number<T> r = trunc(v, pol);
- if(fabs(r) > (std::numeric_limits<long>::max)())
- return policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
- return r.template convert_to<long>();
-}
-#ifndef BOOST_NO_LONG_LONG
-template <class T, class Policy>
-inline long long lltrunc(const detail::big_number_exp<T>& v, const Policy& pol)
-{
- typedef typename detail::expression_type<T>::type number_type;
- number_type r = trunc(v, pol);
- if(fabs(r) > (std::numeric_limits<long long>::max)())
- return policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
- return r.template convert_to<long long>();
-}
-template <class T, class Policy>
-inline long long lltrunc(const big_number<T>& v, const Policy& pol)
-{
- big_number<T> r = trunc(v, pol);
- if(fabs(r) > (std::numeric_limits<long long>::max)())
- return policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
- return r.template convert_to<long long>();
-}
-#endif
-template <class T, class Policy>
-inline int iround(const detail::big_number_exp<T>& v, const Policy& pol)
-{
- typedef typename detail::expression_type<T>::type number_type;
- number_type r = round(v, pol);
- if(fabs(r) > (std::numeric_limits<int>::max)())
- return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
- return r.template convert_to<int>();
-}
-template <class T, class Policy>
-inline int iround(const big_number<T>& v, const Policy& pol)
-{
- big_number<T> r = round(v, pol);
- if(fabs(r) > (std::numeric_limits<int>::max)())
- return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
- return r.template convert_to<int>();
-}
-template <class T, class Policy>
-inline long lround(const detail::big_number_exp<T>& v, const Policy& pol)
-{
- typedef typename detail::expression_type<T>::type number_type;
- number_type r = round(v, pol);
- if(fabs(r) > (std::numeric_limits<long>::max)())
- return policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
- return r.template convert_to<long>();
-}
-template <class T, class Policy>
-inline long lround(const big_number<T>& v, const Policy& pol)
-{
- big_number<T> r = round(v, pol);
- if(fabs(r) > (std::numeric_limits<long>::max)())
- return policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
- return r.template convert_to<long>();
-}
-#ifndef BOOST_NO_LONG_LONG
-template <class T, class Policy>
-inline long long llround(const detail::big_number_exp<T>& v, const Policy& pol)
-{
- typedef typename detail::expression_type<T>::type number_type;
- number_type r = round(v, pol);
- if(fabs(r) > (std::numeric_limits<long long>::max)())
- return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
- return r.template convert_to<long long>();
-}
-template <class T, class Policy>
-inline long long llround(const big_number<T>& v, const Policy& pol)
-{
- big_number<T> r = round(v, pol);
- if(fabs(r) > (std::numeric_limits<long long>::max)())
- return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
- return r.template convert_to<long long>();
-}
-#endif
-//
-// Overload of Boost.Math functions that find the wrong overload when used with big_number:
-//
-namespace detail{
- template <class T> T sinc_pi_imp(T);
- template <class T> T sinhc_pi_imp(T);
-}
-template <class Backend>
-inline big_number<Backend> sinc_pi(const big_number<Backend>& x)
-{
- return detail::sinc_pi_imp(x);
-}
-
-template <class Backend, class Policy>
-inline big_number<Backend> sinc_pi(const big_number<Backend>& x, const Policy&)
-{
- return detail::sinc_pi_imp(x);
-}
-
-template <class Backend>
-inline big_number<Backend> sinhc_pi(const big_number<Backend>& x)
-{
- return detail::sinhc_pi_imp(x);
-}
-
-template <class Backend, class Policy>
-inline big_number<Backend> sinhc_pi(const big_number<Backend>& x, const Policy&)
-{
- return boost::math::sinhc_pi(x);
-}
-
-#define UNARY_OP_FUNCTOR(func)\
-namespace detail{\
-template <class Backend> \
-struct BOOST_JOIN(func, _funct)\
-{\
- void operator()(Backend& result, const Backend& arg)const\
- {\
- using big_num_default_ops::BOOST_JOIN(eval_,func);\
- BOOST_JOIN(eval_,func)(result, arg);\
- }\
-};\
-\
-}\
-\
-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>() \
- , arg \
- );\
-}\
-template <class Backend> \
-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> \
->::type const \
-func(const big_number<Backend>& arg)\
-{\
- return proto::make_expr<proto::tag::function>(\
- detail::BOOST_JOIN(func, _funct)<Backend>() \
- , static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(arg) \
- );\
-}
-
-#define BINARY_OP_FUNCTOR(func)\
-namespace detail{\
-template <class Backend> \
-struct BOOST_JOIN(func, _funct)\
-{\
- void operator()(Backend& result, const Backend& arg, const Backend& a)const\
- {\
- using big_num_default_ops:: BOOST_JOIN(eval_,func);\
- BOOST_JOIN(eval_,func)(result, arg, a);\
- }\
- template <class Arithmetic> \
- void operator()(Backend& result, const Backend& arg, const Arithmetic& a)const\
- {\
- using big_num_default_ops:: BOOST_JOIN(eval_,func);\
- BOOST_JOIN(eval_,func)(result, arg, a);\
- }\
-};\
-\
-}\
-template <class Backend> \
-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<typename proto::terminal<big_number<Backend>*>::type> \
->::type const \
-func(const big_number<Backend>& arg, const big_number<Backend>& a)\
-{\
- return proto::make_expr<proto::tag::function>(\
- 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)\
- );\
-}\
-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)\
-{\
- return proto::make_expr<proto::tag::function>(\
- detail::BOOST_JOIN(func, _funct)<Backend>() \
- , static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(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)\
-{\
- return proto::make_expr<proto::tag::function>(\
- detail::BOOST_JOIN(func, _funct)<Backend>() \
- , arg,\
- static_cast<const detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type>&>(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>() \
- , arg,\
- a\
- );\
-}\
-template <class Backend, class Arithmetic> \
-typename enable_if<\
- is_arithmetic<Arithmetic>,\
- 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> \
- , typename proto::result_of::as_child<const Arithmetic&>::type\
->::type>::type const \
-func(const big_number<Backend>& arg, const Arithmetic& a)\
-{\
- return proto::make_expr<proto::tag::function>(\
- 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)\
- );\
-}\
-template <class Exp, 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>() \
- , arg,\
- proto::as_child(a)\
- );\
-}\
-
-
-#define HETERO_BINARY_OP_FUNCTOR(func, Arg2)\
-namespace detail{\
-template <class Backend> \
-struct BOOST_JOIN(func, _funct)\
-{\
- void operator()(Backend& result, Backend const& arg, Arg2 a)const\
- {\
- using big_num_default_ops:: BOOST_JOIN(eval_,func);\
- BOOST_JOIN(eval_,func)(result, arg, a);\
- }\
-};\
-\
-}\
-\
-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 Backend> \
-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> \
- , typename proto::result_of::as_child<Arg2 const>::type \
->::type const \
-func(const big_number<Backend>& arg, Arg2 const& a)\
-{\
- return proto::make_expr<proto::tag::function>(\
- 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)\
- );\
-}\
-
-UNARY_OP_FUNCTOR(abs)
-UNARY_OP_FUNCTOR(fabs)
-UNARY_OP_FUNCTOR(sqrt)
-UNARY_OP_FUNCTOR(floor)
-UNARY_OP_FUNCTOR(ceil)
-UNARY_OP_FUNCTOR(trunc)
-UNARY_OP_FUNCTOR(exp)
-UNARY_OP_FUNCTOR(log)
-UNARY_OP_FUNCTOR(cos)
-UNARY_OP_FUNCTOR(sin)
-UNARY_OP_FUNCTOR(tan)
-UNARY_OP_FUNCTOR(asin)
-UNARY_OP_FUNCTOR(acos)
-UNARY_OP_FUNCTOR(atan)
-UNARY_OP_FUNCTOR(cosh)
-UNARY_OP_FUNCTOR(sinh)
-UNARY_OP_FUNCTOR(tanh)
-
-HETERO_BINARY_OP_FUNCTOR(ldexp, int)
-HETERO_BINARY_OP_FUNCTOR(frexp, int*)
-BINARY_OP_FUNCTOR(pow)
-BINARY_OP_FUNCTOR(fmod)
-
-#undef BINARY_OP_FUNCTOR
-#undef UNARY_OP_FUNCTOR
-
-}} // namespaces
-
-#endif
-

Deleted: /sandbox/big_number/boost/math/big_number/e_float.hpp
==============================================================================
--- /sandbox/big_number/boost/math/big_number/e_float.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
+++ (empty file)
@@ -1,80 +0,0 @@
-///////////////////////////////////////////////////////////////
-// Copyright 2011 John Maddock. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
-
-#ifndef BOOST_MATH_EFX_BACKEND_HPP
-#define BOOST_MATH_EFX_BACKEND_HPP
-
-#include <boost/math/big_number/arithmetic_backend.hpp>
-#include <boost/e_float/e_float.hpp>
-#include <boost/e_float/e_float_complex.hpp>
-#include <boost/e_float/e_float_elementary_math.hpp>
-#include <fstream>
-
-namespace boost{
-namespace math{
-
-typedef big_number<arithmetic_backend<efx::e_float> > e_float;
-
-template<>
-inline void arithmetic_backend<efx::e_float>::negate()
-{
- m_value.negate();
-}
-template<>
-inline std::string arithmetic_backend<efx::e_float>::str(unsigned digits, bool scientific)const
-{
- std::fstream os;
- os << std::setprecision(digits ? digits : efx::e_float::ef_digits + 5);
- if(scientific)
- os << std::scientific;
- std::string result;
- this->data().wr_string(result, os);
- return result;
-}
-
-inline void eval_abs(arithmetic_backend<efx::e_float>& result, const arithmetic_backend<efx::e_float>& arg)
-{
- result.data() = ef::fabs(arg.data());
-}
-
-inline void eval_fabs(arithmetic_backend<efx::e_float>& result, const arithmetic_backend<efx::e_float>& arg)
-{
- result.data() = ef::fabs(arg.data());
-}
-
-inline bool is_zero(const arithmetic_backend<efx::e_float>& val)
-{
- return val.data().iszero();
-}
-inline int get_sign(const arithmetic_backend<efx::e_float>& val)
-{
- return val.data().isneg() ? -1 : val.data().iszero() ? 0 : 1;
-}
-
-inline void convert_to(boost::uintmax_t* result, const arithmetic_backend<efx::e_float>& val)
-{
- *result = val.data().extract_unsigned_long_long();
-}
-inline void convert_to(boost::intmax_t* result, const arithmetic_backend<efx::e_float>& val)
-{
- *result = val.data().extract_signed_long_long();
-}
-inline void convert_to(double* result, const arithmetic_backend<efx::e_float>& val)
-{
- *result = val.data().extract_double();
-}
-inline void convert_to(long double* result, const arithmetic_backend<efx::e_float>& val)
-{
- *result = val.data().extract_long_double();
-}
-inline int eval_fpclassify(const arithmetic_backend<efx::e_float>& val)
-{
- return val.data().isinf() ? FP_INFINITE : val.data().isnan() ? FP_NAN : val.data().iszero() ? FP_ZERO : FP_NORMAL;
-}
-
-
-}} // namespaces
-
-#endif

Added: sandbox/big_number/boost/multiprecision/backends/functions/pow.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/backends/functions/pow.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
@@ -0,0 +1,97 @@
+
+// Copyright Christopher Kormanyos 2002 - 2011.
+// Copyright 2011 John Maddock. Distributed under the Boost
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This work is based on an earlier work:
+// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations",
+// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469
+//
+// This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp
+//
+
+template<typename T>
+inline void eval_pow(T& result, const T& t, const T& p)
+{
+}
+
+namespace detail{
+
+template<typename T, typename U>
+inline T pow_imp(T& result, const T& t, const U& p, const mpl::false_&)
+{
+ T temp(p);
+ eval_pow(result, t, p);
+}
+
+template<typename T, typename U>
+inline void pow_imp(T& result, const T& t, const U& p, const mpl::true_&)
+{
+ // Compute the pure power of typename T t^p. Binary splitting of the power is
+ // used. The resulting computational complexity has the order of log2[abs(p)].
+
+ typedef typename mpl::front<typename T::signed_types>::type int_type;
+
+ if(p < 0)
+ {
+ T temp;
+ temp = static_cast<int_type>(1);
+ T denom;
+ pow_imp(denom, t, -p, mpl::true_());
+ divide(result, temp, denom);
+ }
+
+ switch(p)
+ {
+ case 0:
+ result = static_cast<int_type>(1);
+ break;
+ case 1:
+ result = t;
+ break;
+ case 2:
+ multiply(result, t, t);
+ break;
+ case 3:
+ multiply(result, t, t);
+ multiply(result, t);
+ break;
+ case 4:
+ multiply(result, t, t);
+ multiply(result, result);
+ break;
+ default:
+ {
+ result = t;
+ U n;
+
+ for(n = static_cast<U>(1); n <= static_cast<U>(p / static_cast<U>(2)); n *= static_cast<U>(2))
+ {
+ multiply(result, result);
+ }
+
+ const U p_minus_n = static_cast<U>(p - n);
+
+ // Call the function recursively for computing the remaining power of n.
+ if(p_minus_n)
+ {
+ T temp;
+ pow_imp(temp, t, p_minus_n, mpl::true_());
+ multiply(result, temp);
+ }
+ }
+ }
+}
+
+} // namespace detail
+
+template<typename T, typename U>
+inline void eval_pow(T& result, const T& t, const U& p)
+{
+ typedef typename is_integral<U>::type tag_type;
+ detail::pow_imp(result, t, p, tag_type());
+}
+
+

Deleted: /sandbox/big_number/boost/math/big_number/gmp.hpp
==============================================================================
--- /sandbox/big_number/boost/math/big_number/gmp.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
+++ (empty file)
@@ -1,1530 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright 2011 John Maddock. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_MATH_ER_GMP_BACKEND_HPP
-#define BOOST_MATH_ER_GMP_BACKEND_HPP
-
-#include <boost/math/big_number.hpp>
-#include <boost/math/special_functions/fpclassify.hpp>
-#include <boost/cstdint.hpp>
-#include <boost/lexical_cast.hpp>
-#include <gmp.h>
-#include <cmath>
-#include <limits>
-#include <climits>
-
-namespace boost{ namespace math{
-
-template <unsigned digits10>
-struct gmp_real;
-
-namespace detail{
-
-template <unsigned digits10>
-struct gmp_real_imp
-{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
- typedef mpl::list<double, long double> real_types;
-
- gmp_real_imp(){}
-
- gmp_real_imp(const gmp_real_imp& o)
- {
- //
- // We have to do an init followed by a set here, otherwise *this may be at
- // a lower precision than o: seems like mpf_init_set copies just enough bits
- // to get the right value, but if it's then used in further calculations
- // things go badly wrong!!
- //
- mpf_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
- mpf_set(m_data, o.m_data);
- }
-#ifndef BOOST_NO_RVALUE_REFERENCES
- gmp_real_imp(gmp_real_imp&& o)
- {
- m_data[0] = o.m_data[0];
- o.m_data[0]._mp_d = 0;
- }
-#endif
- gmp_real_imp& operator = (const gmp_real_imp& o)
- {
- mpf_set(m_data, o.m_data);
- return *this;
- }
-#ifndef BOOST_NO_RVALUE_REFERENCES
- gmp_real_imp& operator = (gmp_real_imp&& o)
- {
- mpf_swap(m_data, o.m_data);
- return *this;
- }
-#endif
- gmp_real_imp& operator = (boost::uintmax_t i)
- {
- boost::uintmax_t mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
- unsigned shift = 0;
- mpf_t t;
- mpf_init2(t, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
- mpf_set_ui(m_data, 0);
- while(i)
- {
- mpf_set_ui(t, static_cast<unsigned>(i & mask));
- if(shift)
- mpf_mul_2exp(t, t, shift);
- mpf_add(m_data, m_data, t);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
- }
- mpf_clear(t);
- return *this;
- }
- gmp_real_imp& operator = (boost::intmax_t i)
- {
- bool neg = i < 0;
- *this = static_cast<boost::uintmax_t>(std::abs(i));
- if(neg)
- mpf_neg(m_data, m_data);
- return *this;
- }
- gmp_real_imp& operator = (unsigned long i)
- {
- mpf_set_ui(m_data, i);
- return *this;
- }
- gmp_real_imp& operator = (long i)
- {
- mpf_set_si(m_data, i);
- return *this;
- }
- gmp_real_imp& operator = (double d)
- {
- mpf_set_d(m_data, d);
- return *this;
- }
- gmp_real_imp& operator = (long double a)
- {
- using std::frexp;
- using std::ldexp;
- using std::floor;
-
- if (a == 0) {
- mpf_set_si(m_data, 0);
- return *this;
- }
-
- if (a == 1) {
- mpf_set_si(m_data, 1);
- return *this;
- }
-
- BOOST_ASSERT(!(boost::math::isinf)(a));
- BOOST_ASSERT(!(boost::math::isnan)(a));
-
- int e;
- long double f, term;
- mpf_init_set_ui(m_data, 0u);
-
- f = frexp(a, &e);
-
- static const int shift = std::numeric_limits<int>::digits - 1;
-
- while(f)
- {
- // extract int sized bits from f:
- f = ldexp(f, shift);
- term = floor(f);
- e -= shift;
- mpf_mul_2exp(m_data, m_data, shift);
- if(term > 0)
- mpf_add_ui(m_data, m_data, static_cast<unsigned>(term));
- else
- mpf_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
- f -= term;
- }
- if(e > 0)
- mpf_mul_2exp(m_data, m_data, e);
- else if(e < 0)
- mpf_div_2exp(m_data, m_data, -e);
- return *this;
- }
- gmp_real_imp& operator = (const char* s)
- {
- mpf_set_str(m_data, s, 10);
- return *this;
- }
- void swap(gmp_real_imp& o)
- {
- mpf_swap(m_data, o.m_data);
- }
- std::string str(unsigned digits, bool scientific)const
- {
- std::string result;
- mp_exp_t e;
- void *(*alloc_func_ptr) (size_t);
- void *(*realloc_func_ptr) (void *, size_t, size_t);
- void (*free_func_ptr) (void *, size_t);
- const char* ps = mpf_get_str (0, &e, 10, digits, m_data);
- std::ptrdiff_t sl = std::strlen(ps);
- if(sl == 0)
- return "0";
- if(*ps == '-')
- --sl; // number of digits excluding sign.
- if(!scientific
- && (sl <= std::numeric_limits<boost::uintmax_t>::digits10 + 1)
- && (e >= sl)
- && (sl <= std::numeric_limits<boost::uintmax_t>::digits10 + 1))
- {
- result = ps;
- result.append(e-sl, '0');
- }
- else
- {
- result = ps;
- if(ps[0] == '-')
- result.insert(2, 1, '.');
- else
- result.insert(1, 1, '.');
- --e;
- if(e)
- result += "e" + lexical_cast<std::string>(e);
- }
- mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
- (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
- return result;
- }
- ~gmp_real_imp()
- {
- if(m_data[0]._mp_d)
- mpf_clear(m_data);
- }
- void negate()
- {
- mpf_neg(m_data, m_data);
- }
- int compare(const gmp_real<digits10>& o)const
- {
- return mpf_cmp(m_data, o.m_data);
- }
- int compare(long i)const
- {
- return mpf_cmp_si(m_data, i);
- }
- int compare(unsigned long i)const
- {
- return mpf_cmp_ui(m_data, i);
- }
- template <class V>
- int compare(V v)const
- {
- gmp_real<digits10> d;
- d = v;
- return compare(d);
- }
- mpf_t& data() { return m_data; }
- const mpf_t& data()const { return m_data; }
-protected:
- mpf_t m_data;
- static unsigned& get_default_precision()
- {
- static unsigned val = 50;
- return val;
- }
-};
-
-} // namespace detail
-
-template <unsigned digits10>
-struct gmp_real : public detail::gmp_real_imp<digits10>
-{
- gmp_real()
- {
- mpf_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
- }
- gmp_real(const gmp_real& o) : detail::gmp_real_imp<digits10>(o) {}
-#ifndef BOOST_NO_RVALUE_REFERENCES
- gmp_real(gmp_real&& o) : detail::gmp_real_imp<digits10>(o) {}
-#endif
- gmp_real& operator=(const gmp_real& o)
- {
- *static_cast<detail::gmp_real_imp<digits10>*>(this) = static_cast<detail::gmp_real_imp<digits10> const&>(o);
- return *this;
- }
-#ifndef BOOST_NO_RVALUE_REFERENCES
- gmp_real& operator=(gmp_real&& o)
- {
- *static_cast<detail::gmp_real_imp<digits10>*>(this) = static_cast<detail::gmp_real_imp<digits10>&&>(o);
- return *this;
- }
-#endif
- template <class V>
- gmp_real& operator=(const V& v)
- {
- *static_cast<detail::gmp_real_imp<digits10>*>(this) = v;
- return *this;
- }
-};
-
-template <>
-struct gmp_real<0> : public detail::gmp_real_imp<0>
-{
- gmp_real()
- {
- mpf_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
- }
- gmp_real(unsigned digits10)
- {
- mpf_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
- }
- gmp_real(const gmp_real& o) : detail::gmp_real_imp<0>(o) {}
-#ifndef BOOST_NO_RVALUE_REFERENCES
- gmp_real(gmp_real&& o) : detail::gmp_real_imp<0>(o) {}
-#endif
- gmp_real(const gmp_real& o, unsigned digits10)
- {
- mpf_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
- *this = o;
- }
-
- gmp_real& operator=(const gmp_real& o)
- {
- *static_cast<detail::gmp_real_imp<0>*>(this) = static_cast<detail::gmp_real_imp<0> const&>(o);
- return *this;
- }
-#ifndef BOOST_NO_RVALUE_REFERENCES
- gmp_real& operator=(gmp_real&& o)
- {
- *static_cast<detail::gmp_real_imp<0>*>(this) = static_cast<detail::gmp_real_imp<0> &&>(o);
- return *this;
- }
-#endif
- template <class V>
- gmp_real& operator=(const V& v)
- {
- *static_cast<detail::gmp_real_imp<0>*>(this) = v;
- return *this;
- }
- static unsigned default_precision()
- {
- return get_default_precision();
- }
- static void default_precision(unsigned v)
- {
- get_default_precision() = v;
- }
- unsigned precision()const
- {
- return mpf_get_prec(this->m_data) * 301L / 1000 - 1;
- }
- void precision(unsigned digits10)
- {
- mpf_set_prec(this->m_data, (digits10 + 1) * 1000L / 301);
- }
-};
-
-template <unsigned digits10>
-inline void add(gmp_real<digits10>& result, const gmp_real<digits10>& o)
-{
- mpf_add(result.data(), result.data(), o.data());
-}
-template <unsigned digits10>
-inline void subtract(gmp_real<digits10>& result, const gmp_real<digits10>& o)
-{
- mpf_sub(result.data(), result.data(), o.data());
-}
-template <unsigned digits10>
-inline void multiply(gmp_real<digits10>& result, const gmp_real<digits10>& o)
-{
- mpf_mul(result.data(), result.data(), o.data());
-}
-template <unsigned digits10>
-inline void divide(gmp_real<digits10>& result, const gmp_real<digits10>& o)
-{
- mpf_div(result.data(), result.data(), o.data());
-}
-template <unsigned digits10>
-inline void add(gmp_real<digits10>& result, unsigned long i)
-{
- mpf_add_ui(result.data(), result.data(), i);
-}
-template <unsigned digits10>
-inline void subtract(gmp_real<digits10>& result, unsigned long i)
-{
- mpf_sub_ui(result.data(), result.data(), i);
-}
-template <unsigned digits10>
-inline void multiply(gmp_real<digits10>& result, unsigned long i)
-{
- mpf_mul_ui(result.data(), result.data(), i);
-}
-template <unsigned digits10>
-inline void divide(gmp_real<digits10>& result, unsigned long i)
-{
- mpf_div_ui(result.data(), result.data(), i);
-}
-template <unsigned digits10>
-inline void add(gmp_real<digits10>& result, long i)
-{
- if(i > 0)
- mpf_add_ui(result.data(), result.data(), i);
- else
- mpf_sub_ui(result.data(), result.data(), std::abs(i));
-}
-template <unsigned digits10>
-inline void subtract(gmp_real<digits10>& result, long i)
-{
- if(i > 0)
- mpf_sub_ui(result.data(), result.data(), i);
- else
- mpf_add_ui(result.data(), result.data(), std::abs(i));
-}
-template <unsigned digits10>
-inline void multiply(gmp_real<digits10>& result, long i)
-{
- mpf_mul_ui(result.data(), result.data(), std::abs(i));
- if(i < 0)
- mpf_neg(result.data(), result.data());
-}
-template <unsigned digits10>
-inline void divide(gmp_real<digits10>& result, long i)
-{
- mpf_div_ui(result.data(), result.data(), std::abs(i));
- if(i < 0)
- mpf_neg(result.data(), result.data());
-}
-//
-// Specialised 3 arg versions of the basic operators:
-//
-template <unsigned digits10>
-inline void add(gmp_real<digits10>& a, const gmp_real<digits10>& x, const gmp_real<digits10>& y)
-{
- mpf_add(a.data(), x.data(), y.data());
-}
-template <unsigned digits10>
-inline void add(gmp_real<digits10>& a, const gmp_real<digits10>& x, unsigned long y)
-{
- mpf_add_ui(a.data(), x.data(), y);
-}
-template <unsigned digits10>
-inline void add(gmp_real<digits10>& a, const gmp_real<digits10>& x, long y)
-{
- if(y < 0)
- mpf_sub_ui(a.data(), x.data(), -y);
- else
- mpf_add_ui(a.data(), x.data(), y);
-}
-template <unsigned digits10>
-inline void add(gmp_real<digits10>& a, unsigned long x, const gmp_real<digits10>& y)
-{
- mpf_add_ui(a.data(), y.data(), x);
-}
-template <unsigned digits10>
-inline void add(gmp_real<digits10>& a, long x, const gmp_real<digits10>& y)
-{
- if(x < 0)
- {
- mpf_ui_sub(a.data(), -x, y.data());
- mpf_neg(a.data(), a.data());
- }
- else
- mpf_add_ui(a.data(), y.data(), x);
-}
-template <unsigned digits10>
-inline void subtract(gmp_real<digits10>& a, const gmp_real<digits10>& x, const gmp_real<digits10>& y)
-{
- mpf_sub(a.data(), x.data(), y.data());
-}
-template <unsigned digits10>
-inline void subtract(gmp_real<digits10>& a, const gmp_real<digits10>& x, unsigned long y)
-{
- mpf_sub_ui(a.data(), x.data(), y);
-}
-template <unsigned digits10>
-inline void subtract(gmp_real<digits10>& a, const gmp_real<digits10>& x, long y)
-{
- if(y < 0)
- mpf_add_ui(a.data(), x.data(), -y);
- else
- mpf_sub_ui(a.data(), x.data(), y);
-}
-template <unsigned digits10>
-inline void subtract(gmp_real<digits10>& a, unsigned long x, const gmp_real<digits10>& y)
-{
- mpf_ui_sub(a.data(), x, y.data());
-}
-template <unsigned digits10>
-inline void subtract(gmp_real<digits10>& a, long x, const gmp_real<digits10>& y)
-{
- if(x < 0)
- {
- mpf_add_ui(a.data(), y.data(), -x);
- mpf_neg(a.data(), a.data());
- }
- else
- mpf_ui_sub(a.data(), x, y.data());
-}
-
-template <unsigned digits10>
-inline void multiply(gmp_real<digits10>& a, const gmp_real<digits10>& x, const gmp_real<digits10>& y)
-{
- mpf_mul(a.data(), x.data(), y.data());
-}
-template <unsigned digits10>
-inline void multiply(gmp_real<digits10>& a, const gmp_real<digits10>& x, unsigned long y)
-{
- mpf_mul_ui(a.data(), x.data(), y);
-}
-template <unsigned digits10>
-inline void multiply(gmp_real<digits10>& a, const gmp_real<digits10>& x, long y)
-{
- if(y < 0)
- {
- mpf_mul_ui(a.data(), x.data(), -y);
- a.negate();
- }
- else
- mpf_mul_ui(a.data(), x.data(), y);
-}
-template <unsigned digits10>
-inline void multiply(gmp_real<digits10>& a, unsigned long x, const gmp_real<digits10>& y)
-{
- mpf_mul_ui(a.data(), y.data(), x);
-}
-template <unsigned digits10>
-inline void multiply(gmp_real<digits10>& a, long x, const gmp_real<digits10>& y)
-{
- if(x < 0)
- {
- mpf_mul_ui(a.data(), y.data(), -x);
- mpf_neg(a.data(), a.data());
- }
- else
- mpf_mul_ui(a.data(), y.data(), x);
-}
-
-template <unsigned digits10>
-inline void divide(gmp_real<digits10>& a, const gmp_real<digits10>& x, const gmp_real<digits10>& y)
-{
- mpf_div(a.data(), x.data(), y.data());
-}
-template <unsigned digits10>
-inline void divide(gmp_real<digits10>& a, const gmp_real<digits10>& x, unsigned long y)
-{
- mpf_div_ui(a.data(), x.data(), y);
-}
-template <unsigned digits10>
-inline void divide(gmp_real<digits10>& a, const gmp_real<digits10>& x, long y)
-{
- if(y < 0)
- {
- mpf_div_ui(a.data(), x.data(), -y);
- a.negate();
- }
- else
- mpf_div_ui(a.data(), x.data(), y);
-}
-template <unsigned digits10>
-inline void divide(gmp_real<digits10>& a, unsigned long x, const gmp_real<digits10>& y)
-{
- mpf_ui_div(a.data(), x, y.data());
-}
-template <unsigned digits10>
-inline void divide(gmp_real<digits10>& a, long x, const gmp_real<digits10>& y)
-{
- if(x < 0)
- {
- mpf_ui_div(a.data(), -x, y.data());
- mpf_neg(a.data(), a.data());
- }
- else
- mpf_ui_div(a.data(), x, y.data());
-}
-
-template <unsigned digits10>
-inline bool is_zero(const gmp_real<digits10>& val)
-{
- return mpf_sgn(val.data()) == 0;
-}
-template <unsigned digits10>
-inline int get_sign(const gmp_real<digits10>& val)
-{
- return mpf_sgn(val.data());
-}
-
-template <unsigned digits10>
-inline void convert_to(unsigned long* result, const gmp_real<digits10>& val)
-{
- *result = mpf_get_ui(val.data());
-}
-template <unsigned digits10>
-inline void convert_to(long* result, const gmp_real<digits10>& val)
-{
- *result = mpf_get_si(val.data());
-}
-template <unsigned digits10>
-inline void convert_to(double* result, const gmp_real<digits10>& val)
-{
- *result = mpf_get_d(val.data());
-}
-
-//
-// Native non-member operations:
-//
-template <unsigned Digits10>
-inline void eval_sqrt(gmp_real<Digits10>& result, const gmp_real<Digits10>& val)
-{
- mpf_sqrt(result.data(), val.data());
-}
-
-template <unsigned Digits10>
-inline void eval_abs(gmp_real<Digits10>& result, const gmp_real<Digits10>& val)
-{
- mpf_abs(result.data(), val.data());
-}
-
-template <unsigned Digits10>
-inline void eval_fabs(gmp_real<Digits10>& result, const gmp_real<Digits10>& val)
-{
- mpf_abs(result.data(), val.data());
-}
-template <unsigned Digits10>
-inline void eval_ceil(gmp_real<Digits10>& result, const gmp_real<Digits10>& val)
-{
- mpf_ceil(result.data(), val.data());
-}
-template <unsigned Digits10>
-inline void eval_floor(gmp_real<Digits10>& result, const gmp_real<Digits10>& val)
-{
- mpf_floor(result.data(), val.data());
-}
-template <unsigned Digits10>
-inline void eval_trunc(gmp_real<Digits10>& result, const gmp_real<Digits10>& val)
-{
- mpf_trunc(result.data(), val.data());
-}
-template <unsigned Digits10>
-inline void eval_ldexp(gmp_real<Digits10>& result, const gmp_real<Digits10>& val, long e)
-{
- if(e > 0)
- mpf_mul_2exp(result.data(), val.data(), e);
- else if(e < 0)
- mpf_div_2exp(result.data(), val.data(), -e);
-}
-template <unsigned Digits10>
-inline void eval_frexp(gmp_real<Digits10>& result, const gmp_real<Digits10>& val, int* e)
-{
- long v;
- mpf_get_d_2exp(&v, val.data());
- *e = v;
- eval_ldexp(result, val, -v);
-}
-template <unsigned Digits10>
-inline void eval_frexp(gmp_real<Digits10>& result, const gmp_real<Digits10>& val, long* e)
-{
- mpf_get_d_2exp(e, val.data());
- eval_ldexp(result, val, -*e);
-}
-
-struct gmp_int
-{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
- typedef mpl::list<double, long double> real_types;
-
- gmp_int()
- {
- mpz_init(this->m_data);
- }
- gmp_int(const gmp_int& o)
- {
- mpz_init_set(m_data, o.m_data);
- }
- gmp_int& operator = (const gmp_int& o)
- {
- mpz_set(m_data, o.m_data);
- return *this;
- }
- gmp_int& operator = (boost::uintmax_t i)
- {
- boost::uintmax_t mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
- unsigned shift = 0;
- mpz_t t;
- mpz_init(m_data);
- mpz_init(t);
- while(i)
- {
- mpz_set_ui(t, static_cast<unsigned>(i & mask));
- if(shift)
- mpz_mul_2exp(t, t, shift);
- mpz_add(m_data, m_data, t);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
- }
- mpz_clear(t);
- return *this;
- }
- gmp_int& operator = (boost::intmax_t i)
- {
- bool neg = i < 0;
- *this = static_cast<boost::uintmax_t>(std::abs(i));
- if(neg)
- mpz_neg(m_data, m_data);
- return *this;
- }
- gmp_int& operator = (unsigned long i)
- {
- mpz_set_ui(m_data, i);
- return *this;
- }
- gmp_int& operator = (long i)
- {
- mpz_set_si(m_data, i);
- return *this;
- }
- gmp_int& operator = (double d)
- {
- mpz_set_d(m_data, d);
- return *this;
- }
- gmp_int& operator = (long double a)
- {
- using std::frexp;
- using std::ldexp;
- using std::floor;
-
- if (a == 0) {
- mpz_set_si(m_data, 0);
- return *this;
- }
-
- if (a == 1) {
- mpz_set_si(m_data, 1);
- return *this;
- }
-
- BOOST_ASSERT(!(boost::math::isinf)(a));
- BOOST_ASSERT(!(boost::math::isnan)(a));
-
- int e;
- long double f, term;
- mpz_init_set_ui(m_data, 0u);
-
- f = frexp(a, &e);
-
- static const int shift = std::numeric_limits<int>::digits - 1;
-
- while(f)
- {
- // extract int sized bits from f:
- f = ldexp(f, shift);
- term = floor(f);
- e -= shift;
- mpz_mul_2exp(m_data, m_data, shift);
- if(term > 0)
- mpz_add_ui(m_data, m_data, static_cast<unsigned>(term));
- else
- mpz_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
- f -= term;
- }
- if(e > 0)
- mpz_mul_2exp(m_data, m_data, e);
- else if(e < 0)
- mpz_div_2exp(m_data, m_data, -e);
- return *this;
- }
- gmp_int& operator = (const char* s)
- {
- mpz_set_str(m_data, s, 10);
- return *this;
- }
- void swap(gmp_int& o)
- {
- mpz_swap(m_data, o.m_data);
- }
- std::string str(unsigned /*digits*/, bool /*scientific*/)const
- {
- void *(*alloc_func_ptr) (size_t);
- void *(*realloc_func_ptr) (void *, size_t, size_t);
- void (*free_func_ptr) (void *, size_t);
- const char* ps = mpz_get_str (0, 10, m_data);
- std::string s = ps;
- mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
- (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
- return s;
- }
- ~gmp_int()
- {
- mpz_clear(m_data);
- }
- void negate()
- {
- mpz_neg(m_data, m_data);
- }
- int compare(const gmp_int& o)const
- {
- return mpz_cmp(m_data, o.m_data);
- }
- int compare(long i)const
- {
- return mpz_cmp_si(m_data, i);
- }
- int compare(unsigned long i)const
- {
- return mpz_cmp_ui(m_data, i);
- }
- template <class V>
- int compare(V v)const
- {
- gmp_int d;
- d = v;
- return compare(d);
- }
- mpz_t& data() { return m_data; }
- const mpz_t& data()const { return m_data; }
-protected:
- mpz_t m_data;
-};
-
-inline void add(gmp_int& t, const gmp_int& o)
-{
- mpz_add(t.data(), t.data(), o.data());
-}
-inline void subtract(gmp_int& t, const gmp_int& o)
-{
- mpz_sub(t.data(), t.data(), o.data());
-}
-inline void multiply(gmp_int& t, const gmp_int& o)
-{
- mpz_mul(t.data(), t.data(), o.data());
-}
-inline void divide(gmp_int& t, const gmp_int& o)
-{
- mpz_div(t.data(), t.data(), o.data());
-}
-inline void modulus(gmp_int& t, const gmp_int& o)
-{
- bool neg = mpz_sgn(t.data()) < 0;
- bool neg2 = mpz_sgn(o.data()) < 0;
- mpz_mod(t.data(), t.data(), o.data());
- if(neg)
- {
- if(!neg2)
- t.negate();
- mpz_add(t.data(), t.data(), o.data());
- if(!neg2)
- t.negate();
- }
-}
-inline void add(gmp_int& t, unsigned long i)
-{
- mpz_add_ui(t.data(), t.data(), i);
-}
-inline void subtract(gmp_int& t, unsigned long i)
-{
- mpz_sub_ui(t.data(), t.data(), i);
-}
-inline void multiply(gmp_int& t, unsigned long i)
-{
- mpz_mul_ui(t.data(), t.data(), i);
-}
-inline void modulus(gmp_int& t, unsigned long i)
-{
- bool neg = mpz_sgn(t.data()) < 0;
- mpz_mod_ui(t.data(), t.data(), i);
- if(neg)
- {
- t.negate();
- mpz_add_ui(t.data(), t.data(), i);
- t.negate();
- }
-}
-inline void divide(gmp_int& t, unsigned long i)
-{
- mpz_div_ui(t.data(), t.data(), i);
-}
-inline void add(gmp_int& t, long i)
-{
- if(i > 0)
- mpz_add_ui(t.data(), t.data(), i);
- else
- mpz_sub_ui(t.data(), t.data(), -i);
-}
-inline void subtract(gmp_int& t, long i)
-{
- if(i > 0)
- mpz_sub_ui(t.data(), t.data(), i);
- else
- mpz_add_ui(t.data(), t.data(), -i);
-}
-inline void multiply(gmp_int& t, long i)
-{
- mpz_mul_ui(t.data(), t.data(), std::abs(i));
- if(i < 0)
- mpz_neg(t.data(), t.data());
-}
-inline void modulus(gmp_int& t, long i)
-{
- bool neg = mpz_sgn(t.data()) < 0;
- bool neg2 = i < 0;
- mpz_mod_ui(t.data(), t.data(), std::abs(i));
- if(neg)
- {
- if(!neg2)
- {
- t.negate();
- mpz_add_ui(t.data(), t.data(), std::abs(i));
- t.negate();
- }
- else
- {
- mpz_sub_ui(t.data(), t.data(), std::abs(i));
- }
- }
-}
-inline void divide(gmp_int& t, long i)
-{
- mpz_div_ui(t.data(), t.data(), std::abs(i));
- if(i < 0)
- mpz_neg(t.data(), t.data());
-}
-template <class UI>
-inline void left_shift(gmp_int& t, UI i)
-{
- mpz_mul_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
-}
-template <class UI>
-inline void right_shift(gmp_int& t, UI i)
-{
- mpz_fdiv_q_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
-}
-template <class UI>
-inline void left_shift(gmp_int& t, const gmp_int& v, UI i)
-{
- mpz_mul_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
-}
-template <class UI>
-inline void right_shift(gmp_int& t, const gmp_int& v, UI i)
-{
- mpz_fdiv_q_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
-}
-
-inline void bitwise_and(gmp_int& result, const gmp_int& v)
-{
- mpz_and(result.data(), result.data(), v.data());
-}
-
-inline void bitwise_or(gmp_int& result, const gmp_int& v)
-{
- mpz_ior(result.data(), result.data(), v.data());
-}
-
-inline void bitwise_xor(gmp_int& result, const gmp_int& v)
-{
- mpz_xor(result.data(), result.data(), v.data());
-}
-
-inline void add(gmp_int& t, const gmp_int& p, const gmp_int& o)
-{
- mpz_add(t.data(), p.data(), o.data());
-}
-inline void subtract(gmp_int& t, const gmp_int& p, const gmp_int& o)
-{
- mpz_sub(t.data(), p.data(), o.data());
-}
-inline void multiply(gmp_int& t, const gmp_int& p, const gmp_int& o)
-{
- mpz_mul(t.data(), p.data(), o.data());
-}
-inline void divide(gmp_int& t, const gmp_int& p, const gmp_int& o)
-{
- mpz_div(t.data(), p.data(), o.data());
-}
-inline void modulus(gmp_int& t, const gmp_int& p, const gmp_int& o)
-{
- bool neg = mpz_sgn(p.data()) < 0;
- bool neg2 = mpz_sgn(o.data()) < 0;
- mpz_mod(t.data(), p.data(), o.data());
- if(neg)
- {
- if(!neg2)
- t.negate();
- mpz_add(t.data(), t.data(), o.data());
- if(!neg2)
- t.negate();
- }
-}
-inline void add(gmp_int& t, const gmp_int& p, unsigned long i)
-{
- mpz_add_ui(t.data(), p.data(), i);
-}
-inline void subtract(gmp_int& t, const gmp_int& p, unsigned long i)
-{
- mpz_sub_ui(t.data(), p.data(), i);
-}
-inline void multiply(gmp_int& t, const gmp_int& p, unsigned long i)
-{
- mpz_mul_ui(t.data(), p.data(), i);
-}
-inline void modulus(gmp_int& t, const gmp_int& p, unsigned long i)
-{
- bool neg = mpz_sgn(p.data()) < 0;
- mpz_mod_ui(t.data(), p.data(), i);
- if(neg)
- {
- t.negate();
- mpz_add_ui(t.data(), t.data(), i);
- t.negate();
- }
-}
-inline void divide(gmp_int& t, const gmp_int& p, unsigned long i)
-{
- mpz_div_ui(t.data(), p.data(), i);
-}
-inline void add(gmp_int& t, const gmp_int& p, long i)
-{
- if(i > 0)
- mpz_add_ui(t.data(), p.data(), i);
- else
- mpz_sub_ui(t.data(), p.data(), -i);
-}
-inline void subtract(gmp_int& t, const gmp_int& p, long i)
-{
- if(i > 0)
- mpz_sub_ui(t.data(), p.data(), i);
- else
- mpz_add_ui(t.data(), p.data(), -i);
-}
-inline void multiply(gmp_int& t, const gmp_int& p, long i)
-{
- mpz_mul_ui(t.data(), p.data(), std::abs(i));
- if(i < 0)
- mpz_neg(t.data(), t.data());
-}
-inline void modulus(gmp_int& t, const gmp_int& p, long i)
-{
- bool neg = mpz_sgn(p.data()) < 0;
- bool neg2 = i < 0;
- mpz_mod_ui(t.data(), p.data(), std::abs(i));
- if(neg)
- {
- if(!neg2)
- {
- t.negate();
- mpz_add_ui(t.data(), t.data(), std::abs(i));
- t.negate();
- }
- else
- {
- mpz_sub_ui(t.data(), t.data(), std::abs(i));
- }
- }
-}
-inline void divide(gmp_int& t, const gmp_int& p, long i)
-{
- mpz_div_ui(t.data(), p.data(), std::abs(i));
- if(i < 0)
- mpz_neg(t.data(), t.data());
-}
-
-inline void bitwise_and(gmp_int& result, const gmp_int& u, const gmp_int& v)
-{
- mpz_and(result.data(), u.data(), v.data());
-}
-
-inline void bitwise_or(gmp_int& result, const gmp_int& u, const gmp_int& v)
-{
- mpz_ior(result.data(), u.data(), v.data());
-}
-
-inline void bitwise_xor(gmp_int& result, const gmp_int& u, const gmp_int& v)
-{
- mpz_xor(result.data(), u.data(), v.data());
-}
-
-inline void complement(gmp_int& result, const gmp_int& u)
-{
- mpz_com(result.data(), u.data());
-}
-
-inline bool is_zero(const gmp_int& val)
-{
- return mpz_sgn(val.data()) == 0;
-}
-inline int get_sign(const gmp_int& val)
-{
- return mpz_sgn(val.data());
-}
-inline void convert_to(unsigned long* result, const gmp_int& val)
-{
- *result = mpz_get_ui(val.data());
-}
-inline void convert_to(long* result, const gmp_int& val)
-{
- *result = mpz_get_si(val.data());
-}
-inline void convert_to(double* result, const gmp_int& val)
-{
- *result = mpz_get_d(val.data());
-}
-
-inline void eval_abs(gmp_int& result, const gmp_int& val)
-{
- mpz_abs(result.data(), val.data());
-}
-
-struct gmp_rational;
-void add(gmp_rational& t, const gmp_rational& o);
-
-struct gmp_rational
-{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
- typedef mpl::list<double, long double> real_types;
-
- gmp_rational()
- {
- mpq_init(this->m_data);
- }
- gmp_rational(const gmp_rational& o)
- {
- mpq_init(m_data);
- mpq_set(m_data, o.m_data);
- }
- gmp_rational& operator = (const gmp_rational& o)
- {
- mpq_set(m_data, o.m_data);
- return *this;
- }
- gmp_rational& operator = (boost::uintmax_t i)
- {
- boost::uintmax_t mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
- unsigned shift = 0;
- mpq_t t;
- mpq_init(m_data);
- mpq_init(t);
- while(i)
- {
- mpq_set_ui(t, static_cast<unsigned>(i & mask), 1);
- if(shift)
- mpq_mul_2exp(t, t, shift);
- mpq_add(m_data, m_data, t);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
- }
- mpq_clear(t);
- return *this;
- }
- gmp_rational& operator = (boost::intmax_t i)
- {
- bool neg = i < 0;
- *this = static_cast<boost::uintmax_t>(std::abs(i));
- if(neg)
- mpq_neg(m_data, m_data);
- return *this;
- }
- gmp_rational& operator = (unsigned long i)
- {
- mpq_set_ui(m_data, i, 1);
- return *this;
- }
- gmp_rational& operator = (long i)
- {
- mpq_set_si(m_data, i, 1);
- return *this;
- }
- gmp_rational& operator = (double d)
- {
- mpq_set_d(m_data, d);
- return *this;
- }
- gmp_rational& operator = (long double a)
- {
- using std::frexp;
- using std::ldexp;
- using std::floor;
- using big_num_default_ops::add;
- using big_num_default_ops::subtract;
-
- if (a == 0) {
- mpq_set_si(m_data, 0, 1);
- return *this;
- }
-
- if (a == 1) {
- mpq_set_si(m_data, 1, 1);
- return *this;
- }
-
- BOOST_ASSERT(!(boost::math::isinf)(a));
- BOOST_ASSERT(!(boost::math::isnan)(a));
-
- int e;
- long double f, term;
- mpq_init(m_data);
- mpq_set_ui(m_data, 0u, 1);
- gmp_rational t;
-
- f = frexp(a, &e);
-
- static const int shift = std::numeric_limits<int>::digits - 1;
-
- while(f)
- {
- // extract int sized bits from f:
- f = ldexp(f, shift);
- term = floor(f);
- e -= shift;
- mpq_mul_2exp(m_data, m_data, shift);
- t = static_cast<long>(term);
- add(*this, t);
- f -= term;
- }
- if(e > 0)
- mpq_mul_2exp(m_data, m_data, e);
- else if(e < 0)
- mpq_div_2exp(m_data, m_data, -e);
- return *this;
- }
- gmp_rational& operator = (const char* s)
- {
- mpq_set_str(m_data, s, 10);
- return *this;
- }
- void swap(gmp_rational& o)
- {
- mpq_swap(m_data, o.m_data);
- }
- std::string str(unsigned /*digits*/, bool /*scientific*/)const
- {
- void *(*alloc_func_ptr) (size_t);
- void *(*realloc_func_ptr) (void *, size_t, size_t);
- void (*free_func_ptr) (void *, size_t);
- const char* ps = mpq_get_str (0, 10, m_data);
- std::string s = ps;
- mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
- (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
- return s;
- }
- ~gmp_rational()
- {
- mpq_clear(m_data);
- }
- void negate()
- {
- mpq_neg(m_data, m_data);
- }
- int compare(const gmp_rational& o)const
- {
- return mpq_cmp(m_data, o.m_data);
- }
- template <class V>
- int compare(V v)const
- {
- gmp_rational d;
- d = v;
- return compare(d);
- }
- int compare(unsigned long v)
- {
- return mpq_cmp_ui(m_data, v, 1);
- }
- int compare(long v)
- {
- return mpq_cmp_si(m_data, v, 1);
- }
- mpq_t& data() { return m_data; }
- const mpq_t& data()const { return m_data; }
-protected:
- mpq_t m_data;
-};
-
-inline void add(gmp_rational& t, const gmp_rational& o)
-{
- mpq_add(t.data(), t.data(), o.data());
-}
-inline void subtract(gmp_rational& t, const gmp_rational& o)
-{
- mpq_sub(t.data(), t.data(), o.data());
-}
-inline void multiply(gmp_rational& t, const gmp_rational& o)
-{
- mpq_mul(t.data(), t.data(), o.data());
-}
-inline void divide(gmp_rational& t, const gmp_rational& o)
-{
- mpq_div(t.data(), t.data(), o.data());
-}
-inline void add(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
-{
- mpq_add(t.data(), p.data(), o.data());
-}
-inline void subtract(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
-{
- mpq_sub(t.data(), p.data(), o.data());
-}
-inline void multiply(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
-{
- mpq_mul(t.data(), p.data(), o.data());
-}
-inline void divide(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
-{
- mpq_div(t.data(), p.data(), o.data());
-}
-
-inline bool is_zero(const gmp_rational& val)
-{
- return mpq_sgn(val.data()) == 0;
-}
-inline int get_sign(const gmp_rational& val)
-{
- return mpq_sgn(val.data());
-}
-inline void convert_to(double* result, const gmp_rational& val)
-{
- *result = mpq_get_d(val.data());
-}
-
-inline void convert_to(long* result, const gmp_rational& val)
-{
- double r;
- convert_to(&r, val);
- *result = r;
-}
-
-inline void convert_to(unsigned long* result, const gmp_rational& val)
-{
- double r;
- convert_to(&r, val);
- *result = r;
-}
-
-inline void eval_abs(gmp_rational& result, const gmp_rational& val)
-{
- mpq_abs(result.data(), val.data());
-}
-
-template<>
-struct is_extended_integer<gmp_int> : public mpl::true_ {};
-
-typedef big_number<gmp_real<50> > mpf_real_50;
-typedef big_number<gmp_real<100> > mpf_real_100;
-typedef big_number<gmp_real<500> > mpf_real_500;
-typedef big_number<gmp_real<1000> > mpf_real_1000;
-typedef big_number<gmp_real<0> > mpf_real;
-typedef big_number<gmp_int > mpz_int;
-typedef big_number<gmp_rational > mpq_rational;
-
-}} // namespaces
-
-namespace std{
-
-#ifdef BOOST_NO_NOEXCEPT
-# define noexcept
-#endif
-
-//
-// numeric_limits [partial] specializations for the types declared in this header:
-//
-template<unsigned Digits10>
-class numeric_limits<boost::math::big_number<boost::math::gmp_real<Digits10> > >
-{
- typedef boost::math::big_number<boost::math::gmp_real<Digits10> > number_type;
-public:
- BOOST_STATIC_CONSTEXPR bool is_specialized = true;
- BOOST_STATIC_CONSTEXPR number_type (min)() noexcept
- {
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 1;
- mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), LONG_MAX);
- }
- return value.second;
- }
- BOOST_STATIC_CONSTEXPR number_type (max)() noexcept
- {
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 1;
- mpf_mul_2exp(value.second.backend().data(), value.second.backend().data(), LONG_MAX - 1);
- }
- return value.second;
- }
- BOOST_STATIC_CONSTEXPR number_type lowest() noexcept
- {
- return -(max)();
- }
- BOOST_STATIC_CONSTEXPR int digits = static_cast<int>(((Digits10 + 1) * 1000L) / 301L);
- BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
- // Is this really correct???
- BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 1;
- BOOST_STATIC_CONSTEXPR bool is_signed = true;
- BOOST_STATIC_CONSTEXPR bool is_integer = false;
- BOOST_STATIC_CONSTEXPR bool is_exact = false;
- BOOST_STATIC_CONSTEXPR int radix = 2;
- BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept
- {
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 1;
- mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
- }
- return value.second;
- }
- // What value should this be????
- BOOST_STATIC_CONSTEXPR number_type round_error() noexcept
- {
- // returns epsilon/2
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 1;
- mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), digits);
- }
- return value.second;
- }
- BOOST_STATIC_CONSTEXPR long min_exponent = LONG_MIN;
- BOOST_STATIC_CONSTEXPR long min_exponent10 = (LONG_MIN / 1000) * 301L;
- BOOST_STATIC_CONSTEXPR long max_exponent = LONG_MAX;
- BOOST_STATIC_CONSTEXPR long max_exponent10 = (LONG_MAX / 1000) * 301L;
- BOOST_STATIC_CONSTEXPR bool has_infinity = false;
- BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
- BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
- BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
- BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
- BOOST_STATIC_CONSTEXPR number_type infinity() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
- BOOST_STATIC_CONSTEXPR bool is_bounded = true;
- BOOST_STATIC_CONSTEXPR bool is_modulo = false;
- BOOST_STATIC_CONSTEXPR bool traps = true;
- BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
- BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
-
-private:
- struct data_initializer
- {
- data_initializer()
- {
- std::numeric_limits<boost::math::big_number<boost::math::gmp_real<digits10> > >::epsilon();
- std::numeric_limits<boost::math::big_number<boost::math::gmp_real<digits10> > >::round_error();
- (std::numeric_limits<boost::math::big_number<boost::math::gmp_real<digits10> > >::min)();
- (std::numeric_limits<boost::math::big_number<boost::math::gmp_real<digits10> > >::max)();
- }
- void do_nothing()const{}
- };
- static const data_initializer initializer;
-};
-
-template<unsigned Digits10>
-const typename numeric_limits<boost::math::big_number<boost::math::gmp_real<Digits10> > >::data_initializer numeric_limits<boost::math::big_number<boost::math::gmp_real<Digits10> > >::initializer;
-
-template<>
-class numeric_limits<boost::math::big_number<boost::math::gmp_real<0> > >
-{
- typedef boost::math::big_number<boost::math::gmp_real<0> > number_type;
-public:
- BOOST_STATIC_CONSTEXPR bool is_specialized = false;
- BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type (max)() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR int digits = 0;
- BOOST_STATIC_CONSTEXPR int digits10 = 0;
- BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
- BOOST_STATIC_CONSTEXPR bool is_signed = false;
- BOOST_STATIC_CONSTEXPR bool is_integer = false;
- BOOST_STATIC_CONSTEXPR bool is_exact = false;
- BOOST_STATIC_CONSTEXPR int radix = 0;
- BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR int min_exponent = 0;
- BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR bool has_infinity = false;
- BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
- BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
- BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
- BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
- BOOST_STATIC_CONSTEXPR number_type infinity() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
- BOOST_STATIC_CONSTEXPR bool is_bounded = false;
- BOOST_STATIC_CONSTEXPR bool is_modulo = false;
- BOOST_STATIC_CONSTEXPR bool traps = false;
- BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
- BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
-};
-
-template<>
-class numeric_limits<boost::math::mpz_int >
-{
- typedef boost::math::mpz_int number_type;
-public:
- BOOST_STATIC_CONSTEXPR bool is_specialized = true;
- //
- // Largest and smallest numbers are bounded only by available memory, set
- // to zero:
- //
- BOOST_STATIC_CONSTEXPR number_type (min)() noexcept
- {
- return number_type();
- }
- BOOST_STATIC_CONSTEXPR number_type (max)() noexcept
- {
- return number_type();
- }
- BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { return (min)(); }
- // Digits are unbounded, use zero for now:
- BOOST_STATIC_CONSTEXPR int digits = 0;
- BOOST_STATIC_CONSTEXPR int digits10 = 0;
- BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
- BOOST_STATIC_CONSTEXPR bool is_signed = true;
- BOOST_STATIC_CONSTEXPR bool is_integer = true;
- BOOST_STATIC_CONSTEXPR bool is_exact = true;
- BOOST_STATIC_CONSTEXPR int radix = 2;
- BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR int min_exponent = 0;
- BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR bool has_infinity = false;
- BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
- BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
- BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
- BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
- BOOST_STATIC_CONSTEXPR number_type infinity() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(); }
- BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
- BOOST_STATIC_CONSTEXPR bool is_bounded = false;
- BOOST_STATIC_CONSTEXPR bool is_modulo = false;
- BOOST_STATIC_CONSTEXPR bool traps = false;
- BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
- BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
-};
-
-#ifdef BOOST_NO_NOEXCEPT
-# undef noexcept
-#endif
-
-} // namespace std
-
-#endif

Deleted: /sandbox/big_number/boost/math/big_number/mpfr.hpp
==============================================================================
--- /sandbox/big_number/boost/math/big_number/mpfr.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
+++ (empty file)
@@ -1,956 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright 2011 John Maddock. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_MATH_BN_MPFR_HPP
-#define BOOST_MATH_BN_MPFR_HPP
-
-#include <boost/math/big_number.hpp>
-#include <boost/math/special_functions/fpclassify.hpp>
-#include <boost/cstdint.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/math/bindings/detail/big_lanczos.hpp>
-#include <mpfr.h>
-#include <cmath>
-#include <algorithm>
-
-namespace boost{ namespace math{
-
-template <unsigned digits10>
-struct mpfr_real_backend;
-
-namespace detail{
-
-long get_default_precision() { return 50; }
-
-template <unsigned digits10>
-struct mpfr_real_imp
-{
- typedef mpl::list<long, long long> signed_types;
- typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
- typedef mpl::list<double, long double> real_types;
-
- mpfr_real_imp(){}
-
- mpfr_real_imp(const mpfr_real_imp& o)
- {
- mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
- mpfr_set(m_data, o.m_data, GMP_RNDN);
- }
-#ifndef BOOST_NO_RVALUE_REFERENCES
- mpfr_real_imp(mpfr_real_imp&& o)
- {
- m_data[0] = o.m_data[0];
- o.m_data[0]._mpfr_d = 0;
- }
-#endif
- mpfr_real_imp& operator = (const mpfr_real_imp& o)
- {
- mpfr_set(m_data, o.m_data, GMP_RNDN);
- return *this;
- }
-#ifndef BOOST_NO_RVALUE_REFERENCES
- mpfr_real_imp& operator = (mpfr_real_imp&& o)
- {
- mpfr_swap(m_data, o.m_data);
- return *this;
- }
-#endif
- mpfr_real_imp& operator = (boost::uintmax_t i)
- {
- boost::uintmax_t mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
- unsigned shift = 0;
- mpfr_t t;
- mpfr_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<boost::uintmax_t>::digits), static_cast<unsigned>(((digits10 + 1) * 1000L) / 301L)));
- mpfr_set_ui(m_data, 0, GMP_RNDN);
- while(i)
- {
- mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
- long e;
- const char* ps = mpfr_get_str (0, &e, 10, 0, t, GMP_RNDN);
- if(shift)
- mpfr_mul_2exp(t, t, shift, GMP_RNDN);
- ps = mpfr_get_str (0, &e, 10, 0, t, GMP_RNDN);
- mpfr_add(m_data, m_data, t, GMP_RNDN);
- ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN);
- shift += std::numeric_limits<unsigned>::digits;
- i >>= std::numeric_limits<unsigned>::digits;
- }
- mpfr_clear(t);
- return *this;
- }
- mpfr_real_imp& operator = (boost::intmax_t i)
- {
- bool neg = i < 0;
- *this = static_cast<boost::uintmax_t>(std::abs(i));
- if(neg)
- mpfr_neg(m_data, m_data, GMP_RNDN);
- return *this;
- }
- mpfr_real_imp& operator = (unsigned long i)
- {
- mpfr_set_ui(m_data, i, GMP_RNDN);
- return *this;
- }
- mpfr_real_imp& operator = (long i)
- {
- mpfr_set_si(m_data, i, GMP_RNDN);
- return *this;
- }
- mpfr_real_imp& operator = (double d)
- {
- mpfr_set_d(m_data, d, GMP_RNDN);
- return *this;
- }
- mpfr_real_imp& operator = (long double a)
- {
- using std::frexp;
- using std::ldexp;
- using std::floor;
-
- if (a == 0) {
- mpfr_set_si(m_data, 0, GMP_RNDN);
- return *this;
- }
-
- if (a == 1) {
- mpfr_set_si(m_data, 1, GMP_RNDN);
- return *this;
- }
-
- BOOST_ASSERT(!(boost::math::isinf)(a));
- BOOST_ASSERT(!(boost::math::isnan)(a));
-
- int e;
- long double f, term;
- mpfr_init_set_ui(m_data, 0u, GMP_RNDN);
-
- f = frexp(a, &e);
-
- static const int shift = std::numeric_limits<int>::digits - 1;
-
- while(f)
- {
- // extract int sized bits from f:
- f = ldexp(f, shift);
- term = floor(f);
- e -= shift;
- mpfr_mul_2exp(m_data, m_data, shift, GMP_RNDN);
- if(term > 0)
- mpfr_add_ui(m_data, m_data, static_cast<unsigned>(term), GMP_RNDN);
- else
- mpfr_sub_ui(m_data, m_data, static_cast<unsigned>(-term), GMP_RNDN);
- f -= term;
- }
- if(e > 0)
- mpfr_mul_2exp(m_data, m_data, e, GMP_RNDN);
- else if(e < 0)
- mpfr_div_2exp(m_data, m_data, -e, GMP_RNDN);
- return *this;
- }
- mpfr_real_imp& operator = (const char* s)
- {
- mpfr_set_str(m_data, s, 10, GMP_RNDN);
- return *this;
- }
- void swap(mpfr_real_imp& o)
- {
- mpfr_swap(m_data, o.m_data);
- }
- std::string str(unsigned digits, bool scientific)const
- {
- std::string result;
- mp_exp_t e;
- char* ps = mpfr_get_str (0, &e, 10, digits, m_data, GMP_RNDN);
- std::ptrdiff_t sl = std::strlen(ps);
- unsigned chars = sl;
- if(sl == 0)
- return "0";
- while(ps[chars-1] == '0')
- --chars;
- if(*ps == '-')
- --chars; // number of digits excluding sign.
- if(chars == 0)
- return "0";
- if(!scientific
- && (chars <= std::numeric_limits<boost::uintmax_t>::digits10 + 1)
- && (e >= (int)chars)
- && (chars <= std::numeric_limits<boost::uintmax_t>::digits10 + 1))
- {
- result.assign(ps, (*ps == '-' ? chars+1 : chars));
- result.append(e-chars, '0');
- }
- else
- {
- result = ps;
- if(ps[0] == '-')
- result.insert(2, 1, '.');
- else
- result.insert(1, 1, '.');
- --e;
- if(e)
- result += "e" + lexical_cast<std::string>(e);
- }
- mpfr_free_str(ps);
- return result;
- }
- ~mpfr_real_imp()
- {
- if(m_data[0]._mpfr_d)
- mpfr_clear(m_data);
- }
- void negate()
- {
- mpfr_neg(m_data, m_data, GMP_RNDN);
- }
- int compare(const mpfr_real_backend<digits10>& o)const
- {
- return mpfr_cmp(m_data, o.m_data);
- }
- int compare(long i)const
- {
- return mpfr_cmp_si(m_data, i);
- }
- int compare(unsigned long i)const
- {
- return mpfr_cmp_ui(m_data, i);
- }
- template <class V>
- int compare(V v)const
- {
- mpfr_real_backend<digits10> d;
- d = v;
- return compare(d);
- }
- mpfr_t& data() { return m_data; }
- const mpfr_t& data()const { return m_data; }
-protected:
- mpfr_t m_data;
- static unsigned& get_default_precision()
- {
- static unsigned val = 50;
- return val;
- }
-};
-
-} // namespace detail
-
-template <unsigned digits10>
-struct mpfr_real_backend : public detail::mpfr_real_imp<digits10>
-{
- mpfr_real_backend()
- {
- mpfr_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
- }
- mpfr_real_backend(const mpfr_real_backend& o) : detail::mpfr_real_imp<digits10>(o) {}
-#ifndef BOOST_NO_RVALUE_REFERENCES
- mpfr_real_backend(mpfr_real_backend&& o) : detail::mpfr_real_imp<digits10>(o) {}
-#endif
- mpfr_real_backend& operator=(const mpfr_real_backend& o)
- {
- *static_cast<detail::mpfr_real_imp<digits10>*>(this) = static_cast<detail::mpfr_real_imp<digits10> const&>(o);
- return *this;
- }
-#ifndef BOOST_NO_RVALUE_REFERENCES
- mpfr_real_backend& operator=(mpfr_real_backend&& o)
- {
- *static_cast<detail::mpfr_real_imp<digits10>*>(this) = static_cast<detail::mpfr_real_imp<digits10>&&>(o);
- return *this;
- }
-#endif
- template <class V>
- mpfr_real_backend& operator=(const V& v)
- {
- *static_cast<detail::mpfr_real_imp<digits10>*>(this) = v;
- return *this;
- }
-};
-
-template <>
-struct mpfr_real_backend<0> : public detail::mpfr_real_imp<0>
-{
- mpfr_real_backend()
- {
- mpfr_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
- }
- mpfr_real_backend(unsigned digits10)
- {
- mpfr_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
- }
- mpfr_real_backend(const mpfr_real_backend& o) : detail::mpfr_real_imp<0>(o) {}
-#ifndef BOOST_NO_RVALUE_REFERENCES
- mpfr_real_backend(mpfr_real_backend&& o) : detail::mpfr_real_imp<0>(o) {}
-#endif
- mpfr_real_backend(const mpfr_real_backend& o, unsigned digits10)
- {
- mpfr_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
- *this = o;
- }
-
- mpfr_real_backend& operator=(const mpfr_real_backend& o)
- {
- *static_cast<detail::mpfr_real_imp<0>*>(this) = static_cast<detail::mpfr_real_imp<0> const&>(o);
- return *this;
- }
-#ifndef BOOST_NO_RVALUE_REFERENCES
- mpfr_real_backend& operator=(mpfr_real_backend&& o)
- {
- *static_cast<detail::mpfr_real_imp<0>*>(this) = static_cast<detail::mpfr_real_imp<0> &&>(o);
- return *this;
- }
-#endif
- template <class V>
- mpfr_real_backend& operator=(const V& v)
- {
- *static_cast<detail::mpfr_real_imp<0>*>(this) = v;
- return *this;
- }
- static unsigned default_precision()
- {
- return get_default_precision();
- }
- static void default_precision(unsigned v)
- {
- get_default_precision() = v;
- }
- unsigned precision()const
- {
- return mpfr_get_prec(this->m_data) * 301L / 1000 - 1;
- }
- void precision(unsigned digits10)
- {
- mpfr_set_prec(this->m_data, (digits10 + 1) * 1000L / 301);
- }
-};
-
-template <unsigned digits10>
-inline void add(mpfr_real_backend<digits10>& result, const mpfr_real_backend<digits10>& o)
-{
- mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void subtract(mpfr_real_backend<digits10>& result, const mpfr_real_backend<digits10>& o)
-{
- mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void multiply(mpfr_real_backend<digits10>& result, const mpfr_real_backend<digits10>& o)
-{
- mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void divide(mpfr_real_backend<digits10>& result, const mpfr_real_backend<digits10>& o)
-{
- mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void add(mpfr_real_backend<digits10>& result, unsigned long i)
-{
- mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void subtract(mpfr_real_backend<digits10>& result, unsigned long i)
-{
- mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void multiply(mpfr_real_backend<digits10>& result, unsigned long i)
-{
- mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void divide(mpfr_real_backend<digits10>& result, unsigned long i)
-{
- mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void add(mpfr_real_backend<digits10>& result, long i)
-{
- if(i > 0)
- mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
- else
- mpfr_sub_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void subtract(mpfr_real_backend<digits10>& result, long i)
-{
- if(i > 0)
- mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
- else
- mpfr_add_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void multiply(mpfr_real_backend<digits10>& result, long i)
-{
- mpfr_mul_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
- if(i < 0)
- mpfr_neg(result.data(), result.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void divide(mpfr_real_backend<digits10>& result, long i)
-{
- mpfr_div_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
- if(i < 0)
- mpfr_neg(result.data(), result.data(), GMP_RNDN);
-}
-//
-// Specialised 3 arg versions of the basic operators:
-//
-template <unsigned digits10>
-inline void add(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, const mpfr_real_backend<digits10>& y)
-{
- mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void add(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, unsigned long y)
-{
- mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void add(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, long y)
-{
- if(y < 0)
- mpfr_sub_ui(a.data(), x.data(), -y, GMP_RNDN);
- else
- mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void add(mpfr_real_backend<digits10>& a, unsigned long x, const mpfr_real_backend<digits10>& y)
-{
- mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void add(mpfr_real_backend<digits10>& a, long x, const mpfr_real_backend<digits10>& y)
-{
- if(x < 0)
- {
- mpfr_ui_sub(a.data(), -x, y.data(), GMP_RNDN);
- mpfr_neg(a.data(), a.data(), GMP_RNDN);
- }
- else
- mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void subtract(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, const mpfr_real_backend<digits10>& y)
-{
- mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void subtract(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, unsigned long y)
-{
- mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void subtract(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, long y)
-{
- if(y < 0)
- mpfr_add_ui(a.data(), x.data(), -y, GMP_RNDN);
- else
- mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void subtract(mpfr_real_backend<digits10>& a, unsigned long x, const mpfr_real_backend<digits10>& y)
-{
- mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void subtract(mpfr_real_backend<digits10>& a, long x, const mpfr_real_backend<digits10>& y)
-{
- if(x < 0)
- {
- mpfr_add_ui(a.data(), y.data(), -x, GMP_RNDN);
- mpfr_neg(a.data(), a.data(), GMP_RNDN);
- }
- else
- mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
-}
-
-template <unsigned digits10>
-inline void multiply(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, const mpfr_real_backend<digits10>& y)
-{
- mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void multiply(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, unsigned long y)
-{
- mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void multiply(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, long y)
-{
- if(y < 0)
- {
- mpfr_mul_ui(a.data(), x.data(), -y, GMP_RNDN);
- a.negate();
- }
- else
- mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void multiply(mpfr_real_backend<digits10>& a, unsigned long x, const mpfr_real_backend<digits10>& y)
-{
- mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void multiply(mpfr_real_backend<digits10>& a, long x, const mpfr_real_backend<digits10>& y)
-{
- if(x < 0)
- {
- mpfr_mul_ui(a.data(), y.data(), -x, GMP_RNDN);
- mpfr_neg(a.data(), a.data(), GMP_RNDN);
- }
- else
- mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
-}
-
-template <unsigned digits10>
-inline void divide(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, const mpfr_real_backend<digits10>& y)
-{
- mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void divide(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, unsigned long y)
-{
- mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void divide(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, long y)
-{
- if(y < 0)
- {
- mpfr_div_ui(a.data(), x.data(), -y, GMP_RNDN);
- a.negate();
- }
- else
- mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
-}
-template <unsigned digits10>
-inline void divide(mpfr_real_backend<digits10>& a, unsigned long x, const mpfr_real_backend<digits10>& y)
-{
- mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void divide(mpfr_real_backend<digits10>& a, long x, const mpfr_real_backend<digits10>& y)
-{
- if(x < 0)
- {
- mpfr_ui_div(a.data(), -x, y.data(), GMP_RNDN);
- mpfr_neg(a.data(), a.data(), GMP_RNDN);
- }
- else
- mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
-}
-
-template <unsigned digits10>
-inline bool is_zero(const mpfr_real_backend<digits10>& val)
-{
- return 0 != mpfr_zero_p(val.data());
-}
-template <unsigned digits10>
-inline int get_sign(const mpfr_real_backend<digits10>& val)
-{
- return mpfr_sgn(val.data());
-}
-
-template <unsigned digits10>
-inline void convert_to(unsigned long* result, const mpfr_real_backend<digits10>& val)
-{
- *result = mpfr_get_ui(val.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void convert_to(long* result, const mpfr_real_backend<digits10>& val)
-{
- *result = mpfr_get_si(val.data(), GMP_RNDN);
-}
-#ifdef _MPFR_H_HAVE_INTMAX_T
-template <unsigned digits10>
-inline void convert_to(boost::uintmax_t* result, const mpfr_real_backend<digits10>& val)
-{
- *result = mpfr_get_uj(val.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void convert_to(boost::intmax_t* result, const mpfr_real_backend<digits10>& val)
-{
- *result = mpfr_get_sj(val.data(), GMP_RNDN);
-}
-#endif
-template <unsigned digits10>
-inline void convert_to(double* result, const mpfr_real_backend<digits10>& val)
-{
- *result = mpfr_get_d(val.data(), GMP_RNDN);
-}
-template <unsigned digits10>
-inline void convert_to(long double* result, const mpfr_real_backend<digits10>& val)
-{
- *result = mpfr_get_ld(val.data(), GMP_RNDN);
-}
-
-//
-// Native non-member operations:
-//
-template <unsigned Digits10>
-inline void eval_sqrt(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
-{
- mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_abs(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
-{
- mpfr_abs(result.data(), val.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_fabs(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
-{
- mpfr_abs(result.data(), val.data(), GMP_RNDN);
-}
-template <unsigned Digits10>
-inline void eval_ceil(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
-{
- mpfr_ceil(result.data(), val.data());
-}
-template <unsigned Digits10>
-inline void eval_floor(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
-{
- mpfr_floor(result.data(), val.data());
-}
-template <unsigned Digits10>
-inline void eval_trunc(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
-{
- mpfr_trunc(result.data(), val.data());
-}
-template <unsigned Digits10>
-inline void eval_ldexp(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val, long e)
-{
- if(e > 0)
- mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN);
- else if(e < 0)
- mpfr_div_2exp(result.data(), val.data(), -e, GMP_RNDN);
-}
-template <unsigned Digits10>
-inline void eval_frexp(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val, int* e)
-{
- long v;
- mpfr_get_d_2exp(&v, val.data(), GMP_RNDN);
- *e = v;
- eval_ldexp(result, val, -v);
-}
-template <unsigned Digits10>
-inline void eval_frexp(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val, long* e)
-{
- mpfr_get_d_2exp(e, val.data(), GMP_RNDN);
- return eval_ldexp(result, val, -*e);
-}
-
-template <unsigned Digits10>
-inline int eval_fpclassify(const mpfr_real_backend<Digits10>& val)
-{
- return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
-}
-
-template <unsigned Digits10>
-inline void eval_pow(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& b, const mpfr_real_backend<Digits10>& e)
-{
- mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10, class Integer>
-inline typename enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<sizeof(Integer) <= sizeof(long)> > >::type eval_pow(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& b, const Integer& e)
-{
- mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
-}
-
-template <unsigned Digits10, class Integer>
-inline typename enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<sizeof(Integer) <= sizeof(long)> > >::type eval_pow(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& b, const Integer& e)
-{
- mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_exp(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_exp(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_log(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_log(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_sin(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_sin(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_cos(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_cos(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_tan(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_tan(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_asin(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_asin(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_acos(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_acos(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_atan(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_atan(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_sinh(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_cosh(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
-}
-
-template <unsigned Digits10>
-inline void eval_tanh(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
-{
- mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
-}
-
-typedef big_number<mpfr_real_backend<50> > mpfr_real_50;
-typedef big_number<mpfr_real_backend<100> > mpfr_real_100;
-typedef big_number<mpfr_real_backend<500> > mpfr_real_500;
-typedef big_number<mpfr_real_backend<1000> > mpfr_real_1000;
-typedef big_number<mpfr_real_backend<0> > mpfr_real;
-
-namespace lanczos{
-
-template<unsigned Digits10, class Policy>
-struct lanczos<big_number<mpfr_real_backend<Digits10> >, Policy>
-{
- typedef typename mpl::if_c<
- Digits10 <= 36,
- lanczos22UDT,
- typename mpl::if_c<
- Digits10 <= 50,
- lanczos31UDT,
- typename mpl::if_c<
- Digits10 <= 110,
- lanczos61UDT,
- undefined_lanczos
- >::type
- >::type
- >::type type;
-};
-
-} // namespace lanczos
-
-
-}} // namespaces
-
-namespace std{
-
-#ifdef BOOST_NO_NOEXCEPT
-# define noexcept
-#endif
-
-//
-// numeric_limits [partial] specializations for the types declared in this header:
-//
-template<unsigned Digits10>
-class numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > >
-{
- typedef boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > number_type;
-public:
- BOOST_STATIC_CONSTEXPR bool is_specialized = true;
- BOOST_STATIC_CONSTEXPR number_type (min)() noexcept
- {
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 0.5;
- mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin(), GMP_RNDN);
- }
- return value.second;
- }
- BOOST_STATIC_CONSTEXPR number_type (max)() noexcept
- {
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 0.5;
- mpfr_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax(), GMP_RNDN);
- }
- return value.second;
- }
- BOOST_STATIC_CONSTEXPR number_type lowest() noexcept
- {
- return -(max)();
- }
- BOOST_STATIC_CONSTEXPR int digits = static_cast<int>(((Digits10 + 1) * 1000L) / 301L);
- BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
- // Is this really correct???
- BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 1;
- BOOST_STATIC_CONSTEXPR bool is_signed = true;
- BOOST_STATIC_CONSTEXPR bool is_integer = false;
- BOOST_STATIC_CONSTEXPR bool is_exact = false;
- BOOST_STATIC_CONSTEXPR int radix = 2;
- BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept
- {
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 1;
- mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
- }
- return value.second;
- }
- // What value should this be????
- BOOST_STATIC_CONSTEXPR number_type round_error() noexcept
- {
- // returns epsilon/2
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 1;
- mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), digits, GMP_RNDN);
- }
- return value.second;
- }
- BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
- BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
- BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
- BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
- BOOST_STATIC_CONSTEXPR bool has_infinity = true;
- BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
- BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
- BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
- BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
- BOOST_STATIC_CONSTEXPR number_type infinity() noexcept
- {
- // returns epsilon/2
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 1;
- mpfr_set_inf(value.second.backend().data(), 1);
- }
- return value.second;
- }
- BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept
- {
- // returns epsilon/2
- initializer.do_nothing();
- static std::pair<bool, number_type> value;
- if(!value.first)
- {
- value.first = true;
- value.second = 1;
- mpfr_set_nan(value.second.backend().data());
- }
- return value.second;
- }
- BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept
- {
- return number_type(0);
- }
- BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
- BOOST_STATIC_CONSTEXPR bool is_bounded = true;
- BOOST_STATIC_CONSTEXPR bool is_modulo = false;
- BOOST_STATIC_CONSTEXPR bool traps = true;
- BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
- BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
-
-private:
- struct data_initializer
- {
- data_initializer()
- {
- std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::epsilon();
- std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::round_error();
- (std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::min)();
- (std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::max)();
- std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::infinity();
- std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::quiet_NaN();
- }
- void do_nothing()const{}
- };
- static const data_initializer initializer;
-};
-
-template<unsigned Digits10>
-const typename numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > >::data_initializer numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > >::initializer;
-
-template<>
-class numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<0> > >
-{
- typedef boost::math::big_number<boost::math::mpfr_real_backend<0> > number_type;
-public:
- BOOST_STATIC_CONSTEXPR bool is_specialized = false;
- BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR number_type (max)() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR int digits = 0;
- BOOST_STATIC_CONSTEXPR int digits10 = 0;
- BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
- BOOST_STATIC_CONSTEXPR bool is_signed = false;
- BOOST_STATIC_CONSTEXPR bool is_integer = false;
- BOOST_STATIC_CONSTEXPR bool is_exact = false;
- BOOST_STATIC_CONSTEXPR int radix = 0;
- BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR int min_exponent = 0;
- BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent = 0;
- BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
- BOOST_STATIC_CONSTEXPR bool has_infinity = false;
- BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
- BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
- BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
- BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
- BOOST_STATIC_CONSTEXPR number_type infinity() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(0); }
- BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
- BOOST_STATIC_CONSTEXPR bool is_bounded = false;
- BOOST_STATIC_CONSTEXPR bool is_modulo = false;
- BOOST_STATIC_CONSTEXPR bool traps = false;
- BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
- BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
-};
-
-#ifdef noexcept
-#undef noexcept
-#endif
-
-} // namespace std
-#endif

Deleted: /sandbox/big_number/boost/math/big_number.hpp
==============================================================================
--- /sandbox/big_number/boost/math/big_number.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
+++ (empty file)
@@ -1,1551 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright 2011 John Maddock. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#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>
-#include <boost/mpl/or.hpp>
-#include <boost/mpl/find_if.hpp>
-#include <boost/assert.hpp>
-#include <boost/type_traits/remove_pointer.hpp>
-#include <boost/type_traits/is_signed.hpp>
-#include <boost/type_traits/is_unsigned.hpp>
-#include <boost/type_traits/is_floating_point.hpp>
-#include <boost/type_traits/is_integral.hpp>
-#include <boost/type_traits/make_unsigned.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/math/big_number/default_ops.hpp>
-
-namespace boost{ namespace math{
-
-template <class Backend>
-class big_number : public detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type >
-{
- 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);
- }
- 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);
- }
- 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 = 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);
- }
-
- template <class Exp>
- big_number& operator=(const detail::big_number_exp<Exp>& e)
- {
- do_assign(e, typename detail::assign_and_eval<Exp>::type());
- return *this;
- }
-
- big_number& operator=(const big_number& e)
- {
- m_backend = e.m_backend;
- return *this;
- }
-
- template <class V>
- typename enable_if<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> >, big_number<Backend>& >::type
- operator=(const V& v)
- {
- m_backend = canonical_value(v);
- return *this;
- }
-
- template <class Exp>
- big_number(const detail::big_number_exp<Exp>& e)
- {
- proto::value(*this) = this;
- BOOST_ASSERT(proto::value(*this) == this);
- do_assign(e, typename detail::assign_and_eval<Exp>::type());
- }
-
-#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& operator=(big_number&& r)
- {
- m_backend.swap(r.m_backend);
- return *this;
- }
-#endif
-
- template <class Exp>
- big_number& operator+=(const detail::big_number_exp<Exp>& 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());
- }
- else
- {
- do_add(e, typename proto::tag_of<Exp>::type());
- }
- return *this;
- }
-
- template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
- operator+=(const V& v)
- {
- using big_num_default_ops::add;
- add(m_backend, canonical_value(v));
- return *this;
- }
-
- template <class Exp>
- big_number& operator-=(const detail::big_number_exp<Exp>& e)
- {
- // Create a copy if e contains this, but not if we're just doing a
- if(contains_self(e))
- {
- self_type temp(e);
- do_subtract(temp, typename proto::tag_of<self_type>::type());
- }
- else
- {
- do_subtract(e, typename proto::tag_of<Exp>::type());
- }
- return *this;
- }
-
- template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
- operator-=(const V& v)
- {
- using big_num_default_ops::subtract;
- subtract(m_backend, canonical_value(v));
- return *this;
- }
-
- template <class Exp>
- big_number& operator*=(const detail::big_number_exp<Exp>& e)
- {
- // Create a temporary if the RHS references *this, but not
- // if we're just doing an x += x;
- if(contains_self(e) && !is_self(e))
- {
- self_type temp(e);
- do_multiplies(temp, typename proto::tag_of<self_type>::type());
- }
- else
- {
- do_multiplies(e, typename proto::tag_of<Exp>::type());
- }
- return *this;
- }
-
- template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
- operator*=(const V& v)
- {
- using big_num_default_ops::multiply;
- multiply(m_backend, canonical_value(v));
- 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");
- // 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());
- }
- else
- {
- do_modulus(e, typename proto::tag_of<Exp>::type());
- }
- return *this;
- }
- template <class V>
- 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");
- using big_num_default_ops::modulus;
- modulus(m_backend, canonical_value(v));
- return *this;
- }
-
- //
- // These operators are *not* proto-ized.
- // The issue is that the increment/decrement must happen
- // even if the result of the operator *is never used*.
- // Possibly we could modify our expression wrapper to
- // execute the increment/decrement on destruction, but
- // correct implemetation will be tricky, so defered for now...
- //
- big_number& operator++()
- {
- using big_num_default_ops::increment;
- increment(m_backend);
- return *this;
- }
-
- big_number& operator--()
- {
- using big_num_default_ops::decrement;
- decrement(m_backend);
- return *this;
- }
-
- big_number operator++(int)
- {
- using big_num_default_ops::increment;
- self_type temp(*this);
- increment(m_backend);
- return temp;
- }
-
- big_number operator--(int)
- {
- using big_num_default_ops::decrement;
- self_type temp(*this);
- decrement(m_backend);
- return temp;
- }
-
- 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");
- check_shift_range(val, mpl::bool_<(sizeof(V) > sizeof(std::size_t))>(), is_signed<V>());
- left_shift(m_backend, canonical_value(val));
- return *this;
- }
-
- 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");
- check_shift_range(val, mpl::bool_<(sizeof(V) > sizeof(std::size_t))>(), is_signed<V>());
- right_shift(m_backend, canonical_value(val));
- return *this;
- }
-
- template <class Exp>
- big_number& operator/=(const detail::big_number_exp<Exp>& e)
- {
- // Create a temporary if the RHS references *this:
- if(contains_self(e))
- {
- self_type temp(e);
- do_divide(temp, typename proto::tag_of<self_type>::type());
- }
- else
- {
- do_divide(e, typename proto::tag_of<Exp>::type());
- }
- return *this;
- }
-
- template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
- operator/=(const V& v)
- {
- using big_num_default_ops::divide;
- divide(m_backend, canonical_value(v));
- return *this;
- }
-
- template <class Exp>
- big_number& operator&=(const detail::big_number_exp<Exp>& e)
- {
- // Create a temporary if the RHS references *this, but not
- // if we're just doing an x &= x;
- if(contains_self(e) && !is_self(e))
- {
- self_type temp(e);
- do_bitwise_and(temp, typename proto::tag_of<self_type>::type());
- }
- else
- {
- do_bitwise_and(e, typename proto::tag_of<Exp>::type());
- }
- return *this;
- }
-
- template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
- operator&=(const V& v)
- {
- using big_num_default_ops::bitwise_and;
- bitwise_and(m_backend, canonical_value(v));
- return *this;
- }
-
- template <class Exp>
- big_number& operator|=(const detail::big_number_exp<Exp>& e)
- {
- // Create a temporary if the RHS references *this, but not
- // if we're just doing an x |= x;
- if(contains_self(e) && !is_self(e))
- {
- self_type temp(e);
- do_bitwise_or(temp, typename proto::tag_of<self_type>::type());
- }
- else
- {
- do_bitwise_or(e, typename proto::tag_of<Exp>::type());
- }
- return *this;
- }
-
- template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
- operator|=(const V& v)
- {
- using big_num_default_ops::bitwise_or;
- bitwise_or(m_backend, canonical_value(v));
- 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());
- }
- else
- {
- do_bitwise_xor(e, typename proto::tag_of<Exp>::type());
- }
- return *this;
- }
-
- template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
- operator^=(const V& v)
- {
- using big_num_default_ops::bitwise_xor;
- bitwise_xor(m_backend, canonical_value(v));
- return *this;
- }
-
- //
- // swap:
- //
- void swap(self_type& other)
- {
- m_backend.swap(other.backend());
- }
- //
- // Zero and sign:
- //
- bool is_zero()
- {
- using big_num_default_ops::is_zero;
- return is_zero(m_backend);
- }
- int sign()
- {
- using big_num_default_ops::get_sign;
- return get_sign(m_backend);
- }
- //
- // String conversion functions:
- //
- std::string str(unsigned digits = 0, bool scientific = true)const
- {
- return m_backend.str(digits, scientific);
- }
- template <class T>
- T convert_to()const
- {
- using big_num_default_ops::convert_to;
- T result;
- convert_to(&result, m_backend);
- return result;
- }
- //
- // Default precision:
- //
- static unsigned default_precision()
- {
- return Backend::default_precision();
- }
- static void default_precision(unsigned digits10)
- {
- Backend::default_precision(digits10);
- }
- unsigned precision()const
- {
- return m_backend.precision();
- }
- void precision(unsigned digits10)
- {
- m_backend.precision(digits10);
- }
- //
- // Comparison:
- //
- int compare(const big_number<Backend>& o)const
- {
- return m_backend.compare(o.m_backend);
- }
- template <class V>
- typename enable_if<is_arithmetic<V>, int>::type compare(const V& o)const
- {
- if(o == 0)
- return get_sign(m_backend);
- return m_backend.compare(canonical_value(o));
- }
- Backend& backend()
- {
- return m_backend;
- }
- const Backend& backend()const
- {
- return m_backend;
- }
-private:
- template <class V>
- void check_shift_range(V val, const mpl::true_&, const mpl::true_&)
- {
- if(val > (std::numeric_limits<std::size_t>::max)())
- BOOST_THROW_EXCEPTION(std::out_of_range("Can not shift by a value greater than std::numeric_limits<std::size_t>::max()."));
- if(val < 0)
- BOOST_THROW_EXCEPTION(std::out_of_range("Can not shift by a negative value."));
- }
- template <class V>
- void check_shift_range(V val, const mpl::false_&, const mpl::true_&)
- {
- if(val < 0)
- BOOST_THROW_EXCEPTION(std::out_of_range("Can not shift by a negative value."));
- }
- template <class V>
- void check_shift_range(V val, const mpl::true_&, const mpl::false_&)
- {
- if(val > (std::numeric_limits<std::size_t>::max)())
- BOOST_THROW_EXCEPTION(std::out_of_range("Can not shift by a value greater than std::numeric_limits<std::size_t>::max()."));
- }
- template <class V>
- void check_shift_range(V val, const mpl::false_&, const mpl::false_&){}
-
- template <class Exp>
- 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())));
- }
-
- 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())));
- 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())));
- }
-
- 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())));
- 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())));
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const detail::multiply_and_negate_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();
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const detail::divide_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())));
- }
-
- 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())));
- m_backend.negate();
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::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());
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::negate&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_assign(proto::left(e), typename detail::assign_and_eval<left_type>::type());
- m_backend.negate();
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::plus&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::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;
-
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
-
- if(bl && is_self(proto::left(e)))
- {
- // Ignore the left node, it's *this, just add the right:
- do_add(proto::right(e), typename proto::tag_of<right_type>::type());
- }
- else if(br && is_self(proto::right(e)))
- {
- // Ignore the right node, it's *this, just add the left:
- do_add(proto::left(e), typename proto::tag_of<left_type>::type());
- }
- else if(bl || br)
- {
- self_type temp(e);
- temp.m_backend.swap(this->m_backend);
- }
- 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());
- }
- 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());
- }
- }
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::minus&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::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;
-
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
-
- if(bl && is_self(proto::left(e)))
- {
- // Ignore the left node, it's *this, just subtract the right:
- do_subtract(proto::right(e), typename proto::tag_of<right_type>::type());
- }
- else if(br && is_self(proto::right(e)))
- {
- // 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());
- m_backend.negate();
- }
- else if(bl || br)
- {
- self_type temp(e);
- temp.m_backend.swap(this->m_backend);
- }
- 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());
- }
- 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());
- m_backend.negate();
- }
- }
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::multiplies&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::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;
-
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
-
- if(bl && is_self(proto::left(e)))
- {
- // Ignore the left node, it's *this, just add the right:
- do_multiplies(proto::right(e), typename proto::tag_of<right_type>::type());
- }
- else if(br && is_self(proto::right(e)))
- {
- // Ignore the right node, it's *this, just add the left:
- do_multiplies(proto::left(e), typename proto::tag_of<left_type>::type());
- }
- else if(bl || br)
- {
- self_type temp(e);
- temp.m_backend.swap(this->m_backend);
- }
- 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());
- }
- 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());
- }
- }
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::divides&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
-
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
-
- if(bl && is_self(proto::left(e)))
- {
- // Ignore the left node, it's *this, just add the right:
- do_divide(proto::right(e), typename proto::tag_of<right_type>::type());
- }
- else if(bl || br)
- {
- self_type temp(e);
- temp.m_backend.swap(this->m_backend);
- }
- 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());
- }
- }
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::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");
-
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::type right_type;
-
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
-
- if(bl && is_self(proto::left(e)))
- {
- // Ignore the left node, it's *this, just add the right:
- do_modulus(proto::right(e), typename proto::tag_of<right_type>::type());
- }
- else if(bl || br)
- {
- self_type temp(e);
- temp.m_backend.swap(this->m_backend);
- }
- 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());
- }
- }
- 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");
- 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())));
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::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");
-
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::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;
-
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
-
- if(bl && is_self(proto::left(e)))
- {
- // Ignore the left node, it's *this, just add the right:
- do_bitwise_and(proto::right(e), typename proto::tag_of<right_type>::type());
- }
- else if(br && is_self(proto::right(e)))
- {
- do_bitwise_and(proto::left(e), typename proto::tag_of<left_type>::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());
- }
- 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());
- }
- }
- 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");
- 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())));
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::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");
-
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::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;
-
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
-
- if(bl && is_self(proto::left(e)))
- {
- // Ignore the left node, it's *this, just add the right:
- do_bitwise_or(proto::right(e), typename proto::tag_of<right_type>::type());
- }
- else if(br && is_self(proto::right(e)))
- {
- do_bitwise_or(proto::left(e), typename proto::tag_of<left_type>::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());
- }
- 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());
- }
- }
- 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");
- 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())));
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::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");
-
- typedef typename proto::result_of::left<Exp>::type left_type;
- typedef typename proto::result_of::right<Exp>::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;
-
- bool bl = contains_self(proto::left(e));
- bool br = contains_self(proto::right(e));
-
- if(bl && is_self(proto::left(e)))
- {
- // Ignore the left node, it's *this, just add the right:
- do_bitwise_xor(proto::right(e), typename proto::tag_of<right_type>::type());
- }
- else if(br && is_self(proto::right(e)))
- {
- do_bitwise_xor(proto::left(e), typename proto::tag_of<left_type>::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());
- }
- 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());
- }
- }
- 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");
- 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())));
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::terminal&)
- {
- if(!is_self(e))
- {
- m_backend = canonical_value(proto::value(e));
- }
- }
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::function&)
- {
- typedef typename proto::arity_of<Exp>::type tag_type;
- do_assign_function(e, tag_type());
- }
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::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;
- 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;
- 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());
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::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;
- 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;
- 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());
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const proto::tag::complement&)
- {
- using big_num_default_ops::complement;
- self_type temp(proto::left(e));
- complement(m_backend, temp.backend());
- }
-
- template <class Exp>
- void do_assign(const Exp& e, const detail::complement_immediates&)
- {
- using big_num_default_ops::complement;
- complement(m_backend, canonical_value(proto::left(e)));
- }
-
- template <class Exp, class Val>
- void do_assign_right_shift(const Exp& e, const Val& val, const proto::tag::terminal&)
- {
- using big_num_default_ops::right_shift;
- right_shift(m_backend, canonical_value(proto::value(e)), val);
- }
-
- template <class Exp, class Val>
- void do_assign_left_shift(const Exp& e, const Val& val, const proto::tag::terminal&)
- {
- using big_num_default_ops::left_shift;
- left_shift(m_backend, canonical_value(proto::value(e)), val);
- }
-
- template <class Exp, class Val, class Tag>
- void do_assign_right_shift(const Exp& e, const Val& val, const Tag&)
- {
- using big_num_default_ops::right_shift;
- self_type temp(e);
- right_shift(m_backend, temp.backend(), val);
- }
-
- template <class Exp, class Val, class Tag>
- void do_assign_left_shift(const Exp& e, const Val& val, const Tag&)
- {
- using big_num_default_ops::left_shift;
- self_type temp(e);
- left_shift(m_backend, temp.backend(), val);
- }
-
- template <class Exp>
- void do_assign_function(const Exp& e, const mpl::long_<1>&)
- {
- proto::value(proto::left(e))(&m_backend);
- }
- template <class Exp>
- void do_assign_function(const Exp& e, const mpl::long_<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());
- }
- template <class F, class Exp>
- void do_assign_function_1(const F& f, const Exp& val, const proto::tag::terminal&)
- {
- f(m_backend, canonical_value(proto::value(val)));
- }
- template <class F, class Exp, class Tag>
- void do_assign_function_1(const F& f, const Exp& val, const Tag&)
- {
- big_number t(val);
- f(m_backend, t.backend());
- }
- template <class Exp>
- void do_assign_function(const Exp& e, const mpl::long_<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());
- }
- 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&)
- {
- f(m_backend, canonical_value(proto::value(val1)), canonical_value(proto::value(val2)));
- }
- template <class F, class Exp1, class Exp2, class Tag1>
- void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const Tag1&, const proto::tag::terminal&)
- {
- self_type temp1(val1);
- f(m_backend, temp1.backend(), canonical_value(proto::value(val2)));
- }
- template <class F, class Exp1, class Exp2, class Tag2>
- void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const proto::tag::terminal&, const Tag2&)
- {
- self_type temp2(val2);
- f(m_backend, canonical_value(proto::value(val1)), temp2.backend());
- }
- template <class F, class Exp1, class Exp2, class Tag1, class Tag2>
- void do_assign_function_2(const F& f, const Exp1& val1, const Exp2& val2, const Tag1&, const Tag2&)
- {
- self_type temp1(val1);
- self_type temp2(val2);
- f(m_backend, temp1.backend(), temp2.backend());
- }
-
- template <class Exp>
- void do_add(const Exp& e, const proto::tag::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());
- }
-
- template <class Exp>
- void do_add(const Exp& e, const proto::tag::negate&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_subtract(proto::left(e), typename proto::tag_of<left_type>::type());
- }
-
- template <class Exp>
- void do_add(const Exp& e, const proto::tag::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());
- }
-
- template <class Exp>
- void do_add(const Exp& e, const proto::tag::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());
- }
-
- template <class Exp, class unknown>
- void do_add(const Exp& e, const unknown&)
- {
- self_type temp(e);
- do_add(temp, proto::tag::terminal());
- }
-
- template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::terminal&)
- {
- using big_num_default_ops::subtract;
- subtract(m_backend, canonical_value(proto::value(e)));
- }
-
- template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::unary_plus&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_subtract(proto::left(e), typename proto::tag_of<left_type>::type());
- }
-
- template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::negate&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_add(proto::left(e), typename proto::tag_of<left_type>::type());
- }
-
- template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::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());
- }
-
- template <class Exp>
- void do_subtract(const Exp& e, const proto::tag::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());
- }
-
- template <class Exp, class unknown>
- void do_subtract(const Exp& e, const unknown&)
- {
- self_type temp(e);
- do_subtract(temp, proto::tag::terminal());
- }
-
- template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::terminal&)
- {
- using big_num_default_ops::multiply;
- multiply(m_backend, canonical_value(proto::value(e)));
- }
-
- template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::unary_plus&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_multiplies(proto::left(e), typename proto::tag_of<left_type>::type());
- }
-
- template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::negate&)
- {
- 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();
- }
-
- template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::multiplies&)
- {
- 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());
- }
-
- template <class Exp>
- void do_multiplies(const Exp& e, const proto::tag::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_divide(proto::right(e), typename proto::tag_of<right_type>::type());
- }
-
- template <class Exp, class unknown>
- void do_multiplies(const Exp& e, const unknown&)
- {
- using big_num_default_ops::multiply;
- self_type temp(e);
- multiply(m_backend, temp.m_backend);
- }
-
- template <class Exp>
- void do_divide(const Exp& e, const proto::tag::terminal&)
- {
- using big_num_default_ops::divide;
- divide(m_backend, canonical_value(proto::value(e)));
- }
-
- template <class Exp>
- void do_divide(const Exp& e, const proto::tag::unary_plus&)
- {
- typedef typename proto::result_of::left<Exp>::type left_type;
- do_divide(proto::left(e), typename proto::tag_of<left_type>::type());
- }
-
- template <class Exp>
- void do_divide(const Exp& e, const proto::tag::negate&)
- {
- 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();
- }
-
- template <class Exp>
- void do_divide(const Exp& e, const proto::tag::multiplies&)
- {
- 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());
- }
-
- template <class Exp>
- void do_divide(const Exp& e, const proto::tag::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_multiplies(proto::right(e), typename proto::tag_of<right_type>::type());
- }
-
- template <class Exp, class unknown>
- void do_divide(const Exp& e, const unknown&)
- {
- using big_num_default_ops::multiply;
- self_type temp(e);
- divide(m_backend, temp.m_backend);
- }
-
- template <class Exp>
- void do_modulus(const Exp& e, const proto::tag::terminal&)
- {
- BOOST_STATIC_ASSERT_MSG(is_extended_integer<Backend>::value, "The modulus operation is only valid for integer types");
- using big_num_default_ops::modulus;
- modulus(m_backend, canonical_value(proto::value(e)));
- }
-
- 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");
- using big_num_default_ops::modulus;
- self_type temp(e);
- modulus(m_backend, canonical_value(proto::value(temp)));
- }
-
- template <class Exp>
- void do_bitwise_and(const Exp& e, const proto::tag::terminal&)
- {
- using big_num_default_ops::bitwise_and;
- bitwise_and(m_backend, canonical_value(proto::value(e)));
- }
- template <class Exp>
- void do_bitwise_and(const Exp& e, const proto::tag::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());
- }
- template <class Exp, class unknown>
- void do_bitwise_and(const Exp& e, const unknown&)
- {
- using big_num_default_ops::bitwise_and;
- self_type temp(e);
- bitwise_and(m_backend, temp.m_backend);
- }
-
- template <class Exp>
- void do_bitwise_or(const Exp& e, const proto::tag::terminal&)
- {
- using big_num_default_ops::bitwise_or;
- bitwise_or(m_backend, canonical_value(proto::value(e)));
- }
- template <class Exp>
- void do_bitwise_or(const Exp& e, const proto::tag::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());
- }
- template <class Exp, class unknown>
- void do_bitwise_or(const Exp& e, const unknown&)
- {
- using big_num_default_ops::bitwise_or;
- self_type temp(e);
- bitwise_or(m_backend, temp.m_backend);
- }
-
- template <class Exp>
- void do_bitwise_xor(const Exp& e, const proto::tag::terminal&)
- {
- using big_num_default_ops::bitwise_xor;
- bitwise_xor(m_backend, canonical_value(proto::value(e)));
- }
- template <class Exp>
- void do_bitwise_xor(const Exp& e, const proto::tag::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());
- }
- template <class Exp, class unknown>
- void do_bitwise_xor(const Exp& e, const unknown&)
- {
- using big_num_default_ops::bitwise_xor;
- self_type temp(e);
- bitwise_xor(m_backend, temp.m_backend);
- }
-
- // Tests if the expression contains a reference to *this:
- template <class Exp>
- bool contains_self(const Exp& e)const
- {
- return contains_self(e, mpl::int_<proto::arity_of<Exp>::value>());
- }
- template <class Exp>
- bool contains_self(const Exp& e, mpl::int_<0> const&)const
- {
- return is_really_self(proto::value(e));
- }
- 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>());
- }
- 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>());
- }
- 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>());
- }
-
- // 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>());
- }
- template <class Exp>
- bool is_self(const Exp& e, mpl::int_<0> const&)const
- {
- return is_really_self(proto::value(e));
- }
- template <class Exp, int v>
- bool is_self(const Exp& e, mpl::int_<v> const&)const
- {
- return false;
- }
-
- 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());
- }
-
- 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; }
- 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;
-};
-
-namespace detail
-{
-
-template <class Backend>
-inline int big_number_compare(const big_number<Backend>& a, const big_number<Backend>& b)
-{
- 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)
-{
- 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)
-{
- return -b.compare(big_number<Backend>(a));
-}
-
-template <class Backend, class Val>
-inline int big_number_compare(const big_number<Backend>& a, const Val b)
-{
- return a.compare(b);
-}
-
-template <class Val, class Backend>
-inline int big_number_compare(const Val a, const big_number<Backend>& b)
-{
- 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)
-{
- typedef typename expression_type<Exp1>::type real1;
- typedef typename expression_type<Exp2>::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)
-{
- typedef typename expression_type<Exp>::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)
-{
- typedef typename expression_type<Exp>::type real;
- return -real(b).compare(a);
-}
-
-template <class Exp1, class Exp2>
-struct is_valid_comparison_imp
-{
- typedef typename mpl::or_<
- is_big_number<Exp1>,
- is_big_number_exp<Exp1>
- >::type is1;
- typedef typename mpl::or_<
- is_big_number<Exp2>,
- is_big_number_exp<Exp2>
- >::type is2;
- typedef typename mpl::or_<
- mpl::and_<
- is1,
- mpl::or_<
- is2,
- is_arithmetic<Exp2>
- >
- >,
- mpl::and_<
- is2,
- mpl::or_<
- is1,
- is_arithmetic<Exp1>
- >
- >
- >::type type;
-};
-
-template <class Exp1, class Exp2>
-struct is_valid_comparison : public boost::math::detail::is_valid_comparison_imp<Exp1, Exp2>::type {};
-
-}
-
-
-template <class Exp1, class Exp2>
-inline typename boost::enable_if<detail::is_valid_comparison<Exp1, Exp2>, bool>::type
- operator == (const Exp1& a, const Exp2& b)
-{
- return 0 == detail::big_number_compare(a, b);
-}
-
-template <class Exp1, class Exp2>
-inline typename boost::enable_if<detail::is_valid_comparison<Exp1, Exp2>, bool>::type
- operator != (const Exp1& a, const Exp2& b)
-{
- return 0 != detail::big_number_compare(a, b);
-}
-
-template <class Exp1, class Exp2>
-inline typename boost::enable_if<detail::is_valid_comparison<Exp1, Exp2>, bool>::type
- operator <= (const Exp1& a, const Exp2& b)
-{
- return 0 >= detail::big_number_compare(a, b);
-}
-
-template <class Exp1, class Exp2>
-inline typename boost::enable_if<detail::is_valid_comparison<Exp1, Exp2>, bool>::type
- operator < (const Exp1& a, const Exp2& b)
-{
- return 0 > detail::big_number_compare(a, b);
-}
-
-template <class Exp1, class Exp2>
-inline typename boost::enable_if<detail::is_valid_comparison<Exp1, Exp2>, bool>::type
- operator >= (const Exp1& a, const Exp2& b)
-{
- return 0 <= detail::big_number_compare(a, b);
-}
-
-template <class Exp1, class Exp2>
-inline typename boost::enable_if<detail::is_valid_comparison<Exp1, Exp2>, bool>::type
- operator > (const Exp1& a, const Exp2& b)
-{
- return 0 < detail::big_number_compare(a, b);
-}
-
-template <class Backend>
-inline std::ostream& operator << (std::ostream& os, const big_number<Backend>& r)
-{
- return os << r.str(static_cast<unsigned>(os.precision(), os.flags() & os.scientific));
-}
-
-namespace detail{
-
-template <class Exp>
-inline std::ostream& operator << (std::ostream& os, const big_number_exp<Exp>& r)
-{
- typedef typename expression_type<detail::big_number_exp<Exp> >::type value_type;
- value_type temp(r);
- return os << temp;
-}
-
-} // namespace detail
-
-template <class Backend>
-inline std::istream& operator >> (std::istream& is, big_number<Backend>& r)
-{
- std::string s;
- is >> s;
- r = s;
- return is;
-}
-
-}} // namespaces
-
-#endif

Modified: sandbox/big_number/boost/multiprecision/concepts/big_number_architypes.hpp
==============================================================================
--- /sandbox/big_number/boost/math/concepts/big_number_architypes.hpp (original)
+++ sandbox/big_number/boost/multiprecision/concepts/big_number_architypes.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
@@ -11,7 +11,7 @@
 #include <cmath>
 #include <boost/cstdint.hpp>
 #include <boost/lexical_cast.hpp>
-#include <boost/math/big_number.hpp>
+#include <boost/multiprecision/mp_number.hpp>
 #include <boost/math/special_functions/trunc.hpp>
 
 namespace boost{
@@ -253,7 +253,7 @@
    result = std::tanh(arg.m_value);
 }
 
-typedef boost::math::big_number<big_number_backend_real_architype> big_number_real_architype;
+typedef boost::math::mp_number<big_number_backend_real_architype> big_number_real_architype;
 
 }}} // namespaces
 

Copied: sandbox/big_number/boost/multiprecision/detail/big_number_base.hpp (from r74479, /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/multiprecision/detail/big_number_base.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
@@ -7,154 +7,19 @@
 #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{
 
 template <class Backend>
-class big_number;
+class mp_number;
 
 namespace detail{
 
 // Forward-declare an expression wrapper
-template<typename Expr>
-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<class tag, class Arg1 = void, class Arg2 = void, class Arg3 = void>
+struct mp_exp;
 
 template <int b>
 struct has_enough_bits
@@ -231,429 +96,872 @@
    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<mp_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<mp_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 mp_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::mp_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::mp_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<mp_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 mp_number<T1> type;
 };
 
-template <class Exp>
-struct assign_and_eval_imp<Exp, proto::tag::modulus>
+template <class T1, class T2>
+struct combine_expression<T1, mp_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;
-};
-
-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;
+ typedef mp_number<T2> 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 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 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>
+struct combine_expression<mp_number<T>, mp_number<T> >
+{
+ typedef mp_number<T> type;
 };
 
-template <class Exp>
-struct assign_and_eval
+template <class T>
+struct arg_type
 {
- typedef typename proto::tag_of<Exp>::type tag_type;
- typedef typename assign_and_eval_imp<Exp, tag_type>::type type;
+ typedef mp_exp<terminal, T> type;
 };
 
-template <class Exp, class tag>
-struct underlying_result_imp
+template <class Tag, class Arg1, class Arg2, class Arg3>
+struct arg_type<mp_exp<Tag, Arg1, Arg2, Arg3> >
 {
- 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 mp_exp<Tag, Arg1, Arg2, Arg3> type;
 };
 
-template <class Exp>
-struct underlying_result_imp<Exp, proto::tag::terminal>
+template <class T>
+struct unmentionable
 {
- typedef typename proto::result_of::value<Exp const &>::type type;
+ static void proc(){}
 };
 
-template <class Exp>
-struct underlying_result
+typedef void (*unmentionable_type)();
+
+template <class T>
+struct big_number_exp_storage
 {
- 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 T>
+struct big_number_exp_storage<T*>
 {
- typedef void type;
+ typedef T* type;
 };
 
-template <class Backend>
-struct combine_expression_type<boost::math::big_number<Backend>, boost::math::big_number<Backend> >
+template <class T>
+struct big_number_exp_storage<const T*>
 {
- typedef boost::math::big_number<Backend> type;
+ typedef const T* type;
 };
 
-template <class Backend, class Exp>
-struct combine_expression_type<boost::math::big_number<Backend>, Exp>
+template <class tag, class A1, class A2, class A3>
+struct big_number_exp_storage<mp_exp<tag, A1, A2, A3> >
 {
- typedef boost::math::big_number<Backend> type;
+ typedef mp_exp<tag, A1, A2, A3> type;
 };
 
-template <class Backend, class Exp>
-struct combine_expression_type<Exp, boost::math::big_number<Backend> >
+template<class tag, class Arg1>
+struct mp_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 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_{};
+ mp_exp(const Arg1& a) : arg(a) {}
 
+ left_type left()const { return arg; }
 
-template <class Exp, int arity>
-struct expression_type_imp;
+ const Arg1& left_ref()const{ return arg; }
 
-template <class Exp>
-struct expression_type_imp<Exp, 0>
-{
- typedef typename remove_pointer<typename proto::result_of::value<Exp>::type>::type type;
-};
+ static const unsigned depth = left_type::depth + 1;
 
-template <class Exp>
-struct expression_type_imp<Exp, 1>
-{
- 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;
-};
+ operator unmentionable_type()const
+ {
+ result_type r(*this);
+ return r ? &unmentionable<void>::proc : 0;
+ }
 
-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;
+private:
+ typename big_number_exp_storage<Arg1>::type arg;
 };
 
-template <class Exp>
-struct expression_type_imp<Exp, 3>
+template<class Arg1>
+struct mp_exp<terminal, Arg1, void, void>
 {
- 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;
-};
+ typedef mpl::int_<0> arity;
+ typedef Arg1 result_type;
+ typedef terminal tag_type;
 
-template <class Exp>
-struct expression_type
-{
- typedef typename expression_type_imp<Exp, proto::arity_of<Exp>::value>::type type;
-};
+ mp_exp(const Arg1& a) : arg(a) {}
 
-template <class Exp>
-struct backend_type
-{
- typedef typename expression_type<Exp>::type num_type;
- typedef typename backend_type<num_type>::type type;
+ const Arg1& value()const { return arg; }
+
+ static const unsigned depth = 0;
+
+ operator unmentionable_type()const
+ {
+ return arg ? &unmentionable<void>::proc : 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 mp_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;
+
+ mp_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<void>::proc : 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>
-struct big_number_exp
- : proto::extends<Expr, big_number_exp<Expr>, big_number_domain>
+template <class tag, class Arg1, class Arg2, class Arg3>
+struct mp_exp
 {
+ 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;
+
+ mp_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<void>::proc : 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 mp_number:
+//
+// Unary operators first:
+//
+template <class B>
+inline const mp_number<B>& operator + (const mp_number<B>& v) { return v; }
+template <class tag, class Arg1, class Arg2, class Arg3>
+inline const detail::mp_exp<tag, Arg1, Arg2, Arg3>& operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
+template <class B>
+inline detail::mp_exp<detail::negate, mp_number<B> > operator - (const mp_number<B>& v) { return v; }
+template <class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::negate, detail::mp_exp<tag, Arg1, Arg2, Arg3> > operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
+template <class B>
+inline detail::mp_exp<detail::complement_immediates, mp_number<B> > operator ~ (const mp_number<B>& v) { return v; }
+template <class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::bitwise_complement, detail::mp_exp<tag, Arg1, Arg2, Arg3> > operator ~ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
+//
+// Then addition:
+//
+template <class B>
+inline detail::mp_exp<detail::add_immediates, mp_number<B>, mp_number<B> >
+ operator + (const mp_number<B>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::add_immediates, mp_number<B>, mp_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::add_immediates, mp_number<B>, V > >::type
+ operator + (const mp_number<B>& a, const V& b)
+{
+ return detail::mp_exp<detail::add_immediates, mp_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::add_immediates, V, mp_number<B> > >::type
+ operator + (const V& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::add_immediates, V, mp_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::plus, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
+ operator + (const mp_number<B>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::plus, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >
+ operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_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::mp_exp<detail::plus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::mp_exp<detail::plus, detail::mp_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::mp_exp<detail::plus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator + (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::plus, V, detail::mp_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::mp_exp<detail::minus, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
+ operator + (const mp_number<B>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::minus, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
+}
+template <class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::minus, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
+ operator + (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::minus, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
+}
+template <class B>
+inline detail::mp_exp<detail::subtract_immediates, mp_number<B>, mp_number<B> >
+ operator + (const mp_number<B>& a, const detail::mp_exp<detail::negate, mp_number<B> >& b)
+{
+ return detail::mp_exp<detail::subtract_immediates, mp_number<B>, mp_number<B> >(a, b.left_ref());
+}
+template <class B>
+inline detail::mp_exp<detail::subtract_immediates, mp_number<B>, mp_number<B> >
+ operator + (const detail::mp_exp<detail::negate, mp_number<B> >& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::subtract_immediates, mp_number<B>, mp_number<B> >(b, a.left_ref());
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::subtract_immediates, mp_number<B>, V > >::type
+ operator + (const detail::mp_exp<detail::negate, mp_number<B> >& a, const V& b)
+{
+ return detail::mp_exp<detail::subtract_immediates, V, mp_number<B> >(b, a.left_ref());
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::subtract_immediates, V, mp_number<B> > >::type
+ operator + (const V& a, const detail::mp_exp<detail::negate, mp_number<B> >& b)
+{
+ return detail::mp_exp<detail::subtract_immediates, mp_number<B>, mp_number<B> >(a, b.left_ref());
+}
+//
+// Subtraction:
+//
+template <class B>
+inline detail::mp_exp<detail::subtract_immediates, mp_number<B>, mp_number<B> >
+ operator - (const mp_number<B>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::subtract_immediates, mp_number<B>, mp_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::subtract_immediates, mp_number<B>, V > >::type
+ operator - (const mp_number<B>& a, const V& b)
+{
+ return detail::mp_exp<detail::subtract_immediates, mp_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::subtract_immediates, V, mp_number<B> > >::type
+ operator - (const V& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::subtract_immediates, V, mp_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::minus, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
+ operator - (const mp_number<B>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::minus, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >
+ operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_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::mp_exp<detail::minus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::mp_exp<detail::minus, detail::mp_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::mp_exp<detail::minus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator - (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::minus, V, detail::mp_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::mp_exp<detail::plus, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
+ operator - (const mp_number<B>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::plus, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
+}
+template <class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::plus, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
+ operator - (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::plus, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
+}
+template <class B>
+inline detail::mp_exp<detail::add_immediates, mp_number<B>, mp_number<B> >
+ operator - (const mp_number<B>& a, const detail::mp_exp<detail::negate, mp_number<B> >& b)
+{
+ return detail::mp_exp<detail::add_immediates, mp_number<B>, mp_number<B> >(a, b.left_ref());
+}
+template <class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::add_immediates, mp_number<B>, mp_number<B> > >
+ operator - (const detail::mp_exp<detail::negate, mp_number<B> >& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::add_immediates, mp_number<B>, mp_number<B> >(b, a.left_ref());
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::negate, detail::mp_exp<detail::add_immediates, mp_number<B>, V > > >::type
+ operator - (const detail::mp_exp<detail::negate, mp_number<B> >& a, const V& b)
+{
+ return detail::mp_exp<detail::add_immediates, V, mp_number<B> >(b, a.left_ref());
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::add_immediates, V, mp_number<B> > >::type
+ operator - (const V& a, const detail::mp_exp<detail::negate, mp_number<B> >& b)
+{
+ return detail::mp_exp<detail::add_immediates, V, mp_number<B> >(a, b.left_ref());
+}
 //
+// Multiplication:
+//
+template <class B>
+inline detail::mp_exp<detail::multiply_immediates, mp_number<B>, mp_number<B> >
+ operator * (const mp_number<B>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::multiply_immediates, mp_number<B>, mp_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::multiply_immediates, mp_number<B>, V > >::type
+ operator * (const mp_number<B>& a, const V& b)
+{
+ return detail::mp_exp<detail::multiply_immediates, mp_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::multiply_immediates, V, mp_number<B> > >::type
+ operator * (const V& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::multiply_immediates, V, mp_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::multiplies, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
+ operator * (const mp_number<B>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::multiplies, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >
+ operator * (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator * (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_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::mp_exp<detail::multiplies, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator * (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::mp_exp<detail::multiplies, detail::mp_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::mp_exp<detail::multiplies, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator * (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::multiplies, V, detail::mp_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::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
+ operator * (const mp_number<B>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::multiplies, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > (a, b.left_ref());
+}
+template <class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::multiplies, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
+ operator * (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::multiplies, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
+}
+template <class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::multiply_immediates, mp_number<B>, mp_number<B> > >
+ operator * (const mp_number<B>& a, const detail::mp_exp<detail::negate, mp_number<B> >& b)
+{
+ return detail::mp_exp<detail::multiply_immediates, mp_number<B>, mp_number<B> >(a, b.left_ref());
+}
+template <class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::multiply_immediates, mp_number<B>, mp_number<B> > >
+ operator * (const detail::mp_exp<detail::negate, mp_number<B> >& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::multiply_immediates, mp_number<B>, mp_number<B> >(b, a.left_ref());
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::negate, detail::mp_exp<detail::multiply_immediates, mp_number<B>, V > > >::type
+ operator * (const detail::mp_exp<detail::negate, mp_number<B> >& a, const V& b)
+{
+ return detail::mp_exp<detail::multiply_immediates, mp_number<B>, V >(a.left_ref(), b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::negate, detail::mp_exp<detail::multiply_immediates, mp_number<B>, V > > >::type
+ operator * (const V& a, const detail::mp_exp<detail::negate, mp_number<B> >& b)
+{
+ return detail::mp_exp<detail::multiply_immediates, mp_number<B>, V >(b.left_ref(), a);
+}
+//
+// Division:
+//
+template <class B>
+inline detail::mp_exp<detail::divide_immediates, mp_number<B>, mp_number<B> >
+ operator / (const mp_number<B>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::divide_immediates, mp_number<B>, mp_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::divide_immediates, mp_number<B>, V > >::type
+ operator / (const mp_number<B>& a, const V& b)
+{
+ return detail::mp_exp<detail::divide_immediates, mp_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::divide_immediates, V, mp_number<B> > >::type
+ operator / (const V& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::divide_immediates, V, mp_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::divides, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
+ operator / (const mp_number<B>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::divides, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >
+ operator / (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator / (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_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::mp_exp<detail::divides, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator / (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::mp_exp<detail::divides, detail::mp_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::mp_exp<detail::divides, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator / (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::divides, V, detail::mp_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::mp_exp<detail::negate, detail::mp_exp<detail::divides, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
+ operator / (const mp_number<B>& a, const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::divides, mp_number<B>, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
+}
+template <class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::divides, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type, mp_number<B> > >
+ operator / (const detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::divides, typename detail::mp_exp<detail::negate, Arg1, Arg2, Arg3>::left_type, mp_number<B> >(a.left_ref(), b);
+}
+template <class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::divide_immediates, mp_number<B>, mp_number<B> > >
+ operator / (const mp_number<B>& a, const detail::mp_exp<detail::negate, mp_number<B> >& b)
+{
+ return detail::mp_exp<detail::divide_immediates, mp_number<B>, mp_number<B> >(a, b.left_ref());
+}
+template <class B>
+inline detail::mp_exp<detail::negate, detail::mp_exp<detail::divide_immediates, mp_number<B>, mp_number<B> > >
+ operator / (const detail::mp_exp<detail::negate, mp_number<B> >& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::divide_immediates, mp_number<B>, mp_number<B> >(a.left_ref(), b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::negate, detail::mp_exp<detail::divide_immediates, mp_number<B>, V > > >::type
+ operator / (const detail::mp_exp<detail::negate, mp_number<B> >& a, const V& b)
+{
+ return detail::mp_exp<detail::divide_immediates, mp_number<B>, V>(a.left_ref(), b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::negate, detail::mp_exp<detail::divide_immediates, V, mp_number<B> > > >::type
+ operator / (const V& a, const detail::mp_exp<detail::negate, mp_number<B> >& b)
+{
+ return detail::mp_exp<detail::divide_immediates, V, mp_number<B> >(a, b.left_ref());
+}
+//
+// Modulus:
+//
+template <class B>
+inline detail::mp_exp<detail::modulus_immediates, mp_number<B>, mp_number<B> >
+ operator % (const mp_number<B>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::modulus_immediates, mp_number<B>, mp_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::modulus_immediates, mp_number<B>, V > >::type
+ operator % (const mp_number<B>& a, const V& b)
+{
+ return detail::mp_exp<detail::modulus_immediates, mp_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::modulus_immediates, V, mp_number<B> > >::type
+ operator % (const V& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::modulus_immediates, V, mp_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::modulus, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
+ operator % (const mp_number<B>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::modulus, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >
+ operator % (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator % (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_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::mp_exp<detail::modulus, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator % (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::mp_exp<detail::modulus, detail::mp_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::mp_exp<detail::modulus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator % (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::modulus, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+//
+// Left shift:
+//
+template <class B, class I>
+inline typename enable_if<is_integral<I>, detail::mp_exp<detail::shift_left, mp_number<B>, I > >::type
+ operator << (const mp_number<B>& a, const I& b)
+{
+ return detail::mp_exp<detail::shift_left, mp_number<B>, I>(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class I>
+inline typename enable_if<is_integral<I>, detail::mp_exp<detail::shift_left, detail::mp_exp<tag, Arg1, Arg2, Arg3>, I> >::type
+ operator << (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const I& b)
+{
+ return detail::mp_exp<detail::shift_left, detail::mp_exp<tag, Arg1, Arg2, Arg3>, I>(a, b);
+}
+//
+// Right shift:
+//
+template <class B, class I>
+inline typename enable_if<is_integral<I>, detail::mp_exp<detail::shift_right, mp_number<B>, I > >::type
+ operator >> (const mp_number<B>& a, const I& b)
+{
+ return detail::mp_exp<detail::shift_right, mp_number<B>, I>(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class I>
+inline typename enable_if<is_integral<I>, detail::mp_exp<detail::shift_right, detail::mp_exp<tag, Arg1, Arg2, Arg3>, I> >::type
+ operator >> (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const I& b)
+{
+ return detail::mp_exp<detail::shift_right, detail::mp_exp<tag, Arg1, Arg2, Arg3>, I>(a, b);
+}
+//
+// Bitwise AND:
+//
+template <class B>
+inline detail::mp_exp<detail::bitwise_and_immediates, mp_number<B>, mp_number<B> >
+ operator & (const mp_number<B>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::bitwise_and_immediates, mp_number<B>, mp_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_and_immediates, mp_number<B>, V > >::type
+ operator & (const mp_number<B>& a, const V& b)
+{
+ return detail::mp_exp<detail::bitwise_and_immediates, mp_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_and_immediates, V, mp_number<B> > >::type
+ operator & (const V& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::bitwise_and_immediates, V, mp_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::bitwise_and, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
+ operator & (const mp_number<B>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::bitwise_and, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >
+ operator & (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator & (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_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::mp_exp<detail::bitwise_and, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator & (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::mp_exp<detail::bitwise_and, detail::mp_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::mp_exp<detail::bitwise_and, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator & (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::bitwise_and, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+//
+// Bitwise OR:
+//
+template <class B>
+inline detail::mp_exp<detail::bitwise_or_immediates, mp_number<B>, mp_number<B> >
+ operator| (const mp_number<B>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::bitwise_or_immediates, mp_number<B>, mp_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_or_immediates, mp_number<B>, V > >::type
+ operator| (const mp_number<B>& a, const V& b)
+{
+ return detail::mp_exp<detail::bitwise_or_immediates, mp_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_or_immediates, V, mp_number<B> > >::type
+ operator| (const V& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::bitwise_or_immediates, V, mp_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::bitwise_or, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
+ operator| (const mp_number<B>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::bitwise_or, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >
+ operator| (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator| (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_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::mp_exp<detail::bitwise_or, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator| (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::mp_exp<detail::bitwise_or, detail::mp_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::mp_exp<detail::bitwise_or, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator| (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::bitwise_or, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+//
+// Bitwise XOR:
+//
+template <class B>
+inline detail::mp_exp<detail::bitwise_xor_immediates, mp_number<B>, mp_number<B> >
+ operator^ (const mp_number<B>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::bitwise_xor_immediates, mp_number<B>, mp_number<B> >(a, b);
+}
+template <class B, class V>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_xor_immediates, mp_number<B>, V > >::type
+ operator^ (const mp_number<B>& a, const V& b)
+{
+ return detail::mp_exp<detail::bitwise_xor_immediates, mp_number<B>, V >(a, b);
+}
+template <class V, class B>
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::bitwise_xor_immediates, V, mp_number<B> > >::type
+ operator^ (const V& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::bitwise_xor_immediates, V, mp_number<B> >(a, b);
+}
+template <class B, class tag, class Arg1, class Arg2, class Arg3>
+inline detail::mp_exp<detail::bitwise_xor, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >
+ operator^ (const mp_number<B>& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::bitwise_xor, mp_number<B>, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class B>
+inline detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >
+ operator^ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const mp_number<B>& b)
+{
+ return detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, mp_number<B> >(a, b);
+}
+template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
+inline detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b> >
+ operator^ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const detail::mp_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
+{
+ return detail::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, detail::mp_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::mp_exp<detail::bitwise_xor, detail::mp_exp<tag, Arg1, Arg2, Arg3>, V > >::type
+ operator^ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
+{
+ return detail::mp_exp<detail::bitwise_xor, detail::mp_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::mp_exp<detail::bitwise_xor, V, detail::mp_exp<tag, Arg1, Arg2, Arg3> > >::type
+ operator^ (const V& a, const detail::mp_exp<tag, Arg1, Arg2, Arg3>& b)
+{
+ return detail::mp_exp<detail::bitwise_xor, V, detail::mp_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<mp_number<Backend> > : public number_category<Backend>{};
+template <class tag, class A1, class A2, class A3>
+struct number_category<detail::mp_exp<tag, A1, A2, A3> > : public number_category<typename detail::mp_exp<tag, A1, A2, A3>::result_type>{};
 
 }} // namespaces
 
@@ -662,10 +970,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::mp_exp<tag, A1, A2, A3> >
 {
- typedef typename boost::math::detail::expression_type<Exp>::type type;
+ typedef typename boost::math::detail::mp_exp<tag, A1, A2, A3>::result_type type;
 };
 
 }}}

Copied: sandbox/big_number/boost/multiprecision/detail/default_ops.hpp (from r74479, /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/multiprecision/detail/default_ops.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
@@ -7,9 +7,11 @@
 #define BOOST_MATH_BIG_NUM_DEF_OPS
 
 #include <boost/math/policies/error_handling.hpp>
-#include <boost/math/big_number/big_number_base.hpp>
+#include <boost/multiprecision/detail/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{
 
@@ -414,215 +416,207 @@
 //
 // These functions are implemented in separate files, but expanded inline here:
 //
-#include <boost/math/big_number/functions/pow.hpp>
+#include <boost/multiprecision/detail/functions/pow.hpp>
 
 }
 
-
 template <class Backend>
-class big_number;
-
-namespace detail{
-
-template<typename Expr>
-struct big_number_exp;
-
-}
+class mp_number;
 
 //
 // Default versions of floating point classification routines:
 //
 template <class Backend>
-inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const mp_number<Backend>& arg)
 {
    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::mp_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type value_type;
    return fpclassify(value_type(arg));
 }
 template <class Backend>
-inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const mp_number<Backend>& arg)
 {
    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::mp_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type value_type;
    return isfinite(value_type(arg));
 }
 template <class Backend>
-inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const mp_number<Backend>& arg)
 {
    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::mp_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type value_type;
    return isnan(value_type(arg));
 }
 template <class Backend>
-inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const mp_number<Backend>& arg)
 {
    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::mp_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3>::result_type value_type;
    return isinf(value_type(arg));
 }
 template <class Backend>
-inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const mp_number<Backend>& arg)
 {
    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::mp_exp<tag, A1, A2, A3>& arg)
 {
- typedef typename detail::expression_type<Exp>::type value_type;
+ typedef typename detail::mp_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::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
 {
- typedef typename detail::expression_type<Exp>::type number_type;
+ typedef typename detail::mp_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>();
    return r.template convert_to<int>();
 }
 template <class Backend, class Policy>
-inline int itrunc(const big_number<Backend>& v, const Policy& pol)
+inline int itrunc(const mp_number<Backend>& v, const Policy& pol)
 {
- big_number<Backend> r = trunc(v, pol);
+ mp_number<Backend> 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>();
    return r.template convert_to<int>();
 }
-template <class T, class Policy>
-inline long ltrunc(const detail::big_number_exp<T>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class Policy>
+inline long ltrunc(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
 {
- typedef typename detail::expression_type<T>::type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3>::result_result number_type;
    number_type r = trunc(v, pol);
    if(fabs(r) > (std::numeric_limits<long>::max)())
       return policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
    return r.template convert_to<long>();
 }
 template <class T, class Policy>
-inline long ltrunc(const big_number<T>& v, const Policy& pol)
+inline long ltrunc(const mp_number<T>& v, const Policy& pol)
 {
- big_number<T> r = trunc(v, pol);
+ mp_number<T> r = trunc(v, pol);
    if(fabs(r) > (std::numeric_limits<long>::max)())
       return policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
    return r.template convert_to<long>();
 }
 #ifndef BOOST_NO_LONG_LONG
-template <class T, class Policy>
-inline long long lltrunc(const detail::big_number_exp<T>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class Policy>
+inline long long lltrunc(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
 {
- typedef typename detail::expression_type<T>::type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3>::result_result number_type;
    number_type r = trunc(v, pol);
    if(fabs(r) > (std::numeric_limits<long long>::max)())
       return policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
    return r.template convert_to<long long>();
 }
 template <class T, class Policy>
-inline long long lltrunc(const big_number<T>& v, const Policy& pol)
+inline long long lltrunc(const mp_number<T>& v, const Policy& pol)
 {
- big_number<T> r = trunc(v, pol);
+ mp_number<T> r = trunc(v, pol);
    if(fabs(r) > (std::numeric_limits<long long>::max)())
       return policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
    return r.template convert_to<long long>();
 }
 #endif
-template <class T, class Policy>
-inline int iround(const detail::big_number_exp<T>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class Policy>
+inline int iround(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
 {
- typedef typename detail::expression_type<T>::type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3>::result_result number_type;
    number_type r = round(v, pol);
    if(fabs(r) > (std::numeric_limits<int>::max)())
       return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
    return r.template convert_to<int>();
 }
 template <class T, class Policy>
-inline int iround(const big_number<T>& v, const Policy& pol)
+inline int iround(const mp_number<T>& v, const Policy& pol)
 {
- big_number<T> r = round(v, pol);
+ mp_number<T> r = round(v, pol);
    if(fabs(r) > (std::numeric_limits<int>::max)())
       return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
    return r.template convert_to<int>();
 }
-template <class T, class Policy>
-inline long lround(const detail::big_number_exp<T>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class Policy>
+inline long lround(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
 {
- typedef typename detail::expression_type<T>::type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3>::result_result number_type;
    number_type r = round(v, pol);
    if(fabs(r) > (std::numeric_limits<long>::max)())
       return policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
    return r.template convert_to<long>();
 }
 template <class T, class Policy>
-inline long lround(const big_number<T>& v, const Policy& pol)
+inline long lround(const mp_number<T>& v, const Policy& pol)
 {
- big_number<T> r = round(v, pol);
+ mp_number<T> r = round(v, pol);
    if(fabs(r) > (std::numeric_limits<long>::max)())
       return policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
    return r.template convert_to<long>();
 }
 #ifndef BOOST_NO_LONG_LONG
-template <class T, class Policy>
-inline long long llround(const detail::big_number_exp<T>& v, const Policy& pol)
+template <class tag, class A1, class A2, class A3, class Policy>
+inline long long llround(const detail::mp_exp<tag, A1, A2, A3>& v, const Policy& pol)
 {
- typedef typename detail::expression_type<T>::type number_type;
+ typedef typename detail::mp_exp<tag, A1, A2, A3>::result_result number_type;
    number_type r = round(v, pol);
    if(fabs(r) > (std::numeric_limits<long long>::max)())
       return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
    return r.template convert_to<long long>();
 }
 template <class T, class Policy>
-inline long long llround(const big_number<T>& v, const Policy& pol)
+inline long long llround(const mp_number<T>& v, const Policy& pol)
 {
- big_number<T> r = round(v, pol);
+ mp_number<T> r = round(v, pol);
    if(fabs(r) > (std::numeric_limits<long long>::max)())
       return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
    return r.template convert_to<long long>();
 }
 #endif
 //
-// Overload of Boost.Math functions that find the wrong overload when used with big_number:
+// Overload of Boost.Math functions that find the wrong overload when used with mp_number:
 //
 namespace detail{
    template <class T> T sinc_pi_imp(T);
    template <class T> T sinhc_pi_imp(T);
 }
 template <class Backend>
-inline big_number<Backend> sinc_pi(const big_number<Backend>& x)
+inline mp_number<Backend> sinc_pi(const mp_number<Backend>& x)
 {
    return detail::sinc_pi_imp(x);
 }
 
 template <class Backend, class Policy>
-inline big_number<Backend> sinc_pi(const big_number<Backend>& x, const Policy&)
+inline mp_number<Backend> sinc_pi(const mp_number<Backend>& x, const Policy&)
 {
    return detail::sinc_pi_imp(x);
 }
 
 template <class Backend>
-inline big_number<Backend> sinhc_pi(const big_number<Backend>& x)
+inline mp_number<Backend> sinhc_pi(const mp_number<Backend>& x)
 {
    return detail::sinhc_pi_imp(x);
 }
 
 template <class Backend, class Policy>
-inline big_number<Backend> sinhc_pi(const big_number<Backend>& x, const Policy&)
+inline mp_number<Backend> sinhc_pi(const mp_number<Backend>& x, const Policy&)
 {
    return boost::math::sinhc_pi(x);
 }
@@ -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::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+> \
+func(const detail::mp_exp<tag, A1, A2, A3>& arg)\
+{\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+> (\
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>() \
       , arg \
     );\
 }\
 template <class Backend> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
+detail::mp_exp<\
+ detail::function\
   , detail::BOOST_JOIN(func, _funct)<Backend> \
- , detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type> \
->::type const \
-func(const big_number<Backend>& arg)\
+ , mp_number<Backend> \
+> \
+func(const mp_number<Backend>& arg)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , mp_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::mp_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 \
-func(const big_number<Backend>& arg, const big_number<Backend>& a)\
+ , mp_number<Backend> \
+ , mp_number<Backend> \
+> \
+func(const mp_number<Backend>& arg, const mp_number<Backend>& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , mp_number<Backend> \
+ , mp_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::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , mp_number<Backend> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+> \
+func(const mp_number<Backend>& arg, const detail::mp_exp<tag, A1, A2, A3>& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , mp_number<Backend> \
+ , detail::mp_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::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+ , mp_number<Backend> \
+> \
+func(const detail::mp_exp<tag, A1, A2, A3>& arg, const mp_number<Backend>& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+ , mp_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::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::mp_exp<tagb, A1b, A2b, A3b> \
+> \
+func(const detail::mp_exp<tag, A1, A2, A3>& arg, const detail::mp_exp<tagb, A1b, A2b, A3b>& a)\
+{\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+ , detail::mp_exp<tagb, A1b, A2b, A3b> \
+ >(\
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::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::mp_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 \
-func(const big_number<Backend>& arg, const Arithmetic& a)\
+ , mp_number<Backend> \
+ , Arithmetic\
+ > \
+>::type \
+func(const mp_number<Backend>& arg, const Arithmetic& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , mp_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::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+ , Arithmetic\
+ > \
+>::type \
+func(const detail::mp_exp<tag, A1, A2, A3>& arg, const Arithmetic& a)\
+{\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+ , Arithmetic\
+ >(\
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_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::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+ , Arg2\
+> \
+func(const detail::mp_exp<tag, A1, A2, A3>& arg, Arg2 const& a)\
+{\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type> \
+ , detail::mp_exp<tag, A1, A2, A3> \
+ , Arg2\
+ >(\
+ detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::mp_exp<tag, A1, A2, A3> >::type>() \
+ , arg, a \
     );\
 }\
 template <class Backend> \
-typename proto::result_of::make_expr<\
- proto::tag::function\
+detail::mp_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 \
-func(const big_number<Backend>& arg, Arg2 const& a)\
+ , mp_number<Backend> \
+ , Arg2\
+> \
+func(const mp_number<Backend>& arg, Arg2 const& a)\
 {\
- return proto::make_expr<proto::tag::function>(\
+ return detail::mp_exp<\
+ detail::function\
+ , detail::BOOST_JOIN(func, _funct)<Backend> \
+ , mp_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\
     );\
 }\
 

Copied: sandbox/big_number/boost/multiprecision/e_float.hpp (from r74479, /sandbox/big_number/boost/math/big_number/e_float.hpp)
==============================================================================
--- /sandbox/big_number/boost/math/big_number/e_float.hpp (original)
+++ sandbox/big_number/boost/multiprecision/e_float.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
@@ -6,7 +6,7 @@
 #ifndef BOOST_MATH_EFX_BACKEND_HPP
 #define BOOST_MATH_EFX_BACKEND_HPP
 
-#include <boost/math/big_number/arithmetic_backend.hpp>
+#include <boost/multiprecision/arithmetic_backend.hpp>
 #include <boost/e_float/e_float.hpp>
 #include <boost/e_float/e_float_complex.hpp>
 #include <boost/e_float/e_float_elementary_math.hpp>
@@ -15,7 +15,7 @@
 namespace boost{
 namespace math{
 
-typedef big_number<arithmetic_backend<efx::e_float> > e_float;
+typedef mp_number<arithmetic_backend<efx::e_float> > e_float;
 
 template<>
 inline void arithmetic_backend<efx::e_float>::negate()

Copied: sandbox/big_number/boost/multiprecision/gmp.hpp (from r74479, /sandbox/big_number/boost/math/big_number/gmp.hpp)
==============================================================================
--- /sandbox/big_number/boost/math/big_number/gmp.hpp (original)
+++ sandbox/big_number/boost/multiprecision/gmp.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
@@ -6,7 +6,7 @@
 #ifndef BOOST_MATH_ER_GMP_BACKEND_HPP
 #define BOOST_MATH_ER_GMP_BACKEND_HPP
 
-#include <boost/math/big_number.hpp>
+#include <boost/multiprecision/mp_number.hpp>
 #include <boost/math/special_functions/fpclassify.hpp>
 #include <boost/cstdint.hpp>
 #include <boost/lexical_cast.hpp>
@@ -1305,15 +1305,17 @@
 }
 
 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;
-typedef big_number<gmp_real<500> > mpf_real_500;
-typedef big_number<gmp_real<1000> > mpf_real_1000;
-typedef big_number<gmp_real<0> > mpf_real;
-typedef big_number<gmp_int > mpz_int;
-typedef big_number<gmp_rational > mpq_rational;
+typedef mp_number<gmp_real<50> > mpf_real_50;
+typedef mp_number<gmp_real<100> > mpf_real_100;
+typedef mp_number<gmp_real<500> > mpf_real_500;
+typedef mp_number<gmp_real<1000> > mpf_real_1000;
+typedef mp_number<gmp_real<0> > mpf_real;
+typedef mp_number<gmp_int > mpz_int;
+typedef mp_number<gmp_rational > mpq_rational;
 
 }} // namespaces
 
@@ -1327,9 +1329,9 @@
 // numeric_limits [partial] specializations for the types declared in this header:
 //
 template<unsigned Digits10>
-class numeric_limits<boost::math::big_number<boost::math::gmp_real<Digits10> > >
+class numeric_limits<boost::math::mp_number<boost::math::gmp_real<Digits10> > >
 {
- typedef boost::math::big_number<boost::math::gmp_real<Digits10> > number_type;
+ typedef boost::math::mp_number<boost::math::gmp_real<Digits10> > number_type;
 public:
    BOOST_STATIC_CONSTEXPR bool is_specialized = true;
    BOOST_STATIC_CONSTEXPR number_type (min)() noexcept
@@ -1419,10 +1421,10 @@
    {
       data_initializer()
       {
- std::numeric_limits<boost::math::big_number<boost::math::gmp_real<digits10> > >::epsilon();
- std::numeric_limits<boost::math::big_number<boost::math::gmp_real<digits10> > >::round_error();
- (std::numeric_limits<boost::math::big_number<boost::math::gmp_real<digits10> > >::min)();
- (std::numeric_limits<boost::math::big_number<boost::math::gmp_real<digits10> > >::max)();
+ std::numeric_limits<boost::math::mp_number<boost::math::gmp_real<digits10> > >::epsilon();
+ std::numeric_limits<boost::math::mp_number<boost::math::gmp_real<digits10> > >::round_error();
+ (std::numeric_limits<boost::math::mp_number<boost::math::gmp_real<digits10> > >::min)();
+ (std::numeric_limits<boost::math::mp_number<boost::math::gmp_real<digits10> > >::max)();
       }
       void do_nothing()const{}
    };
@@ -1430,12 +1432,12 @@
 };
 
 template<unsigned Digits10>
-const typename numeric_limits<boost::math::big_number<boost::math::gmp_real<Digits10> > >::data_initializer numeric_limits<boost::math::big_number<boost::math::gmp_real<Digits10> > >::initializer;
+const typename numeric_limits<boost::math::mp_number<boost::math::gmp_real<Digits10> > >::data_initializer numeric_limits<boost::math::mp_number<boost::math::gmp_real<Digits10> > >::initializer;
 
 template<>
-class numeric_limits<boost::math::big_number<boost::math::gmp_real<0> > >
+class numeric_limits<boost::math::mp_number<boost::math::gmp_real<0> > >
 {
- typedef boost::math::big_number<boost::math::gmp_real<0> > number_type;
+ typedef boost::math::mp_number<boost::math::gmp_real<0> > number_type;
 public:
    BOOST_STATIC_CONSTEXPR bool is_specialized = false;
    BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return number_type(); }

Copied: sandbox/big_number/boost/multiprecision/mp_number.hpp (from r74479, /sandbox/big_number/boost/math/big_number.hpp)
==============================================================================
--- /sandbox/big_number/boost/math/big_number.hpp (original)
+++ sandbox/big_number/boost/multiprecision/mp_number.hpp 2011-09-26 12:29:44 EDT (Mon, 26 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>
@@ -20,116 +19,95 @@
 #include <boost/type_traits/is_integral.hpp>
 #include <boost/type_traits/make_unsigned.hpp>
 #include <boost/throw_exception.hpp>
-#include <boost/math/big_number/default_ops.hpp>
+#include <boost/multiprecision/detail/default_ops.hpp>
 
 namespace boost{ namespace math{
 
 template <class Backend>
-class big_number : public detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type >
+class mp_number
 {
- typedef detail::big_number_exp<typename proto::terminal<big_number<Backend>*>::type > base_type;
- typedef big_number<Backend> self_type;
+ typedef mp_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);
- }
+ mp_number(){}
+ mp_number(const mp_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)
+ mp_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);
- }
+ mp_number(const mp_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)
+ mp_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)
    {
- 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);
- }
+ mp_number(V v, typename enable_if<mpl::and_<is_convertible<V, Backend>, mpl::not_<boost::is_arithmetic<V> > > >::type* dummy1 = 0)
+ : 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>
+ mp_number& operator=(const detail::mp_exp<tag, Arg1, Arg2, Arg3>& e)
    {
- do_assign(e, typename detail::assign_and_eval<Exp>::type());
+ do_assign(e, tag());
       return *this;
    }
 
- big_number& operator=(const big_number& e)
+ mp_number& operator=(const mp_number& e)
    {
       m_backend = e.m_backend;
       return *this;
    }
 
    template <class V>
- typename enable_if<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> >, big_number<Backend>& >::type
+ typename enable_if<mpl::or_<boost::is_arithmetic<V>, is_same<std::string, V>, is_convertible<V, const char*> >, mp_number<Backend>& >::type
       operator=(const V& v)
    {
       m_backend = canonical_value(v);
       return *this;
    }
 
- template <class Exp>
- big_number(const detail::big_number_exp<Exp>& e)
+ template <class tag, class Arg1, class Arg2, class Arg3>
+ mp_number(const detail::mp_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& operator=(big_number&& r)
+ mp_number(mp_number&& r) : m_backend(r.m_backend){}
+ mp_number& operator=(mp_number&& r)
    {
       m_backend.swap(r.m_backend);
       return *this;
    }
 #endif
 
- template <class Exp>
- big_number& operator+=(const detail::big_number_exp<Exp>& e)
+ mp_number& operator+=(const self_type& val)
+ {
+ do_add(detail::mp_exp<detail::terminal, self_type>(val), detail::terminal());
+ return *this;
+ }
+
+ template <class tag, class Arg1, class Arg2, class Arg3>
+ mp_number& operator+=(const detail::mp_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::mp_exp<detail::terminal, self_type>(temp), detail::terminal());
       }
       else
       {
- do_add(e, typename proto::tag_of<Exp>::type());
+ do_add(e, tag());
       }
       return *this;
    }
 
    template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
+ typename enable_if<boost::is_arithmetic<V>, mp_number<Backend>& >::type
       operator+=(const V& v)
    {
       using big_num_default_ops::add;
@@ -137,24 +115,30 @@
       return *this;
    }
 
+ mp_number& operator-=(const self_type& val)
+ {
+ do_subtract(detail::mp_exp<detail::terminal, self_type>(val), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
- big_number& operator-=(const detail::big_number_exp<Exp>& e)
+ mp_number& operator-=(const detail::mp_exp<Exp>& e)
    {
       // Create a copy if e contains this, but not if we're just doing a
       if(contains_self(e))
       {
          self_type temp(e);
- do_subtract(temp, typename proto::tag_of<self_type>::type());
+ do_subtract(temp, typename self_type::tag_type());
       }
       else
       {
- do_subtract(e, typename proto::tag_of<Exp>::type());
+ do_subtract(e, typename Exp::tag_type());
       }
       return *this;
    }
 
    template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
+ typename enable_if<boost::is_arithmetic<V>, mp_number<Backend>& >::type
       operator-=(const V& v)
    {
       using big_num_default_ops::subtract;
@@ -162,25 +146,32 @@
       return *this;
    }
 
+
+ mp_number& operator *= (const self_type& e)
+ {
+ do_multiplies(detail::mp_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
- big_number& operator*=(const detail::big_number_exp<Exp>& e)
+ mp_number& operator*=(const detail::mp_exp<Exp>& e)
    {
       // Create a temporary if the RHS references *this, but not
       // if we're just doing an x += x;
       if(contains_self(e) && !is_self(e))
       {
          self_type temp(e);
- do_multiplies(temp, typename proto::tag_of<self_type>::type());
+ do_multiplies(detail::mp_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;
    }
 
    template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
+ typename enable_if<boost::is_arithmetic<V>, mp_number<Backend>& >::type
       operator*=(const V& v)
    {
       using big_num_default_ops::multiply;
@@ -188,27 +179,33 @@
       return *this;
    }
 
+ mp_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::mp_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
    template <class Exp>
- big_number& operator%=(const detail::big_number_exp<Exp>& e)
+ mp_number& operator%=(const detail::mp_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 self_type::tag_type());
       }
       else
       {
- do_modulus(e, typename proto::tag_of<Exp>::type());
+ do_modulus(e, typename Exp::tag_type());
       }
       return *this;
    }
    template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
+ typename enable_if<boost::is_arithmetic<V>, mp_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;
@@ -222,21 +219,21 @@
    // execute the increment/decrement on destruction, but
    // correct implemetation will be tricky, so defered for now...
    //
- big_number& operator++()
+ mp_number& operator++()
    {
       using big_num_default_ops::increment;
       increment(m_backend);
       return *this;
    }
 
- big_number& operator--()
+ mp_number& operator--()
    {
       using big_num_default_ops::decrement;
       decrement(m_backend);
       return *this;
    }
 
- big_number operator++(int)
+ mp_number operator++(int)
    {
       using big_num_default_ops::increment;
       self_type temp(*this);
@@ -244,7 +241,7 @@
       return temp;
    }
 
- big_number operator--(int)
+ mp_number operator--(int)
    {
       using big_num_default_ops::decrement;
       self_type temp(*this);
@@ -253,41 +250,47 @@
    }
 
    template <class V>
- typename enable_if<is_integral<V>, big_number&>::type operator <<= (V val)
+ typename enable_if<is_integral<V>, mp_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;
    }
 
    template <class V>
- typename enable_if<is_integral<V>, big_number&>::type operator >>= (V val)
+ typename enable_if<is_integral<V>, mp_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;
    }
 
+ mp_number& operator /= (const self_type& e)
+ {
+ do_divide(detail::mp_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
- big_number& operator/=(const detail::big_number_exp<Exp>& e)
+ mp_number& operator/=(const detail::mp_exp<Exp>& e)
    {
       // Create a temporary if the RHS references *this:
       if(contains_self(e))
       {
          self_type temp(e);
- do_divide(temp, typename proto::tag_of<self_type>::type());
+ do_divide(detail::mp_exp<detail::terminal, self_type>(temp), typename self_type::tag_type());
       }
       else
       {
- do_divide(e, typename proto::tag_of<Exp>::type());
+ do_divide(e, typename Exp::tag_type());
       }
       return *this;
    }
 
    template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
+ typename enable_if<boost::is_arithmetic<V>, mp_number<Backend>& >::type
       operator/=(const V& v)
    {
       using big_num_default_ops::divide;
@@ -295,25 +298,31 @@
       return *this;
    }
 
+ mp_number& operator&=(const self_type& e)
+ {
+ do_bitwise_and(detail::mp_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
- big_number& operator&=(const detail::big_number_exp<Exp>& e)
+ mp_number& operator&=(const detail::mp_exp<Exp>& e)
    {
       // Create a temporary if the RHS references *this, but not
       // if we're just doing an x &= x;
       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 self_type::tag_type());
       }
       else
       {
- do_bitwise_and(e, typename proto::tag_of<Exp>::type());
+ do_bitwise_and(e, typename Exp::tag_type());
       }
       return *this;
    }
 
    template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
+ typename enable_if<boost::is_arithmetic<V>, mp_number<Backend>& >::type
       operator&=(const V& v)
    {
       using big_num_default_ops::bitwise_and;
@@ -321,25 +330,31 @@
       return *this;
    }
 
+ mp_number& operator|=(const self_type& e)
+ {
+ do_bitwise_or(detail::mp_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
- big_number& operator|=(const detail::big_number_exp<Exp>& e)
+ mp_number& operator|=(const detail::mp_exp<Exp>& e)
    {
       // Create a temporary if the RHS references *this, but not
       // if we're just doing an x |= x;
       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 self_type::tag_type());
       }
       else
       {
- do_bitwise_or(e, typename proto::tag_of<Exp>::type());
+ do_bitwise_or(e, typename Exp::tag_type());
       }
       return *this;
    }
 
    template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
+ typename enable_if<boost::is_arithmetic<V>, mp_number<Backend>& >::type
       operator|=(const V& v)
    {
       using big_num_default_ops::bitwise_or;
@@ -347,29 +362,44 @@
       return *this;
    }
 
+ mp_number& operator^=(const self_type& e)
+ {
+ do_bitwise_xor(detail::mp_exp<detail::terminal, self_type>(e), detail::terminal());
+ return *this;
+ }
+
    template <class Exp>
- big_number& operator^=(const detail::big_number_exp<Exp>& e)
+ mp_number& operator^=(const detail::mp_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 self_type::tag_type());
       }
       else
       {
- do_bitwise_xor(e, typename proto::tag_of<Exp>::type());
+ do_bitwise_xor(e, typename Exp::tag_type());
       }
       return *this;
    }
 
    template <class V>
- typename enable_if<boost::is_arithmetic<V>, big_number<Backend>& >::type
+ typename enable_if<boost::is_arithmetic<V>, mp_number<Backend>& >::type
       operator^=(const V& v)
    {
       using big_num_default_ops::bitwise_xor;
       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);
@@ -428,13 +458,14 @@
    //
    // Comparison:
    //
- int compare(const big_number<Backend>& o)const
+ int compare(const mp_number<Backend>& o)const
    {
       return m_backend.compare(o.m_backend);
    }
    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,53 +979,53 @@
    }
 
    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&)
    {
- big_number t(val);
+ mp_number t(val);
       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::mp_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::mp_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;
 };
 
@@ -1390,55 +1409,55 @@
 {
 
 template <class Backend>
-inline int big_number_compare(const big_number<Backend>& a, const big_number<Backend>& b)
+inline int big_number_compare(const mp_number<Backend>& a, const mp_number<Backend>& b)
 {
    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 mp_number<Backend>& a, const mp_exp<tag, A1, A2, A3>& b)
 {
- return a.compare(big_number<Backend>(b));
+ return a.compare(mp_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 mp_exp<tag, A1, A2, A3>& a, const mp_number<Backend>& b)
 {
- return -b.compare(big_number<Backend>(a));
+ return -b.compare(mp_number<Backend>(a));
 }
 
 template <class Backend, class Val>
-inline int big_number_compare(const big_number<Backend>& a, const Val b)
+inline int big_number_compare(const mp_number<Backend>& a, const Val b)
 {
    return a.compare(b);
 }
 
 template <class Val, class Backend>
-inline int big_number_compare(const Val a, const big_number<Backend>& b)
+inline int big_number_compare(const Val a, const mp_number<Backend>& b)
 {
    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 mp_exp<tag, A1, A2, A3>& a, const mp_exp<tag2, A1b, A2b, A3b>& b)
 {
- typedef typename expression_type<Exp1>::type real1;
- typedef typename expression_type<Exp2>::type real2;
+ typedef typename mp_exp<tag, A1, A2, A3>::result_type real1;
+ typedef typename mp_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 mp_exp<tag, A1, A2, A3>& a, const Val b)
 {
- typedef typename expression_type<Exp>::type real;
+ typedef typename mp_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 mp_exp<tag, A1, A2, A3>& b)
 {
- typedef typename expression_type<Exp>::type real;
+ typedef typename mp_exp<tag, A1, A2, A3>::result_type real;
    return -real(b).compare(a);
 }
 
@@ -1520,17 +1539,17 @@
 }
 
 template <class Backend>
-inline std::ostream& operator << (std::ostream& os, const big_number<Backend>& r)
+inline std::ostream& operator << (std::ostream& os, const mp_number<Backend>& r)
 {
    return os << r.str(static_cast<unsigned>(os.precision(), os.flags() & os.scientific));
 }
 
 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 mp_exp<tag, A1, A2, A3>& r)
 {
- typedef typename expression_type<detail::big_number_exp<Exp> >::type value_type;
+ typedef typename mp_exp<tag, A1, A2, A3>::result_type value_type;
    value_type temp(r);
    return os << temp;
 }
@@ -1538,7 +1557,7 @@
 } // namespace detail
 
 template <class Backend>
-inline std::istream& operator >> (std::istream& is, big_number<Backend>& r)
+inline std::istream& operator >> (std::istream& is, mp_number<Backend>& r)
 {
    std::string s;
    is >> s;

Copied: sandbox/big_number/boost/multiprecision/mpfr.hpp (from r74479, /sandbox/big_number/boost/math/big_number/mpfr.hpp)
==============================================================================
--- /sandbox/big_number/boost/math/big_number/mpfr.hpp (original)
+++ sandbox/big_number/boost/multiprecision/mpfr.hpp 2011-09-26 12:29:44 EDT (Mon, 26 Sep 2011)
@@ -6,7 +6,7 @@
 #ifndef BOOST_MATH_BN_MPFR_HPP
 #define BOOST_MATH_BN_MPFR_HPP
 
-#include <boost/math/big_number.hpp>
+#include <boost/multiprecision/mp_number.hpp>
 #include <boost/math/special_functions/fpclassify.hpp>
 #include <boost/cstdint.hpp>
 #include <boost/lexical_cast.hpp>
@@ -67,13 +67,9 @@
       while(i)
       {
          mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
- long e;
- const char* ps = mpfr_get_str (0, &e, 10, 0, t, GMP_RNDN);
          if(shift)
             mpfr_mul_2exp(t, t, shift, GMP_RNDN);
- ps = mpfr_get_str (0, &e, 10, 0, t, GMP_RNDN);
          mpfr_add(m_data, m_data, t, GMP_RNDN);
- ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN);
          shift += std::numeric_limits<unsigned>::digits;
          i >>= std::numeric_limits<unsigned>::digits;
       }
@@ -734,16 +730,16 @@
    mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
 }
 
-typedef big_number<mpfr_real_backend<50> > mpfr_real_50;
-typedef big_number<mpfr_real_backend<100> > mpfr_real_100;
-typedef big_number<mpfr_real_backend<500> > mpfr_real_500;
-typedef big_number<mpfr_real_backend<1000> > mpfr_real_1000;
-typedef big_number<mpfr_real_backend<0> > mpfr_real;
+typedef mp_number<mpfr_real_backend<50> > mpfr_real_50;
+typedef mp_number<mpfr_real_backend<100> > mpfr_real_100;
+typedef mp_number<mpfr_real_backend<500> > mpfr_real_500;
+typedef mp_number<mpfr_real_backend<1000> > mpfr_real_1000;
+typedef mp_number<mpfr_real_backend<0> > mpfr_real;
 
 namespace lanczos{
 
 template<unsigned Digits10, class Policy>
-struct lanczos<big_number<mpfr_real_backend<Digits10> >, Policy>
+struct lanczos<mp_number<mpfr_real_backend<Digits10> >, Policy>
 {
    typedef typename mpl::if_c<
       Digits10 <= 36,
@@ -775,9 +771,9 @@
 // numeric_limits [partial] specializations for the types declared in this header:
 //
 template<unsigned Digits10>
-class numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > >
+class numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<Digits10> > >
 {
- typedef boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > number_type;
+ typedef boost::math::mp_number<boost::math::mpfr_real_backend<Digits10> > number_type;
 public:
    BOOST_STATIC_CONSTEXPR bool is_specialized = true;
    BOOST_STATIC_CONSTEXPR number_type (min)() noexcept
@@ -894,12 +890,12 @@
    {
       data_initializer()
       {
- std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::epsilon();
- std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::round_error();
- (std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::min)();
- (std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::max)();
- std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::infinity();
- std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::quiet_NaN();
+ std::numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<digits10> > >::epsilon();
+ std::numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<digits10> > >::round_error();
+ (std::numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<digits10> > >::min)();
+ (std::numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<digits10> > >::max)();
+ std::numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<digits10> > >::infinity();
+ std::numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<digits10> > >::quiet_NaN();
       }
       void do_nothing()const{}
    };
@@ -907,12 +903,12 @@
 };
 
 template<unsigned Digits10>
-const typename numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > >::data_initializer numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > >::initializer;
+const typename numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<Digits10> > >::data_initializer numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<Digits10> > >::initializer;
 
 template<>
-class numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<0> > >
+class numeric_limits<boost::math::mp_number<boost::math::mpfr_real_backend<0> > >
 {
- typedef boost::math::big_number<boost::math::mpfr_real_backend<0> > number_type;
+ typedef boost::math::mp_number<boost::math::mpfr_real_backend<0> > number_type;
 public:
    BOOST_STATIC_CONSTEXPR bool is_specialized = false;
    BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return number_type(0); }


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