$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r54213 - in sandbox/mp_math: boost/mp_math boost/mp_math/integer boost/mp_math/integer/detail boost/mp_math/integer/detail/asm boost/mp_math/integer/detail/base boost/mp_math/integer/detail/base/asm boost/mp_math/integer/detail/base/asm/asm boost/mp_math/integer/detail/base/asm/asm/x86 boost/mp_math/mp_int libs/mp_math libs/mp_math/examples libs/mp_math/test libs/mp_math/test/unbounded libs/mp_math/test/unbounded/signed libs/mp_math/test/unbounded/unsigned libs/mp_math/tools/benchmark
From: baraclese_at_[hidden]
Date: 2009-06-22 14:57:36
Author: baraclese
Date: 2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
New Revision: 54213
URL: http://svn.boost.org/trac/boost/changeset/54213
Log:
* this is a complete rewrite which changes and renames the mp_int class template to integer
* the integer class template now acts as a frontend for different backends
* backends: GMP, libtommath and the native Boost one
* experimental code for unsigned unbounded integers, known to be broken
* increased test coverage
* moving away from the libtommath code for the native Boost implementation because it does not lend itself to assembly optimizations
Added:
   sandbox/mp_math/boost/mp_math/gmp.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/
      - copied from r54148, /sandbox/mp_math/boost/mp_math/mp_int/
   sandbox/mp_math/boost/mp_math/integer.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int.hpp
   sandbox/mp_math/boost/mp_math/integer/contexts.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/modpow_ctx.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/base/
   sandbox/mp_math/boost/mp_math/integer/detail/base/adder.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/asm/
   sandbox/mp_math/boost/mp_math/integer/detail/base/asm/asm/
      - copied from r54148, /sandbox/mp_math/boost/mp_math/mp_int/detail/asm/
   sandbox/mp_math/boost/mp_math/integer/detail/base/bitmanipulator.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/bitwise_ops.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/divider.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/from_integral.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/multiplier.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/primitive_ops.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/detail/primitive_ops.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/base/shifter.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/to_integral.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_int.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_int_fwd.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_int_integral.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_uint.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_uint_fwd.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_uint_integral.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/divider.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/detail/div.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/gcd.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/gcd.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/jacobi.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/jacobi.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/lcm.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/lcm.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/multiplier.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/mul.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/power.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/pow.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/root.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/root.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/string_conversion.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/string_conversion.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/unbounded_int_integral.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/detail/unbounded_uint_integral.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/gmp_integer.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/integer.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/mp_int.hpp
   sandbox/mp_math/boost/mp_math/integer/integer_fwd.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/mp_int_fwd.hpp
   sandbox/mp_math/boost/mp_math/integer/libtom_integer.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/unbounded.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/unbounded_int.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer/unbounded_traits.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int/traits.hpp
   sandbox/mp_math/boost/mp_math/integer/unbounded_uint.hpp   (contents, props changed)
   sandbox/mp_math/boost/mp_math/integer_serialization.hpp
      - copied, changed from r54148, /sandbox/mp_math/boost/mp_math/mp_int_serialization.hpp
   sandbox/mp_math/boost/mp_math/libtom.hpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/examples/
   sandbox/mp_math/libs/mp_math/examples/answer.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/examples/drops_in_the_ocean.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/examples/gmp.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/examples/jamfile.v2   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/jamfile.v2   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/abs.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/add.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/add.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/assign.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/bitmanipulation.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/bitmanipulation.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/bitwise_ops.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/bitwise_ops.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/bool_conversion.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/bool_conversion.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/cmp.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/cmp.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/ctors.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/ctors.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/div.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/div.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/gcd.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/gcd.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/integral_ops.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/integral_ops.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/jacobi.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/jacobi.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/jamfile.v2
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/jamfile.v2
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/lcm.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/lcm.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/modinv.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/modinv.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/modpow.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/modpow.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/mul.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/mul.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/numeric_limits.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/pow.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/pow.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/prerequisite.hpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/prerequisite.hpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/prime.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/prime.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/random.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/random.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/root.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/root.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/serialization.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/serialization.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/shift.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/shift.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/sqr.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/sqr.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/stream_io.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/stream_io.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/string_ops.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/string_ops.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/sub.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/sub.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/swap.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/to_integral.cpp
      - copied, changed from r54148, /sandbox/mp_math/libs/mp_math/test/to_integral.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/traits.cpp
      - copied unchanged from r54148, /sandbox/mp_math/libs/mp_math/test/traits.cpp
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/abs.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/add.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/bitmanipulation.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/bitwise_ops.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/bool_conversion.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/cmp.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/ctors.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/div.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/gcd.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/integral_ops.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/jacobi.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/jamfile.v2   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/lcm.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/modinv.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/mul.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/numeric_limits.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/pow.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/prerequisite.hpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/root.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/serialization.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/shift.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/sqr.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/stream_io.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/string_ops.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/sub.cpp   (contents, props changed)
   sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/to_integral.cpp   (contents, props changed)
Removed:
   sandbox/mp_math/boost/mp_math/integer/abs.hpp
   sandbox/mp_math/boost/mp_math/integer/add.hpp
   sandbox/mp_math/boost/mp_math/integer/ctors.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/asm/
   sandbox/mp_math/boost/mp_math/integer/detail/div.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/integral_ops.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/primitive_ops.hpp
   sandbox/mp_math/boost/mp_math/integer/detail/string_conversion_constants.hpp
   sandbox/mp_math/boost/mp_math/integer/div.hpp
   sandbox/mp_math/boost/mp_math/integer/gcd.hpp
   sandbox/mp_math/boost/mp_math/integer/jacobi.hpp
   sandbox/mp_math/boost/mp_math/integer/lcm.hpp
   sandbox/mp_math/boost/mp_math/integer/mod.hpp
   sandbox/mp_math/boost/mp_math/integer/modinv.hpp
   sandbox/mp_math/boost/mp_math/integer/modpow.hpp
   sandbox/mp_math/boost/mp_math/integer/modpow_ctx.hpp
   sandbox/mp_math/boost/mp_math/integer/mp_int.hpp
   sandbox/mp_math/boost/mp_math/integer/mp_int_fwd.hpp
   sandbox/mp_math/boost/mp_math/integer/mul.hpp
   sandbox/mp_math/boost/mp_math/integer/operators.hpp
   sandbox/mp_math/boost/mp_math/integer/pow.hpp
   sandbox/mp_math/boost/mp_math/integer/root.hpp
   sandbox/mp_math/boost/mp_math/integer/sqr.hpp
   sandbox/mp_math/boost/mp_math/integer/string_conversion.hpp
   sandbox/mp_math/boost/mp_math/integer/sub.hpp
   sandbox/mp_math/boost/mp_math/integer/traits.hpp
   sandbox/mp_math/boost/mp_math/mp_int/
   sandbox/mp_math/boost/mp_math/mp_int.hpp
   sandbox/mp_math/boost/mp_math/mp_int_serialization.hpp
   sandbox/mp_math/libs/mp_math/test/add.cpp
   sandbox/mp_math/libs/mp_math/test/bitmanipulation.cpp
   sandbox/mp_math/libs/mp_math/test/bitwise_ops.cpp
   sandbox/mp_math/libs/mp_math/test/bool_conversion.cpp
   sandbox/mp_math/libs/mp_math/test/cmp.cpp
   sandbox/mp_math/libs/mp_math/test/compile_all.cpp
   sandbox/mp_math/libs/mp_math/test/ctors.cpp
   sandbox/mp_math/libs/mp_math/test/div.cpp
   sandbox/mp_math/libs/mp_math/test/gcd.cpp
   sandbox/mp_math/libs/mp_math/test/integral_ops.cpp
   sandbox/mp_math/libs/mp_math/test/jacobi.cpp
   sandbox/mp_math/libs/mp_math/test/lcm.cpp
   sandbox/mp_math/libs/mp_math/test/modinv.cpp
   sandbox/mp_math/libs/mp_math/test/modpow.cpp
   sandbox/mp_math/libs/mp_math/test/mul.cpp
   sandbox/mp_math/libs/mp_math/test/pow.cpp
   sandbox/mp_math/libs/mp_math/test/prerequisite.hpp
   sandbox/mp_math/libs/mp_math/test/prime.cpp
   sandbox/mp_math/libs/mp_math/test/random.cpp
   sandbox/mp_math/libs/mp_math/test/root.cpp
   sandbox/mp_math/libs/mp_math/test/serialization.cpp
   sandbox/mp_math/libs/mp_math/test/shift.cpp
   sandbox/mp_math/libs/mp_math/test/sqr.cpp
   sandbox/mp_math/libs/mp_math/test/stream_io.cpp
   sandbox/mp_math/libs/mp_math/test/string_ops.cpp
   sandbox/mp_math/libs/mp_math/test/sub.cpp
   sandbox/mp_math/libs/mp_math/test/to_integral.cpp
   sandbox/mp_math/libs/mp_math/test/traits.cpp
Text files modified: 
   sandbox/mp_math/boost/mp_math/integer.hpp                                               |    21                                         
   sandbox/mp_math/boost/mp_math/integer/contexts.hpp                                      |   173 ---                                     
   sandbox/mp_math/boost/mp_math/integer/detail/base/asm/asm/x86/gnu_386_primitive_ops.hpp |    31                                         
   sandbox/mp_math/boost/mp_math/integer/detail/base/primitive_ops.hpp                     |  1971 ++++++++++++++++++++++++++++++++++++++- 
   sandbox/mp_math/boost/mp_math/integer/detail/divider.hpp                                |   214 ++-                                     
   sandbox/mp_math/boost/mp_math/integer/detail/gcd.hpp                                    |   108 +                                       
   sandbox/mp_math/boost/mp_math/integer/detail/jacobi.hpp                                 |    37                                         
   sandbox/mp_math/boost/mp_math/integer/detail/lcm.hpp                                    |    68                                         
   sandbox/mp_math/boost/mp_math/integer/detail/meta_math.hpp                              |     6                                         
   sandbox/mp_math/boost/mp_math/integer/detail/modinv.hpp                                 |   157 +-                                      
   sandbox/mp_math/boost/mp_math/integer/detail/modpow.hpp                                 |   421 ++++++-                                 
   sandbox/mp_math/boost/mp_math/integer/detail/modular_reduction.hpp                      |   255 ++--                                    
   sandbox/mp_math/boost/mp_math/integer/detail/multiplier.hpp                             |   859 ++++++++++++----                        
   sandbox/mp_math/boost/mp_math/integer/detail/power.hpp                                  |   156 ++                                      
   sandbox/mp_math/boost/mp_math/integer/detail/prime_tab.hpp                              |     6                                         
   sandbox/mp_math/boost/mp_math/integer/detail/root.hpp                                   |   301 +++--                                   
   sandbox/mp_math/boost/mp_math/integer/detail/string_conversion.hpp                      |  1127 ++++++++++++++++++----                  
   sandbox/mp_math/boost/mp_math/integer/integer.hpp                                       |   948 +-----------------                      
   sandbox/mp_math/boost/mp_math/integer/integer_fwd.hpp                                   |    17                                         
   sandbox/mp_math/boost/mp_math/integer/numeric_limits.hpp                                |   401 +++++++                                 
   sandbox/mp_math/boost/mp_math/integer/unbounded_traits.hpp                              |    67                                         
   sandbox/mp_math/boost/mp_math/integer_serialization.hpp                                 |    64 +                                       
   sandbox/mp_math/libs/mp_math/index.html                                                 |     2                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/add.cpp                              |   166 +-                                      
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/bitmanipulation.cpp                  |    79                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/bitwise_ops.cpp                      |    94 +                                       
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/bool_conversion.cpp                  |    43                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/cmp.cpp                              |   570 ++++++++++-                             
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/ctors.cpp                            |   277 +++-                                    
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/div.cpp                              |   174 ++-                                     
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/gcd.cpp                              |    56                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/integral_ops.cpp                     |   320 ++++--                                  
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/jacobi.cpp                           |    26                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/jamfile.v2                           |    15                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/lcm.cpp                              |    72                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/modinv.cpp                           |    26                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/modpow.cpp                           |   106 +-                                      
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/mul.cpp                              |    83                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/pow.cpp                              |    76 +                                       
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/prerequisite.hpp                     |    64                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/prime.cpp                            |    55                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/random.cpp                           |    49                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/root.cpp                             |    54                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/serialization.cpp                    |    30                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/shift.cpp                            |    36                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/sqr.cpp                              |    80 +                                       
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/stream_io.cpp                        |    74                                         
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/string_ops.cpp                       |   101 -                                       
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/sub.cpp                              |   107 +-                                      
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/to_integral.cpp                      |   112 +-                                      
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.cpp                          |    10                                         
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.hpp                          |    43                                         
   sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.hpp                      |    23                                         
   sandbox/mp_math/libs/mp_math/tools/benchmark/jamfile.v2                                 |    11                                         
   sandbox/mp_math/libs/mp_math/tools/benchmark/main.cpp                                   |    34                                         
   sandbox/mp_math/libs/mp_math/tools/benchmark/modes.cpp                                  |    96 +                                       
   56 files changed, 7170 insertions(+), 3402 deletions(-)
Added: sandbox/mp_math/boost/mp_math/gmp.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/gmp.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,12 @@
+// Copyright Kevin Sopp 2009.
+// 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_MP_MATH_GMP_HPP
+#define BOOST_MP_MATH_GMP_HPP
+
+#include <boost/mp_math/integer/gmp_integer.hpp>
+
+#endif
+
Copied: sandbox/mp_math/boost/mp_math/integer.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,21 +1,16 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_HPP
-#define BOOST_MP_MATH_MP_INT_HPP
+#ifndef BOOST_MP_MATH_INTEGER_HPP
+#define BOOST_MP_MATH_INTEGER_HPP
 
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-#include <boost/mp_math/mp_int/mp_int.hpp>
+#include <boost/mp_math/integer/integer_fwd.hpp>
+#include <boost/mp_math/integer/integer.hpp>
 
-#include <boost/mp_math/mp_int/gcd.hpp>
-#include <boost/mp_math/mp_int/jacobi.hpp>
-#include <boost/mp_math/mp_int/lcm.hpp>
-#include <boost/mp_math/mp_int/modinv.hpp>
-#include <boost/mp_math/mp_int/modpow.hpp>
-#include <boost/mp_math/mp_int/numeric_limits.hpp>
-#include <boost/mp_math/mp_int/prime.hpp>
-#include <boost/mp_math/mp_int/root.hpp>
+#include <boost/mp_math/integer/numeric_limits.hpp>
+#include <boost/mp_math/integer/prime.hpp>
+#include <boost/mp_math/integer/random.hpp>
 
 #endif
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/abs.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/abs.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,12 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-template<class A, class T>
-mp_int<A,T> abs(const mp_int<A,T>& x)
-{
-  mp_int<A,T> tmp(x);
-  tmp.set_sign(1);
-  return tmp;
-}
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/add.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/add.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,83 +0,0 @@
-// Copyright Kevin Sopp 2008 - 2009.
-// 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)
-
-template<class A, class T>
-void mp_int<A,T>::add_digit(digit_type b)
-{
-  if (is_positive())
-  {
-    grow_capacity(size_ + 1);
-    const digit_type carry =
-      ops_type::add_single_digit(digits_, digits_, size_, b);
-    if (carry)
-      push(carry);
-  }
-  else
-  {
-    if (digits_[0] > b) // example: -16 + 5 = -11
-      digits_[0] -= b;
-    else
-    {
-      if (size_ == 1) // example: -1 + 5 = 4, or -5 + 5 = 0
-      {
-        digits_[0] = b - digits_[0];
-        set_sign(1);
-      }
-      else            // example -1000 + 5 = -995
-      {
-        ops_type::subtract_single_digit(digits_, digits_, size_, b);
-        if (!digits_[size_-1])
-          --size_;
-      }
-    }
-  }
-}
-
-// low level addition, based on HAC pp.594, Algorithm 14.7
-// does not handle sign
-template<class A, class T>
-void mp_int<A,T>::add_magnitude(const mp_int& rhs)
-{
-  const mp_int* x;
-  const mp_int* y;
-
-  // x will point to the number with the most digits
-  if (size_ > rhs.size_)
-  {
-    x = this;
-    y = &rhs;
-  }
-  else
-  {
-    x = &rhs;
-    y = this;
-  }
-
-  grow_capacity(x->size_ + 1);
-
-  digit_type carry = ops_type::add_digits(digits_,
-                                          x->digits_,
-                                          y->digits_, y->size_);
-
-  size_type n = ops_type::ripple_carry(digits_ + y->size_,
-                                       x->digits_ + y->size_,
-                                       x->size_ - y->size_, carry);
-  n += y->size_;
-
-  if (n < x->size_) // this implies that there is no carry left
-  {
-    if (x != this)
-    {
-      std::memcpy(digits_ + n, x->digits_ + n, sizeof(digit_type) * (x->size_ - n));
-      size_ = x->size_;
-    }
-    return;
-  }
-  else if (carry) // at this point n equals x->size_
-    digits_[n++] = carry;
-
-  size_ = n;
-}
-
Copied: sandbox/mp_math/boost/mp_math/integer/contexts.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/modpow_ctx.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/modpow_ctx.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/contexts.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,181 +1,18 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2009.
 // 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_MP_MATH_MP_INT_MODPOW_CTX_HPP
-#define BOOST_MP_MATH_MP_INT_MODPOW_CTX_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
+#ifndef BOOST_MP_MATH_INTEGER_CONTEXTS_HPP
+#define BOOST_MP_MATH_INTEGER_CONTEXTS_HPP
 
 namespace boost {
 namespace mp_math {
 
 
-// r = x mod m given x and m
-template<class A, class T>
+template<class ApInt>
 struct modpow_ctx
-{
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  typedef typename mp_int<A,T>::word_type  word_type;
-  typedef typename mp_int<A,T>::size_type  size_type;
-
-  // dr means diminished radix
-  enum modulus_type_t
-  {                           // R is our radix, i.e. digit_max
-    mod_restricted_dr,        // m = R**k - d; d <= R
-    mod_unrestricted_dr,      // m = 2**k - d; d <= R
-    mod_unrestricted_dr_slow, // m = 2**k - d; d <  d**(k/2)
-    mod_odd,
-    mod_generic
-  }modulus_type;
-
-  modpow_ctx() : precalculated(false){}
-
-  modulus_type_t do_detect(const mp_int<A,T>& m) const;
-
-  void detect_modulus_type(const mp_int<A,T>& m)
-  {
-    modulus_type = do_detect(m);
-  }
-  
-  void precalculate(const mp_int<A,T>& m);
-
-  mp_int<A,T> mu;
-  digit_type rho;
-  bool precalculated;
-};
-
-
-template<class A, class T>
-typename modpow_ctx<A,T>::modulus_type_t
-modpow_ctx<A,T>::do_detect(const mp_int<A,T>& m) const
-{
-  if (m.size() == 1)
-    return mod_unrestricted_dr;
-
-  typename mp_int<A,T>::size_type count = 0;
-
-  const int bits = m.precision() % mp_int<A,T>::valid_bits;
-  
-  if (!bits && m[m.size()-1] == mp_int<A,T>::digit_max)
-    ++count;
-
-  for (typename mp_int<A,T>::const_reverse_iterator d = m.rbegin() + 1;
-       d != m.rend(); ++d)
-  {
-    if (*d != mp_int<A,T>::digit_max)
-      break;
-    else
-      ++count;
-  }
-
-  // if all bits are set
-  if (count == m.size() - 1)
-    return mod_restricted_dr;
-  
-  // if all bits until the most significant digit are set
-  if (count == m.size() - 2)
-  {
-    bool all_bits_set = true;
-    
-    // handle the remaining bits in the most significant digit
-    typename mp_int<A,T>::digit_type mask = 1;
-    for (int i = 0; i < bits; ++i)
-    {
-      if ((m[m.size()-1] & mask) == 0)
-      {
-        all_bits_set = false;
-        break;
-      }
-      mask <<= 1;
-    }
-    if (all_bits_set)
-      return mod_unrestricted_dr;
-  }
-
-  // if more than half of the bits are set
-  if (count >= m.size() / 2)
-    return mod_unrestricted_dr_slow;
-
-  if (m.is_odd())
-    return mod_odd;
-
-  return mod_generic;
-}
-
-template<class A, class T>
-void modpow_ctx<A,T>::precalculate(const mp_int<A,T>& m)
-{
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  typedef typename mp_int<A,T>::word_type  word_type;
-
-  switch (modulus_type)
-  {
-    case mod_restricted_dr:
-    {
-      rho = (word_type(1) << static_cast<word_type>(mp_int<A,T>::valid_bits))
-          - static_cast<word_type>(m[0]);
-      break;
-    }
-    case mod_unrestricted_dr:
-    {
-      const size_type p = m.precision();
-
-      mp_int<A,T> tmp;
-      tmp.pow2(p);
-      tmp.sub_smaller_magnitude(m);
-
-      rho = tmp[0];
-      break;
-    }
-    case mod_unrestricted_dr_slow:
-    {
-      mp_int<A,T> tmp;
-
-      tmp.pow2(m.precision());
-      mu = tmp - m;
-      break;
-    }
-    case mod_odd:
-    {
-      assert(m.is_odd());
-
-      // fast inversion mod 2**k
-      //
-      // Based on the fact that
-      //
-      // XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
-      //                    =>  2*X*A - X*X*A*A = 1
-      //                    =>  2*(1) - (1)     = 1
-      const digit_type b = m[0];
-
-      static const typename mp_int<A,T>::size_type S = 
-        sizeof(digit_type) * std::numeric_limits<unsigned char>::digits;
-
-      digit_type x = (((b + 2) & 4) << 1) + b; // here x*a==1 mod 2**4
-      x *= 2 - b * x;                          // here x*a==1 mod 2**8
-      if (S != 8)
-        x *= 2 - b * x;                        // here x*a==1 mod 2**16
-      if (S == 64 || !(S == 8 || S == 16))
-        x *= 2 - b * x;                        // here x*a==1 mod 2**32
-      if (S == 64)
-        x *= 2 - b * x;                        // here x*a==1 mod 2**64
-
-      // rho = -1/m mod b
-      rho = (word_type(1) << (static_cast<word_type>(mp_int<A,T>::valid_bits))) - x;
-      break;
-    }
-    case mod_generic:
-    {
-      // mu = b**2k/m
-      mu.pow2(m.size() * 2 * mp_int<A,T>::digit_bits);
-      mu /= m;
-      break;
-    }
-  }
-  precalculated = true;
-}
+{};
 
 
 } // namespace mp_math
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/ctors.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/ctors.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,272 +0,0 @@
-// Copyright Kevin Sopp 2008 - 2009.
-// 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)
-
-template<class A, class T>
-mp_int<A,T>::mp_int()
-:
-  digits_(0),
-  size_(0),
-  capacity_(0)
-{
-}
-
-template<class A, class T>
-mp_int<A,T>::mp_int(const allocator_type& a)
-:
-  base_allocator_type(a),
-  digits_(0),
-  size_(0),
-  capacity_(0)
-{
-}
-
-template<class A, class T>
-template<typename IntegralT>
-mp_int<A,T>::mp_int(
-    IntegralT b,
-    const allocator_type& a,
-    typename enable_if<is_integral<IntegralT> >::type*)
-:
-  base_allocator_type(a),
-  digits_(0),
-  size_(0),
-  capacity_(0)
-{
-  detail::integral_ops<IntegralT>::assign(*this, b);
-}
-
-template<class A, class T>
-template<typename RandomAccessIterator>
-void mp_int<A,T>::init(RandomAccessIterator c, RandomAccessIterator last)
-{
-  assert(size_ == 0);
-
-  if (c == last)
-  {
-    set_sign(1);
-    return;
-  }
-
-  int sign;
-
-  if (*c == '-')
-  {
-    ++c;
-    sign = -1;
-  }
-  else
-  {
-    if (*c == '+')
-      ++c;
-    sign = 1;
-  }
-
-  // detect the radix
-  unsigned int radix;
-
-  if (c != last)
-  {
-    if (*c == '0') // octal
-    {
-      ++c;
-      if (c != last && (*c == 'x' || *c == 'X')) // hex
-      {
-        radix = 16;
-        ++c;
-      }
-      else
-      {
-        radix = 8;
-        --c; // keep the zero, necessary for mp_int("0")
-      }
-    }
-    else // decimal
-      radix = 10;
-  }
-  else
-    throw std::invalid_argument("mp_int ctor: malformed string");
-
-  set_sign(sign);
-
-  from_string(c, last, radix);
-}
-
-template<class A, class T>
-template<typename RandomAccessIterator>
-void mp_int<A,T>::init(RandomAccessIterator c,
-                       RandomAccessIterator last,
-                       std::ios_base::fmtflags f)
-{
-  assert(size_ == 0);
-
-  if (c == last)
-  {
-    set_sign(1);
-    return;
-  }
-
-  if (*c == '-')
-  {
-    set_sign(-1);
-    ++c;
-  }
-  else
-  {
-    if (f & std::ios_base::showpos)
-    {
-      if (*c == '+')
-        ++c;
-      else
-        throw std::invalid_argument("mp_int<>::init: expected a '+' sign");
-    }
-    set_sign(1);
-  }
-
-  const bool uppercase = f & std::ios_base::uppercase;
-  const bool showbase  = f & std::ios_base::showbase;
-
-  bool bad_prefix = false;
-  unsigned radix;
-
-  if (f & std::ios_base::hex)
-  {
-    if (showbase)
-    {
-      if (*c == '0')
-        ++c;
-      else
-        bad_prefix = true;
-      if (*c == 'x' || (*c == 'X' && uppercase))
-        ++c;
-      else
-        bad_prefix = true;
-    }
-    radix = 16;
-  }
-  else if (f & std::ios_base::oct)
-  {
-    if (showbase)
-    {
-      if (*c == '0')
-        ++c;
-      else
-        bad_prefix = true;
-    }
-    radix = 8;
-  }
-  else if (f & std::ios_base::dec)
-    radix = 10;
-  else
-    throw std::invalid_argument("mp_int<>::init: unknown radix");
-
-  if (bad_prefix)
-    throw std::invalid_argument("mp_int<>::init: bad radix prefix");
-
-  from_string(c, last, radix);
-}
-
-
-template<class A, class T>
-template<typename RandomAccessIterator>
-mp_int<A,T>::mp_int(RandomAccessIterator first,
-                    RandomAccessIterator last,
-                    const allocator_type& a)
-:
-  base_allocator_type(a),
-  digits_(0),
-  size_(0),
-  capacity_(0)
-{
-  init(first, last);
-}
-
-template<class A, class T>
-template<typename charT>
-mp_int<A,T>::mp_int(const charT* s, const allocator_type& a)
-:
-  base_allocator_type(a),
-  digits_(0),
-  size_(0),
-  capacity_(0)
-{
-  init(s, s + std::char_traits<charT>::length(s));
-}
-
-template<class A, class T>
-template<typename charT>
-mp_int<A,T>::mp_int(const charT* s,
-                    std::ios_base::fmtflags f,
-                    const allocator_type& a)
-:
-  base_allocator_type(a),
-  digits_(0),
-  size_(0),
-  capacity_(0)
-{
-  init(s, s + std::char_traits<charT>::length(s), f);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-mp_int<A,T>::mp_int(const std::basic_string<charT,traits,Alloc>& s,
-                    const allocator_type& a)
-:
-  base_allocator_type(a),
-  digits_(0),
-  size_(0),
-  capacity_(0)
-{
-  init(s.begin(), s.end());
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-mp_int<A,T>::mp_int(const std::basic_string<charT,traits,Alloc>& s,
-                    std::ios_base::fmtflags f,
-                    const allocator_type& a)
-:
-  base_allocator_type(a),
-  digits_(0),
-  size_(0),
-  capacity_(0)
-{
-  init(s.begin(), s.end(), f);
-}
-
-
-template<class A, class T>
-mp_int<A,T>::mp_int(const mp_int& copy)
-:
-  base_allocator_type(copy.get_allocator())
-{
-  digits_ = this->allocate(copy.size_);
-  std::memcpy(digits_, copy.digits_, copy.size_ * sizeof(digit_type));
-  size_ = copy.size_;
-  set_capacity(copy.size_);
-  set_sign(copy.sign());
-}
-
-#ifdef BOOST_HAS_RVALUE_REFS
-template<class A, class T>
-mp_int<A,T>::mp_int(mp_int&& copy)
-:
-  digits_(copy.digits_),
-  size_(copy.size_),
-  capacity_(copy.capacity_) // this copies capacity and sign
-{
-  copy.digits_ = 0;
-  copy.size_ = 0;
-  copy.capacity_ = 0;
-}
-#endif
-
-
-template<class A, class T>
-mp_int<A,T>::~mp_int()
-{
-  if (digits_)
-    this->deallocate(digits_, capacity());
-}
-
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/adder.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/adder.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,87 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_ADDER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_ADDER_HPP
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+
+template<class ApInt>
+struct adder
+{
+  typedef typename ApInt::traits_type      traits_type;
+  typedef typename traits_type::digit_type digit_type;
+  typedef typename traits_type::size_type  size_type;
+  typedef typename traits_type::ops_type   ops_type;
+
+  static void add_smaller_magnitude(ApInt& z,
+                                    const ApInt& x, const ApInt& y);
+
+  static void subtract_smaller_magnitude(ApInt& z, const ApInt& x);
+  static void subtract_smaller_magnitude(ApInt& z,
+                                         const ApInt& x, const ApInt& y);
+};
+
+
+template<class ApInt>
+void adder<ApInt>::add_smaller_magnitude(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  assert(x.size() >= y.size());
+
+  digit_type carry = ops_type::add_digits(z.digits(),
+                                          x.digits(),
+                                          y.digits(), y.size());
+
+  size_type n = ops_type::ripple_carry(z.digits() + y.size(),
+                                       x.digits() + y.size(),
+                                       x.size() - y.size(), carry);
+  n += y.size();
+
+  if (n < x.size()) // this implies that there is no carry left
+  {
+    if (&x != &z)
+    {
+      std::memcpy(z.digits() + n,
+                  x.digits() + n,
+                  sizeof(digit_type) * (x.size() - n));
+      z.set_size(x.size());
+    }
+    return;
+  }
+  else if (carry) // at this point n equals x.size()
+    z[n++] = carry;
+
+  z.set_size(n);
+}
+
+template<class ApInt>
+void adder<ApInt>::subtract_smaller_magnitude(ApInt& z, const ApInt& x)
+{
+  ApInt::traits_type::ops_type::sub_smaller_magnitude(
+      z.digits(), z.digits(), z.size(), x.digits(), x.size());
+
+  z.clamp();
+}
+
+template<class ApInt>
+void adder<ApInt>::subtract_smaller_magnitude(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  ApInt::traits_type::ops_type::sub_smaller_magnitude(
+      z.digits(), x.digits(), x.size(), y.digits(), y.size());
+
+  z.clamp();
+}
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
Modified: sandbox/mp_math/boost/mp_math/integer/detail/base/asm/asm/x86/gnu_386_primitive_ops.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/asm/x86/gnu_386_primitive_ops.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/asm/asm/x86/gnu_386_primitive_ops.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,25 +1,27 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
 
-template
-struct primitive_ops<unsigned int, unsigned int, std::size_t>
+template<>
+struct primitive_ops<unsigned int, unsigned int, unsigned int>
+:
+  basic_primitive_ops<unsigned int,unsigned int,unsigned int>
 {
   typedef unsigned int dword;
-  static unsigned int add_digits(dword* dst, const dword* y, std::size_t n);
-  static unsigned int subtract_digits(dword* dst, const dword* y, std::size_t n);
+  static unsigned int add_digits     (dword* x, const dword* y, dword n);
+  static unsigned int subtract_digits(dword* x, const dword* y, dword n);
 };
 
 
-template
+template<>
 inline
 unsigned int
-primitive_ops<unsigned int, unsigned int, std::size_t>::
-add_digits(unsigned int* x, const unsigned int* y, std::size_t n)
+primitive_ops<unsigned int, unsigned int, unsigned int>::
+add_digits(dword* x, const dword* y, dword n)
 {
-  unsigned int carry = 0;
- 
+  dword carry = 0;
+
   __asm__ __volatile__(
       "clc                \n\t"
     "0:                   \n\t"
@@ -42,14 +44,13 @@
   return carry;
 }
 
-
-template
+template<>
 inline
 unsigned int
-primitive_ops<unsigned int, unsigned int, std::size_t>::
-subtract_digits(unsigned int* x, const unsigned int* y, std::size_t n)
+primitive_ops<unsigned int, unsigned int, unsigned int>::
+subtract_digits(dword* x, const dword* y, dword n)
 {
-  unsigned int carry = 0;
+  dword carry = 0;
 
   __asm__ __volatile__(
       "clc                \n\t"
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/bitmanipulator.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/bitmanipulator.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,171 @@
+// Copyright Kevin Sopp 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_BITMANIPULATOR_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_BITMANIPULATOR_HPP
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+
+template<
+  class ApInt1,
+  class ApInt2,
+  int Cmp = ApInt1::traits_type::radix_bits < ApInt2::traits_type::radix_bits ? -1
+          : ApInt1::traits_type::radix_bits > ApInt2::traits_type::radix_bits ? : 1
+          : 0
+>
+struct bit_copier;
+
+
+template<class ApInt1, class ApInt2>
+struct bit_copier<ApInt1, ApInt2, -1>
+{
+  typedef typename ApInt1::size_type size_type1;
+  typedef typename ApInt2::size_type size_type2;
+  typedef typename ApInt1::digit_type digit_type1;
+  typedef typename ApInt2::digit_type digit_type2;
+
+  static const unsigned radix_bits1 = ApInt1::traits_type::radix_bits;
+  static const unsigned radix_bits2 = ApInt2::traits_type::radix_bits;
+
+  static void copy_bits(ApInt1&       dst, size_type1 dst_offset,
+                        const ApInt2& src, size_type2 src_offset, size_type1 n);
+};
+
+
+template<class ApInt1, class ApInt2>
+struct bit_copier<ApInt1, ApInt2, 1>
+{
+  typedef typename ApInt1::size_type size_type1;
+  typedef typename ApInt2::size_type size_type2;
+  typedef typename ApInt1::digit_type digit_type1;
+  typedef typename ApInt2::digit_type digit_type2;
+
+  static const unsigned radix_bits1 = ApInt1::traits_type::radix_bits;
+  static const unsigned radix_bits2 = ApInt2::traits_type::radix_bits;
+
+  static void copy_bits(ApInt1&       dst, size_type1 dst_offset,
+                        const ApInt2& src, size_type2 src_offset, size_type1 n);
+};
+
+
+template<class ApInt1, class ApInt2>
+struct bit_copier<ApInt1, ApInt2, 0>
+{
+  typedef typename ApInt1::size_type size_type1;
+  typedef typename ApInt2::size_type size_type2;
+  typedef typename ApInt1::digit_type digit_type1;
+  typedef typename ApInt2::digit_type digit_type2;
+
+  static const digit_type1 z1 = ~digit_type1(0);
+  static const digit_type2 z2 = ~digit_type2(0);
+  static const unsigned radix_bits = ApInt1::traits_type::radix_bits;
+
+  static void copy_bits(ApInt1&       dst, size_type1 dst_offset,
+                        const ApInt2& src, size_type2 src_offset, size_type1 n);
+};
+
+
+template<class ApInt1, class ApInt2>
+void bit_copier<ApInt1, ApInt2, 0>::copy_bits(
+    ApInt1&       dst, size_type1 dst_offset,
+    const ApInt2& src, size_type2 src_offset, size_type1 num)
+{
+  if (!num)
+    return;
+
+  const size_type1 q1 = dst_offset / radix_bits;
+  const size_type1 r1 = dst_offset % radix_bits;
+  const size_type2 q2 = src_offset / radix_bits;
+  const size_type2 r2 = src_offset % radix_bits;
+
+  const digit_type1 r1_inv = radix_bits - r1;
+  const digit_type2 r2_inv = radix_bits - r2;
+
+  digit_type1* d       = dst.digits() + q1;
+  const digit_type2* s = src.digits() + q2;
+
+  // If the offset into the first destination digit is not zero, i.e. r1 ==
+  // true, then we fill it up manually (normalize it) and then start the
+  // normalized copy loop.
+  if (!r1)
+  {
+    if (!r2)
+    {
+      const size_type1 num_digits = (num + (radix_bits - 1)) / radix_bits;
+      std::memcpy(d, s, num_digits * sizeof(digit_type2));
+      return;
+    }
+    else
+      goto normalized_bitcopy;
+  }
+  else
+  {
+    if (num < r1_inv)
+    {
+      *d &= (z1 >> r1_inv) | (z1 << (r1_inv + num));
+      *d |= ((*s >> r2) & ~(z2 << num)) << r1;
+      return;
+    }
+    else
+    {
+      *d &= ~(z1 << r1);
+
+      if (num < r2_inv)
+      {
+        *d |= ((*s >> r2) & ~(z2 << num)) << r1;
+        return;
+      }
+      else
+      {
+        *d |= (*s >> r2) << r1;
+        ++s;
+        num -= r2_inv;
+        *d |= (*s & ~(z2 << (radix_bits - num))) << (r1 + r2_inv);
+        goto normalized_bitcopy;
+      }
+    }
+  }
+
+normalized_bitcopy:
+
+  // fill one whole destination digit per iteration
+  while (num >= radix_bits)
+  {
+    *d = *s >> r2;
+    ++s;
+    *d |= *s << r2_inv;
+    ++d;
+    num -= radix_bits;
+  }
+
+  // copy remaining bits manually
+  if (num)
+  {
+    *d &= ~(z1 >> (radix_bits - num));
+
+    if (num < r2_inv)
+      *d |= (*s >> r2) & ~(z2 << num);
+    else
+    {
+      *d |= (*s >> r2);
+      ++s;
+      num -= r2;
+      *d |= (*s & (z2 >> (radix_bits - num))) << r2;
+    }
+  }
+}
+
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/bitwise_ops.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/bitwise_ops.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,148 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_BITWISE_OPS_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_BITWISE_OPS_HPP
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+
+template<class ApInt, bool IsSigned = ApInt::is_signed>
+struct bitwise_ops;
+
+
+template<class ApInt>
+struct bitwise_ops<ApInt,false>
+{
+  typedef typename ApInt::traits_type::digit_type digit_type;
+  typedef typename ApInt::traits_type::size_type  size_type;
+
+  static void or_bits (ApInt& z, const ApInt& x, const ApInt& y);
+  static void and_bits(ApInt& z, const ApInt& x, const ApInt& y);
+  static void xor_bits(ApInt& z, const ApInt& x, const ApInt& y);
+  static void compl_bits(ApInt& z, const ApInt& x);
+};
+
+
+template<class ApInt>
+void
+bitwise_ops<ApInt,false>::or_bits(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  if (x.size() < y.size())
+  {
+    std::memcpy(z.digits() + x.size(),
+                y.digits() + x.size(),
+                (y.size() - x.size()) * sizeof(digit_type));
+    z.set_size(y.size());
+  }
+
+  for (size_type i = 0; i < std::min(x.size(), y.size()); ++i)
+    z[i] = x[i] | y[i];
+}
+
+template<class ApInt>
+void
+bitwise_ops<ApInt,false>::and_bits(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  const size_type m = std::min(x.size(), y.size());
+
+  for (size_type i = 0; i < m; ++i)
+    z[i] = z[i] & y[i];
+
+  z.set_size(m);
+  z.clamp();
+}
+
+template<class ApInt>
+void
+bitwise_ops<ApInt,false>::xor_bits(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  const size_type m = std::min(x.size(), y.size());
+
+  if (x.size() < y.size())
+  {
+    std::memcpy(z.digits() + x.size(),
+                y.digits() + x.size(),
+                (y.size() - x.size()) * sizeof(digit_type));
+    z.set_size(y.size());
+  }
+
+  for (size_type i = 0; i < m; ++i)
+    z[i] = x[i] ^ y[i];
+
+  z.clamp();
+}
+
+template<class ApInt>
+void
+bitwise_ops<ApInt,false>::compl_bits(ApInt& z, const ApInt& x)
+{
+  size_type i = 0;
+  for (; i < x.size() - 1; ++i)
+    z[i] = ~x[i];
+
+  unsigned count = 0;
+  digit_type bit = digit_type(1) << (ApInt::traits_type::radix_bits - 1);
+
+  if (x[i])
+    while (!(x[i] & bit))
+    {
+      bit >>= 1;
+      ++count;
+      if (count > 40)
+        break;
+    }
+  else
+    count = ApInt::traits_type::radix_bits - 1;
+
+  digit_type mask = ~digit_type(0);
+  mask >>= count;
+  z[i] = ~x[i] & mask;
+
+  z.set_size(x.size());
+  z.clamp_high_digit();
+}
+
+
+template<class ApInt>
+struct bitwise_ops<ApInt,true>
+{
+  static void or_bits (ApInt& z, const ApInt& x, const ApInt& y)
+  {
+    bitwise_ops<ApInt,false>::or_bits(z, x, y);
+    z.set_sign_bit(x.sign_bit() | y.sign_bit());
+  }
+
+  static void and_bits(ApInt& z, const ApInt& x, const ApInt& y)
+  {
+    bitwise_ops<ApInt,false>::and_bits(z, x, y);
+    z.set_sign_bit(x.sign_bit() & y.sign_bit());
+  }
+
+  static void xor_bits(ApInt& z, const ApInt& x, const ApInt& y)
+  {
+    bitwise_ops<ApInt,false>::xor_bits(z, x, y);
+    z.set_sign_bit(x.sign_bit() ^ y.sign_bit());
+  }
+
+  static void compl_bits(ApInt& z, const ApInt& x)
+  {
+    bitwise_ops<ApInt,false>::compl_bits(z, x);
+    z.set_sign_bit(z && x.is_positive() ? 1 : 0);
+  }
+};
+
+
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/divider.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/divider.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,105 @@
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_DIVIDER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_DIVIDER_HPP
+
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+
+template<class ApInt>
+struct divider
+{
+  typedef typename ApInt::traits_type traits_type;
+  typedef typename ApInt::digit_type  digit_type;
+  typedef typename ApInt::size_type   size_type;
+
+  // z = z % 2^n
+  static void modulo_pow2(ApInt& z, size_type n);
+  static void divide_by_2(ApInt& z);
+  static void divide_by_3(ApInt& z);
+};
+
+
+template<class ApInt>
+void divider<ApInt>::modulo_pow2(ApInt& z, size_type n)
+{
+  // if modulus >= z then return
+  if (n >= z.size() * traits_type::radix_bits)
+    return;
+
+  // clear high bits
+  const digit_type mask =
+    (1 << (static_cast<digit_type>(n % traits_type::radix_bits))) - 1;
+
+  z[n / traits_type::radix_bits] &= mask;
+
+  z.set_size(n / traits_type::radix_bits + 1);
+  // TODO was z.clamp() hope it is correct now with the +1! check again!
+
+  z.clamp();
+  // TODO if (!z) z.set_sign_bit(0) is necessary here
+}
+
+template<class ApInt>
+inline void divider<ApInt>::divide_by_2(ApInt& z)
+{
+  traits_type::ops_type::divide_by_two(z.digits(), z.digits(), z.size());
+
+  z.clamp_high_digit();
+}
+
+// divide by three (based on routine from MPI and the GMP manual)
+template<class ApInt>
+inline void divider<ApInt>::divide_by_3(ApInt& z)
+{
+  typedef typename traits_type::word_type word_type;
+
+  // b = 2^radix_bits / 3
+  static const word_type b = (word_type(1) << traits_type::radix_bits) / 3;
+
+  word_type w = 0;
+  for (typename ApInt::reverse_iterator d = z.rbegin(); d != z.rend(); ++d)
+  {
+    w = (w << static_cast<word_type>(traits_type::radix_bits))
+      | static_cast<word_type>(*d);
+
+    word_type t;
+    if (w >= 3U)
+    {
+      // multiply w by [1/3]
+      t = (w * b) >> static_cast<word_type>(traits_type::radix_bits);
+
+      // now subtract 3 * [w/3] from w, to get the remainder
+      w -= t+t+t;
+
+      // fixup the remainder as required since the optimization is not exact.
+      while (w >= 3U)
+      {
+        t += 1;
+        w -= 3;
+      }
+    }
+    else
+      t = 0;
+
+    *d = static_cast<digit_type>(t);
+  }
+
+  z.clamp(); // TODO clamp_high_digit should suffice
+}
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/from_integral.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/from_integral.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,191 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_FROM_INTEGRAL_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_FROM_INTEGRAL_HPP
+
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+
+template<
+  class ApInt,
+  typename IntegralT,
+  bool ApIntIsSigned = ApInt::is_signed,
+  bool IsSigned = std::numeric_limits<IntegralT>::is_signed,
+  bool fits_into_digit_type =
+    std::numeric_limits<IntegralT>::digits <=
+    std::numeric_limits<typename ApInt::digit_type>::digits
+    // TODO shouldn't we cmp against signed digit_type for signed integral types?
+>
+struct from_integral_converter;
+
+
+// Specializations for unsigned ApInts //
+/////////////////////////////////////////
+
+template<class ApInt, typename IntegralT>
+struct from_integral_converter<ApInt, IntegralT, false, false, true>
+{
+  static void convert(ApInt& z, IntegralT x)
+  {
+    z[0] = x;
+    z.set_size(1);
+  }
+};
+
+
+template<class ApInt, typename IntegralT>
+struct from_integral_converter<ApInt, IntegralT, false, true, true>
+{
+  static void convert(ApInt& z, IntegralT x)
+  {
+    if (x >= 0)
+    {
+      z[0] = static_cast<typename ApInt::digit_type>(x);
+      z.set_size(1);
+    }
+    else
+      throw std::domain_error("from_integral_converter::convert: "
+          "cannot convert negative integral value to unsigned integer value");
+  }
+};
+
+
+template<class ApInt, typename IntegralT>
+struct from_integral_converter<ApInt, IntegralT, false, false, false>
+{
+  static void convert(ApInt& z, IntegralT x);
+};
+
+
+template<class ApInt, typename IntegralT>
+void from_integral_converter<ApInt, IntegralT, false, false, false>::
+convert(ApInt& z, IntegralT x)
+{
+  static const IntegralT mask = ~(~IntegralT(0) << ApInt::traits_type::radix_bits);
+
+  if (x == 0)
+  {
+    z[0] = 0;
+    z.set_size(1);
+    return;
+  }
+
+  typename ApInt::iterator z_iter = z.begin();
+  while (x)
+  {
+    *z_iter++ = static_cast<typename ApInt::digit_type>(x & mask);
+    x >>= ApInt::traits_type::radix_bits;
+  }
+
+  z.set_size(z_iter - z.begin());
+}
+
+
+template<class ApInt, typename IntegralT>
+struct from_integral_converter<ApInt, IntegralT, false, true, false>
+{
+  typedef typename make_unsigned<IntegralT>::type unsigned_integral_type;
+
+  static void convert(ApInt& z, IntegralT x)
+  {
+    if (x >= 0)
+      from_integral_converter<
+        ApInt, unsigned_integral_type
+      >::convert(z, static_cast<unsigned_integral_type>(x));
+    else
+      throw std::domain_error("from_integral_converter::convert: "
+          "cannot convert negative integral value to unsigned integer value");
+  }
+};
+
+
+// Specializations for signed ApInts //
+///////////////////////////////////////
+
+template<class ApInt, typename IntegralT>
+struct from_integral_converter<ApInt, IntegralT, true, false, true>
+{
+  static void convert(ApInt& z, IntegralT x)
+  {
+    z[0] = x;
+    z.set_size(1);
+    z.set_sign_bit(1);
+  }
+};
+
+
+template<class ApInt, typename IntegralT>
+struct from_integral_converter<ApInt, IntegralT, true, true, true>
+{
+  static void convert(ApInt& z, IntegralT x)
+  {
+    if (x >= 0)
+    {
+      z[0] = static_cast<typename ApInt::digit_type>(x);
+      z.set_sign_bit(0);
+    }
+    else
+    {
+      z[0] = static_cast<typename ApInt::digit_type>(-x);
+      z.set_sign_bit(1);
+    }
+    z.set_size(1);
+  }
+};
+
+
+template<class ApInt, typename IntegralT>
+struct from_integral_converter<ApInt, IntegralT, true, false, false>
+{
+  static void convert(ApInt& z, IntegralT x)
+  {
+    from_integral_converter<ApInt, IntegralT, false, false, false>::
+      convert(z, x);
+    z.set_sign_bit(0);
+  }
+};
+
+
+template<class ApInt, typename IntegralT>
+struct from_integral_converter<ApInt, IntegralT, true, true, false>
+{
+  typedef typename make_unsigned<IntegralT>::type unsigned_integral_type;
+
+  static void convert(ApInt& z, IntegralT x)
+  {
+    if (x >= 0)
+    {
+      from_integral_converter<
+        ApInt, unsigned_integral_type, false, true, false
+      >::convert(z, static_cast<unsigned_integral_type>(x));
+      z.set_sign_bit(0);
+    }
+    else
+    {
+      from_integral_converter<
+        ApInt, IntegralT, false, true, false
+      >::convert(z, static_cast<unsigned_integral_type>(-x));
+      z.set_sign_bit(1);
+    }
+  }
+};
+
+
+
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/multiplier.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/multiplier.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,108 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_MULTIPLIER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_MULTIPLIER_HPP
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+
+template<class ApInt>
+struct multiplier
+{
+  typedef ApInt                          int_type;
+  typedef typename int_type::digit_type  digit_type;
+  typedef typename int_type::traits_type traits_type;
+  typedef typename traits_type::ops_type ops_type;
+
+  static void multiply_or_square(ApInt& z, const ApInt& x, const ApInt& y);
+
+  static void mul      (ApInt& z, const ApInt& x, const ApInt& y);
+  static void comba_mul(ApInt& z, const ApInt& x, const ApInt& y);
+
+  static void comba_sqr(ApInt& z, const ApInt& x);
+};
+
+
+template<class ApInt>
+void
+multiplier<ApInt>::multiply_or_square(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  if (&x == &y)
+    comba_sqr(z, x);
+  else
+    mul(z, x, y);
+}
+
+template<class ApInt>
+void multiplier<ApInt>::mul(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  // always multiply larger by smaller number
+  const ApInt* a = &x;
+  const ApInt* b = &y;
+  if (a->size() < b->size())
+    std::swap(a, b);
+
+  if (b->size() == 1U)
+  {
+    if ((*b)[0] == 0U)
+    {
+      z[0] = 0;
+      z.set_size(1);
+      // TODO set_sign_bit(0) for signed ApInt!
+      return;
+    }
+    else if ((*b)[0] == 1U)
+    {
+      z = *a;
+      return;
+    }
+
+    ApInt::template integral_ops<digit_type>::multiply(z, *a, (*b)[0]);
+
+    return;
+  }
+
+  comba_mul(z, *a, *b);
+}
+
+template<class ApInt>
+void multiplier<ApInt>::comba_mul(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  // We assert this because otherwise we would need to call z.clamp() below.
+  assert(x);
+  assert(y);
+
+  if (x.size() == y.size())
+    ops_type::comba_mul(z.digits(), x.digits(), y.digits(), y.size());
+  else
+    ops_type::comba_mul(z.digits(), x.digits(), x.size(),
+                                    y.digits(), y.size());
+
+  z.set_size(x.size() + y.size());
+  z.clamp_high_digit();
+}
+
+template<class ApInt>
+void multiplier<ApInt>::comba_sqr(ApInt& z, const ApInt& x)
+{
+  ops_type::comba_sqr(z.digits(), x.digits(), x.size());
+
+  z.set_size(x.size() + x.size());
+
+  z.clamp_high_digit();
+}
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Copied: sandbox/mp_math/boost/mp_math/integer/detail/base/primitive_ops.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/detail/primitive_ops.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/primitive_ops.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/primitive_ops.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,19 +1,27 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_DETAIL_PRIMITIVE_OPS
-#define BOOST_MP_MATH_MP_INT_DETAIL_PRIMITIVE_OPS
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_BASE_PRIMITIVE_OPS
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_PRIMITIVE_OPS
+
+#include <cassert>
+#include <cstring>
+#include <algorithm>
+#include <boost/cstdint.hpp>
+#include <iostream>
 
 namespace boost {
 namespace mp_math {
 namespace detail {
+namespace base {
 
 
 // this struct contains some basic arithmetic algorithms
 // which can be implemented via assembly rather easily
 
+#ifdef BOOST_MP_MATH_PRIMITIVE_OPS_OLD
 template<typename DigitT, typename WordT, typename SizeT>
 struct basic_primitive_ops
 {
@@ -24,6 +32,15 @@
   static const word_type digit_bits = std::numeric_limits<digit_type>::digits;
 
   // ADD ------------------------------------
+  // z = x + y, returns carry
+  static digit_type add(digit_type& z, digit_type x, digit_type y);
+  // z += x, returns carry
+  static digit_type add(digit_type& z, digit_type x);
+  // z += x * y, returns carry
+  static digit_type multiply_add(digit_type& z_hi, digit_type& z_lo,
+                                 digit_type x, digit_type y);
+  // z = x * y, returns high part of the product
+  static digit_type mul(digit_type& z, digit_type x, digit_type y);
 
   // add y to the digits in x and store result in z
   // xlen must be > 0
@@ -102,6 +119,24 @@
                         const digit_type* x,
                         const digit_type* y, size_type xylen);
 
+  // z = x * y; precondition: xlen >= ylen and workspace must have at least ylen
+  // digits this function is only used by the integral ops interaction code, it
+  // allows x and z to be the same pointer.
+  static void comba_mul(digit_type* z, const digit_type* x, size_type xlen,
+                                       const digit_type* y, size_type ylen,
+                                       digit_type* workspace);
+
+  // computes the lower num digits of the product of x and y
+  static void comba_mul_lo(digit_type* z, const digit_type* x, size_type xlen,
+                                          const digit_type* y, size_type ylen,
+                                          size_type num);
+
+  // computes the high product of x and y without num least significant digits
+  // basically the result is: z = (x*y) >> radix^num
+  static void comba_mul_hi(digit_type* z, const digit_type* x, size_type xlen,
+                                          const digit_type* y, size_type ylen,
+                                          size_type num);
+
   // SQR ------------------------------------
 
   // z = x * x;
@@ -109,11 +144,10 @@
 
   // MADD ------------------------------------
 
-  // z = w * x + y
+  // z = z + x * y
   static digit_type multiply_add_digits(digit_type* z,
-                                        const digit_type* w,
-                                        digit_type x,
-                                        const digit_type* y,
+                                        const digit_type* x,
+                                        digit_type y,
                                         size_type n);
 
   // DIV -------------------------------------
@@ -126,12 +160,109 @@
   static digit_type divide_by_digit(digit_type* z,
                                     const digit_type* x, size_type xlen,
                                     digit_type y);
+
+  // q = x/y, r = x%y; workspace must have length of ylen + 1
+  static void divide(digit_type* q, digit_type* r,
+                     const digit_type* x, size_type xlen,
+                     const digit_type* y, size_type ylen,
+                     digit_type* workspace);
+
+  // SHIFT -----------------------------------
+
+  // shifts x by n bits to the left, where n > 0 && n < digit_bits
+  // returns carry
+  static digit_type shift_bits_left(digit_type* x, size_type xlen, size_type n);
+
+  // shifts x by n bits to the right, where n > 0 && n < digit_bits
+  static void shift_bits_right(digit_type* x, size_type xlen, size_type n);
+
+  // CMP -------------------------------------
+
+  // returns  1 if x  > y
+  // returns  0 if x == y
+  // returns -1 if x  < y
+  static int compare_magnitude(const digit_type* x, size_type xlen,
+                               const digit_type* y, size_type ylen);
 };
 
 
 
 template<typename D, typename W, typename S>
 inline
+D basic_primitive_ops<D,W,S>::add(digit_type& z, digit_type x, digit_type y)
+{
+  z = x + y;
+  return z < x;
+}
+
+template<typename D, typename W, typename S>
+inline
+D basic_primitive_ops<D,W,S>::add(digit_type& z, digit_type x)
+{
+  z += x;
+  return z < x;
+}
+
+template<typename D, typename W, typename S>
+inline
+D basic_primitive_ops<D,W,S>::multiply_add(digit_type& z_hi, digit_type& z_lo,
+                                           digit_type x, digit_type y)
+{
+  static const digit_type lo_mask = (1 << digit_bits / 2) - 1;
+
+  const digit_type x_lo = x & lo_mask;
+  const digit_type x_hi = x >> digit_bits/2;
+  const digit_type y_lo = y & lo_mask;
+  const digit_type y_hi = y >> digit_bits/2;
+
+  const digit_type z0 = x_lo * y_lo;
+  const digit_type z1 = x_lo * y_hi;
+  const digit_type z2 = x_hi * y_lo;
+  const digit_type z3 = x_hi * y_hi;
+
+  digit_type z12 = z1 + (z0 >> digit_bits/2);
+  const digit_type carry = add(z12, z2);
+
+  const digit_type w_lo = (z12 << digit_bits/2) + (z0 & lo_mask);
+  const digit_type w_hi = z3 + (carry << digit_bits/2) + (z12 >> digit_bits/2);
+
+  digit_type u = add(z_lo, w_lo);
+  digit_type v = add(z_hi, u);
+
+  return v + add(z_hi, w_hi);
+}
+
+template<typename D, typename W, typename S>
+inline
+D basic_primitive_ops<D,W,S>::mul(digit_type& z_lo, digit_type x, digit_type y)
+{
+  static const digit_type lo_mask = (1 << digit_bits / 2) - 1;
+  static const digit_type hi_mask = lo_mask << (digit_bits / 2);
+
+  const digit_type x_lo = x & lo_mask;
+  const digit_type x_hi = x & hi_mask;
+  const digit_type y_lo = y & lo_mask;
+  const digit_type y_hi = y & hi_mask;
+
+  // do a normal school multiplication on the 'half digits'
+  const digit_type z0 = x_lo * y_lo;
+  const digit_type z1 = x_lo * y_hi;
+  const digit_type z2 = x_hi * y_lo;
+  const digit_type z3 = x_hi * y_hi;
+
+  digit_type z12 = z1 + (z0 & hi_mask);
+  const digit_type carry = add(z12, z2);
+
+  z_lo = (z12 << digit_bits/2) | (z0 & lo_mask);
+
+  const digit_type z_hi = z3 + (carry << digit_bits/2) + (z12 & hi_mask);
+
+  return z_hi;
+}
+
+//////////////////////////////////////////////////////////////
+template<typename D, typename W, typename S>
+inline
 D basic_primitive_ops<D,W,S>::add_single_digit(digit_type* z,
                                                const digit_type* x,
                                                size_type xlen,
@@ -397,58 +528,67 @@
 {
   assert(xlen >= ylen);
 
-  word_type acc = 0;  // accumulator for each column
-  word_type carry = 0;
+  // instead of initializing acc and carry with zero and entering the loop below
+  // we manually calculate the first low digit of the result here
+  // acc is the accumulator for each column
+  word_type acc = static_cast<word_type>(*x) * static_cast<word_type>(*y++);
+  word_type carry = acc >> digit_bits;
+  acc = static_cast<digit_type>(acc);
+  *z++ = static_cast<digit_type>(acc);
+  acc = static_cast<digit_type>(carry);
+  carry >>= digit_bits;
 
   // phase 1
-  for (size_type i = 0; i < ylen; ++i)
+  for (size_type i = 1; i < ylen; ++i)
   {
-    const digit_type* a = x;
-    const digit_type* b = y + i;
-
     for (size_type j = 0; j <= i; ++j)
     {
-      acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
+      acc += static_cast<word_type>(*x++) * static_cast<word_type>(*y--);
       carry += acc >> digit_bits;
       acc = static_cast<digit_type>(acc);
     }
 
+    x -= i + 1;
+    y += i + 2;
     *z++ = static_cast<digit_type>(acc);
     acc  = static_cast<digit_type>(carry);
     carry >>= digit_bits;
   }
 
   // phase 2
+  --y; // now y is at index ylen - 1
   for (size_type i = 0; i < xlen - ylen; ++i)
   {
-    const digit_type* a = x + ylen + i;
-    const digit_type* b = y;
+    ++x;
 
     for (size_type j = 0; j < ylen; ++j)
     {
-      acc += static_cast<word_type>(*a--) * static_cast<word_type>(*b++);
+      acc += static_cast<word_type>(*x++) * static_cast<word_type>(*y--);
       carry += acc >> digit_bits;
       acc = static_cast<digit_type>(acc);
     }
 
+    x -= ylen;
+    y += ylen;
     *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
+    acc  = static_cast<digit_type>(carry);
     carry >>= digit_bits;
   }
 
   // phase 3
   for (size_type i = 0; i < ylen - 1; ++i)
   {
-    const digit_type* a = x + xlen - 1;
-    const digit_type* b = y + i + 1;
+    ++x;
 
     for (size_type j = i + 1; j < ylen; ++j)
     {
-      acc += static_cast<word_type>(*a--) * static_cast<word_type>(*b++);
+      acc += static_cast<word_type>(*x++) * static_cast<word_type>(*y--);
       carry += acc >> digit_bits;
       acc = static_cast<digit_type>(acc);
     }
 
+    x -= ylen - 1 - i;
+    y += ylen - 1 - i;
     *z++ = static_cast<digit_type>(acc);
     acc  = static_cast<digit_type>(carry);
     carry >>= digit_bits;
@@ -463,11 +603,68 @@
                                       const digit_type* x,
                                       const digit_type* y, size_type xylen)
 {
+  // phase 1
+  // instead of initializing acc and carry with zero and entering the loop below
+  // we manually calculate the first low digit of the result here
+  word_type acc = static_cast<word_type>(*x) * static_cast<word_type>(*y++);
+  word_type carry = acc >> digit_bits;
+  acc = static_cast<digit_type>(acc);
+  *z++ = static_cast<digit_type>(acc);
+  acc = static_cast<digit_type>(carry);
+  carry >>= digit_bits;
+
+  for (size_type i = 1; i < xylen; ++i)
+  {
+    for (size_type j = 0; j <= i; ++j)
+    {
+      acc += static_cast<word_type>(*x++) * static_cast<word_type>(*y--);
+      carry += acc >> digit_bits;
+      acc = static_cast<digit_type>(acc);
+    }
+
+    x -= i + 1;
+    y += i + 2;
+    *z++ = static_cast<digit_type>(acc);
+    acc = static_cast<digit_type>(carry);
+    carry >>= digit_bits;
+  }
+  --y;
+  // phase 2
+  while (--xylen)
+  {
+    ++x;
+    for (size_type j = 0; j < xylen; ++j)
+    {
+      acc += static_cast<word_type>(*x++) * static_cast<word_type>(*y--);
+      carry += acc >> digit_bits;
+      acc = static_cast<digit_type>(acc);
+    }
+
+    x -= xylen;
+    y += xylen;
+    *z++ = static_cast<digit_type>(acc);
+    acc = static_cast<digit_type>(carry);
+    carry >>= digit_bits;
+  }
+
+  *z = static_cast<digit_type>(acc);
+}
+
+template<typename D, typename W, typename S>
+void
+basic_primitive_ops<D,W,S>::comba_mul(digit_type* z,
+                                      const digit_type* x, size_type xlen,
+                                      const digit_type* y, size_type ylen,
+                                      digit_type* workspace)
+{
+  assert(xlen >= ylen);
+
+  digit_type* w = workspace;
   word_type acc = 0;  // accumulator for each column
   word_type carry = 0;
 
   // phase 1
-  for (size_type i = 0; i < xylen; ++i)
+  for (size_type i = 0; i < ylen; ++i)
   {
     const digit_type* a = x;
     const digit_type* b = y + i;
@@ -479,29 +676,231 @@
       acc = static_cast<digit_type>(acc);
     }
 
-    *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
+    *w++ = static_cast<digit_type>(acc);
+    acc  = static_cast<digit_type>(carry);
     carry >>= digit_bits;
   }
 
+  w -= ylen;
+
   // phase 2
-  for (size_type i = 1; i < xylen; ++i)
+  for (size_type i = 0; i < xlen - ylen; ++i)
   {
-    const digit_type* a = y + xylen - 1;
-    const digit_type* b = x + i;
+    const digit_type* a = x + 1 + i;
+    const digit_type* b = y + ylen - 1;
 
-    for (size_type j = 0; j < xylen - i; ++j)
+    for (size_type j = 0; j < ylen; ++j)
     {
-      acc += static_cast<word_type>(*a--) * static_cast<word_type>(*b++);
+      acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
       carry += acc >> digit_bits;
       acc = static_cast<digit_type>(acc);
     }
 
-    *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
+    *z++ = *w;
+    *w++ = static_cast<digit_type>(acc);
+
+    if (static_cast<size_type>(w - workspace) == ylen)
+      w -= ylen;
+
+    acc  = static_cast<digit_type>(carry);
+    carry >>= digit_bits;
+  }
+
+  // phase 3
+  for (size_type i = 0; i < ylen - 1; ++i)
+  {
+    const digit_type* a = x + xlen - (ylen - 1);
+    const digit_type* b = y + ylen - 1;
+
+    for (size_type j = i + 1; j < ylen; ++j)
+    {
+      acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
+      carry += acc >> digit_bits;
+      acc = static_cast<digit_type>(acc);
+    }
+
+    *z++ = *w;
+    *w++ = static_cast<digit_type>(acc);
+
+    if (static_cast<size_type>(w - workspace) == ylen)
+      w -= ylen;
+
+    acc  = static_cast<digit_type>(carry);
     carry >>= digit_bits;
   }
 
+  const digit_type* ws_index = w;
+
+  while (w < (workspace + ylen))
+    *z++ = *w++;
+
+  w = workspace;
+
+  while (w < ws_index)
+    *z++ = *w++;
+
+  *z = static_cast<digit_type>(acc);
+}
+
+template<typename D, typename W, typename S>
+void
+basic_primitive_ops<D,W,S>::comba_mul_lo(digit_type* z,
+                                         const digit_type* x, size_type xlen,
+                                         const digit_type* y, size_type ylen,
+                                         size_type num)
+{
+  //assert(xlen >= ylen);
+  assert(num <= (xlen + ylen));
+
+  word_type acc = 0;  // accumulator for each column
+  word_type carry = 0;
+
+  // phase 1
+  if (num)
+  {
+    const size_type m = ylen < num ? ylen : num;
+    for (size_type i = 0; i < m; ++i)
+    {
+      const digit_type* a = x;
+      const digit_type* b = y + i;
+
+      for (size_type j = 0; j <= i; ++j)
+      {
+        acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
+        carry += acc >> digit_bits;
+        acc = static_cast<digit_type>(acc);
+      }
+
+      *z++ = static_cast<digit_type>(acc);
+      acc  = static_cast<digit_type>(carry);
+      carry >>= digit_bits;
+    }
+  }
+
+  // phase 2
+  if (num >= ylen)
+  {
+    const size_type m = xlen - ylen < num ? xlen - ylen : num;
+    for (size_type i = 0; i < m; ++i)
+    {
+      const digit_type* a = x + 1 + i;
+      const digit_type* b = y + ylen - 1;
+
+      for (size_type j = 0; j < ylen; ++j)
+      {
+        acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
+        carry += acc >> digit_bits;
+        acc = static_cast<digit_type>(acc);
+      }
+
+      *z++ = static_cast<digit_type>(acc);
+      acc  = static_cast<digit_type>(carry);
+      carry >>= digit_bits;
+    }
+  }
+
+  // phase 3
+  if (num >= xlen + ylen)
+  {
+    const size_type m = ylen - 1 < num ? ylen - 1 : num;
+    for (size_type i = 0; i < m; ++i)
+    {
+      const digit_type* a = x + xlen - (ylen - 1);
+      const digit_type* b = y + ylen - 1;
+
+      for (size_type j = i + 1; j < ylen; ++j)
+      {
+        acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
+        carry += acc >> digit_bits;
+        acc = static_cast<digit_type>(acc);
+      }
+
+      *z++ = static_cast<digit_type>(acc);
+      acc  = static_cast<digit_type>(carry);
+      carry >>= digit_bits;
+    }
+  }
+
+  *z = static_cast<digit_type>(acc);
+}
+
+template<typename D, typename W, typename S>
+void
+basic_primitive_ops<D,W,S>::comba_mul_hi(digit_type* z,
+                                         const digit_type* x, size_type xlen,
+                                         const digit_type* y, size_type ylen,
+                                         size_type num)
+{
+  //assert(xlen >= ylen);
+  assert(num > 0);
+  assert(num < (xlen + ylen));
+
+  word_type acc = 0;  // accumulator for each column
+  word_type carry = 0;
+
+  // phase 1
+  if (num < ylen)
+  {
+    for (size_type i = num; i < ylen; ++i)
+    {
+      const digit_type* a = x;
+      const digit_type* b = y + i;
+
+      for (size_type j = 0; j <= i; ++j)
+      {
+        acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
+        carry += acc >> digit_bits;
+        acc = static_cast<digit_type>(acc);
+      }
+
+      *z++ = static_cast<digit_type>(acc);
+      acc  = static_cast<digit_type>(carry);
+      carry >>= digit_bits;
+    }
+  }
+
+  // phase 2
+  if (num < xlen)
+  {
+    for (size_type i = num - ylen; i < xlen - ylen; ++i)
+    {
+      const digit_type* a = x + 1 + i;
+      const digit_type* b = y + ylen - 1;
+
+      for (size_type j = 0; j < ylen; ++j)
+      {
+        acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
+        carry += acc >> digit_bits;
+        acc = static_cast<digit_type>(acc);
+      }
+
+      *z++ = static_cast<digit_type>(acc);
+      acc  = static_cast<digit_type>(carry);
+      carry >>= digit_bits;
+    }
+  }
+
+  // phase 3
+  if (num < (xlen + ylen))
+  {
+    for (size_type i = num - (xlen + ylen); i < ylen - 1; ++i)
+    {
+      const digit_type* a = x + xlen - (ylen - 1);
+      const digit_type* b = y + ylen - 1;
+
+      for (size_type j = i + 1; j < ylen; ++j)
+      {
+        acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
+        carry += acc >> digit_bits;
+        acc = static_cast<digit_type>(acc);
+      }
+
+      *z++ = static_cast<digit_type>(acc);
+      acc  = static_cast<digit_type>(carry);
+      carry >>= digit_bits;
+    }
+  }
+
   *z = static_cast<digit_type>(acc);
 }
 
@@ -558,7 +957,6 @@
 
   *z = static_cast<digit_type>(acc);*/
 
-
   word_type acc = 0;  // accumulator for each column
   word_type carry = 0;
 
@@ -583,12 +981,12 @@
   // phase 2
   for (size_type i = 1; i < xlen; ++i)
   {
-    const digit_type* a = x + xlen - 1;
-    const digit_type* b = x + i;
+    const digit_type* a = x + i;
+    const digit_type* b = x + xlen - 1;
 
     for (size_type j = 0; j < xlen - i; ++j)
     {
-      acc += static_cast<word_type>(*a--) * static_cast<word_type>(*b++);
+      acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
       carry += acc >> digit_bits;
       acc = static_cast<digit_type>(acc);
     }
@@ -603,24 +1001,25 @@
 
 template<typename D, typename W, typename S>
 D basic_primitive_ops<D,W,S>::multiply_add_digits(digit_type* z,
-                                                  const digit_type* w,
-                                                  digit_type x,
-                                                  const digit_type* y,
+                                                  const digit_type* x,
+                                                  digit_type y,
                                                   size_type n)
 {
-  word_type carry = 0;
+  digit_type carry = 0;
   while (n--)
   {
-    const word_type r = static_cast<word_type>(*w++)
-                      * static_cast<word_type>(x)
-                      + static_cast<word_type>(*y++)
-                      + carry;
-
-    *z++ = static_cast<digit_type>(r);
-    carry = r >> digit_bits;
+    const word_type r = static_cast<word_type>(*z)
+                      + static_cast<word_type>(*x)
+                      * static_cast<word_type>(y)
+                      + static_cast<word_type>(carry);
+
+    *z = static_cast<digit_type>(r);
+    carry = static_cast<digit_type>(r >> digit_bits);
+    ++z;
+    ++x;
   }
 
-  return static_cast<digit_type>(carry);
+  return carry;
 }
 
 
@@ -644,12 +1043,68 @@
     carry = r;
   }
 }
+/*
+// divides half digits [x1, x2, x3] by [y1, y2] and returns remainder
+template<typename D, typename W, typename S>
+D basic_primitive_ops<D,W,S>::divide_half_digits(
+                                      digit_type& q,
+                                      digit_type x12, digit_type x3,
+                                      digit_type y1, digit_type y2)
+{
+  q = x12 / y1;
+  const digit_type c = x12 - q * y1;
+  const digit_type D = q * y2;
+
+  digit_type R = (c << digit_bits / 2) | x3;
+
+  if (R < D) // R is too large by at most 2
+  {
+    const digit_type y = (y1 << digit_bits / 2) | y2;
+    --q;
+    R += y;
+    if (R < D)
+    {
+      --q;
+      R += y;
+    }
+  }
+
+  return R - D;
+}
+
+// divide two digit number x by one digit number y
+// returns remainder
+// q = x / y , r = x % y
+template<typename D, typename W, typename S>
+D basic_primitive_ops<D,W,S>::divide(digit_type& q,
+                                     digit_type x_hi, digit_type x_lo,
+                                     digit_type y)
+{
+  static const digit_type lo_mask = (1 << digit_bits / 2) - 1;
+  static const digit_type hi_mask = lo_mask << (digit_bits / 2);
+
+  digit_type q1, q2;
+  const digit_type r = divide_half_digits(q1, x_hi, x_lo & hi_mask,
+                                              y & hi_mask, y & lo_mask);
+  const digit_type s = divide_half_digits(q2, r, x_lo & lo_mask,
+                                              y & hi_mask, y & lo_mask);
+  q = (q1 << digit_bits / 2) & q2;
+  return s;
+}*/
 
 template<typename D, typename W, typename S>
 D basic_primitive_ops<D,W,S>::divide_by_digit(digit_type* z,
                                               const digit_type* x, size_type n,
                                               digit_type y)
 {
+/*  z += n - 1;
+  x += n - 1;
+
+  while (n--)
+  {
+    if ()
+  }*/
+
   z += n - 1;
   x += n - 1;
 
@@ -658,47 +1113,1427 @@
   while (n--)
   {
     w = (w << digit_bits) | static_cast<word_type>(*x--);
-    digit_type tmp;
+    //this turned out to be slower:
+    //const digit_type q = static_cast<digit_type>(w / y);
+    //w -= q * y;
+    //*z-- = q;
+    digit_type q;
     if (w >= y)
     {
-      tmp = static_cast<digit_type>(w / y);
-      w -= tmp * y;
+      q = static_cast<digit_type>(w / y);
+      w -= q * y;
     }
     else
-      tmp = 0;
-    *z-- = tmp;
+      q = 0;
+    *z-- = q;
   }
 
   return static_cast<digit_type>(w);
 }
 
+// This is basically a Knuth division with the difference that we form the trial
+// quotient by using a 3 digit by 2 digit division instead of a 2 by 1. This has
+// the effect of limiting the error in q_hat to 1 instead of 2.
+/*template<typename D, typename W, typename S>
+void basic_primitive_ops<D,W,S>::divide(digit_type* q, digit_type* r,
+                                        const digit_type* x, size_type xlen,
+                                        const digit_type* y, size_type ylen,
+                                        digit_type* ws)
+{
+  assert(xlen >= 3);
+  assert(ylen >= 2);
 
+  if (y[ylen-1] & (1 << (digit_bits-1))) // if y is already normalized
+  {
+    digit_type q_estimate =
+      div3by2(x[xlen - 1], x[xlen - 2], x[xlen - 3],
+              y[ylen - 1], y[ylen - 2]);
+
+    // multiply subtract in place
+    digit_type* ws_ptr = ws;
+    digit_type borrow = 0;
+    for (size_type i = 0; i < ylen; ++i)
+    {
+      const word_type tmp = static_cast<word_type>(*y++)
+                          * static_cast<word_type>(q_estimate);
+      *ws_ptr++ = x_ptr - static_cast<digit_type>(tmp);
+      borrow = static_cast<digit_type>(tmp >> digit_bits);
+    }
 
+    return borrow;
+  }
+  else
+  {
+    //count leading zero bits
+    norm = 1;
 
-// This exists to ease development of primitive_ops specializations. If a
-// specialized function isn't available yet, the compiler will just choose the
-// inherited one. It also means that whenever we add a new function to
-// basic_primitive_ops no code will break since it will be available to all
-// specializations as well.
-template<typename D, typename W, typename S>
-struct primitive_ops : basic_primitive_ops<D,W,S>
-{};
+    // store normalized y at ws[0] and normalized x at ws[ylen]
+    digit_type q_estimate =
+      div3by2(ws[xlen - 1], ws[xlen - 2], ws[xlen - 3],
+              ws[ylen - 1], ws[ylen - 2]);
+  }
 
 
-// Here we include primitive_ops specializations that use assembler
+  // TODO normalize in place or store normalized y at ws and let wslen be
+  // ylen * 2 + 1.
 
-#if defined(BOOST_MP_MATH_MP_INT_USE_ASM)
+  const digit_type* x_beg = x;
+  x += xlen - 3;
 
-  #if defined(__GNU__)
-    #if defined(__386__)
-      #include <boost/mp_math/mp_int/detail/asm/x86/gnu_386_primitive_ops.hpp>
-    #endif
-  #endif
+  digit_type q_hat = div3by2(x, y + ylen - 2);
+  *(ws + ylen) = multiply_by_digit(ws, y, ylen, q_hat);
 
-#endif
+  const digit_type borrow = subtract_digits(ws, x, ws, ylen + 1);
+  if (borrow)
+  {
+    ++q_hat;
+    add_digits(ws, ws, y, ylen);
+  }
+
+  *q++ = q_hat;
+  --x;
+
+  ++ws;
+
+  // TODO need to multiply_subtract otherwise I'd need a second buffer to hold
+  // the result of multiply_by_digit
+  while (x != x_beg)
+  {
+    digit_type q_hat = div3by2(ws, y + ylen - 2);
+    *(ws + ylen) = multiply_by_digit(ws, y, ylen, q_hat);
+
+    const digit_type borrow = subtract_digits(ws, x, ws, ylen + 1);
+    if (borrow)
+    {
+      ++q_hat;
+      add_digits(ws, ws, y, ylen);
+    }
+
+    *q++ = q_hat;
+    --x;
+    *(ws - 1) = *x;
+  }
+}*/
+
+template<typename D, typename W, typename S>
+D basic_primitive_ops<D,W,S>::shift_bits_left(digit_type* x,
+                                              size_type xlen,
+                                              size_type n)
+{
+  assert(n > 0 && n < digit_bits);
+
+  // shift for msbs
+  const digit_type shift = digit_bits - n;
+
+  digit_type carry = 0;
+  while (xlen--)
+  {
+    const digit_type c = (*x >> shift);
+    *x = (*x << n) | carry;
+    carry = c;
+    ++x;
+  }
+
+  return carry;
+}
 
+template<typename D, typename W, typename S>
+void basic_primitive_ops<D,W,S>::shift_bits_right(digit_type* x,
+                                                  size_type xlen,
+                                                  size_type n)
+{
+  assert(n > 0 && n < digit_bits);
+
+  const digit_type mask = (digit_type(1) << n) - 1;
+
+  // shift for lsb
+  const digit_type shift = digit_bits - n;
+
+  x += xlen;
+
+  digit_type carry = 0;
+  while (xlen--)
+  {
+    --x;
+    const digit_type c = *x & mask;
+    *x = (*x >> n) | (carry << shift);
+    carry = c;
+  }
+}
+
+template<typename D, typename W, typename S>
+int basic_primitive_ops<D,W,S>::compare_magnitude(const digit_type* x,
+                                                  size_type xlen,
+                                                  const digit_type* y,
+                                                  size_type ylen)
+{
+  if (xlen > ylen)
+    return 1;
+
+  if (xlen < ylen)
+    return -1;
+
+  // compare all digits
+  x += xlen;
+  y += ylen;
+  while (xlen--)
+  {
+    --x; --y;
+    if (*x > *y)
+      return 1;
+    if (*x < *y)
+      return -1;
+  }
+
+  return 0;
+}
+
+
+// This exists to ease development of primitive_ops specializations. If a
+// specialized function isn't available yet, the compiler will just choose the
+// inherited one. It also means that whenever we add a new function to
+// basic_primitive_ops no code will break since it will be available to all
+// specializations as well.
+template<typename D, typename W, typename S>
+struct primitive_ops : basic_primitive_ops<D,W,S>
+{};
+
+
+#else
+
+template<typename DigitT, typename SizeT>
+struct basic_primitive_ops
+{
+  typedef DigitT digit_type;
+  typedef SizeT  size_type;
+
+  static const digit_type digit_bits = std::numeric_limits<digit_type>::digits;
+
+  // ADD ------------------------------------
+
+  // z = x + y, returns carry
+  static digit_type add(digit_type& z, digit_type x, digit_type y);
+
+  // z += x, returns carry
+  static digit_type add(digit_type& z, digit_type x);
+
+  // add y to the digits in x and store result in z
+  // xlen must be > 0
+  // returns: the last carry (it will not get stored in z)
+  static digit_type add_single_digit(digit_type* z,
+                                     const digit_type* x, size_type xlen,
+                                     digit_type y);
+
+  // z = x + y, returns last carry
+  static digit_type add_digits(digit_type* z,
+                               const digit_type* x,
+                               const digit_type* y,
+                               size_type num);
+
+  // ripples the carry c up through n digits of x and stores results in z
+  // returns the number of digits the carry rippled through and stores the last
+  // carry in c. If there isn't a last carry then c will be 0.
+  static size_type ripple_carry(digit_type* z,
+                                const digit_type* x,
+                                size_type n,
+                                digit_type& c);
+
+  // z = x + y, where xlen >= ylen
+  // returns last carry
+  static digit_type add_smaller_magnitude(digit_type* z,
+                                          const digit_type* x, size_type xlen,
+                                          const digit_type* y, size_type ylen);
+
+  // SUB ------------------------------------
+
+  // z = x - y, returns borrow
+  static digit_type sub(digit_type& z, digit_type x, digit_type y);
+
+  // z -= x, returns borrow
+  static digit_type sub(digit_type& z, digit_type x);
+
+  // subtracts x from the digits in y and store result in z
+  static void subtract_single_digit(digit_type* z,
+                                    const digit_type* x, size_type xlen,
+                                    digit_type y);
+
+  // z = x - y, returns last borrow
+  static digit_type subtract_digits(digit_type* z,
+                                    const digit_type* x,
+                                    const digit_type* y,
+                                    size_type num);
+
+  // ripples the borrow up through n digits of x and stores results in z
+  // returns the number of digits the borrow rippled through
+  static size_type ripple_borrow(digit_type* z,
+                                 const digit_type* x,
+                                 size_type n,
+                                 digit_type borrow);
+
+  // z = x - y, where x >= y
+  static void sub_smaller_magnitude(digit_type* z,
+                                    const digit_type* x, size_type xlen,
+                                    const digit_type* y, size_type ylen);
+
+  // MUL ------------------------------------
+
+  // z = x * y, returns high part of the product
+  static digit_type mul(digit_type& z, digit_type x, digit_type y);
+
+  // z *= x, returns high part of the product
+  static digit_type mul(digit_type& z, digit_type x);
+
+  // multiply y of length ylen with x and store result in z
+  // returns: the last carry (it will not get stored in z)
+  static digit_type multiply_by_digit(digit_type* z,
+                                      const digit_type* x, size_type xlen,
+                                      digit_type y);
+
+  // z = x * 2
+  static digit_type multiply_by_two(digit_type* z,
+                                    const digit_type* x, size_type len);
+
+  // z = x * y; precondition: xlen >= ylen
+  static void long_mul(digit_type* z, const digit_type* x, size_type xlen,
+                                      const digit_type* y, size_type ylen);
+
+  // z = x * y; precondition: xlen >= ylen
+  static void comba_mul(digit_type* z, const digit_type* x, size_type xlen,
+                                       const digit_type* y, size_type ylen);
+
+  // z = x * y; for numbers of the same size
+  static void comba_mul(digit_type* z,
+                        const digit_type* x,
+                        const digit_type* y, size_type xylen);
+
+  // z = x * y; precondition: xlen >= ylen and workspace must have at least ylen
+  // digits this function is only used by the integral ops interaction code, it
+  // allows x and z to be the same pointer.
+  static void comba_mul(digit_type* z, const digit_type* x, size_type xlen,
+                                       const digit_type* y, size_type ylen,
+                                       digit_type* workspace);
+
+  // computes the lower num digits of the product of x and y
+  static void comba_mul_lo(digit_type* z, const digit_type* x, size_type xlen,
+                                          const digit_type* y, size_type ylen,
+                                          size_type num);
+
+  // computes the high product of x and y without num least significant digits
+  // basically the result is: z = (x*y) >> radix^num
+  static void comba_mul_hi(digit_type* z, const digit_type* x, size_type xlen,
+                                          const digit_type* y, size_type ylen,
+                                          size_type num);
+
+  // SQR ------------------------------------
+
+  // z = x * x;
+  static void comba_sqr(digit_type* z, const digit_type* x, size_type xlen);
+
+  // MADD ------------------------------------
+
+  // z = z + x * y, returns carry
+  static digit_type multiply_add(digit_type& z,
+                                 digit_type x, digit_type y);
+
+  // z = z + x * y, returns carry
+  static digit_type multiply_add(digit_type& z_hi, digit_type& z_lo,
+                                 digit_type x, digit_type y);
+
+  // z = z + x * y
+  static digit_type multiply_add_digits(digit_type* z,
+                                        const digit_type* x,
+                                        digit_type y,
+                                        size_type n);
+
+  // DIV -------------------------------------
+
+  // z = x / 2
+  static void divide_by_two(digit_type* z, const digit_type* x, size_type len);
+
+  // z = x / y
+  // returns remainder
+  static digit_type divide_by_digit(digit_type* z,
+                                    const digit_type* x, size_type xlen,
+                                    digit_type y);
+
+  // SHIFT -----------------------------------
+
+  // shifts x by n bits to the left, where n > 0 && n < digit_bits
+  // returns carry
+  static digit_type shift_bits_left(digit_type* x, size_type xlen, size_type n);
+
+  // shifts x by n bits to the right, where n > 0 && n < digit_bits
+  static void shift_bits_right(digit_type* x, size_type xlen, size_type n);
+
+  // CMP -------------------------------------
+
+  // returns  1 if x  > y
+  // returns  0 if x == y
+  // returns -1 if x  < y
+  static int compare_magnitude(const digit_type* x, size_type xlen,
+                               const digit_type* y, size_type ylen);
+
+private:
+
+  // divides half digits [x1, x2, x3] by [y1, y2] and returns remainder
+  // this function is used by divide_by_digit
+  static digit_type divide_half_digits(digit_type& q,
+                                       digit_type x12, digit_type x3,
+                                       digit_type y1, digit_type y2);
+};
+
+
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::add(digit_type& z, digit_type x, digit_type y)
+{
+  z = x + y;
+  return z < x;
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::add(digit_type& z, digit_type x)
+{
+  z += x;
+  return z < x;
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::add_single_digit(digit_type* z,
+                                             const digit_type* x,
+                                             size_type xlen,
+                                             digit_type y)
+{
+  digit_type carry = add(*z++, *x++, y);
+
+  while (carry && --xlen)
+    carry = add(*z++, *x++, carry);
+
+  return carry;
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::add_digits(digit_type* z,
+                                       const digit_type* x,
+                                       const digit_type* y, size_type n)
+{
+  digit_type carry = 0;
+  while (n--)
+  {
+    const digit_type c0 = add(*z, *x++, *y++);
+    const digit_type c1 = add(*z++, carry);
+    carry = c0 | c1;
+  }
+
+  return carry;
+}
+
+template<typename D, typename S>
+inline
+S basic_primitive_ops<D,S>::ripple_carry(digit_type* z,
+                                         const digit_type* x,
+                                         size_type n,
+                                         digit_type& carry)
+{
+  size_type i = 0;
+
+  for (; carry && (i < n); ++i)
+    carry = add(*z++, *x++, carry);
+
+  return i;
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::add_smaller_magnitude(digit_type* z,
+                                                  const digit_type* x,
+                                                  size_type xlen,
+                                                  const digit_type* y,
+                                                  size_type ylen)
+{
+  digit_type carry = add_digits(z, x, y, ylen);
+
+  size_type n = ripple_carry(z + ylen, x + ylen, xlen - ylen, carry);
+
+  n += ylen;
+
+  if (n < xlen && z != x)
+    std::memcpy(z + n, x + n, sizeof(digit_type) * (xlen - n));
+
+  return carry;
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::sub(digit_type& z, digit_type x, digit_type y)
+{
+  z = x - y;
+  return z > x;
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::sub(digit_type& z, digit_type x)
+{
+  const digit_type tmp = z;
+  z -= x;
+  return z > tmp;
+}
+
+template<typename D, typename S>
+inline
+void
+basic_primitive_ops<D,S>::subtract_single_digit(digit_type* z,
+                                                const digit_type* y,
+                                                size_type ylen,
+                                                digit_type x)
+{
+  digit_type borrow = sub(*z++, *y++, x);
+
+  while (borrow && --ylen)
+    borrow = sub(*z++, *y++, borrow);
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::subtract_digits(digit_type* z,
+                                            const digit_type* x,
+                                            const digit_type* y,
+                                            size_type n)
+{
+  digit_type borrow = 0;
+
+  while (n--)
+  {
+    const digit_type b0 = sub(*z, *x++, *y++);
+    const digit_type b1 = sub(*z++, borrow);
+    borrow = b0 | b1;
+  }
+
+  return borrow;
+}
+
+template<typename D, typename S>
+inline
+S basic_primitive_ops<D,S>::ripple_borrow(digit_type* z,
+                                          const digit_type* x,
+                                          size_type n,
+                                          digit_type borrow)
+{
+  size_type i = 0;
+
+  for (; borrow && (i < n); ++i)
+    borrow = sub(*z++, *x++, borrow);
+
+  return i;
+}
+
+template<typename D, typename S>
+inline
+void basic_primitive_ops<D,S>::sub_smaller_magnitude(
+    digit_type* z,
+    const digit_type* x, size_type xlen,
+    const digit_type* y, size_type ylen)
+{
+  const digit_type borrow = subtract_digits(z, x, y, ylen);
+
+  size_type n = ripple_borrow(z + ylen, x + ylen, xlen - ylen, borrow);
+
+  if (z != x)
+  {
+    n += ylen;
+    std::memcpy(z + n, x + n, (xlen - n) * sizeof(digit_type));
+  }
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::mul(digit_type& z_lo, digit_type x, digit_type y)
+{
+  static const digit_type lo_mask = (1 << digit_bits / 2) - 1;
+
+  const digit_type x_lo = x & lo_mask;
+  const digit_type x_hi = x >> digit_bits/2;
+  const digit_type y_lo = y & lo_mask;
+  const digit_type y_hi = y >> digit_bits/2;
+
+  const digit_type z0 = x_lo * y_lo;
+  const digit_type z1 = x_lo * y_hi;
+  const digit_type z2 = x_hi * y_lo;
+  const digit_type z3 = x_hi * y_hi;
+
+  digit_type z12 = z1 + (z0 >> digit_bits/2);
+  const digit_type carry = add(z12, z2);
+
+  z_lo = (z12 << digit_bits/2) + (z0 & lo_mask);
+
+  const digit_type z_hi = z3 + (carry << digit_bits/2) + (z12 >> digit_bits/2);
+
+  return z_hi;
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::mul(digit_type& z, digit_type x)
+{
+  return mul(z, z, x);
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::multiply_by_digit(digit_type* z,
+                                              const digit_type* y,
+                                              size_type ylen,
+                                              digit_type x)
+{
+  digit_type carry = 0;
+
+  while (ylen--)
+  {
+    const digit_type tmp = mul(*z, *y++, x);
+    carry = tmp + add(*z++, carry);
+  }
+
+  return carry;
+}
+
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::multiply_by_two(digit_type* z,
+                                            const digit_type* x, size_type n)
+{
+  static const digit_type one = 1U;
+
+  digit_type carry = 0;
+
+  while (n--)
+  {
+    // get carry bit for next iteration
+    const digit_type r = *x >> (digit_bits - one);
+
+    *z++ = (*x++ << one) | carry;
+
+    carry = r;
+  }
+
+  return carry;
+}
+
+template<typename D, typename S>
+void
+basic_primitive_ops<D,S>::long_mul(digit_type* z,
+                                   const digit_type* x, size_type xlen,
+                                   const digit_type* y, size_type ylen)
+{
+  assert(xlen >= ylen);
+  z[xlen] = multiply_by_digit(z++, x, xlen, *(y++));
+  --ylen;
+  while(--ylen)
+    z[xlen] = multiply_add_digits(z++, x, xlen, *(y++));
+}
+
+template<typename D, typename S>
+void
+basic_primitive_ops<D,S>::comba_mul(digit_type* z,
+                                    const digit_type* x, size_type xlen,
+                                    const digit_type* y, size_type ylen)
+{
+  assert(xlen >= ylen);
+
+  digit_type acc_hi = 0;  // accumulator for each column
+  digit_type acc_lo = 0;
+  digit_type carry_hi = 0;
+  digit_type carry_lo = 0;
+
+  // phase 1
+  for (size_type i = 0; i < ylen; ++i)
+  {
+    const digit_type* a = x;
+    const digit_type* b = y + i;
+
+    for (size_type j = 0; j <= i; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *z++     = acc_lo;
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  // phase 2
+  for (size_type i = 0; i < xlen - ylen; ++i)
+  {
+    const digit_type* a = x + 1 + i;
+    const digit_type* b = y + ylen - 1;
+
+    for (size_type j = 0; j < ylen; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *z++     = acc_lo;
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  // phase 3
+  for (size_type i = 0; i < ylen - 1; ++i)
+  {
+    const digit_type* a = x + xlen - (ylen - 1) + i;
+    const digit_type* b = y + ylen - 1;
+
+    for (size_type j = i + 1; j < ylen; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *z++     = acc_lo;
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  *z = acc_lo;
+}
+
+template<typename D, typename S>
+void
+basic_primitive_ops<D,S>::comba_mul(digit_type* z,
+                                    const digit_type* x,
+                                    const digit_type* y, size_type xylen)
+{
+  digit_type acc_hi = 0;  // accumulator for each column
+  digit_type acc_lo = 0;
+  digit_type carry_hi = 0;
+  digit_type carry_lo = 0;
+
+  // phase 1
+  for (size_type i = 0; i < xylen; ++i)
+  {
+    const digit_type* a = x;
+    const digit_type* b = y + i;
+
+    for (size_type j = 0; j <= i; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *z++     = acc_lo;
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  // phase 2
+  for (size_type i = 1; i < xylen; ++i)
+  {
+    const digit_type* a = y + xylen - 1;
+    const digit_type* b = x + i;
+
+    for (size_type j = 0; j < xylen - i; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a--, *b++);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *z++     = acc_lo;
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  *z = acc_lo;
+}
+
+template<typename D, typename S>
+void
+basic_primitive_ops<D,S>::comba_mul(digit_type* z,
+                                    const digit_type* x, size_type xlen,
+                                    const digit_type* y, size_type ylen,
+                                    digit_type* workspace)
+{
+  assert(xlen >= ylen);
+
+  digit_type* w = workspace;
+  digit_type acc_hi = 0;  // accumulator for each column
+  digit_type acc_lo = 0;
+  digit_type carry_hi = 0;
+  digit_type carry_lo = 0;
+
+  // phase 1
+  for (size_type i = 0; i < ylen; ++i)
+  {
+    const digit_type* a = x;
+    const digit_type* b = y + i;
+
+    for (size_type j = 0; j <= i; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *w++     = acc_lo;
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  w -= ylen;
+
+  // phase 2
+  for (size_type i = 0; i < xlen - ylen; ++i)
+  {
+    const digit_type* a = x + 1 + i;
+    const digit_type* b = y + ylen - 1;
+
+    for (size_type j = 0; j < ylen; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *z++ = *w;
+    *w++ = acc_lo;
+
+    if (static_cast<size_type>(w - workspace) == ylen)
+      w -= ylen;
+
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  // phase 3
+  for (size_type i = 0; i < ylen - 1; ++i)
+  {
+    const digit_type* a = x + xlen - (ylen - 1) + i;
+    const digit_type* b = y + ylen - 1;
+
+    for (size_type j = i + 1; j < ylen; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *z++ = *w;
+    *w++ = acc_lo;
+
+    if (static_cast<size_type>(w - workspace) == ylen)
+      w -= ylen;
+
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  const digit_type* ws_index = w;
+
+  while (w < (workspace + ylen))
+    *z++ = *w++;
+
+  w = workspace;
+
+  while (w < ws_index)
+    *z++ = *w++;
+
+  *z = acc_lo;
+}
+
+template<typename D, typename S>
+void
+basic_primitive_ops<D,S>::comba_mul_lo(digit_type* z,
+                                       const digit_type* x, size_type xlen,
+                                       const digit_type* y, size_type ylen,
+                                       size_type num)
+{
+  //assert(xlen >= ylen);
+  assert(num <= (xlen + ylen));
+
+  digit_type acc_hi = 0;  // accumulator for each column
+  digit_type acc_lo = 0;
+  digit_type carry_hi = 0;
+  digit_type carry_lo = 0;
+
+  // phase 1
+  if (num)
+  {
+    const size_type m = ylen < num ? ylen : num;
+    for (size_type i = 0; i < m; ++i)
+    {
+      const digit_type* a = x;
+      const digit_type* b = y + i;
+
+      for (size_type j = 0; j <= i; ++j)
+      {
+        const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+        carry_hi += add(carry_lo, carry);
+        carry_hi += add(carry_lo, acc_hi);
+        acc_hi = 0;
+      }
+
+      *z++     = acc_lo;
+      acc_lo   = carry_lo;
+      carry_lo = carry_hi;
+      carry_hi = 0;
+    }
+  }
+
+  // phase 2
+  if (num >= ylen)
+  {
+    const size_type m = xlen - ylen < num ? xlen - ylen : num;
+    for (size_type i = 0; i < m; ++i)
+    {
+      const digit_type* a = x + 1 + i;
+      const digit_type* b = y + ylen - 1;
+
+      for (size_type j = 0; j < ylen; ++j)
+      {
+        const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+        carry_hi += add(carry_lo, carry);
+        carry_hi += add(carry_lo, acc_hi);
+        acc_hi = 0;
+      }
+
+      *z++     = acc_lo;
+      acc_lo   = carry_lo;
+      carry_lo = carry_hi;
+      carry_hi = 0;
+    }
+  }
+
+  // phase 3
+  if (num >= xlen + ylen)
+  {
+    const size_type m = ylen - 1 < num ? ylen - 1 : num;
+    for (size_type i = 0; i < m; ++i)
+    {
+      const digit_type* a = x + xlen - (ylen - 1);
+      const digit_type* b = y + ylen - 1;
+
+      for (size_type j = i + 1; j < ylen; ++j)
+      {
+        const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+        carry_hi += add(carry_lo, carry);
+        carry_hi += add(carry_lo, acc_hi);
+        acc_hi = 0;
+      }
+
+      *z++     = acc_lo;
+      acc_lo   = carry_lo;
+      carry_lo = carry_hi;
+      carry_hi = 0;
+    }
+  }
+
+  *z = acc_lo;
+}
+
+template<typename D, typename S>
+void
+basic_primitive_ops<D,S>::comba_mul_hi(digit_type* z,
+                                       const digit_type* x, size_type xlen,
+                                       const digit_type* y, size_type ylen,
+                                       size_type num)
+{
+  //assert(xlen >= ylen);
+  assert(num > 0);
+  assert(num < (xlen + ylen));
+
+  digit_type acc_hi = 0;  // accumulator for each column
+  digit_type acc_lo = 0;
+  digit_type carry_hi = 0;
+  digit_type carry_lo = 0;
+
+  // phase 1
+  if (num < ylen)
+  {
+    for (size_type i = num; i < ylen; ++i)
+    {
+      const digit_type* a = x;
+      const digit_type* b = y + i;
+
+      for (size_type j = 0; j <= i; ++j)
+      {
+        const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+        carry_hi += add(carry_lo, carry);
+        carry_hi += add(carry_lo, acc_hi);
+        acc_hi = 0;
+      }
+
+      *z++     = acc_lo;
+      acc_lo   = carry_lo;
+      carry_lo = carry_hi;
+      carry_hi = 0;
+    }
+  }
+
+  // phase 2
+  if (num < xlen)
+  {
+    for (size_type i = num - ylen; i < xlen - ylen; ++i)
+    {
+      const digit_type* a = x + 1 + i;
+      const digit_type* b = y + ylen - 1;
+
+      for (size_type j = 0; j < ylen; ++j)
+      {
+        const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+        carry_hi += add(carry_lo, carry);
+        carry_hi += add(carry_lo, acc_hi);
+        acc_hi = 0;
+      }
+
+      *z++     = acc_lo;
+      acc_lo   = carry_lo;
+      carry_lo = carry_hi;
+      carry_hi = 0;
+    }
+  }
+
+  // phase 3
+  if (num < (xlen + ylen))
+  {
+    for (size_type i = num - (xlen + ylen); i < ylen - 1; ++i)
+    {
+      const digit_type* a = x + xlen - (ylen - 1);
+      const digit_type* b = y + ylen - 1;
+
+      for (size_type j = i + 1; j < ylen; ++j)
+      {
+        const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+        carry_hi += add(carry_lo, carry);
+        carry_hi += add(carry_lo, acc_hi);
+        acc_hi = 0;
+      }
+
+      *z++     = acc_lo;
+      acc_lo   = carry_lo;
+      carry_lo = carry_hi;
+      carry_hi = 0;
+    }
+  }
+
+  *z = acc_lo;
+}
+
+template<typename D, typename S>
+void
+basic_primitive_ops<D,S>::comba_sqr(digit_type* z,
+                                    const digit_type* x,
+                                    size_type xlen)
+{
+  digit_type acc_hi = 0;  // accumulator for each column
+  digit_type acc_lo = 0;
+  digit_type carry_hi = 0;
+  digit_type carry_lo = 0;
+
+  // phase 1
+  for (size_type i = 0; i < xlen; ++i)
+  {
+    const digit_type* a = x;
+    const digit_type* b = x + i;
+
+    for (size_type j = 0; j <= i; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *z++     = acc_lo;
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  // phase 2
+  for (size_type i = 1; i < xlen; ++i)
+  {
+    const digit_type* a = x + i;
+    const digit_type* b = x + xlen - 1;
+
+    for (size_type j = 0; j < xlen - i; ++j)
+    {
+      const digit_type carry = multiply_add(acc_hi, acc_lo, *a++, *b--);
+      carry_hi += add(carry_lo, carry);
+      carry_hi += add(carry_lo, acc_hi);
+      acc_hi = 0;
+    }
+
+    *z++     = acc_lo;
+    acc_lo   = carry_lo;
+    carry_lo = carry_hi;
+    carry_hi = 0;
+  }
+
+  *z = acc_lo;
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::multiply_add(digit_type& z_hi, digit_type& z_lo,
+                                         digit_type x, digit_type y)
+{
+  static const digit_type lo_mask = (1 << digit_bits / 2) - 1;
+
+  const digit_type x_lo = x & lo_mask;
+  const digit_type x_hi = x >> digit_bits/2;
+  const digit_type y_lo = y & lo_mask;
+  const digit_type y_hi = y >> digit_bits/2;
+
+  const digit_type z0 = x_lo * y_lo;
+  const digit_type z1 = x_lo * y_hi;
+  const digit_type z2 = x_hi * y_lo;
+  const digit_type z3 = x_hi * y_hi;
+
+  digit_type z12 = z1 + (z0 >> digit_bits/2);
+  const digit_type carry = add(z12, z2);
+
+  const digit_type w_lo = (z12 << digit_bits/2) + (z0 & lo_mask);
+  const digit_type w_hi = z3 + (carry << digit_bits/2) + (z12 >> digit_bits/2);
+
+  digit_type u = add(z_lo, w_lo);
+  digit_type v = add(z_hi, u);
+
+  return v + add(z_hi, w_hi);
+}
+
+template<typename D, typename S>
+inline
+D basic_primitive_ops<D,S>::multiply_add(digit_type& z,
+                                         digit_type x, digit_type y)
+{
+  static const digit_type lo_mask = (1 << digit_bits / 2) - 1;
+
+  const digit_type x_lo = x & lo_mask;
+  const digit_type x_hi = x >> digit_bits/2;
+  const digit_type y_lo = y & lo_mask;
+  const digit_type y_hi = y >> digit_bits/2;
+
+  const digit_type z0 = x_lo * y_lo;
+  const digit_type z1 = x_lo * y_hi;
+  const digit_type z2 = x_hi * y_lo;
+  const digit_type z3 = x_hi * y_hi;
+
+  digit_type z12 = z1 + (z0 >> digit_bits/2);
+  const digit_type carry = add(z12, z2);
+
+  const digit_type w_lo = (z12 << digit_bits/2) + (z0 & lo_mask);
+  const digit_type w_hi = z3 + (carry << digit_bits/2) + (z12 >> digit_bits/2);
+
+  const digit_type u = add(z, w_lo);
+
+  return u + w_hi;
+}
+
+template<typename D, typename S>
+D basic_primitive_ops<D,S>::multiply_add_digits(digit_type* z,
+                                                const digit_type* x,
+                                                digit_type y,
+                                                size_type n)
+{
+  digit_type carry = 0;
+  while (n--)
+  {
+    carry = add(*z, carry);
+    carry += multiply_add(*z, *x, y);
+    ++z; ++x;
+  }
+
+  return carry;
+}
+
+template<typename D, typename S>
+inline
+void basic_primitive_ops<D,S>::divide_by_two(digit_type* z,
+                                             const digit_type* x, size_type n)
+{
+  z += n - 1;
+  x += n - 1;
+
+  digit_type carry = 0;
+
+  while (n--)
+  {
+    // get carry for next iteration
+    const digit_type r = *x & 1;
+
+    *z-- = (*x-- >> 1) | (carry << (digit_bits - 1));
+
+    carry = r;
+  }
+}
+
+template<typename D, typename S>
+D basic_primitive_ops<D,S>::divide_by_digit(digit_type* z,
+                                            const digit_type* x, size_type n,
+                                            digit_type y)
+{
+  /*if (n == 1)
+  {
+    *z = *x / y;
+    return *x % y;
+  }*/
+  static const digit_type lo_mask = (1 << digit_bits / 2) - 1;
+  static const digit_type hi_mask = lo_mask << (digit_bits / 2);
+  static const digit_type hi_bit = 1 << (digit_bits - 1);
+  static const digit_type d2 = digit_bits / 2;
+
+  z += n - 1;
+  x += n - 1;
+
+  digit_type w_hi, w_lo = 0;
+
+  if (y & hi_bit) // if y is normalized
+  {
+    while (n--)
+    {
+      w_hi = w_lo;
+      w_lo = *x--;
+      // Do a 2 digit by 1 digit division -> [w_hi, w_lo] / y
+      if (w_hi || w_lo >= y) // if w >= y
+      {
+        digit_type q_hi, q_lo;
+        const digit_type rem = divide_half_digits(
+            q_hi,
+            w_hi, (w_lo & hi_mask) >> d2,
+            (y & hi_mask) >> d2, y & lo_mask);
+
+        w_lo = divide_half_digits(
+            q_lo,
+            rem, w_lo & lo_mask,
+            (y & hi_mask) >> d2, y & lo_mask);
+
+        if (w_hi >= y)
+          ++q_lo;
+
+        *z-- = (q_hi << d2) | q_lo;
+      }
+      else
+        *z-- = 0;
+
+      // q is never larger than one digit because w_hi is always set to the
+      // remainder and thus w_hi can never be greater than y which is the
+      // precondition for producing a quotient carry.
+      // TODO we could do a 2 by 1 division before the loop, that could produce
+      // a q carry. And then continue on as usual.
+    }
+
+    return w_lo;
+  }
+  else
+  {
+    // count leading zeros
+    unsigned norm = 0;
+    while (!(y & hi_bit))
+    {
+      ++norm;
+      y <<= 1;
+    }
+
+    // we're going to normalize the number in place
+    const digit_type shift = digit_bits - norm;
+
+    w_hi = *x >> shift;
+
+    while (n--)
+    {
+      w_lo = (*x << norm);
+      if (n)
+      {
+        --x;
+        w_lo |= *x >> shift;
+      }
+
+      // Do a 2 digit by 1 digit division -> [w_hi, w_lo] / y
+      if (w_hi || w_lo >= y) // if w >= y
+      {
+        digit_type q_hi, q_lo;
+        const digit_type rem = divide_half_digits(
+            q_hi,
+            w_hi, (w_lo & hi_mask) >> d2,
+            (y & hi_mask) >> d2, y & lo_mask);
+
+        w_lo = divide_half_digits(
+            q_lo,
+            rem, w_lo & lo_mask,
+            (y & hi_mask) >> d2, y & lo_mask);
+
+        *z-- = (q_hi << d2) | q_lo;
+      }
+      else
+        *z-- = 0;
+
+      w_hi = w_lo;
+    }
+
+    return w_lo >> norm;
+  }
+}
+
+template<typename D, typename S>
+D basic_primitive_ops<D,S>::divide_half_digits(digit_type& q,
+                                               digit_type x12, digit_type x3,
+                                               digit_type y1, digit_type y2)
+{
+  const digit_type y = (y1 << digit_bits / 2) | y2;
+  //if (x12 >= y)
+  //  x12 -= y;
+
+  q = x12 / y1;
+
+  const digit_type c = x12 - q * y1;
+  const digit_type D_ = q * y2;
+
+  digit_type R = (c << digit_bits / 2) | x3;
+
+  if (R < D_) // R is too large by at most 2
+  {
+    static const digit_type z = ~digit_type(0);
+    --q;
+    R += y;
+    if (R < y) // overflow
+      return z - D_ + R + 1;
+    if (R < D_)
+    {
+      --q;
+      R += y;
+      if (R < y) // overflow
+        return z - D_ + R + 1;
+    }
+  }
+
+  return R - D_;
+}
+
+template<typename D, typename S>
+D basic_primitive_ops<D,S>::shift_bits_left(digit_type* x,
+                                            size_type xlen,
+                                            size_type n)
+{
+  assert(n > 0 && n < digit_bits);
+
+  // shift for msbs
+  const digit_type shift = digit_bits - n;
+
+  digit_type carry = 0;
+  while (xlen--)
+  {
+    const digit_type c = (*x >> shift);
+    *x = (*x << n) | carry;
+    carry = c;
+    ++x;
+  }
+
+  return carry;
+}
+
+template<typename D, typename S>
+void basic_primitive_ops<D,S>::shift_bits_right(digit_type* x,
+                                                size_type xlen,
+                                                size_type n)
+{
+  assert(n > 0 && n < digit_bits);
+
+  const digit_type mask = (digit_type(1) << n) - 1;
+
+  // shift for lsb
+  const digit_type shift = digit_bits - n;
+
+  x += xlen;
+
+  digit_type carry = 0;
+  while (xlen--)
+  {
+    --x;
+    const digit_type c = *x & mask;
+    *x = (*x >> n) | (carry << shift);
+    carry = c;
+  }
+}
+
+template<typename D, typename S>
+int basic_primitive_ops<D,S>::compare_magnitude(const digit_type* x,
+                                                size_type xlen,
+                                                const digit_type* y,
+                                                size_type ylen)
+{
+  if (xlen > ylen)
+    return 1;
+
+  if (xlen < ylen)
+    return -1;
+
+  // compare all digits
+  x += xlen;
+  y += ylen;
+  while (xlen--)
+  {
+    --x; --y;
+    if (*x > *y)
+      return 1;
+    if (*x < *y)
+      return -1;
+  }
+
+  return 0;
+}
+
+template<typename D, typename S>
+struct primitive_ops : basic_primitive_ops<D,S>
+{};
+
+#endif
+
+
+
+
+/*
+// Here we include primitive_ops specializations that use assembler
+
+#if defined(BOOST_MP_MATH_INTEGER_USE_ASM)
+
+  #if defined(__GNU__)
+    #if defined(__386__)
+      #include <boost/mp_math/mp_int/detail/base/asm/x86/gnu_386_primitive_ops.hpp>
+    #endif
+  #endif
+
+#endif
+*/
 
 
+} // namespace base
 } // namespace detail
 } // namespace mp_math
 } // namespace boost
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/shifter.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/shifter.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,154 @@
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_SHIFTER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_SHIFTER_HPP
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+template<class ApInt, bool IsSigned=ApInt::is_signed>
+struct shifter;
+
+
+template<class ApInt>
+struct shifter<ApInt, false>
+{
+  typedef ApInt                          int_type;
+  typedef typename int_type::traits_type traits_type;
+  typedef typename traits_type::ops_type ops_type;
+  typedef typename int_type::digit_type  digit_type;
+  typedef typename int_type::size_type   size_type;
+
+  static void shift_bits_left (ApInt& z, size_type n);
+  static void shift_bits_right(ApInt& z, size_type n);
+
+  static void shift_digits_left(ApInt& z, size_type n);
+  static void shift_digits_right(ApInt& z, size_type n);
+};
+
+
+template<class ApInt>
+void shifter<ApInt,false>::shift_bits_left(ApInt& z, size_type n)
+{
+  assert(z != digit_type(0));
+
+  if (n)
+  {
+    // shift by as many digits in the bit count
+    if (n >= traits_type::radix_bits)
+      shift_digits_left(z, n / traits_type::radix_bits);
+
+    // shift any bit count < radix_bits
+    const digit_type b = static_cast<digit_type>(n % traits_type::radix_bits);
+
+    if (b)
+    {
+      const digit_type carry =
+        ops_type::shift_bits_left(z.digits(), z.size(), b);
+
+      if (carry)
+        z.push(carry);
+    }
+  }
+}
+
+template<class ApInt>
+void shifter<ApInt,false>::shift_bits_right(ApInt& z, size_type n)
+{
+  if (n)
+  {
+    // shift by as many digits in the bit count
+    if (n >= traits_type::radix_bits)
+      shift_digits_right(z, n / traits_type::radix_bits);
+
+    // shift any bit count < valid_bits
+    const digit_type b = n % traits_type::radix_bits;
+    if (b)
+      ops_type::shift_bits_right(z.digits(), z.size(), b);
+
+    z.clamp_high_digit();
+  }
+}
+
+// {A,B,C,D,E} shifted left by 2 digits becomes
+// {0,0,A,B,C,D,E}
+template<class ApInt>
+void shifter<ApInt,false>::shift_digits_left(ApInt& z, size_type n)
+{
+  assert(z != digit_type(0));
+
+  if (n == 0)
+    return;
+
+  std::memmove(z.digits() + n, z.digits(), z.size() * sizeof(digit_type));
+
+  // zero the lower digits
+  std::memset(z.digits(), 0, n * sizeof(digit_type));
+
+  z.set_size(z.size() + n);
+}
+
+// {A,B,C,D,E} shifted right by 2 digits becomes
+// {C,D,E}
+template<class ApInt>
+void shifter<ApInt,false>::shift_digits_right(ApInt& z, size_type n)
+{
+  if (n == 0)
+    return;
+
+  if (z.size() <= n)
+  {
+    z = digit_type(0);
+    return;
+  }
+
+  std::memmove(z.digits(), z.digits() + n, (z.size() - n) * sizeof(digit_type));
+
+  z.set_size(z.size() - n);
+}
+
+
+template<class ApInt>
+struct shifter<ApInt, true>
+{
+  typedef ApInt                          int_type;
+  typedef typename int_type::size_type   size_type;
+
+  static void shift_bits_left(ApInt& z, size_type n)
+  {
+    shifter<ApInt, false>::shift_bits_left(z, n);
+  }
+
+  static void shift_bits_right(ApInt& z, size_type n)
+  {
+    shifter<ApInt, false>::shift_bits_right(z, n);
+    if (!z)
+      z.set_sign_bit(0);
+  }
+
+  static void shift_digits_left(ApInt& z, size_type n)
+  {
+    shifter<ApInt, false>::shift_digits_left(z, n);
+  }
+
+  static void shift_digits_right(ApInt& z, size_type n)
+  {
+    shifter<ApInt, false>::shift_digits_right(z, n);
+  }
+};
+
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/to_integral.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/to_integral.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,183 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_TO_INTEGRAL_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_TO_INTEGRAL_HPP
+
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+// TODO throw std::overflow_error?
+
+template<
+  class ApInt,
+  typename IntegralT,
+  bool fits = static_cast<unsigned int>(std::numeric_limits<IntegralT>::digits)
+            <= ApInt::traits_type::radix_bits
+>
+struct converter_base;
+
+
+template<class ApInt, typename IntegralT>
+struct converter_base<ApInt, IntegralT, false>
+{
+  typedef typename ApInt::size_type size_type;
+  static IntegralT convert(const ApInt& x, size_type x_precision);
+};
+
+
+template<class ApInt, typename IntegralT>
+IntegralT
+converter_base<ApInt, IntegralT, false>::convert(
+    const ApInt& x, size_type x_precision)
+{
+  IntegralT y = 0;
+  const typename ApInt::digit_type* d = x.digits() + x.size() - 1;
+
+  for (size_type i = 0; i < x_precision; i += ApInt::traits_type::radix_bits)
+  {
+    y <<= ApInt::traits_type::radix_bits;
+    y |= *d--;
+  }
+  return y;
+}
+
+
+template<class ApInt, typename IntegralT>
+struct converter_base<ApInt, IntegralT, true>
+{
+  typedef typename ApInt::size_type size_type;
+  static IntegralT convert(const ApInt& x, size_type /*x_precision*/)
+  {
+    return static_cast<IntegralT>(x[0]);
+  }
+};
+
+
+template<
+  class ApInt,
+  typename IntegralT,
+  bool Is_ApInt_Signed = ApInt::is_signed,
+  bool Is_IntegralT_Signed = std::numeric_limits<IntegralT>::is_signed
+>
+struct to_integral_converter;
+
+
+template<class ApInt, typename IntegralT>
+struct to_integral_converter<ApInt, IntegralT, false, false>
+{
+  typedef typename ApInt::size_type size_type;
+
+  static IntegralT convert_without_check(const ApInt& x, size_type x_precision)
+  {
+    return converter_base<ApInt, IntegralT>::convert(x, x_precision);
+  }
+
+  static void check(size_type p)
+  {
+    if (p > static_cast<size_type>(std::numeric_limits<IntegralT>::digits))
+      throw std::runtime_error("to_integral_converter::check: "
+          "integral type does not have enough precision to hold result");
+  }
+
+  static IntegralT convert(const ApInt& x)
+  {
+    const size_type p = x.precision();
+    check(p);
+    return convert_without_check(x, p);
+  }
+};
+
+
+template<class ApInt, typename IntegralT>
+struct to_integral_converter<ApInt, IntegralT, false, true>
+{
+  typedef typename ApInt::size_type size_type;
+  typedef typename make_unsigned<IntegralT>::type unsigned_type;
+
+  static void check(size_type p)
+  {
+    to_integral_converter<ApInt, IntegralT, false, false>::check(p);
+  }
+
+  static IntegralT convert(const ApInt& x)
+  {
+    return static_cast<IntegralT>(
+        to_integral_converter<ApInt, unsigned_type, false, false>::convert(x));
+  }
+};
+
+
+template<class ApInt, typename IntegralT>
+struct to_integral_converter<ApInt, IntegralT, true, false>
+{
+  typedef typename ApInt::size_type size_type;
+
+  static void check(size_type p)
+  {
+    to_integral_converter<ApInt, IntegralT, false, false>::check(p);
+  }
+
+  static IntegralT convert(const ApInt& x)
+  {
+    const size_type p = x.precision();
+    check(p);
+    if (x.is_positive())
+      return to_integral_converter<ApInt, IntegralT, false, false>::
+        convert_without_check(x, p);
+    else
+      throw std::runtime_error("to_integral_converter::convert: "
+          "cannot convert negative number to unsigned integral type");
+  }
+};
+
+
+template<class ApInt, typename IntegralT>
+struct to_integral_converter<ApInt, IntegralT, true, true>
+{
+  typedef typename ApInt::size_type size_type;
+
+  static void check(size_type p)
+  {
+    // TODO static_cast<unsigned_type>(-IntegralT::min())
+    // check if x fits into the unsigned type,
+    // if yes then convert and check against the absolute min value and the max
+    // else throw exception
+    //
+    // It is not the right thing to check only the precision, change to non
+    // static member function, add reset member function, store precision as
+    // member variable and change signature to check(const ApInt& x);
+  }
+
+  static IntegralT convert(const ApInt& x)
+  {
+    const size_type p = x.precision();
+    check(p);
+
+    typedef typename make_unsigned<IntegralT>::type unsigned_type;
+    const unsigned_type y =
+      to_integral_converter<ApInt, unsigned_type, false, false>::
+        convert_without_check(x, p);
+
+    if (x.is_positive())
+      return static_cast<IntegralT>(y);
+    else
+      return -static_cast<IntegralT>(y);
+  }
+};
+
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_int.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_int.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,226 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_INT_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_INT_HPP
+
+#include <boost/mp_math/integer/detail/base/unbounded_int_integral.hpp>
+#include <boost/mp_math/integer/detail/base/unbounded_uint.hpp>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+// This class template inherits from unbounded_uint and adds functionality
+// which is meaningful to signed integers.
+
+// We store the sign in the high bit of capacity_ since capacity_ isn't updated
+// as often as size_. This also allows unbounded_uint to function
+// uninhibitedly since it will only update size_ but not capacity_.
+
+template<class Traits, bool Debug>
+struct unbounded_int
+:
+  unbounded_uint<Traits, Debug>
+{
+protected:
+
+  template<typename IntegralT>
+  struct integral_ops
+  :
+    unbounded_int_integral_ops<unbounded_int<Traits>, IntegralT>
+  {};
+
+public:
+
+  typedef Traits                              traits_type;
+  typedef unbounded_uint<Traits, Debug>       magnitude_type;
+  typedef typename magnitude_type::digit_type digit_type;
+  typedef typename magnitude_type::size_type  size_type;
+
+  static const bool is_signed = true;
+
+private:
+
+  static const size_type sign_bit_ =
+    size_type(1) << (std::numeric_limits<size_type>::digits - 1U);
+
+public:
+
+  unbounded_int(){}
+
+  unbounded_int(digit_type* d, size_type size, size_type capacity)
+  :
+    magnitude_type(d, size, capacity)
+  {}
+
+  bool is_positive() const
+  {
+    return !(magnitude_type::capacity_ & sign_bit_);
+  }
+
+  bool is_negative() const
+  {
+    return magnitude_type::capacity_ & sign_bit_;
+  }
+
+  size_type capacity() const
+  {
+    return magnitude_type::capacity_ & ~sign_bit_;
+  }
+
+  void set_capacity(size_type c)
+  {
+    magnitude_type::capacity_ = c | (magnitude_type::capacity_ & sign_bit_);
+  }
+
+  int sign() const
+  {
+    return (magnitude_type::capacity_ & sign_bit_) ? -1 : 1;
+  }
+
+  void set_sign(int s)
+  {
+    if (s == 1)
+      magnitude_type::capacity_ &= ~sign_bit_;
+    else
+      magnitude_type::capacity_ |= sign_bit_;
+  }
+
+  bool sign_bit() const { return magnitude_type::capacity_ & sign_bit_; }
+
+  void set_sign_bit(bool s)
+  {
+    magnitude_type::capacity_ &= ~sign_bit_;
+    magnitude_type::capacity_ |= static_cast<size_type>(s)
+                              << (std::numeric_limits<size_type>::digits - 1U);
+  }
+
+  unbounded_int& operator ++()
+  {
+    integral_ops<digit_type>::add(*this, 1);
+    return *this;
+  }
+
+  unbounded_int& operator --()
+  {
+    integral_ops<digit_type>::subtract(*this, 1);
+    return *this;
+  }
+
+  unbounded_int& operator |= (const unbounded_int& rhs)
+  {
+    bitwise_ops<unbounded_int>::or_bits(*this, *this, rhs);
+    return *this;
+  }
+
+  unbounded_int& operator &= (const unbounded_int& rhs)
+  {
+    bitwise_ops<unbounded_int>::and_bits(*this, *this, rhs);
+    return *this;
+  }
+
+  unbounded_int& operator ^= (const unbounded_int& rhs)
+  {
+    bitwise_ops<unbounded_int>::xor_bits(*this, *this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator += (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::add(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator -= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::subtract(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator *= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::multiply(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator /= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::divide(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator %= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::modulo(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator |= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::bitwise_or(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator &= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::bitwise_and(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator ^= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::bitwise_xor(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  IntegralT to_integral() const
+  {
+    return to_integral_converter<
+      unbounded_int<traits_type, Debug>, IntegralT>::convert(*this);
+  }
+
+  void truncate(size_type prec)
+  {
+    magnitude_type::truncate(prec);
+    if (magnitude_type::is_uninitialized())
+      set_sign_bit(0);
+  }
+
+  void print(bool all = false) const
+  {
+    if (is_negative())
+      std::cout << "-";
+    magnitude_type::print(all);
+  }
+};
+
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_int_fwd.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_int_fwd.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,23 @@
+// Copyright Kevin Sopp 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_INT_FWD_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_INT_FWD_HPP
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+template<class Traits, bool Debug = Traits::enable_debug_mode>
+struct unbounded_int;
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_int_integral.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_int_integral.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,905 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_INT_INTEGRAL_OPS_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_INT_INTEGRAL_OPS_HPP
+
+#include <boost/mp_math/integer/detail/base/unbounded_int_fwd.hpp>
+#include <boost/mp_math/integer/detail/base/unbounded_uint_integral.hpp>
+
+// Here we optimize interaction with built in integral types.
+// This code is hairy and subtle.
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+// We create four partial specializations out of this class template:
+// 1) IntegralT = digit_type,              is_signed = false
+// 2) IntegralT = make_signed<digit_type>, is_signed = true
+// 3) is_signed = false
+// 4) is_signed = true
+// The actual dispatching to the correct specialization is done in
+// unbounded_int_integral_ops.
+// All IntegralT that fit into a digit_type are dispatched to 1).
+// All IntegralT that fit into a 'signed digit_type' are dispatched to 2).
+// All IntegralT larger than a digit_type are dispatched to 3).
+// All IntegralT larger than a 'signed digit_type' are dispatched to 4).
+template<
+  class UnboundedInt,
+  typename IntegralT,
+  bool IsSigned = std::numeric_limits<IntegralT>::is_signed
+>
+struct unbounded_int_integral_ops_impl;
+
+
+// 1)
+template<class UnboundedInt>
+struct unbounded_int_integral_ops_impl<
+  UnboundedInt,
+  typename UnboundedInt::digit_type,
+  false
+>
+{
+  typedef UnboundedInt                             unbounded_int_type;
+  typedef typename unbounded_int_type::digit_type  integral_type;
+  typedef typename unbounded_int_type::traits_type traits_type;
+
+  typedef unbounded_uint_integral_ops<
+    unbounded_int_type, integral_type
+  >                                        magnitude_type_integral_ops;
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs[0] = rhs;
+    lhs.set_size(1);
+    lhs.set_sign_bit(0);
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.is_negative())
+      return false;
+    if (lhs.size() > 1)
+      return false;
+    return lhs[0] == rhs;
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.is_negative())
+      return true;
+    if (lhs.size() > 1)
+      return false;
+    return lhs[0] < rhs;
+  }
+
+  static void add     (unbounded_int_type& lhs, integral_type rhs);
+  static void subtract(unbounded_int_type& lhs, integral_type rhs);
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    multiply(lhs, lhs, rhs);
+  }
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y);
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::divide(lhs, rhs);
+    if (!lhs)
+      lhs.set_sign_bit(0);
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::modulo(lhs, rhs);
+    // TODO sign
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs[0] |= rhs;
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs[0] &= rhs;
+    lhs.set_sign_bit(0);
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs[0] ^= rhs;
+  }
+};
+
+
+template<class UnboundedInt>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt, typename UnboundedInt::digit_type, false
+>::add(unbounded_int_type& lhs, integral_type rhs)
+{
+  if (lhs.is_positive())
+    magnitude_type_integral_ops::add(lhs, rhs);
+  else
+  {
+    if (lhs[0] > rhs) // example: -16 + 5 = -11
+      lhs[0] -= rhs;
+    else
+    {
+      if (lhs.size() == 1) // example: -1 + 5 = 4, or -5 + 5 = 0
+      {
+        lhs[0] = rhs - lhs[0];
+        lhs.set_sign_bit(0);
+      }
+      else            // example -1000 + 5 = -995
+      {
+        traits_type::ops_type::subtract_single_digit(
+            lhs.digits(), lhs.digits(), lhs.size(), rhs);
+        lhs.clamp_high_digit();
+      }
+    }
+  }
+}
+
+template<class UnboundedInt>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt, typename UnboundedInt::digit_type, false
+>::subtract(unbounded_int_type& lhs, integral_type rhs)
+{
+  if (lhs.is_negative())
+  {
+    const integral_type carry =
+      traits_type::ops_type::add_single_digit(
+          lhs.digits(), lhs.digits(), lhs.size(), rhs);
+    if (carry)
+      lhs.push(carry);
+    return;
+  }
+
+  if (lhs.size() == 1)
+  {
+    if (lhs[0] < rhs) // example: 2 - 6 = -4
+    {
+      lhs[0] = rhs - lhs[0];
+      lhs.set_sign_bit(1);
+    }
+    else // example: 8 - 7 = 1 or 5 - 5 = 0
+      lhs[0] -= rhs;
+  }
+  else
+  {
+    traits_type::ops_type::subtract_single_digit(
+        lhs.digits(), lhs.digits(), lhs.size(), rhs);
+    lhs.clamp_high_digit();
+  }
+}
+
+template<class UnboundedInt>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt, typename UnboundedInt::digit_type, false
+>::multiply(unbounded_int_type& z,
+            const unbounded_int_type& x, integral_type y)
+{
+  if (y == 0)
+  {
+    assign(z, integral_type(0));
+    return;
+  }
+  else if (y == 1)
+    return;
+
+  const integral_type carry =
+    traits_type::ops_type::multiply_by_digit(
+        z.digits(), x.digits(), x.size(), y);
+
+  if (carry)
+    z.push(carry);
+}
+
+
+// 2)
+template<class UnboundedInt>
+struct unbounded_int_integral_ops_impl<
+  UnboundedInt,
+  typename make_signed<typename UnboundedInt::digit_type>::type,
+  true
+>
+{
+  typedef UnboundedInt                             unbounded_int_type;
+  typedef typename make_signed<
+    typename unbounded_int_type::digit_type
+  >::type                                          integral_type;
+  typedef std::numeric_limits<integral_type>       integral_type_limits;
+  typedef typename unbounded_int_type::traits_type traits_type;
+
+  typedef unbounded_int_integral_ops_impl<
+    unbounded_int_type,
+    typename unbounded_int_type::digit_type
+  >                                                impl_type;
+
+  typedef unbounded_uint_integral_ops<
+    typename unbounded_int_type::magnitude_type,
+    typename unbounded_int_type::digit_type
+  >                                                magnitude_type_integral_ops;
+
+  static const unsigned radix_bits = traits_type::radix_bits;
+  static const unsigned q =
+    (integral_type_limits::digits + (radix_bits - 1))
+    / radix_bits;
+
+  static typename unbounded_int_type::digit_type get_absolute(integral_type x)
+  {
+    if (x >= 0)
+      return static_cast<typename unbounded_int_type::digit_type>(x);
+    else
+      return static_cast<typename unbounded_int_type::digit_type>(-x);
+  }
+
+  static bool get_sign_bit(integral_type x)
+  {
+    if (x >= 0)
+      return 0;
+    else
+      return 1;
+  }
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs[0] = get_absolute(rhs);
+    lhs.set_size(1);
+    lhs.set_sign_bit(get_sign_bit(rhs));
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.sign_bit() == get_sign_bit(rhs))
+    {
+      return magnitude_type_integral_ops::equal(lhs, get_absolute(rhs));
+    }
+    else
+      return false;
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs);
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.sign_bit() == get_sign_bit(rhs))
+      magnitude_type_integral_ops::add(lhs, get_absolute(rhs));
+    else
+      impl_type::subtract(lhs, get_absolute(rhs));
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs);
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::multiply(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(lhs.sign_bit() ^ get_sign_bit(rhs));
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::divide(lhs, get_absolute(rhs));
+    if (lhs)
+      lhs.set_sign_bit(lhs.sign_bit() ^ get_sign_bit(rhs));
+    else
+      lhs.set_sign_bit(0);
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::modulo(lhs, get_absolute(rhs));
+    // TODO sign
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::bitwise_or(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(lhs.sign_bit() | get_sign_bit(rhs));
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::bitwise_and(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(lhs.sign_bit() & get_sign_bit(rhs));
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::bitwise_xor(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(lhs.sign_bit() ^ get_sign_bit(rhs));
+  }
+};
+
+
+template<class UnboundedInt>
+bool
+unbounded_int_integral_ops_impl<
+  UnboundedInt,
+  typename make_signed<typename UnboundedInt::digit_type>::type,
+  true
+>::less(const unbounded_int_type& lhs, integral_type rhs)
+{
+  if (lhs.is_positive())
+  {
+    if (rhs < 0)
+      return false;
+    else
+      return magnitude_type_integral_ops::less(lhs, get_absolute(rhs));
+  }
+  else
+  {
+    if (rhs >= 0)
+      return true;
+    else
+    {
+      if (lhs.size() <= q)
+      {
+        typedef to_integral_converter<
+          unbounded_int_type, integral_type> converter_type;
+
+        converter_type c;
+
+        const integral_type x = c.convert(lhs);
+
+        return x < rhs;
+      }
+      else
+        return true;
+    }
+  }
+
+}
+
+template<class UnboundedInt>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt,
+  typename make_signed<typename UnboundedInt::digit_type>::type,
+  true
+>::subtract(unbounded_int_type& lhs, integral_type rhs)
+{
+  if (lhs.is_positive())
+  {
+    if (rhs >= 0)
+      impl_type::subtract(lhs, get_absolute(rhs));
+    else
+      magnitude_type_integral_ops::add(lhs, get_absolute(rhs));
+  }
+  else
+  {
+    if (rhs >= 0)
+      magnitude_type_integral_ops::add(lhs, get_absolute(rhs));
+    else
+      impl_type::subtract(lhs, get_absolute(rhs));
+  }
+}
+
+
+// 3
+template<class UnboundedInt, typename IntegralT>
+struct unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, false
+>
+:
+  unbounded_uint_integral_ops_impl<UnboundedInt, IntegralT, false>
+{
+  typedef UnboundedInt                             unbounded_int_type;
+  typedef IntegralT                                integral_type;
+  typedef typename unbounded_int_type::traits_type traits_type;
+
+  typedef unbounded_uint_integral_ops<
+    typename unbounded_int_type::magnitude_type,
+    integral_type
+  >                                     magnitude_type_integral_ops;
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::assign(lhs, rhs);
+    lhs.set_sign_bit(0);
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.is_negative())
+      return false;
+    return magnitude_type_integral_ops::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.is_negative())
+      return true;
+    return magnitude_type_integral_ops::less(lhs, rhs);
+  }
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.is_positive())
+      magnitude_type_integral_ops::add(lhs, rhs);
+    else
+      subtract_smaller(lhs, rhs, 0);
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.is_negative())
+      magnitude_type_integral_ops::add(lhs, rhs);
+    else
+      subtract_smaller(lhs, rhs, ~lhs.sign_bit());
+  }
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::multiply(lhs, rhs);
+    if (!lhs)
+      lhs.set_sign_bit(0);
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::divide(lhs, rhs);
+    if (!lhs)
+      lhs.set_sign_bit(0);
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::modulo(lhs, rhs);
+    if (!lhs)
+      lhs.set_sign_bit(0);
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::bitwise_and(lhs, rhs);
+    lhs.set_sign_bit(0);
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::bitwise_xor(lhs, rhs);
+    lhs.set_sign_bit(lhs.sign_bit() ^ 0);
+  }
+
+  static void subtract_smaller(unbounded_int_type& lhs,
+                               integral_type rhs,
+                               bool final_sign);
+};
+
+
+template<class UnboundedInt, typename IntegralT>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, false
+>::subtract_smaller(unbounded_int_type& lhs,
+                    integral_type rhs,
+                    bool final_sign)
+{
+  static const unsigned radix_bits = traits_type::radix_bits;
+
+  static const unsigned q =
+    (std::numeric_limits<integral_type>::digits + (radix_bits - 1))
+    / radix_bits;
+
+  typedef unbounded_uint<traits_type> unbounded_uint_type;
+
+  typename traits_type::digit_type tmp_digits[q];
+
+  unbounded_uint_type tmp(tmp_digits, q, q);
+
+  from_integral_converter<
+    unbounded_uint_type, integral_type
+  >::convert(tmp, rhs);
+
+  const unbounded_uint_type* x;
+  const unbounded_uint_type* y;
+
+  if (!unbounded_uint_integral_ops<
+        unbounded_int_type, integral_type>::less(lhs, rhs)) // lhs >= rhs
+  {
+    x = &lhs;
+    y = &tmp;
+  }
+  else
+  {
+    x = &tmp;
+    y = &lhs;
+    lhs.set_sign_bit(final_sign);
+  }
+
+  traits_type::ops_type::sub_smaller_magnitude(
+      lhs.digits(), x->digits(), x->size(),
+                    y->digits(), y->size());
+
+  lhs.set_size(x->size());
+  lhs.clamp();
+
+  if (!lhs)
+    lhs.set_sign_bit(0);
+}
+
+
+// 4
+template<class UnboundedInt, typename IntegralT>
+struct unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, true
+>
+{
+  typedef UnboundedInt                                unbounded_int_type;
+  typedef IntegralT                                   integral_type;
+  typedef std::numeric_limits<integral_type>          integral_type_limits;
+  typedef typename unbounded_int_type::traits_type    traits_type;
+  typedef typename make_unsigned<integral_type>::type unsigned_integral_type;
+
+  typedef unbounded_uint_integral_ops<
+    typename unbounded_int_type::magnitude_type,
+    unsigned_integral_type
+  >                                          magnitude_type_integral_ops;
+
+  static const unsigned radix_bits = traits_type::radix_bits;
+  static const unsigned q =
+    (integral_type_limits::digits + (radix_bits - 1))
+    / radix_bits;
+
+  static unsigned_integral_type get_absolute(integral_type x)
+  {
+    if (x >= 0)
+      return static_cast<unsigned_integral_type>(x);
+    else
+      return static_cast<unsigned_integral_type>(-x);
+  }
+
+  static bool get_sign_bit(integral_type x)
+  {
+    if (x >= 0)
+      return 0;
+    else
+      return 1;
+  }
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::assign(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(get_sign_bit(rhs));
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.sign_bit() != get_sign_bit(rhs))
+      return false;
+    return magnitude_type_integral_ops::equal(lhs, get_absolute(rhs));
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs);
+
+  static void add     (unbounded_int_type& lhs, integral_type rhs);
+  static void subtract(unbounded_int_type& lhs, integral_type rhs);
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::multiply(lhs, get_absolute(rhs));
+    if (lhs)
+      lhs.set_sign_bit(lhs.sign_bit() ^ get_sign_bit(rhs));
+    else
+      lhs.set_sign_bit(0);
+  }
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y)
+  {
+    magnitude_type_integral_ops::multiply(z, x, get_absolute(y));
+    if (z)
+      z.set_sign_bit(x.sign_bit() ^ get_sign_bit(y));
+    else
+      z.set_sign_bit(0);
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::divide(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(lhs.sign_bit() ^ get_sign_bit(rhs));
+  }
+
+static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::modulo(lhs, get_absolute(rhs));
+    // TODO sign
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::bitwise_or(lhs, rhs);
+    lhs.set_sign_bit(lhs.sign_bit() | get_sign_bit(rhs));
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::bitwise_and(lhs, rhs);
+    lhs.set_sign_bit(lhs.sign_bit() & get_sign_bit(rhs));
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    magnitude_type_integral_ops::bitwise_xor(lhs, rhs);
+    lhs.set_sign_bit(lhs.sign_bit() ^ get_sign_bit(rhs));
+  }
+};
+
+
+template<class UnboundedInt, typename IntegralT>
+bool
+unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, true>::less(const unbounded_int_type& lhs,
+                                       integral_type rhs)
+{
+  if (lhs.is_positive())
+  {
+    if (rhs < 0)
+      return false;
+    else
+      return magnitude_type_integral_ops::less(lhs, get_absolute(rhs));
+  }
+  else
+  {
+    if (rhs >= 0)
+      return true;
+    else
+    {
+      if (lhs.size() <= q)
+      {
+        typedef to_integral_converter<
+          unbounded_int_type, integral_type> converter_type;
+
+        converter_type c;
+
+        const integral_type x = c.convert(lhs);
+
+        return x < rhs;
+      }
+      else
+        return true;
+    }
+  }
+}
+
+template<class UnboundedInt, typename IntegralT>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, true>::add(unbounded_int_type& lhs,
+                                      integral_type rhs)
+{
+  if (lhs.sign_bit() == get_sign_bit(rhs))
+    magnitude_type_integral_ops::add(lhs, get_absolute(rhs));
+  else
+    subtract_smaller(lhs, rhs, get_sign_bit(rhs));
+}
+
+template<class UnboundedInt, typename IntegralT>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, true>::subtract(unbounded_int_type& lhs,
+                                           integral_type rhs)
+{
+  if (lhs.sign_bit() != get_sign_bit(rhs))
+    magnitude_type_integral_ops::add(lhs, get_absolute(rhs));
+  else
+    subtract_smaller(lhs, rhs, ~lhs.sign_bit());
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////
+
+template<
+  class UnboundedInt,
+  typename IntegralT,
+  bool less_equal =
+      std::numeric_limits<IntegralT>::is_signed ?
+      (
+        std::numeric_limits<IntegralT>::digits <=
+        std::numeric_limits<
+          typename make_signed<typename UnboundedInt::digit_type>::type
+        >::digits
+      ):
+      (
+        std::numeric_limits<IntegralT>::digits <=
+        std::numeric_limits<typename UnboundedInt::digit_type>::digits
+      )
+>
+struct unbounded_int_integral_ops;
+
+
+// Dispatches integral types that fit into a digit_type by casting it to
+// digit_type or signed digit_type and using the specialization at the top.
+template<
+  class UnboundedInt,
+  typename IntegralT
+>
+struct unbounded_int_integral_ops<UnboundedInt,IntegralT,true>
+{
+  BOOST_STATIC_ASSERT(is_integral<IntegralT>::value);
+
+  typedef UnboundedInt unbounded_int_type;
+  typedef IntegralT    integral_type;
+
+  typedef unbounded_int_integral_ops_impl<
+    unbounded_int_type,
+    typename mpl::if_<
+      is_signed<integral_type>,
+      typename make_signed<
+        typename unbounded_int_type::digit_type
+      >::type,
+      typename unbounded_int_type::digit_type
+    >::type
+  >                    impl_type;
+
+  typedef typename impl_type::integral_type  to_integral_type;
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, static_cast<to_integral_type>(y));
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, static_cast<to_integral_type>(rhs));
+  }
+};
+
+
+template<
+  class UnboundedInt,
+  typename IntegralT
+>
+struct unbounded_int_integral_ops<UnboundedInt,IntegralT,false>
+{
+  BOOST_STATIC_ASSERT(is_integral<IntegralT>::value);
+
+  typedef UnboundedInt unbounded_int_type;
+  typedef IntegralT    integral_type;
+
+  typedef unbounded_int_integral_ops_impl<
+      unbounded_int_type, integral_type
+  >                     impl_type;
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, rhs);
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, rhs);
+  }
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, rhs);
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, rhs);
+  }
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, rhs);
+  }
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, y);
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, rhs);
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, rhs);
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, rhs);
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, rhs);
+  }
+};
+
+
+
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_uint.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_uint.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,881 @@
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_UINT_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_UINT_HPP
+
+#include <algorithm> // swap
+#include <cassert>
+#include <iostream>
+#include <iterator> // reverse_iterator
+#include <boost/config.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mp_math/integer/detail/base/adder.hpp>
+#include <boost/mp_math/integer/detail/base/bitwise_ops.hpp>
+#include <boost/mp_math/integer/detail/base/shifter.hpp>
+#include <boost/mp_math/integer/detail/base/to_integral.hpp>
+#include <boost/mp_math/integer/detail/base/unbounded_uint_integral.hpp>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+// The unbounded_uint_common class template provide all the functions that
+// don't need to allocate memory. This is useful for the optimization of some
+// high level algorithms where you allocate a pool of memory once and then
+// construct some unbounded_uint objects in it.
+
+// Internally the least significant digit is stored at digits_[0], while the
+// most significant is stored at digits_[size_-1].
+
+template<class Traits>
+struct unbounded_uint_common
+{
+protected:
+
+  template<typename IntegralT>
+  struct integral_ops
+  :
+    unbounded_uint_integral_ops<unbounded_uint_common<Traits>, IntegralT>
+  {};
+
+public:
+
+  typedef Traits                           traits_type;
+  typedef typename traits_type::digit_type digit_type;
+  typedef typename traits_type::size_type  size_type;
+
+  typedef digit_type&                           reference;
+  typedef const digit_type&                     const_reference;
+  typedef digit_type*                           iterator;
+  typedef const digit_type*                     const_iterator;
+  typedef std::reverse_iterator<iterator>       reverse_iterator;
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+  static const bool is_signed = false;
+
+  unbounded_uint_common(){}
+
+  unbounded_uint_common(digit_type* d, size_type size, size_type capacity)
+  :
+    digits_(d), size_(size), capacity_(capacity)
+  {}
+
+  #ifdef BOOST_HAS_RVALUE_REFS
+  void swap(unbounded_uint_common&& rhs);
+  #else
+  void swap(unbounded_uint_common& rhs);
+  #endif
+
+  iterator       begin()       { return digits_;         }
+  iterator       end  ()       { return digits_ + size_; }
+  const_iterator begin() const { return digits_;         }
+  const_iterator end  () const { return digits_ + size_; }
+  reverse_iterator       rbegin()       { return reverse_iterator(end());   }
+  reverse_iterator       rend  ()       { return reverse_iterator(begin()); }
+  const_reverse_iterator rbegin() const { return const_reverse_iterator(end());   }
+  const_reverse_iterator rend  () const { return const_reverse_iterator(begin()); }
+
+  digit_type&       operator[](size_type i)       { return digits_[i]; }
+  const digit_type& operator[](size_type i) const { return digits_[i]; }
+
+  digit_type*       digits()       { return digits_; }
+  const digit_type* digits() const { return digits_; }
+
+#ifdef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
+private:
+
+  typedef size_type unbounded_uint_common::*unspecified_bool_type;
+
+public:
+
+  operator unspecified_bool_type() const
+  {
+	  return !(size_ == 1 && digits_[0] == 0) ?
+           &unbounded_uint_common::size_ : 0;
+  }
+#else
+  explicit operator bool() const { return !(size_ == 1 && digits_[0] == 0); }
+#endif
+
+  bool is_even() const { return (digits_[0] & 1U) == 0U; }
+  bool is_odd () const { return (digits_[0] & 1U) == 1U; }
+  bool is_initialized  () const { return size_ != 0U; }
+  bool is_uninitialized() const { return size_ == 0U; }
+
+  size_type size() const          { return size_; }
+  void      set_size(size_type s) { size_ = s;    }
+
+  size_type capacity() const          { return capacity_; }
+  void      set_capacity(size_type c) { capacity_ = c;    }
+
+  void push(digit_type x) { digits_[size_++] = x; }
+  void pop() { --size_; }
+
+  reference       least_significant()       { return digits_[0]; }
+  const_reference least_significant() const { return digits_[0]; }
+
+  reference       most_significant()       { return digits_[size_ - 1]; }
+  const_reference most_significant() const { return digits_[size_ - 1]; }
+
+  void clamp();
+  void clamp_high_digit();
+
+  void set_bit(size_type bit)
+  {
+    digits_[bit / traits_type::radix_bits] |=
+      digit_type(1) << (bit % traits_type::radix_bits);
+  }
+
+  void clear_bit(size_type bit)
+  {
+    digits_[bit / traits_type::radix_bits] &=
+      ~(digit_type(1) << (bit % traits_type::radix_bits));
+  }
+
+  void set_bits  (size_type beg, size_type end);
+  void clear_bits(size_type beg, size_type end);
+
+  void truncate(size_type prec);
+
+  size_type precision() const;
+
+  void set_precision(size_type bits)
+  {
+    size_ = (bits + (traits_type::radix_bits - 1)) / traits_type::radix_bits;
+  }
+
+  void zero();
+
+  size_type count_trailing_zero_bits() const;
+
+  unbounded_uint_common& operator ++()
+  {
+    integral_ops<digit_type>::add(*this, 1);
+    return *this;
+  }
+
+  unbounded_uint_common& operator --()
+  {
+    integral_ops<digit_type>::subtract(*this, 1);
+    return *this;
+  }
+
+  unbounded_uint_common& operator <<= (size_type);
+  unbounded_uint_common& operator >>= (size_type);
+
+  unbounded_uint_common& operator += (const unbounded_uint_common&);
+  unbounded_uint_common& operator -= (const unbounded_uint_common&);
+
+  unbounded_uint_common& operator |= (const unbounded_uint_common& rhs)
+  {
+    bitwise_ops<unbounded_uint_common>::or_bits(*this, *this, rhs);
+    return *this;
+  }
+
+  unbounded_uint_common& operator &= (const unbounded_uint_common& rhs)
+  {
+    bitwise_ops<unbounded_uint_common>::and_bits(*this, *this, rhs);
+    return *this;
+  }
+
+  unbounded_uint_common& operator ^= (const unbounded_uint_common& rhs)
+  {
+    bitwise_ops<unbounded_uint_common>::xor_bits(*this, *this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint_common&>::type
+  operator += (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::add(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint_common&>::type
+  operator -= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::subtract(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint_common&>::type
+  operator *= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::multiply(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint_common&>::type
+  operator /= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::divide(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint_common&>::type
+  operator %= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::modulo(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint_common&>::type
+  operator |= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::bitwise_or(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint_common&>::type
+  operator &= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::bitwise_and(*this, rhs);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint_common&>::type
+  operator ^= (IntegralT rhs)
+  {
+    integral_ops<IntegralT>::bitwise_xor(*this, rhs);
+    return *this;
+  }
+
+  // TODO it may not be possible to do the string stuff correctly because we
+  // can't just call *this += uint_type(s). We could implement some kind of
+  // digit_type iterator that iterates over the string and returns a digit_type.
+  // and then write the algorithm in such a way that it retrieves the next digit
+  // on demand. This may be too slow for things like *= wich jumps all over the
+  // place with its memory accesses.
+  template<typename charT> unbounded_uint_common& operator += (const charT*);
+  template<typename charT> unbounded_uint_common& operator -= (const charT*);
+  template<typename charT> unbounded_uint_common& operator |= (const charT*);
+  template<typename charT> unbounded_uint_common& operator &= (const charT*);
+  template<typename charT> unbounded_uint_common& operator ^= (const charT*);
+
+  template<typename charT, class traits, class alloc>
+  unbounded_uint_common&
+  operator += (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint_common&
+  operator -= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint_common&
+  operator |= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint_common&
+  operator &= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint_common&
+  operator ^= (const std::basic_string<charT,traits,alloc>&);
+
+  void print(bool all = false) const;
+
+  template<typename IntegralT>
+  IntegralT to_integral() const
+  {
+    return to_integral_converter<
+      unbounded_uint_common<traits_type>, IntegralT>::convert(*this);
+  }
+
+protected:
+
+  digit_type* digits_;
+  size_type   size_;
+  size_type   capacity_;
+};
+
+
+template<class Traits>
+#ifdef BOOST_HAS_RVALUE_REFS
+void unbounded_uint_common<Traits>::swap(unbounded_uint_common&& rhs)
+#else
+void unbounded_uint_common<Traits>::swap(unbounded_uint_common& rhs)
+#endif
+{
+  std::swap(digits_,   rhs.digits_  );
+  std::swap(size_,     rhs.size_    );
+  std::swap(capacity_, rhs.capacity_);
+}
+
+template<class Traits>
+inline void swap(unbounded_uint_common<Traits>& x,
+                 unbounded_uint_common<Traits>& y)
+{
+  x.swap(y);
+}
+
+#ifdef BOOST_HAS_RVALUE_REFS
+template<class Traits>
+inline void swap(unbounded_uint_common<Traits>&& x,
+                 unbounded_uint_common<Traits>& y)
+{
+  x.swap(y);
+}
+
+template<class Traits>
+inline void swap(unbounded_uint_common<Traits>& x,
+                 unbounded_uint_common<Traits>&& y)
+{
+  x.swap(y);
+}
+#endif
+
+// This is used to ensure that leading zero digits are trimmed.
+template<class Traits>
+void unbounded_uint_common<Traits>::clamp()
+{
+  while (size_ > 1U && digits_[size_-1] == 0U)
+    --size_;
+}
+
+// For when we know that only one leading zero digit may exist.
+template<class Traits>
+inline void unbounded_uint_common<Traits>::clamp_high_digit()
+{
+  if (size_ > 1U && digits_[size_-1] == 0U)
+    --size_;
+}
+
+template<class Traits>
+void
+unbounded_uint_common<Traits>::set_bits(size_type beg, size_type end)
+{
+  const size_type beg_index  = beg / traits_type::digit_bits;
+  const size_type end_index  = end / traits_type::digit_bits;
+  const size_type first_bits = beg % traits_type::digit_bits;
+  const size_type last_bits  = end % traits_type::digit_bits;
+
+  static const digit_type z = ~digit_type(0);
+
+  digit_type mask = z << first_bits;
+  if (beg_index == end_index && last_bits)
+    mask &= z >> (traits_type::digit_bits - last_bits);
+
+  digits_[beg_index] |= mask;
+
+  for (size_type i = beg_index + ((beg % traits_type::digit_bits) ? 1 : 0);
+       i < end_index; ++i)
+    digits_[i] = traits_type::max_digit_value;
+
+  if (beg_index != end_index && last_bits)
+    digits_[end_index] |= z >> (traits_type::digit_bits - last_bits);
+}
+
+template<class Traits>
+void
+unbounded_uint_common<Traits>::clear_bits(size_type beg, size_type end)
+{
+  const size_type beg_index  = beg / traits_type::digit_bits;
+  const size_type end_index  = end / traits_type::digit_bits;
+  const size_type first_bits = beg % traits_type::digit_bits;
+  const size_type last_bits  = end % traits_type::digit_bits;
+
+  static const digit_type z = ~digit_type(0);
+
+  digit_type mask;
+  if (first_bits)
+    mask = z >> (traits_type::digit_bits - first_bits);
+  else
+    mask = 0;
+
+  if (beg_index == end_index)
+    mask |= z << last_bits;
+
+  digits_[beg_index] &= mask;
+
+  if (beg_index != end_index)
+  {
+    std::memset(digits_ + beg_index + 1, 0,
+        sizeof(digit_type) * (end_index - beg_index - 1));
+
+    if (last_bits)
+      digits_[end_index] &= z << last_bits;
+  }
+}
+
+// TODO no need to call clamp after truncate since we call set_precision here
+template<class Traits>
+void unbounded_uint_common<Traits>::truncate(size_type prec)
+{
+  set_precision(prec);
+  const size_type last_bits = prec % traits_type::radix_bits;
+  if (last_bits)
+  {
+    static const digit_type z = ~digit_type(0);
+    const digit_type mask = z >> (traits_type::radix_bits - last_bits);
+    digits_[size_ - 1] &= mask;
+  }
+}
+
+template<class Traits>
+typename unbounded_uint_common<Traits>::size_type
+unbounded_uint_common<Traits>::precision() const
+{
+  if (is_initialized())
+  {
+    size_type p = (size_ - 1) * traits_type::radix_bits;
+
+    // count bits in most significant digit
+    digit_type q = digits_[size_ - 1];
+    while (q > 0U)
+    {
+      ++p;
+      q >>= 1;
+    }
+
+    return p;
+  }
+  else
+    return 0;
+}
+
+// TODO remove this function?
+template<class Traits>
+inline void unbounded_uint_common<Traits>::zero()
+{
+  digits_[0] = 0;
+  size_ = 1;
+}
+
+// Counts the number of lsbs which are zero before the first one bit
+template<class Traits>
+typename unbounded_uint_common<Traits>::size_type
+unbounded_uint_common<Traits>::count_trailing_zero_bits() const
+{
+  static const size_type lnz[16] = {
+    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+  };
+
+  if (!*this)
+    return 0;
+
+  size_type bits = 0;
+
+  // scan lower digits until non-zero
+  const_iterator d = begin();
+  while (bits < size_ && *d == 0)
+  {
+    ++bits;
+    ++d;
+  }
+
+  bits *= traits_type::radix_bits;
+
+  digit_type q = *d;
+  // now scan this digit until a 1 is found
+  if ((q & 1) == 0)
+  {
+    digit_type qq;
+    do
+    {
+      qq    = q & 15;
+      bits += lnz[qq];
+      q >>= 4;
+    } while (qq == 0);
+  }
+
+  return bits;
+}
+
+template<class Traits>
+void unbounded_uint_common<Traits>::print(bool all) const
+{
+  using std::cout;
+  cout << size_ << "{";
+  for (size_type i = 0; i < size(); ++i)
+  {
+    cout << static_cast<typename traits_type::word_type>(digits()[i]);
+    if (i < size()  - 1)
+      cout << ",";
+  }
+  cout << "}";
+
+  if (all)
+  {
+    cout << capacity() - size() << "{";
+    for (size_type i = size(); i < capacity(); ++i)
+    {
+      cout << static_cast<typename traits_type::word_type>(digits()[i]);
+      if (i < capacity()  - 1)
+        cout << ",";
+    }
+    cout << "}";
+  }
+  cout << "\n";
+}
+
+
+template<class Traits>
+unbounded_uint_common<Traits>&
+unbounded_uint_common<Traits>::operator <<= (const size_type n)
+{
+  if (*this != digit_type(0))
+    shifter<unbounded_uint_common<Traits> >::shift_bits_left(*this, n);
+  return *this;
+}
+
+template<class Traits>
+unbounded_uint_common<Traits>&
+unbounded_uint_common<Traits>::operator >>= (const size_type n)
+{
+  shifter<unbounded_uint_common<Traits> >::shift_bits_right(*this, n);
+  return *this;
+}
+
+template<class Traits>
+unbounded_uint_common<Traits>&
+unbounded_uint_common<Traits>::
+operator += (const unbounded_uint_common<Traits>& rhs)
+{
+  const unbounded_uint_common<Traits> *a, *b;
+  if (size() > rhs.size())
+  {
+    a = this;
+    b = &rhs;
+  }
+  else
+  {
+    a = &rhs;
+    b = this;
+  }
+
+  typedef adder<unbounded_uint_common<Traits> > adder_type;
+
+  adder_type::add_smaller_magnitude(*this, *a, *b);
+
+  return *this;
+}
+
+template<class Traits>
+unbounded_uint_common<Traits>&
+unbounded_uint_common<Traits>::
+operator -= (const unbounded_uint_common<Traits>& rhs)
+{
+  const unbounded_uint_common<Traits> *a, *b;
+  if (size() > rhs.size())
+  {
+    a = this;
+    b = &rhs;
+  }
+  else
+  {
+    a = &rhs;
+    b = this;
+  }
+
+  typedef adder<unbounded_uint_common<Traits> > adder_type;
+
+  adder_type::subtract_smaller_magnitude(*this, *a, *b);
+
+  return *this;
+}
+
+/*
+template<class Traits>
+unbounded_uint_common<Traits>&
+unbounded_uint_common<Traits>::
+operator |= (const unbounded_uint_common<Traits>& rhs)
+{
+  if (size() < rhs.size())
+  {
+    std::memcpy(digits() + size(),
+                rhs.digits() + size(),
+                (rhs.size() - size()) * sizeof(digit_type));
+    set_size(rhs.size());
+  }
+
+  for (size_type i = 0; i < std::min(size(), rhs.size()); ++i)
+    digits()[i] |= rhs[i];
+
+  return *this;
+}
+
+template<class Traits>
+unbounded_uint_common<Traits>&
+unbounded_uint_common<Traits>::
+operator &= (const unbounded_uint_common<Traits>& rhs)
+{
+  const size_type m = std::min(size(), rhs.size());
+
+  for (size_type i = 0; i < m; ++i)
+    digits()[i] &= rhs[i];
+
+  set_size(m);
+  clamp();
+
+  return *this;
+}
+
+template<class Traits>
+unbounded_uint_common<Traits>&
+unbounded_uint_common<Traits>::
+operator ^= (const unbounded_uint_common<Traits>& rhs)
+{
+  const size_type min = std::min(size(), rhs.size());
+
+  if (size() < rhs.size())
+  {
+    std::memcpy(digits() + size(),
+                rhs.digits() + size(),
+                (rhs.size() - size()) * sizeof(digit_type));
+    set_size(rhs.size());
+  }
+
+  for (size_type i = 0; i < min; ++i)
+    digits()[i] ^= rhs[i];
+
+  clamp();
+
+  return *this;
+}*/
+
+
+
+
+
+
+
+/*
+
+// x += y
+template<class Traits, bool Debug>
+void add_smaller_magnitude(unbounded_uint<Traits,Debug>& x,
+                           const unbounded_uint<Traits,Debug>& y)
+{
+  assert(x.size() > y.size());
+
+  const digit_type carry =
+    traits_type::ops_type::add_digits(x.digits(),
+                                      x.digits(),
+                                      y.digits(), y.size());
+
+  size_type n =
+    traits_type::ops_type::ripple_carry(x.digits() + y.size(),
+                                        x.digits() + y.size(),
+                                        x.size() - y.size(), carry);
+  n += y.size();
+
+  if (n < x.size()) // this implies that there is no carry left
+    return;
+  else if (carry) // at this point n equals x->size_
+    x[n++] = carry;
+
+  x.set_size(n);
+}
+
+// x -= y
+template<class Traits, bool Debug>
+void sub_smaller_magnitude()
+{
+  traits_type::ops_type::sub_smaller_magnitude(digits(),
+                                               x->digits(), x->size(),
+                                               y->digits(), y->size());
+
+  set_size(x->size());
+
+  clamp();
+}*/
+
+
+template<class Traits>
+inline
+bool operator < (const unbounded_uint_common<Traits>& lhs,
+                 const unbounded_uint_common<Traits>& rhs)
+{
+  const int b = Traits::ops_type::compare_magnitude(lhs.digits(), lhs.size(),
+                                                    rhs.digits(), rhs.size());
+  return b == -1;
+}
+
+template<class Traits>
+inline
+bool operator > (const unbounded_uint_common<Traits>& lhs,
+                 const unbounded_uint_common<Traits>& rhs)
+{
+  const int b = Traits::ops_type::compare_magnitude(lhs.digits(), lhs.size(),
+                                                    rhs.digits(), rhs.size());
+  return b == 1;
+}
+
+template<class Traits>
+inline
+bool operator <= (const unbounded_uint_common<Traits>& lhs,
+                  const unbounded_uint_common<Traits>& rhs)
+{
+  const int b = Traits::ops_type::compare_magnitude(lhs.digits(), lhs.size(),
+                                                    rhs.digits(), rhs.size());
+  return b != 1;
+}
+
+template<class Traits>
+inline
+bool operator >= (const unbounded_uint_common<Traits>& lhs,
+                  const unbounded_uint_common<Traits>& rhs)
+{
+  const int b = Traits::ops_type::compare_magnitude(lhs.digits(), lhs.size(),
+                                                    rhs.digits(), rhs.size());
+  return b != -1;
+}
+
+
+
+
+
+
+
+// Now we add a layer of debug functionality. This functionality
+// is meant to be used by developers that develop new algorithms for this
+// library.
+template<class Traits>
+struct unbounded_uint<Traits, false>
+:
+  unbounded_uint_common<Traits>
+{
+  typedef unbounded_uint_common<Traits> base_type;
+
+  typedef Traits traits_type;
+  typedef typename traits_type::digit_type digit_type;
+  typedef typename traits_type::size_type  size_type;
+
+  unbounded_uint(){}
+
+  unbounded_uint(digit_type* d, size_type size, size_type capacity)
+  :
+    base_type(d, size, capacity)
+  {}
+
+  void assert_invariants() const{}
+};
+
+
+template<class Traits>
+struct unbounded_uint<Traits, true>
+:
+  unbounded_uint_common<Traits>
+{
+  typedef unbounded_uint_common<Traits> base_type;
+
+  typedef Traits traits_type;
+  typedef typename traits_type::digit_type digit_type;
+  typedef typename traits_type::size_type  size_type;
+
+  unbounded_uint(){}
+
+  unbounded_uint(digit_type* d, size_type size, size_type capacity)
+  :
+    base_type(d, size, capacity)
+  {}
+
+  // replace some inherited functions from the base class with debug versions
+/*  digit_type&       operator[](size_type i)
+  {
+    assert(i < base_type::size_);
+    return digits_[i];
+  }
+
+  const digit_type& operator[](size_type i) const
+  {
+    assert(i < size_)
+    return digits_[i];
+  }
+
+  void push(digit_type x)
+  {
+    assert(size_ < capacity());
+    digits_[size_++] = x;
+  }
+
+  void pop()
+  {
+    assert(size_ > 0);
+    --size_;
+  }
+
+  void set_bit  (size_type bit);
+  void clear_bit(size_type bit);
+
+  void set_bits  (size_type beg, size_type end);
+  void clear_bits(size_type beg, size_type end);
+
+  void set_precision(size_type bits);*/
+
+  void assert_invariants() const;
+};
+
+/*
+template<class Traits>
+void unbounded_uint<Traits,true>::set_bit(size_type bit)
+{
+  const size_type index = bit / traits_type::radix_bits;
+  assert(index < size_);
+  base_type::set_bit(bit);
+}
+
+template<class Traits>
+void unbounded_uint<Traits,true>::clear_bit(size_type bit)
+{
+  const size_type index = bit / traits_type::radix_bits;
+  assert(index < size_);
+  base_type::clear_bit(bit);
+}
+
+template<class Traits>
+void unbounded_uint<Traits,true>::set_bits(size_type beg, size_type end)
+{
+  assert(beg < end);
+  const size_type index = bit / traits_type::radix_bits;
+  assert(index < size_);
+  base_type::set_bits(beg, end);
+}
+
+template<class Traits>
+void unbounded_uint<Traits,true>::clear_bits(size_type beg, size_type end)
+{
+  assert(beg < end);
+  const size_type index = bit / traits_type::radix_bits;
+  assert(index < size_);
+  base_type::clear_bits(beg, end);
+}
+
+template<class Traits>
+void unbounded_uint<Traits,true>::set_precision(size_type bits)
+{
+  const size_type new_size = bits / traits_type::radix_bits;
+  assert(new_size < this->capacity());
+  base_type::set_precision();
+}*/
+
+template<class Traits>
+void unbounded_uint<Traits,true>::assert_invariants() const
+{
+  if (base_type::is_initialized())
+  {
+    assert(base_type::size() <= base_type::capacity());
+    if (base_type::size() > 1U)
+      assert(base_type::digits()[base_type::size()-1] != 0U);
+  }
+}
+
+
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_uint_fwd.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_uint_fwd.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,26 @@
+// Copyright Kevin Sopp 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_UINT_FWD_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_UINT_FWD_HPP
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+template<class Traits>
+struct unbounded_uint_common;
+
+template<class Traits, bool Debug = Traits::enable_debug_mode>
+struct unbounded_uint;
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_uint_integral.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/unbounded_uint_integral.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,1044 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_UINT_INTEGRAL_OPS_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_BASE_UNBOUNDED_UINT_INTEGRAL_OPS_HPP
+
+#include <boost/static_assert.hpp>
+#include <boost/mpl/less_equal.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/make_signed.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+#include <boost/mp_math/integer/detail/base/from_integral.hpp>
+#include <boost/mp_math/integer/detail/base/to_integral.hpp>
+#include <boost/mp_math/integer/detail/base/unbounded_uint_fwd.hpp>
+
+// Here we optimize interaction with built in integral types.
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+namespace base {
+
+template<
+  typename IntegralT,
+  bool IsSigned = std::numeric_limits<IntegralT>::is_signed
+>
+struct integral_info;
+
+
+template<typename IntegralT>
+struct integral_info<IntegralT, false>
+{
+  typedef IntegralT integral_type;
+  typedef typename make_signed<integral_type>::type signed_integral_type;
+
+  static const bool is_signed = false;
+};
+
+
+template<typename IntegralT>
+struct integral_info<IntegralT, true>
+{
+  typedef IntegralT integral_type;
+  typedef typename make_unsigned<integral_type>::type unsigned_integral_type;
+
+  static unsigned_integral_type get_absolute(integral_type x)
+  {
+    if (x >= 0)
+      return static_cast<unsigned_integral_type>(x);
+    else
+      return static_cast<unsigned_integral_type>(-x);
+  }
+
+  static bool get_sign_bit(integral_type x)
+  {
+    if (x >= 0)
+      return 0;
+    else
+      return 1;
+  }
+
+  static const bool is_signed = true;
+};
+
+
+// We create four partial specializations out of this class template:
+// 1) IntegralT = digit_type,              is_signed = false
+// 2) IntegralT = make_signed<digit_type>, is_signed = true
+// 3) is_signed = false
+// 4) is_signed = true
+// The actual dispatching to the correct specialization is done in
+// unbounded_uint_integral_ops.
+// All IntegralT that fit into a digit_type are dispatched to 1).
+// All IntegralT that fit into a 'signed digit_type' are dispatched to 2).
+// All IntegralT larger than a digit_type are dispatched to 3).
+// All IntegralT larger than a 'signed digit_type' are dispatched to 4).
+template<
+  class UnboundedUInt,
+  typename IntegralT,
+  bool IsSigned = std::numeric_limits<IntegralT>::is_signed
+>
+struct unbounded_uint_integral_ops_impl;
+
+
+// 1)
+template<class UnboundedUInt>
+struct unbounded_uint_integral_ops_impl<
+  UnboundedUInt,
+  typename UnboundedUInt::digit_type,
+  false
+>
+{
+  typedef UnboundedUInt                             unbounded_uint_type;
+  typedef typename unbounded_uint_type::digit_type  integral_type;
+  typedef typename unbounded_uint_type::traits_type traits_type;
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs[0] = rhs;
+    lhs.set_size(1);
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    if (lhs.size() > 1)
+      return false;
+    return lhs[0] == rhs;
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    if (lhs.size() > 1)
+      return false;
+    return lhs[0] < rhs;
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    const integral_type carry =
+      traits_type::ops_type::add_single_digit(
+          lhs.digits(), lhs.digits(), lhs.size(), rhs);
+    if (carry)
+      lhs.push(carry);
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs);
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    multiply(lhs, lhs, rhs);
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y);
+
+  static void divide  (unbounded_uint_type& lhs, integral_type rhs);
+  static void modulo  (unbounded_uint_type& lhs, integral_type rhs);
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs[0] |= rhs;
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs[0] &= rhs;
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs[0] ^= rhs;
+  }
+};
+
+
+template<class UnboundedUInt>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, typename UnboundedUInt::digit_type, false
+>::subtract(unbounded_uint_type& lhs, integral_type rhs)
+{
+  if (!less(lhs, rhs))
+  {
+    if (lhs.size() == 1)
+      lhs[0] -= rhs;
+    else
+    {
+      traits_type::ops_type::subtract_single_digit(
+          lhs.digits(), lhs.digits(), lhs.size(), rhs);
+      lhs.clamp_high_digit();
+    }
+  }
+  else
+    throw std::runtime_error("unbounded_uint_integral_ops_impl::subtract: "
+        "result is negative");
+}
+
+template<class UnboundedUInt>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, typename UnboundedUInt::digit_type, false
+>::multiply(unbounded_uint_type& z,
+            const unbounded_uint_type& x, integral_type y)
+{
+  if (y == 0)
+  {
+    assign(z, integral_type(0));
+    return;
+  }
+  else if (y == 1)
+    return;
+
+  const integral_type carry =
+    traits_type::ops_type::multiply_by_digit(
+        z.digits(), x.digits(), x.size(), y);
+
+  if (carry)
+    z.push(carry);
+}
+
+template<class UnboundedUInt>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, typename UnboundedUInt::digit_type, false
+>::divide(unbounded_uint_type& lhs, integral_type rhs)
+{
+  if (rhs == 0)
+    throw std::domain_error(
+        "unbounded_uint_integral_ops_impl::divide: division by zero");
+
+  if (rhs == 1 || !lhs)
+    return;
+
+  const bool is_power_of_two = (rhs & (rhs-1)) == 0;
+
+  if (!is_power_of_two)
+    traits_type::ops_type::divide_by_digit(
+        lhs.digits(), lhs.digits(), lhs.size(), rhs);
+  else
+  {
+    integral_type i = 2;
+    while ((i < traits_type::radix_bits) && (rhs != integral_type(1) << i))
+      ++i;
+
+    traits_type::ops_type::shift_bits_right(lhs.digits(), lhs.size(), i);
+  }
+
+  lhs.clamp_high_digit();
+}
+
+template<class UnboundedUInt>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, typename UnboundedUInt::digit_type, false
+>::modulo(unbounded_uint_type& lhs, integral_type rhs)
+{
+  if (rhs == 0)
+    throw std::domain_error(
+        "unbounded_uint_integral_ops_impl::modulo: division by zero");
+
+  if (rhs == 1 || !lhs)
+  {
+    assign(lhs, 0);
+    return;
+  }
+
+  const bool is_power_of_two = (rhs & (rhs-1)) == 0;
+
+  if (!is_power_of_two)
+    lhs[0] =
+      traits_type::ops_type::divide_by_digit(
+          lhs.digits(), lhs.digits(), lhs.size(), rhs);
+  else
+  {
+    integral_type i = 2;
+    while ((i < traits_type::radix_bits) && (rhs != integral_type(1) << i))
+      ++i;
+
+    lhs[0] &= ((integral_type(1) << i) - 1);
+  }
+
+  lhs.set_size(1);
+}
+
+
+
+// 2)
+// just casts to digit_type and dispatches to above specialization
+template<class UnboundedUInt>
+struct unbounded_uint_integral_ops_impl<
+  UnboundedUInt,
+  typename make_signed<typename UnboundedUInt::digit_type>::type,
+  true
+>
+{
+  typedef UnboundedUInt                             unbounded_uint_type;
+  typedef typename make_signed<
+    typename unbounded_uint_type::digit_type
+  >::type                                           integral_type;
+
+  typedef typename unbounded_uint_type::digit_type  unsigned_integral_type;
+
+  typedef unbounded_uint_integral_ops_impl<
+    unbounded_uint_type,
+    unsigned_integral_type
+  > impl_type;
+
+  static unsigned_integral_type promote(integral_type rhs)
+  {
+    // TODO if (rhs < 0)
+    //  throw integral_promotion_error();
+    return static_cast<unsigned_integral_type>(rhs);
+  }
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, static_cast<unsigned_integral_type>(y));
+  }
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+};
+
+
+// 3
+template<class UnboundedUInt, typename IntegralT>
+struct unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false
+>
+{
+  typedef UnboundedUInt                             unbounded_uint_type;
+  typedef IntegralT                                 integral_type;
+  typedef std::numeric_limits<integral_type>        integral_type_limits;
+  typedef typename unbounded_uint_type::traits_type traits_type;
+
+  static const unsigned radix_bits      = traits_type::radix_bits;
+  static const unsigned max_digit_value = traits_type::max_digit_value;
+
+  static const unsigned q =
+    (integral_type_limits::digits + (radix_bits - 1))
+    / radix_bits;
+
+  static void assign  (unbounded_uint_type& lhs, integral_type rhs);
+  static bool equal   (const unbounded_uint_type& lhs, integral_type rhs);
+  static bool less    (const unbounded_uint_type& lhs, integral_type rhs);
+  static void add     (unbounded_uint_type& lhs, integral_type rhs);
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs);
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs);
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y);
+  static void divide  (unbounded_uint_type& lhs, integral_type rhs);
+  static void modulo  (unbounded_uint_type& lhs, integral_type rhs);
+
+  static void bitwise_or (unbounded_uint_type& lhs, integral_type rhs);
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs);
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs);
+
+  typedef typename traits_type::digit_type digit_type;
+};
+
+
+template<class UnboundedUInt, typename IntegralT>
+const unsigned unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::q;
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::assign(unbounded_uint_type& lhs,
+                                           integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    lhs[0] = static_cast<digit_type>(rhs);
+    lhs.set_size(1);
+  }
+  else
+  {
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(lhs, rhs);
+  }
+}
+
+template<class UnboundedUInt, typename IntegralT>
+bool
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::equal(const unbounded_uint_type& lhs,
+                                          integral_type rhs)
+{
+  if (lhs.size() <= q)
+  {
+    typedef to_integral_converter<
+      unbounded_uint_type, integral_type> converter_type;
+
+    converter_type c;
+
+    // TODO it's faster to convert from integral type but comparison is faster
+    // between integral types, measure which one is better!
+    const integral_type x = c.convert(lhs);
+
+    return x == rhs;
+  }
+
+  return false;
+}
+
+template<class UnboundedUInt, typename IntegralT>
+bool
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::less(const unbounded_uint_type& lhs,
+                                         integral_type rhs)
+{
+  // TODO reroute to 1) if rhs <= digit_max
+  if (lhs.size() <= q)
+  {
+    typedef to_integral_converter<
+      unbounded_uint_type, integral_type> converter_type;
+
+    converter_type c;
+
+    const integral_type x = c.convert(lhs);
+
+    return x < rhs;
+  }
+
+  return false;
+}
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::add(unbounded_uint_type& lhs,
+                                        integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    unbounded_uint_integral_ops_impl<
+      UnboundedUInt, digit_type
+    >::add(lhs, static_cast<digit_type>(rhs));
+  }
+  else
+  {
+    digit_type tmp_digits[q];
+
+    unbounded_uint_type tmp(tmp_digits, q, q);
+
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(tmp, rhs);
+
+    lhs += tmp;
+  }
+}
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::subtract(unbounded_uint_type& lhs,
+                                             integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    unbounded_uint_integral_ops_impl<
+      UnboundedUInt, digit_type
+    >::subtract(lhs, static_cast<digit_type>(rhs));
+  }
+  else
+  {
+    digit_type tmp_digits[q];
+
+    unbounded_uint_type tmp(tmp_digits, q, q);
+
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(tmp, rhs);
+
+    lhs -= tmp;
+  }
+}
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::multiply(unbounded_uint_type& lhs,
+                                             integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    unbounded_uint_integral_ops_impl<
+      UnboundedUInt, digit_type
+    >::multiply(lhs, static_cast<digit_type>(rhs));
+  }
+  else
+  {
+    digit_type tmp_digits[q];
+
+    unbounded_uint_type tmp(tmp_digits, q, q);
+
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(tmp, rhs);
+
+    unbounded_uint_type *a, *b;
+    if (lhs.size() > tmp.size())
+    {
+      a = &lhs;
+      b = &tmp;
+    }
+    else
+    {
+      a = &tmp;
+      b = &lhs;
+    }
+
+    digit_type workspace[q];
+    traits_type::ops_type::comba_mul(lhs.digits(),
+                                     a->digits(), a->size(),
+                                     b->digits(), b->size(), workspace);
+    lhs.set_size(lhs.size() + tmp.size());
+    lhs.clamp_high_digit();
+  }
+}
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::multiply(unbounded_uint_type& z,
+                                             const unbounded_uint_type& x,
+                                             integral_type y)
+{
+  if (y <= max_digit_value)
+  {
+    unbounded_uint_integral_ops_impl<
+      UnboundedUInt, digit_type
+    >::multiply(z, x, static_cast<digit_type>(y));
+  }
+  else
+  {
+    digit_type tmp_digits[q];
+
+    unbounded_uint_type tmp(tmp_digits, q, q);
+
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(tmp, y);
+
+    unbounded_uint_type *a, *b;
+    if (x.size() > tmp.size())
+    {
+      a = &x;
+      b = &tmp;
+    }
+    else
+    {
+      a = &tmp;
+      b = &x;
+    }
+
+    digit_type workspace[q];
+    traits_type::ops_type::comba_mul(z.digits(), a->digits(), a->size(),
+                                                 b->digits(), b->size());
+    z.set_size(x.size() + tmp.size());
+    z.clamp_high_digit();
+  }
+}
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::divide(unbounded_uint_type& lhs,
+                                           integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    unbounded_uint_integral_ops_impl<
+      UnboundedUInt, digit_type
+    >::divide(lhs, static_cast<digit_type>(rhs));
+  }
+  else
+  {
+    digit_type tmp_digits[q];
+
+    unbounded_uint_type tmp(tmp_digits, q, q);
+
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(tmp, rhs);
+
+    digit_type remainder_digits[q] = {0};
+
+    unbounded_uint_type remainder(remainder_digits, q, q);
+
+    //divide(lhs, &remainder, lhs, tmp);
+
+    remainder.clamp();
+
+    typedef to_integral_converter<
+      unbounded_uint_type, integral_type> converter_type;
+
+    converter_type c;
+
+    assign(lhs, c.convert_without_check(remainder, remainder.precision()));
+  }
+}
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::modulo(unbounded_uint_type& lhs,
+                                           integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    unbounded_uint_integral_ops_impl<
+      UnboundedUInt, digit_type
+    >::divide(lhs, static_cast<digit_type>(rhs));
+  }
+  else
+  {
+    digit_type tmp_digits[q];
+
+    unbounded_uint_type tmp(tmp_digits, q, q);
+
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(tmp, rhs);
+
+    digit_type remainder_digits[q] = {0};
+
+    unbounded_uint_type remainder(remainder_digits, q, q);
+
+    //divide(&lhs, &remainder, lhs, tmp);
+
+    remainder.clamp();
+
+    typedef to_integral_converter<
+      unbounded_uint_type, integral_type> converter_type;
+
+    converter_type c;
+
+    assign(lhs, c.convert_without_check(remainder, remainder.precision()));
+  }
+}
+
+// TODO first need to write
+// divide(unbounded_uint_type* q, unbounded_uint_type* r,
+//        const unbounded_uint_type& x, const unbounded_uint_type& y);
+// or don't implement this function if it is not possible to do so without the
+// use of temporary memory.
+
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::bitwise_or(unbounded_uint_type& lhs,
+                                               integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    unbounded_uint_integral_ops_impl<
+      UnboundedUInt, digit_type
+    >::bitwise_or(lhs, static_cast<digit_type>(rhs));
+  }
+  else
+  {
+    digit_type tmp_digits[q];
+
+    unbounded_uint_type tmp(tmp_digits, q, q);
+
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(tmp, rhs);
+
+    lhs |= tmp;
+  }
+}
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::bitwise_and(unbounded_uint_type& lhs,
+                                                integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    unbounded_uint_integral_ops_impl<
+      UnboundedUInt, digit_type
+    >::bitwise_and(lhs, static_cast<digit_type>(rhs));
+  }
+  else
+  {
+    digit_type tmp_digits[q];
+
+    unbounded_uint_type tmp(tmp_digits, q, q);
+
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(tmp, rhs);
+
+    lhs &= tmp;
+  }
+}
+
+template<class UnboundedUInt, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, false>::bitwise_xor(unbounded_uint_type& lhs,
+                                                integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    unbounded_uint_integral_ops_impl<
+      UnboundedUInt, digit_type
+    >::bitwise_xor(lhs, static_cast<digit_type>(rhs));
+  }
+  else
+  {
+    digit_type tmp_digits[q];
+
+    unbounded_uint_type tmp(tmp_digits, q, q);
+
+    from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(tmp, rhs);
+
+    lhs ^= tmp;
+  }
+}
+
+
+// 4
+template<class UnboundedUInt, typename IntegralT>
+struct unbounded_uint_integral_ops_impl<
+  UnboundedUInt, IntegralT, true
+>
+{
+  typedef UnboundedUInt unbounded_uint_type;
+  typedef IntegralT     integral_type;
+
+  typedef typename make_unsigned<integral_type>::type unsigned_integral_type;
+
+  // this is spec 3
+  typedef unbounded_uint_integral_ops_impl<
+    unbounded_uint_type,
+    unsigned_integral_type
+  > impl_type;
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, static_cast<unsigned_integral_type>(y));
+  }
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+};
+
+
+
+
+////////////////////////////////////////////////////////////////////
+
+template<
+  class UnboundedUInt,
+  typename IntegralT,
+  bool less_equal =
+      std::numeric_limits<IntegralT>::is_signed ?
+      (
+        std::numeric_limits<IntegralT>::digits <=
+        std::numeric_limits<
+          typename make_signed<typename UnboundedUInt::digit_type>::type
+        >::digits
+      ):
+      (
+        std::numeric_limits<IntegralT>::digits <=
+        std::numeric_limits<typename UnboundedUInt::digit_type>::digits
+      )
+>
+struct unbounded_uint_integral_ops;
+
+
+// Dispatches integral types that fit into a digit_type by casting it to
+// digit_type or signed digit_type and using the specialization at the top.
+template<
+  class UnboundedUInt,
+  typename IntegralT
+>
+struct unbounded_uint_integral_ops<UnboundedUInt,IntegralT,true>
+{
+  BOOST_STATIC_ASSERT(is_integral<IntegralT>::value);
+
+  typedef UnboundedUInt unbounded_uint_type;
+  typedef IntegralT     integral_type;
+
+  typedef unbounded_uint_integral_ops_impl<
+    unbounded_uint_type,
+    typename mpl::if_<
+      is_signed<integral_type>,
+      typename make_signed<
+        typename unbounded_uint_type::digit_type
+      >::type,
+      typename unbounded_uint_type::digit_type
+    >::type
+  >                     impl_type;
+
+  typedef typename impl_type::integral_type  to_integral_type;
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, static_cast<to_integral_type>(y));
+  }
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, static_cast<to_integral_type>(rhs));
+  }
+};
+
+
+template<
+  class UnboundedUInt,
+  typename IntegralT
+>
+struct unbounded_uint_integral_ops<UnboundedUInt,IntegralT,false>
+{
+  BOOST_STATIC_ASSERT(is_integral<IntegralT>::value);
+
+  typedef UnboundedUInt unbounded_uint_type;
+  typedef IntegralT     integral_type;
+
+  typedef unbounded_uint_integral_ops_impl<
+      unbounded_uint_type, integral_type
+  >                     impl_type;
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, rhs);
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, rhs);
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, rhs);
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, rhs);
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, rhs);
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, y);
+  }
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, rhs);
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, rhs);
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, rhs);
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, rhs);
+  }
+};
+
+
+
+} // namespace base
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/detail/div.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/div.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,174 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_DETAIL_DIV_HPP
-#define BOOST_MP_MATH_MP_INT_DETAIL_DIV_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-
-namespace boost {
-namespace mp_math {
-namespace detail {
-
-// integer signed division. 
-// q*b + r == a
-// HAC pp.598 Algorithm 14.20
-//
-// Note that the description in HAC is horribly incomplete.  For example, it
-// doesn't consider the case where digits are removed from 'x' in the inner
-// loop.  It also doesn't consider the case that y has fewer than three digits,
-// etc..
-// The overall algorithm is as described as 14.20 from HAC but fixed to treat
-// these cases.
-
-// divide a by b, optionally store remainder
-template<class A, class T>
-void classic_divide(const mp_int<A,T>& a, const mp_int<A,T>& b,
-                    mp_int<A,T>& q, mp_int<A,T>* remainder = 0)
-{
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  typedef typename mp_int<A,T>::word_type  word_type;
-  typedef typename mp_int<A,T>::size_type  size_type;
-
-  if (!b)
-    throw std::domain_error("mp_int::divide: division by zero");
-
-  // if *this < b then q=0, r = *this
-  if (a.compare_magnitude(b) == -1)
-  {
-    if (remainder)
-      *remainder = a;
-    q.zero();
-    return;
-  }
-
-  q.grow_capacity(a.size() + 2);
-  q.set_size(a.size() + 2);
-  std::memset(q.digits(), 0, q.size() * sizeof(digit_type));
-
-  mp_int<A,T> x(a);
-  mp_int<A,T> y(b);
-
-  // fix the sign
-  const int neg = (a.sign() == b.sign()) ? 1 : -1;
-  x.set_sign(1);
-  y.set_sign(1);
-
-  // normalize both x and y, ensure that y >= beta/2, [beta == 2**valid_bits]
-  size_type norm = y.precision() % mp_int<A,T>::valid_bits;
-  if (norm < mp_int<A,T>::valid_bits - 1)
-  {
-    norm = mp_int<A,T>::valid_bits - 1 - norm;
-    x <<= norm;
-    y <<= norm;
-  }
-  else
-    norm = 0;
-
-  // note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4
-  const size_type n = x.size() - 1;
-  const size_type t = y.size() - 1;
-
-  // find leading digit of the quotient
-  // while (x >= y*beta**(n-t)) do { q[n-t] += 1; x -= y*beta**(n-t) }
-  y.shift_digits_left(n - t); // y = y*beta**(n-t)
-
-  while (x.compare(y) != -1)
-  {
-    ++q[n - t];
-    x -= y;
-  }
-
-  // reset y by shifting it back down
-  y.shift_digits_right(n - t);
-
-  // find the remainder of the digits
-  // step 3. for i from n down to (t + 1)
-  for (size_type i = n; i >= (t + 1); --i)
-  {
-    if (i > x.size())
-      continue;
-
-    // step 3.1 if xi == yt then set q{i-t-1} to beta-1, 
-    // otherwise set q{i-t-1} to (xi*beta + x{i-1})/yt
-    if (x[i] == y[t])
-      q[i - t - 1] = mp_int<A,T>::digit_max;
-    else
-    {
-      word_type tmp  = static_cast<word_type>(x[i])
-                    << static_cast<word_type>(mp_int<A,T>::valid_bits);
-      tmp |= x[i - 1];
-      tmp /= y[t];
-      q[i - t - 1] = static_cast<digit_type>(tmp);
-    }
-
-    // now fixup quotient estimation
-    // while (q{i-t-1} * (yt * beta + y{t-1})) >
-    //       xi * beta**2 + xi-1 * beta + xi-2
-    //
-    // do q{i-t-1} -= 1;
-
-    mp_int<A,T> t1, t2;
-    t1.grow_capacity(3);
-    t2.grow_capacity(3);
-
-    ++q[i - t - 1];
-    do
-    {
-      --q[i - t - 1];
-
-      // find left hand
-      t1.zero();
-      t1[0] = (t == 0) ? 0 : y[t - 1];
-      t1[1] = y[t];
-      t1.set_size(2);
-      t1.multiply_by_digit(q[i - t - 1]);
-
-      // find right hand
-      t2[0] = (i < 2) ? 0 : x[i - 2];
-      t2[1] = (i == 0) ? 0 : x[i - 1];
-      t2[2] = x[i];
-      t2.set_size(3);
-    } while (t1.compare_magnitude(t2) == 1);
-
-    // step 3.3 x = x - q{i-t-1} * y * beta**{i-t-1}
-    t1 = y;
-    t1.multiply_by_digit(q[i - t -1]);
-    t1.shift_digits_left(i - t - 1);
-    x -= t1;
-
-    // if x < 0 then { x = x + y*beta**{i-t-1}; q{i-t-1} -= 1; }
-    if (x.is_negative())
-    {
-      t1 = y;
-      t1.shift_digits_left(i - t -1);
-      x += t1;
-
-      --q[i - t - 1] = q[i - t - 1];
-    }
-  }
-
-  // now q is the quotient and x is the remainder [which we have to normalize]
-  
-  // get sign before writing to q
-  x.set_sign(!x ? 1 : a.sign());
-
-  q.clamp();
-  q.set_sign(neg);
-
-  if (remainder)
-  {
-    x >>= norm;
-    remainder->swap(x);
-  }
-}
-
-
-} // namespace detail
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Copied: sandbox/mp_math/boost/mp_math/integer/detail/divider.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/detail/div.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/div.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/divider.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,165 +1,229 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_DETAIL_DIV_HPP
-#define BOOST_MP_MATH_MP_INT_DETAIL_DIV_HPP
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_DIVIDER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_DIVIDER_HPP
 
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
+#include <iostream>
+#include <boost/mp_math/integer/detail/shifter.hpp>
 
 namespace boost {
 namespace mp_math {
 namespace detail {
 
-// integer signed division. 
+template<class ApInt>
+struct divider
+{
+  typedef ApInt                          int_type;
+  typedef typename int_type::traits_type traits_type;
+  typedef typename traits_type::ops_type ops_type;
+  typedef typename int_type::digit_type  digit_type;
+  typedef typename int_type::size_type   size_type;
+  typedef shifter<int_type>              shifter_type;
+
+  // divide a by b, optionally store remainder
+  static void classic_divide(const ApInt& a, const ApInt& b,
+                             ApInt& q, ApInt* remainder = 0);
+};
+
+
+// integer signed division.
 // q*b + r == a
 // HAC pp.598 Algorithm 14.20
 //
-// Note that the description in HAC is horribly incomplete.  For example, it
+// Note that the description in HAC is horribly incomplete. For example, it
 // doesn't consider the case where digits are removed from 'x' in the inner
-// loop.  It also doesn't consider the case that y has fewer than three digits,
+// loop. It also doesn't consider the case that y has fewer than three digits,
 // etc..
 // The overall algorithm is as described as 14.20 from HAC but fixed to treat
 // these cases.
-
-// divide a by b, optionally store remainder
-template<class A, class T>
-void classic_divide(const mp_int<A,T>& a, const mp_int<A,T>& b,
-                    mp_int<A,T>& q, mp_int<A,T>* remainder = 0)
+template<class ApInt>
+void divider<ApInt>::classic_divide(const ApInt& a, const ApInt& b,
+                                    ApInt& q, ApInt* remainder)
 {
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  typedef typename mp_int<A,T>::word_type  word_type;
-  typedef typename mp_int<A,T>::size_type  size_type;
+  typedef typename traits_type::word_type word_type;
 
   if (!b)
-    throw std::domain_error("mp_int::divide: division by zero");
+    throw std::domain_error("unbounded::divide: division by zero");
+
+  if (b.size() == 1)
+  {
+    q.reserve(a.size());
+    q.set_size(a.size());
+    const digit_type r =
+      ops_type::divide_by_digit(q.digits(), a.digits(), a.size(), b[0]);
+    q.clamp();
+    if (remainder)
+      *remainder = r;
+    return;
+  }
 
-  // if *this < b then q=0, r = *this
-  if (a.compare_magnitude(b) == -1)
+  if (ops_type::compare_magnitude(a.digits(), a.size(),
+                                  b.digits(), b.size()) == -1)
   {
     if (remainder)
       *remainder = a;
-    q.zero();
+    q = digit_type(0);
     return;
   }
 
-  q.grow_capacity(a.size() + 2);
+  q.reserve(a.size() + 2);
   q.set_size(a.size() + 2);
   std::memset(q.digits(), 0, q.size() * sizeof(digit_type));
 
-  mp_int<A,T> x(a);
-  mp_int<A,T> y(b);
+  ApInt x;
+  ApInt y;
+
+  x.reserve(a.size() + 1);
+  y.reserve(b.size() + 1);
 
-  // fix the sign
-  const int neg = (a.sign() == b.sign()) ? 1 : -1;
-  x.set_sign(1);
-  y.set_sign(1);
-
-  // normalize both x and y, ensure that y >= beta/2, [beta == 2**valid_bits]
-  size_type norm = y.precision() % mp_int<A,T>::valid_bits;
-  if (norm < mp_int<A,T>::valid_bits - 1)
-  {
-    norm = mp_int<A,T>::valid_bits - 1 - norm;
-    x <<= norm;
-    y <<= norm;
+  // TODO optimize by creating shift_bits_left(digit_type* z,
+  // const digit_type* x, size_type xlen, size_type n) function and using it in
+  // the if below
+  std::memcpy(x.digits(), a.digits(), a.size() * sizeof(digit_type));
+  std::memcpy(y.digits(), b.digits(), b.size() * sizeof(digit_type));
+
+  x.set_size(a.size());
+  y.set_size(b.size());
+
+  // normalize both x and y, ensure that y >= radix/2
+  size_type norm = y.precision() % traits_type::radix_bits;
+  if (norm < traits_type::radix_bits - 1)
+  {
+    norm = traits_type::radix_bits - 1 - norm;
+    {
+      const digit_type carry =
+        ops_type::shift_bits_left(x.digits(), x.size(), norm);
+      if (carry)
+        x.push(carry);
+    }
+    {
+      const digit_type carry =
+        ops_type::shift_bits_left(y.digits(), y.size(), norm);
+      if (carry)
+        y.push(carry);
+    }
   }
   else
     norm = 0;
 
-  // note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4
+  // note hac does 0 based, so if size==5 then its 0,1,2,3,4, e.g. use 4
   const size_type n = x.size() - 1;
   const size_type t = y.size() - 1;
 
   // find leading digit of the quotient
-  // while (x >= y*beta**(n-t)) do { q[n-t] += 1; x -= y*beta**(n-t) }
-  y.shift_digits_left(n - t); // y = y*beta**(n-t)
+  // while (x >= y*radix^(n-t)) do { q[n-t] += 1; x -= y*radix^(n-t) }
 
-  while (x.compare(y) != -1)
+  // here we pretend that we shifted y by (n-t) digits to the left
+  while (ops_type::compare_magnitude(
+        x.digits() + (n-t), y.size(), y.digits(), y.size()) != -1)
   {
     ++q[n - t];
-    x -= y;
+    ops_type::sub_smaller_magnitude(
+        x.digits() + (n-t), x.digits() + (n-t), y.size(), y.digits(), y.size());
+    x.clamp();
   }
 
-  // reset y by shifting it back down
-  y.shift_digits_right(n - t);
+  // moved temporary construction out of the loop below
+  ApInt u;
+  u.reserve(y.size() + (n - t));
 
   // find the remainder of the digits
-  // step 3. for i from n down to (t + 1)
   for (size_type i = n; i >= (t + 1); --i)
   {
     if (i > x.size())
       continue;
 
-    // step 3.1 if xi == yt then set q{i-t-1} to beta-1, 
-    // otherwise set q{i-t-1} to (xi*beta + x{i-1})/yt
+    const size_type offset = i - t - 1;
+
+    // step 3.1 if xi == yt then set q{i-t-1} to radix-1,
+    // otherwise set q{i-t-1} to (xi*radix + x{i-1})/yt
     if (x[i] == y[t])
-      q[i - t - 1] = mp_int<A,T>::digit_max;
+      q[offset] = traits_type::max_digit_value;
     else
     {
       word_type tmp  = static_cast<word_type>(x[i])
-                    << static_cast<word_type>(mp_int<A,T>::valid_bits);
+                    << static_cast<word_type>(traits_type::radix_bits);
       tmp |= x[i - 1];
       tmp /= y[t];
-      q[i - t - 1] = static_cast<digit_type>(tmp);
+      q[offset] = static_cast<digit_type>(tmp);
     }
 
     // now fixup quotient estimation
-    // while (q{i-t-1} * (yt * beta + y{t-1})) >
-    //       xi * beta**2 + xi-1 * beta + xi-2
+    // while (q{i-t-1} * (yt * radix + y{t-1})) >
+    //       xi * radix^2 + xi-1 * radix + xi-2
     //
     // do q{i-t-1} -= 1;
 
-    mp_int<A,T> t1, t2;
-    t1.grow_capacity(3);
-    t2.grow_capacity(3);
+    digit_type t1[3];
+    digit_type t2[3];
 
-    ++q[i - t - 1];
+    ++q[offset];
     do
     {
-      --q[i - t - 1];
+      --q[offset];
 
       // find left hand
-      t1.zero();
       t1[0] = (t == 0) ? 0 : y[t - 1];
       t1[1] = y[t];
-      t1.set_size(2);
-      t1.multiply_by_digit(q[i - t - 1]);
+      t1[2] = ops_type::multiply_by_digit(t1, t1, 2, q[offset]);
 
       // find right hand
       t2[0] = (i < 2) ? 0 : x[i - 2];
       t2[1] = (i == 0) ? 0 : x[i - 1];
       t2[2] = x[i];
-      t2.set_size(3);
-    } while (t1.compare_magnitude(t2) == 1);
-
-    // step 3.3 x = x - q{i-t-1} * y * beta**{i-t-1}
-    t1 = y;
-    t1.multiply_by_digit(q[i - t -1]);
-    t1.shift_digits_left(i - t - 1);
-    x -= t1;
+    } while (ops_type::compare_magnitude(t1, 3, t2, 3) == 1);
 
-    // if x < 0 then { x = x + y*beta**{i-t-1}; q{i-t-1} -= 1; }
-    if (x.is_negative())
+    // step 3.3 x = x - q{i-t-1} * y * radix^{i-t-1}
+    std::memset(u.digits(), 0, offset * sizeof(digit_type));
+    const digit_type carry =
+      ops_type::multiply_by_digit(u.digits() + offset,
+                                  y.digits(), y.size(), q[offset]);
+    u.set_size(y.size() + offset);
+    if (carry)
+      u.push(carry);
+    u.clamp();
+
+    // if x < 0 then { x = x + y*radix^{i-t-1}; q{i-t-1} -= 1; }
+    // We check if x will become less than zero before we subtract, in that case
+    // we adjust x before the subtraction.
+    if (ops_type::compare_magnitude(x.digits(), x.size(),
+                                    u.digits(), u.size()) == -1)
     {
-      t1 = y;
-      t1.shift_digits_left(i - t -1);
-      x += t1;
+      digit_type* x_off = x.digits() + offset;
+
+      digit_type carry =
+        ops_type::add_digits(x_off, x_off, y.digits(), y.size());
 
-      --q[i - t - 1] = q[i - t - 1];
+      ops_type::ripple_carry(x_off + y.size(),
+                             x_off + y.size(),
+                             x.size() - y.size() - offset,
+                             carry);
+
+      if (carry)
+      {
+        // TODO can this happen, do I need to reserve one more digit?
+        x.push(carry);
+      }
+
+      --q[offset];
     }
+
+    ops_type::sub_smaller_magnitude(x.digits(), x.digits(), x.size(),
+                                                u.digits(), u.size());
+    x.clamp();
   }
 
   // now q is the quotient and x is the remainder [which we have to normalize]
-  
-  // get sign before writing to q
-  x.set_sign(!x ? 1 : a.sign());
 
   q.clamp();
-  q.set_sign(neg);
 
   if (remainder)
   {
+    // TODO optimize by having shift_right(z, x, xlen, n) function
     x >>= norm;
     remainder->swap(x);
   }
Copied: sandbox/mp_math/boost/mp_math/integer/detail/gcd.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/gcd.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/gcd.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/gcd.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,68 +1,116 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_GCD_HPP
-#define BOOST_MP_MATH_MP_INT_GCD_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_GCD_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_GCD_HPP
 
 namespace boost {
 namespace mp_math {
+namespace detail {
 
-// Greatest Common Divisor using the binary method
-template<class A, class T>
-mp_int<A,T> gcd(const mp_int<A,T>& a, const mp_int<A,T>& b)
+
+template<class ApInt, bool IsSigned = ApInt::is_signed>
+struct gcd_finder;
+
+
+template<class ApInt>
+struct gcd_finder<ApInt, false>
+{
+  static void gcd(ApInt& z, const ApInt& a, const ApInt& b);
+  static void binary_method(ApInt& z, ApInt& u, ApInt& v);
+};
+
+
+template<class ApInt>
+void gcd_finder<ApInt, false>::gcd(ApInt& z, const ApInt& a, const ApInt& b)
 {
   // either zero then gcd is the largest
   if (!a)
-    return abs(b);
+  {
+    z = b;
+    return;
+  }
+
   if (!b)
-    return abs(a);
+  {
+    z = a;
+    return;
+  }
 
   // get copies of a and b we can modify
-  mp_int<A,T> u = abs(a);
-  mp_int<A,T> v = abs(b);
+  ApInt u(a);
+  ApInt v(b);
 
-  typedef typename mp_int<A,T>::size_type size_type;
+  binary_method(z, u, v);
+}
+
+// Greatest Common Divisor using the binary method
+template<class ApInt>
+void gcd_finder<ApInt, false>::binary_method(ApInt& z, ApInt& u, ApInt& v)
+{
+  typedef typename ApInt::size_type size_type;
 
   // Find the common power of two for u and v
-  const size_type u_lsb = u.count_lsb();
-  const size_type v_lsb = v.count_lsb();
-  const size_type     k = std::min(u_lsb, v_lsb);
+  const size_type u_tzb = u.count_trailing_zero_bits();
+  const size_type v_tzb = v.count_trailing_zero_bits();
+  const size_type     k = std::min(u_tzb, v_tzb);
 
   // divide out powers of two
-  u >>= u_lsb;
-  v >>= v_lsb;
+  u >>= u_tzb;
+  v >>= v_tzb;
 
   while (v)
   {
     if (u > v)
       u.swap(v);
-     
-    v.sub_smaller_magnitude(u);
+
+    v -= u;
 
     // Divide out all factors of two
-    v >>= v.count_lsb();
-  } 
+    v >>= v.count_trailing_zero_bits();
+  }
 
-  // multiply by 2**k which we divided out at the beginning
+  // multiply by 2^k which we divided out at the beginning
   u <<= k;
 
-  return u;
+  swap(z, u);
 }
 
-#ifdef BOOST_HAS_VARIADIC_TMPL
-template<class A, class T, class... MpInts>
-mp_int<A,T> gcd(const mp_int<A,T>& a, const mp_int<A,T>& b, const MpInts&... args)
+
+template<class ApInt>
+struct gcd_finder<ApInt, true>
+{
+  static void gcd(ApInt& z, const ApInt& a, const ApInt& b);
+};
+
+
+template<class ApInt>
+void gcd_finder<ApInt, true>::gcd(ApInt& z, const ApInt& a, const ApInt& b)
 {
-  return gcd(gcd(a, b), args...);
+  // either zero then gcd is the largest
+  if (!a)
+  {
+    z = abs(b);
+    return;
+  }
+  if (!b)
+  {
+    z = abs(a);
+    return;
+  }
+
+  // get copies of a and b we can modify
+  ApInt u = abs(a);
+  ApInt v = abs(b);
+
+  gcd_finder<ApInt, false>::binary_method(z, u, v);
 }
-#endif
 
 
+} // namespace detail
 } // namespace mp_math
 } // namespace boost
 
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/detail/integral_ops.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/integral_ops.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,713 +0,0 @@
-// Copyright Kevin Sopp 2008 - 2009.
-// 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_MP_MATH_MP_INT_DETAIL_INTEGRAL_OPS_HPP
-#define BOOST_MP_MATH_MP_INT_DETAIL_INTEGRAL_OPS_HPP
-
-#include <boost/static_assert.hpp>
-#include <boost/mpl/greater.hpp>
-#include <boost/type_traits/is_integral.hpp>
-#include <boost/type_traits/make_unsigned.hpp>
-#include <boost/mp_math/mp_int/detail/meta_math.hpp>
-
-// here we optimize interaction with built in integral types
-
-namespace boost {
-namespace mp_math {
-
-template<class A, class T>
-struct mp_int;
-
-namespace detail {
-
-
-template<
-  typename IntegralT,
-  class MpInt,
-  bool is_signed = std::numeric_limits<IntegralT>::is_signed
->
-struct integral_ops_impl
-{};
-
-
-template<
-  typename IntegralT,
-  class MpInt
->
-struct integral_ops_impl<IntegralT, MpInt, false>
-{
-  static void assign  (MpInt& lhs, IntegralT rhs);
-
-  static bool equal   (const MpInt& lhs, IntegralT rhs);
-  static bool less    (const MpInt& lhs, IntegralT rhs);
-
-  static void add     (MpInt& lhs, IntegralT rhs);
-  static void subtract(MpInt& lhs, IntegralT rhs);
-  static void multiply(MpInt& lhs, IntegralT rhs);
-  static void divide  (MpInt& lhs, IntegralT rhs);
-  static void modulo  (MpInt& lhs, IntegralT rhs);
-
-  static void bitwise_or (MpInt& lhs, IntegralT rhs);
-  static void bitwise_and(MpInt& lhs, IntegralT rhs);
-  static void bitwise_xor(MpInt& lhs, IntegralT rhs);
-
-private:
-
-  static const typename MpInt::size_type q =
-    std::numeric_limits<IntegralT>::digits / (MpInt::valid_bits + 1) + 1;
-
-  static bool equal_to_integral_type(const MpInt& x, IntegralT y)
-  {
-    try
-    {
-      return x.template to_integral<IntegralT>() == y;
-    }
-    catch (const std::overflow_error&)
-    {
-      return false;
-    }
-  }
-};
-
-
-template<
-  typename IntegralT,
-  class MpInt
->
-struct integral_ops_impl<IntegralT, MpInt, true>
-{
-  static void assign  (MpInt& lhs, IntegralT rhs);
-
-  static bool equal   (const MpInt& lhs, IntegralT rhs);
-  static bool less    (const MpInt& lhs, IntegralT rhs);
-
-  static void add     (MpInt& lhs, IntegralT rhs);
-  static void subtract(MpInt& lhs, IntegralT rhs);
-  static void multiply(MpInt& lhs, IntegralT rhs);
-  static void divide  (MpInt& lhs, IntegralT rhs);
-  static void modulo  (MpInt& lhs, IntegralT rhs);
-
-  static void bitwise_or (MpInt& lhs, IntegralT rhs);
-  static void bitwise_and(MpInt& lhs, IntegralT rhs);
-  static void bitwise_xor(MpInt& lhs, IntegralT rhs);
-
-private:
-
-  typedef typename make_unsigned<IntegralT>::type unsigned_type;
-
-  static const typename MpInt::size_type q =
-    (std::numeric_limits<IntegralT>::digits + (MpInt::valid_bits - 1))
-    / MpInt::valid_bits;
-
-  static bool equal_to_integral_type(const MpInt& x, IntegralT y)
-  {
-    try
-    {
-      return x.template to_integral<IntegralT>() == y;
-    }
-    catch (const std::overflow_error&)
-    {
-      return false;
-    }
-  }
-};
-
-
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, false>::assign(MpInt& lhs, IntegralT rhs)
-{
-  lhs.zero();
-
-  typedef typename MpInt::digit_type digit_type;
-
-  if (rhs <= MpInt::digit_max)
-    lhs[0] = static_cast<digit_type>(rhs);
-  else
-  {
-    static const int ud = std::numeric_limits<IntegralT>::digits;
-    static const int dd = MpInt::valid_bits;
-    static const int m = dd < ud ? dd : ud;
-    static const int h = m / 2;
-    // set h bits at a time
-    for (int i = 0; i < ud / h; ++i)
-    {
-      // shift the number up h bits
-      lhs <<= h;
-      // TODO optimize shift. only need to call grow_capacity once here
-      // then use lower level shift_left(lhs.digits_, h);
-
-      // OR in the top h bits of the source
-      lhs[0] |= (rhs >> (ud-h)) & (power<IntegralT,2,h>::value - 1);
-
-      // shift the source up to the next h bits
-      rhs <<= h;
-    }
-    lhs.clamp();
-  }
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, true>::assign(MpInt& lhs, IntegralT rhs)
-{
-  int sign;
-  unsigned_type tmp;
-  if (rhs >= 0)
-  {
-    sign = 1;
-    tmp = rhs;
-  }
-  else
-  {
-    sign = -1;
-    // XXX using unary - may lose information on platforms without two's
-    // complement binary representation of integers. This conversion is well
-    // defined only within the minimum guaranteed integral limits given by the
-    // standard. In the functions below we use this several times again.
-    tmp = -rhs;
-  }
-
-  integral_ops_impl<unsigned_type,MpInt>::assign(lhs, tmp);
-
-  lhs.set_sign(sign);
-}
-
-template<typename IntegralT, class MpInt>
-bool
-integral_ops_impl<IntegralT, MpInt, false>::equal(const MpInt& lhs, IntegralT rhs)
-{
-  if (lhs.size() > q)
-    return false;
-
-  return equal_to_integral_type(lhs, rhs);
-}
-
-template<typename IntegralT, class MpInt>
-bool
-integral_ops_impl<IntegralT, MpInt, true>::equal(const MpInt& lhs, IntegralT rhs)
-{
-  const int rhs_sign = rhs < 0 ? -1 : 1;
-
-  if (lhs.sign() != rhs_sign)
-    return false;
-
-  if (lhs.size() > q)
-    return false;
-
-  return equal_to_integral_type(lhs, rhs);
-}
-
-template<typename IntegralT, class MpInt>
-bool
-integral_ops_impl<IntegralT, MpInt, false>::less(const MpInt& lhs, IntegralT rhs)
-{
-  if (lhs.sign() == -1)
-    return true;
-
-  if (lhs.size() > q)
-    return false;
-
-  return lhs.template to_integral<IntegralT>() < rhs;
-}
-
-template<typename IntegralT, class MpInt>
-bool
-integral_ops_impl<IntegralT, MpInt, true>::less(const MpInt& lhs, IntegralT rhs)
-{
-  if (lhs.sign() == -1 && rhs >= 0)
-    return true;
-
-  if (lhs.sign() == 1 && rhs < 0)
-    return false;
-
-  static const typename MpInt::size_type rhs_precision =
-    static_cast<typename MpInt::size_type>(
-        std::numeric_limits<IntegralT>::digits);
-
-  if (lhs.precision() > rhs_precision)
-    return lhs.sign() == -1;
-
-  return lhs.template to_integral<IntegralT>() < rhs;
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, false>::add(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs <= MpInt::digit_max)
-    lhs.add_digit(static_cast<typename MpInt::digit_type>(rhs));
-  else
-    lhs += MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, true>::add(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs >= 0)
-  {
-    if (static_cast<unsigned_type>(rhs) <= MpInt::digit_max)
-    {
-      lhs.add_digit(static_cast<typename MpInt::digit_type>(rhs));
-      return;
-    }
-  }
-  else
-  {
-    const unsigned_type tmp(-rhs);
-    if (tmp <= MpInt::digit_max)
-    {
-      lhs.sub_digit(static_cast<typename MpInt::digit_type>(tmp));
-      return;
-    }
-  }
-
-  // TODO: we're touching the allocator below...
-  // we can probably do better maybe we can store the Integral to a
-  // digits array on the stack, then use the addition algorithm to
-  // add the numbers, or create a fixed precision int that can live on
-  // the stack and write operator += to let mp_int interact with fp_int
-  // the same goes for all other ops in this file that do this kind of stuff.
-  lhs += MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, false>::subtract(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs <= MpInt::digit_max)
-    lhs.sub_digit(static_cast<typename MpInt::digit_type>(rhs));
-  else
-    lhs -= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, true>::subtract(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs >= 0)
-  {
-    if (static_cast<unsigned_type>(rhs) <= MpInt::digit_max)
-    {
-      lhs.sub_digit(static_cast<typename MpInt::digit_type>(rhs));
-      return;
-    }
-  }
-  else
-  {
-    const unsigned_type tmp(-rhs);
-    if (tmp <= MpInt::digit_max)
-    {
-      lhs.add_digit(static_cast<typename MpInt::digit_type>(tmp));
-      return;
-    }
-  }
-
-  lhs -= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, false>::multiply(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs <= MpInt::digit_max)
-    lhs.multiply_by_digit(static_cast<typename MpInt::digit_type>(rhs));
-  else
-    lhs *= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, true>::multiply(MpInt& lhs, IntegralT rhs)
-{
-  int sign;
-  unsigned_type tmp;
-  if (rhs >= 0)
-  {
-    sign = 1;
-    tmp = rhs;
-  }
-  else
-  {
-    sign = -1;
-    tmp = -rhs;
-  }
-
-  if (tmp <= MpInt::digit_max)
-  {
-    lhs.multiply_by_digit(static_cast<typename MpInt::digit_type>(tmp));
-    lhs.set_sign(lhs.sign() * sign);
-  }
-  else
-    lhs *= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, false>::divide(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs <= MpInt::digit_max)
-    lhs.divide_by_digit(rhs);
-  else
-    lhs /= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, true>::divide(MpInt& lhs, IntegralT rhs)
-{
-  int sign;
-  unsigned_type tmp;
-  if (rhs >= 0)
-  {
-    sign = 1;
-    tmp = rhs;
-  }
-  else
-  {
-    sign = -1;
-    tmp = -rhs;
-  }
-
-  if (tmp <= MpInt::digit_max)
-  {
-    lhs.divide_by_digit(static_cast<typename MpInt::digit_type>(tmp));
-    lhs.set_sign(lhs.sign() / sign);
-  }
-  else
-    lhs /= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, false>::modulo(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs <= MpInt::digit_max)
-  {
-    lhs[0] = lhs.divide_by_digit(rhs);
-    lhs.set_size(1);
-  }
-  else
-    lhs %= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, true>::modulo(MpInt& lhs, IntegralT rhs)
-{
-  unsigned_type tmp;
-  if (rhs >= 0)
-    tmp = rhs;
-  else
-    tmp = -rhs;
-
-  if (tmp <= MpInt::digit_max)
-  {
-    lhs[0] = lhs.divide_by_digit(static_cast<typename MpInt::digit_type>(tmp));
-    lhs.set_size(1);
-  }
-  else
-    lhs %= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, false>::bitwise_or(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs <= MpInt::digit_max)
-    lhs[0] |= static_cast<typename MpInt::digit_type>(rhs);
-  else
-    lhs |= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, true>::bitwise_or(MpInt& lhs, IntegralT rhs)
-{
-  // we care only about the absolute value of rhs
-  unsigned_type tmp;
-  if (rhs >= 0)
-    tmp = rhs;
-  else
-    tmp = -rhs;
-
-  if (tmp <= MpInt::digit_max)
-    lhs[0] |= static_cast<typename MpInt::digit_type>(tmp);
-  else
-    lhs |= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, false>::bitwise_and(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs <= MpInt::digit_max)
-    lhs[0] &= static_cast<typename MpInt::digit_type>(rhs);
-  else
-    lhs &= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, true>::bitwise_and(MpInt& lhs, IntegralT rhs)
-{
-  unsigned_type tmp;
-  if (rhs >= 0)
-    tmp = rhs;
-  else
-    tmp = -rhs;
-
-  if (tmp <= MpInt::digit_max)
-    lhs[0] &= static_cast<typename MpInt::digit_type>(tmp);
-  else
-    lhs &= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, false>::bitwise_xor(MpInt& lhs, IntegralT rhs)
-{
-  if (rhs <= MpInt::digit_max)
-    lhs[0] ^= static_cast<typename MpInt::digit_type>(rhs);
-  else
-    lhs ^= MpInt(rhs);
-}
-
-template<typename IntegralT, class MpInt>
-void
-integral_ops_impl<IntegralT, MpInt, true>::bitwise_xor(MpInt& lhs, IntegralT rhs)
-{
-  unsigned_type tmp;
-  if (rhs >= 0)
-    tmp = rhs;
-  else
-    tmp = -rhs;
-
-  if (tmp <= MpInt::digit_max)
-    lhs[0] ^= static_cast<typename MpInt::digit_type>(tmp);
-  else
-    lhs ^= MpInt(rhs);
-}
-
-
-
-
-
-template<
-  typename IntegralT,
-  class MpInt,
-  bool is_signed = std::numeric_limits<IntegralT>::is_signed,
-  bool is_larger = (std::numeric_limits<IntegralT>::digits > MpInt::valid_bits)
->
-struct integral_ops2
-{};
-
-
-template<typename IntegralT, class MpInt>
-struct integral_ops2<IntegralT, MpInt, true, true>
-{
-  typedef std::numeric_limits<IntegralT> integral_type_limits;
-  typedef typename make_unsigned<IntegralT>::type unsigned_type;
-
-  static IntegralT to_integral(const MpInt& x);
-};
-
-template<typename IntegralT, class MpInt>
-struct integral_ops2<IntegralT, MpInt, true, false>
-{
-  typedef std::numeric_limits<IntegralT> integral_type_limits;
-  typedef typename make_unsigned<IntegralT>::type unsigned_type;
-
-  static IntegralT to_integral(const MpInt& x);
-};
-
-template<typename IntegralT, class MpInt>
-struct integral_ops2<IntegralT, MpInt, false, true>
-{
-  typedef std::numeric_limits<IntegralT> integral_type_limits;
-
-  static IntegralT apply_shift(const MpInt& x);
-  static IntegralT to_integral(const MpInt& x);
-};
-
-template<typename IntegralT, class MpInt>
-struct integral_ops2<IntegralT, MpInt, false, false>
-{
-  typedef std::numeric_limits<IntegralT> integral_type_limits;
-
-  static IntegralT apply_shift(const MpInt& x);
-  static IntegralT to_integral(const MpInt& x);
-};
-
-
-template<typename IntegralT, class MpInt>
-IntegralT integral_ops2<IntegralT, MpInt, true, true>::to_integral(const MpInt& x)
-{
-  if (x.size() == 1)
-  {
-    if (x.digits()[0] <= integral_type_limits::max())
-      return static_cast<IntegralT>(x.sign()) *
-             static_cast<IntegralT>(x[0]);
-    throw std::overflow_error(
-        "to_integral: integral type does not have enough precision to hold result");
-  }
-
-  const unsigned_type tmp = integral_ops2<unsigned_type, MpInt>::apply_shift(x);
-
-  return static_cast<IntegralT>(x.sign()) * static_cast<IntegralT>(tmp);
-}
-
-template<typename IntegralT, class MpInt>
-IntegralT integral_ops2<IntegralT, MpInt, true, false>::to_integral(const MpInt& x)
-{
-  if (x.size() == 1)
-    return static_cast<IntegralT>(x.sign()) * static_cast<IntegralT>(x[0]);
-
-  const unsigned_type tmp = integral_ops2<unsigned_type, MpInt>::apply_shift(x);
-
-  return static_cast<IntegralT>(x.sign()) * static_cast<IntegralT>(tmp);
-}
-
-template<typename IntegralT, class MpInt>
-IntegralT integral_ops2<IntegralT, MpInt, false, true>::apply_shift(const MpInt& x)
-{
-  int shift_count = 0;
-  IntegralT tmp = 0;
-
-  for (typename MpInt::const_reverse_iterator digit = x.rbegin();
-      digit != x.rend(); ++digit)
-  {
-    tmp <<= MpInt::valid_bits;
-    if (shift_count++ * MpInt::valid_bits > integral_type_limits::digits)
-      throw std::overflow_error(
-          "to_integral: integral type does not have enough precision to hold result");
-    tmp |= *digit & (power<IntegralT,2,MpInt::valid_bits>::value - 1);
-  }
-
-  return tmp;
-}
-
-template<typename IntegralT, class MpInt>
-IntegralT integral_ops2<IntegralT, MpInt, false, true>::to_integral(const MpInt& x)
-{
-  if (x.sign() == 1)
-  {
-    if (x.size() == 1 && x[0] <= integral_type_limits::max())
-      return static_cast<IntegralT>(x[0]);
-  }
-  else
-    throw std::overflow_error(
-        "to_integral: cannot convert negative number to unsigned integral type");
-
-  return apply_shift(x);
-}
-
-template<typename IntegralT, class MpInt>
-IntegralT integral_ops2<IntegralT, MpInt, false, false>::apply_shift(const MpInt&)
-{
-  throw std::overflow_error(
-      "to_integral: integral type does not have enough precision to hold result");
-}
-
-template<typename IntegralT, class MpInt>
-IntegralT integral_ops2<IntegralT, MpInt, false, false>::to_integral(const MpInt& x)
-{
-  if (x.size() == 1)
-    return static_cast<IntegralT>(x[0]);
-  else
-    return apply_shift(x);
-}
-
-
-
-////////////////////////////////////////////////////////////////////////////
-
-template<typename IntegralT>
-struct integral_ops
-{
-  BOOST_STATIC_ASSERT(boost::is_integral<IntegralT>::value);
-
-  template<class A, class T>
-  static IntegralT convert(const mp_int<A,T>& x)
-  {
-    return integral_ops2<IntegralT, mp_int<A,T> >::to_integral(x);
-  }
-
-  template<class A, class T>
-  static void assign(mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    integral_ops_impl<IntegralT, mp_int<A,T> >::assign(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static bool equal(const mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    return integral_ops_impl<IntegralT, mp_int<A,T> >::equal(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static bool less(const mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    return integral_ops_impl<IntegralT, mp_int<A,T> >::less(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static void add(mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    integral_ops_impl<IntegralT, mp_int<A,T> >::add(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static void subtract(mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    integral_ops_impl<IntegralT, mp_int<A,T> >::subtract(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static void multiply(mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    integral_ops_impl<IntegralT, mp_int<A,T> >::multiply(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static void divide(mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    integral_ops_impl<IntegralT, mp_int<A,T> >::divide(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static void modulo(mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    integral_ops_impl<IntegralT, mp_int<A,T> >::modulo(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static void bitwise_or(mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    integral_ops_impl<IntegralT, mp_int<A,T> >::bitwise_or(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static void bitwise_and(mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    integral_ops_impl<IntegralT, mp_int<A,T> >::bitwise_and(lhs, rhs);
-  }
-
-  template<class A, class T>
-  static void bitwise_xor(mp_int<A,T>& lhs, IntegralT rhs)
-  {
-    integral_ops_impl<IntegralT, mp_int<A,T> >::bitwise_xor(lhs, rhs);
-  }
-};
-
-
-} // namespace detail
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Copied: sandbox/mp_math/boost/mp_math/integer/detail/jacobi.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/jacobi.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/jacobi.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/jacobi.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,31 +1,33 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_JACOBI_HPP
-#define BOOST_MP_MATH_MP_INT_JACOBI_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_JACOBI_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_JACOBI_HPP
 
 
 namespace boost {
 namespace mp_math {
+namespace detail {
 
 // computes the jacobi c = (a | p) (or Legendre if p is prime)
 // HAC pp. 73 Algorithm 2.149
-template<class A, class T>
-int jacobi(const mp_int<A,T>& a, const mp_int<A,T>& p)
+template<class ApInt>
+int jacobi(const ApInt& a, const ApInt& p)
 {
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  typedef typename mp_int<A,T>::size_type  size_type;
+  typedef typename ApInt::digit_type digit_type;
+  typedef typename ApInt::size_type  size_type;
 
   if (p <= digit_type(0))
     throw std::domain_error("jacobi: p must be greater than 0");
 
+  std::cout << "a = "; a.print();
+  std::cout << "p = "; p.print();
   if (!a)
     return 0;
-  
+
   if (a == digit_type(1))
     return 1;
 
@@ -33,19 +35,19 @@
   int s = 0;
 
   // write a = a1 * 2**k
-  mp_int<A,T> a1(a);
+  ApInt a1(a);
 
   // find largest power of two that divides a1
-  const size_type k = a1.count_lsb();
+  const size_type k = a1.count_trailing_zero_bits();
   // now divide by it
-  a1.shift_right(k,0);
+  a1 >>= k;
 
   // if k is even set s=1
   if ((k & 1) == 0)
     s = 1;
   else
   {
-    // calculate p.digits_[0] mod 8
+    // calculate p[0] mod 8
     const digit_type residue = p[0] & 7;
 
     if (residue == 1 || residue == 7)
@@ -58,16 +60,15 @@
   if (((p[0] & 3) == 3) && ((a1[0] & 3) == 3))
     s = -s;
 
+  std::cout << "a1 = "; a1.print();
   if (a1 == digit_type(1))
     return s;
   else
-  {
-    const mp_int<A,T> p1(p % a1);
-    return s * jacobi(p1, a1);
-  }
+    return s * jacobi(p % a1, a1);
 }
 
 
+} // namespace detail
 } // namespace mp_math
 } // namespace boost
 
Copied: sandbox/mp_math/boost/mp_math/integer/detail/lcm.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/lcm.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/lcm.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/lcm.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,45 +1,69 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_LCM_HPP
-#define BOOST_MP_MATH_MP_INT_LCM_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_LCM_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_LCM_HPP
 
 
 namespace boost {
 namespace mp_math {
+namespace detail {
+
+// compute least common multiple as |a*b|/gcd(a,b)
+
+template<class ApInt, bool IsSigned = ApInt::is_signed>
+struct lcm_finder;
 
-// computes least common multiple as |a*b|/gcd(a,b)
-template<class A, class T>
-mp_int<A,T> lcm(const mp_int<A,T>& a, const mp_int<A,T>& b)
+
+template<class ApInt>
+struct lcm_finder<ApInt, false>
+{
+  static void lcm(ApInt& z, const ApInt& a, const ApInt& b);
+};
+
+
+template<class ApInt>
+void lcm_finder<ApInt, false>::lcm(ApInt& z, const ApInt& a, const ApInt& b)
 {
-  mp_int<A,T> result;
-    
   if (!a || !b)
   {
-    result.zero();
-    return result;
+    z = typename ApInt::digit_type(0);
+    return;
   }
-  
-  result = a / gcd(a, b) * b;
 
-  result.set_sign(1);
-  
-  return result;
+  const ApInt u(a);
+  const ApInt v(b);
+
+  z = u / gcd(u, v) * v;
 }
 
-#ifdef BOOST_HAS_VARIADIC_TMPL
-template<class A, class T, class... MpInts>
-mp_int<A,T> lcm(const mp_int<A,T>& a, const mp_int<A,T>& b, const MpInts&... args)
+
+template<class ApInt>
+struct lcm_finder<ApInt, true>
 {
-  return lcm(lcm(a, b), args...);
+  static void lcm(ApInt& z, const ApInt& a, const ApInt& b);
+};
+
+
+template<class ApInt>
+void lcm_finder<ApInt, true>::lcm(ApInt& z, const ApInt& a, const ApInt& b)
+{
+  if (!a || !b)
+  {
+    z = typename ApInt::digit_type(0);
+    return;
+  }
+
+  const ApInt u = abs(a);
+  const ApInt v = abs(b);
+
+  z = u / gcd(u, v) * v;
 }
-#endif
 
 
+} // namespace detail
 } // namespace mp_math
 } // namespace boost
 
Modified: sandbox/mp_math/boost/mp_math/integer/detail/meta_math.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/meta_math.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/meta_math.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -14,7 +14,7 @@
 
 
 // power -----------------------------------------------------------------------
-
+/*
 template<
         typename IntegralT,
         IntegralT X, IntegralT Y,
@@ -40,7 +40,7 @@
 struct power
 {
         static const IntegralT value = power_impl<IntegralT,X,Y>::value;
-};
+};*/
 
 
 
Modified: sandbox/mp_math/boost/mp_math/integer/detail/modinv.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/modinv.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/modinv.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,67 +1,98 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_DETAIL_MODINV_HPP
-#define BOOST_MP_MATH_MP_INT_DETAIL_MODINV_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_MODINV_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_MODINV_HPP
 
+#include <boost/mp_math/integer/detail/base/divider.hpp>
 
 namespace boost {
 namespace mp_math {
 namespace detail {
 
-// hac 14.61, pp608
-template<class A1, class T>
-mp_int<A1,T> even_modinv(const mp_int<A1,T>& z, const mp_int<A1,T>& m)
+
+template<class ApInt>
+struct modular_inverter
+{
+  typedef typename ApInt::digit_type digit_type;
+  typedef base::divider<ApInt>       base_divider_type;
+
+  static void modinv     (ApInt& z, const ApInt& x, const ApInt& m);
+  static void even_modinv(ApInt& z, const ApInt& x, const ApInt& m);
+  static void odd_modinv (ApInt& z, const ApInt& x, const ApInt& m);
+};
+
+
+// returns the modular multiplicative inverse z of x (mod m) such that
+// z * x = 1 (mod m)  =>
+// x^-1  = z (mod m)
+// The inverse exists only if a and m are coprime (i.e. gcd(a,m) = 1).
+// If no inverse exists this function will throw std::domain_error.
+template<class ApInt>
+void
+modular_inverter<ApInt>::modinv(ApInt& z, const ApInt& x, const ApInt& m)
 {
-  typedef typename mp_int<A1,T>::digit_type digit_type;
+  if (m.is_negative())
+    throw std::domain_error("modinv: modulus is negative");
+  if (!m)
+    throw std::domain_error("modinv: modulus is zero");
+
+  // if the modulus is odd we can use a faster routine
+  if (m.is_odd())
+    odd_modinv(z, x, m);
+  else
+    even_modinv(z, x, m);
+}
 
+// HAC 14.61, pp608
+template<class ApInt>
+void
+modular_inverter<ApInt>::even_modinv(ApInt& z, const ApInt& x, const ApInt& m)
+{
   assert(m.is_even());
 
-  static const char* const err_msg = "mp_int::modinv: inverse does not exist";
+  static const char* const err_msg = "modinv: inverse does not exist";
+
+  const ApInt y = x % m;
 
-  const mp_int<A1,T> x = z % m;
-  
-  if (x.is_even())
+  if (y.is_even())
     throw std::domain_error(err_msg);
 
-  mp_int<A1,T> u(x);
-  mp_int<A1,T> v(m);
-  mp_int<A1,T> A = digit_type(1);
-  mp_int<A1,T> B = digit_type(0);
-  mp_int<A1,T> C = digit_type(0);
-  mp_int<A1,T> D = digit_type(1);
+  ApInt u(y);
+  ApInt v(m);
+  ApInt A = digit_type(1);
+  ApInt B = digit_type(0);
+  ApInt C = digit_type(0);
+  ApInt D = digit_type(1);
 
 top:
   while (u.is_even())
   {
-    u.divide_by_2();
-    
+    base_divider_type::divide_by_2(u);
+
     if (A.is_odd() || B.is_odd())
     {
-      // A = (A+m)/2, B = (B-x)/2
       A += m;
-      B -= x;
+      B -= y;
     }
-    A.divide_by_2();
-    B.divide_by_2();
+    base_divider_type::divide_by_2(A);
+    base_divider_type::divide_by_2(B);
   }
 
   while (v.is_even())
   {
-    v.divide_by_2();
+    base_divider_type::divide_by_2(v);
 
     if (C.is_odd() || D.is_odd())
     {
-      // C = (C+m)/2, D = (D-x)/2
       C += m;
-      D -= x;
+      D -= y;
     }
-    C.divide_by_2();
-    D.divide_by_2();
+    base_divider_type::divide_by_2(C);
+    base_divider_type::divide_by_2(D);
   }
 
   if (u >= v)
@@ -87,66 +118,64 @@
     throw std::domain_error(err_msg);
 
   // if it's too low
-  while (C.compare_to_digit(0) == -1)
+  while (C.is_negative())
     C += m;
-  
+
   // too big
-  while (C.compare_magnitude(m) != -1)
+  while (compare_magnitude(C, m) != -1)
     C -= m;
-  
-  return C;
+
+  swap(z, C);
 }
 
-/* computes the modular inverse via binary extended euclidean algorithm, 
- * that is z = 1 / z mod m
- *
- * Based on even modinv except this is optimized for the case where m is 
- * odd as per HAC Note 14.64 on pp. 610
- */
-template<class A1, class T>
-mp_int<A1,T> odd_modinv(const mp_int<A1,T>& z, const mp_int<A1,T>& m)
+// computes the modular inverse via binary extended euclidean algorithm,
+// that is z = 1 / z mod m
+//
+// Based on even modinv except this is optimized for the case where m is
+// odd as per HAC Note 14.64 on pp. 610
+template<class ApInt>
+void
+modular_inverter<ApInt>::odd_modinv(ApInt& z, const ApInt& x, const ApInt& m)
 {
-  typedef typename mp_int<A1,T>::digit_type digit_type;
-
   assert(m.is_odd());
 
   // m == modulus, y == value to invert
   // we need y = |a|
-  const mp_int<A1,T> y = z % m;
+  const ApInt y = x % m;
 
-  mp_int<A1,T> u(m);
-  mp_int<A1,T> v(y);
-  mp_int<A1,T> A = digit_type(1);
-  mp_int<A1,T> B = digit_type(0);
-  mp_int<A1,T> C = digit_type(0);
-  mp_int<A1,T> D = digit_type(1);
+  ApInt u(m);
+  ApInt v(y);
+  ApInt A = digit_type(1);
+  ApInt B = digit_type(0);
+  ApInt C = digit_type(0);
+  ApInt D = digit_type(1);
 
 top:
   while (u.is_even())
   {
-    u.divide_by_2();
-    
+    base_divider_type::divide_by_2(u);
+
     if (B.is_odd())
       B -= m;
-    
-    B.divide_by_2();
+
+    base_divider_type::divide_by_2(B);
   }
 
   while (v.is_even())
   {
-    v.divide_by_2();
+    base_divider_type::divide_by_2(v);
 
     if (D.is_odd())
-      D -= m;      
+      D -= m;
 
-    D.divide_by_2();
+    base_divider_type::divide_by_2(D);
   }
 
   if (u >= v)
   {
-    /* u = u - v, B = B - D */
+    // u = u - v, B = B - D
     u -= v;
-    B -=D;
+    B -= D;
   }
   else
   {
@@ -157,15 +186,15 @@
   if (u)
     goto top;
 
-  /* now a = C, m = D, gcd == g*v */
+  // now a = C, m = D, gcd == g*v
 
   if (v != digit_type(1))
-    throw std::domain_error("mp_int::modinv: inverse does not exist");
+    throw std::domain_error("modinv: inverse does not exist");
 
   while (D.is_negative())
     D += m;
 
-  return D;
+  swap(z, D);
 }
 
 
Modified: sandbox/mp_math/boost/mp_math/integer/detail/modpow.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/modpow.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/modpow.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,31 +1,289 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_INTEGER_DETAIL_MODPOW_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_MODPOW_HPP
 
-#ifndef BOOST_MP_MATH_MP_INT_DETAIL_MODPOW_HPP
-#define BOOST_MP_MATH_MP_INT_DETAIL_MODPOW_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-#include <boost/mp_math/mp_int/detail/modular_reduction.hpp>
+#include <boost/mp_math/integer/detail/modular_reduction.hpp>
 
 namespace boost {
 namespace mp_math {
 namespace detail {
 
 
-template<class A, class T>
-mp_int<A,T> barret_modpow(const mp_int<A,T>& base,
-                          const mp_int<A,T>& exp,
-                          const mp_int<A,T>& m,
-                          int redmode,
-                          mp_int<A,T>& mu)
+// modpow_ctx allows us to precalculate and store certain values so that modpow
+// calls with the same modulus are sped up. We should probably store a pointer
+// value to the original modulus value here and then assert that we are handed
+// the same modulus in subsequent invocations.
+
+template<class ApInt>
+struct modpow_ctx
+{
+  typedef typename ApInt::digit_type  digit_type;
+  typedef typename ApInt::size_type   size_type;
+  typedef typename ApInt::traits_type traits_type;
+
+  // dr means diminished radix
+  enum modulus_type_t
+  {                           // R is our radix
+    mod_restricted_dr,        // m = R^k - d; d <= R
+    mod_unrestricted_dr,      // m = 2^k - d; d <= R
+    mod_unrestricted_dr_slow, // m = 2^k - d; d <  d^(k/2)
+    mod_odd,
+    mod_generic
+  }modulus_type;
+
+  modpow_ctx() : precalculated(false) {}
+
+  modulus_type_t do_detect(const ApInt& m) const;
+
+  void detect_modulus_type(const ApInt& m)
+  {
+    modulus_type = do_detect(m);
+  }
+
+  void precalculate(const ApInt& m);
+
+  ApInt mu;
+  digit_type rho;
+  bool precalculated;
+};
+
+
+template<class ApInt>
+typename modpow_ctx<ApInt>::modulus_type_t
+modpow_ctx<ApInt>::do_detect(const ApInt& m) const
 {
-  typedef typename mp_int<A,T>::size_type size_type;
-  typedef typename mp_int<A,T>::size_type digit_type;
+  if (m.size() == 1)
+    return mod_unrestricted_dr;
+
+  size_type count = 0;
+
+  const size_type bits = m.precision() % traits_type::radix_bits;
 
-  void (*redux)(mp_int<A,T>&, const mp_int<A,T>&, const mp_int<A,T>&);
+  if (!bits && m[m.size()-1] == traits_type::max_digit_value)
+    ++count;
+
+  for (typename ApInt::const_reverse_iterator d = m.rbegin() + 1;
+       d != m.rend(); ++d)
+  {
+    if (*d != traits_type::max_digit_value)
+      break;
+    else
+      ++count;
+  }
+
+  // if all bits are set
+  if (count == m.size() - 1)
+    return mod_restricted_dr;
+
+  // if all bits until the most significant digit are set
+  if (count == m.size() - 2)
+  {
+    bool all_bits_set = true;
+
+    // handle the remaining bits in the most significant digit
+    digit_type mask = 1;
+    for (size_type i = 0; i < bits; ++i)
+    {
+      if ((m[m.size()-1] & mask) == 0)
+      {
+        all_bits_set = false;
+        break;
+      }
+      mask <<= 1;
+    }
+    if (all_bits_set)
+      return mod_unrestricted_dr;
+  }
+
+  // if more than half of the bits are set
+  if (count >= m.size() / 2)
+    return mod_unrestricted_dr_slow;
+
+  if (m.is_odd())
+    return mod_odd;
+
+  return mod_generic;
+}
+
+template<class ApInt>
+void modpow_ctx<ApInt>::precalculate(const ApInt& m)
+{
+  switch (modulus_type)
+  {
+    case mod_restricted_dr:
+    {
+      rho = traits_type::max_digit_value - m[0] + 1U;
+      break;
+    }
+    case mod_unrestricted_dr:
+    {
+      const size_type p = m.precision();
+
+      ApInt tmp;
+      power<ApInt>::pow2(tmp, p);
+      base::adder<ApInt>::subtract_smaller_magnitude(tmp, m);
+
+      rho = tmp[0];
+      break;
+    }
+    case mod_unrestricted_dr_slow:
+    {
+      ApInt tmp;
+
+      power<ApInt>::pow2(tmp, m.precision());
+      mu = tmp - m;
+      break;
+    }
+    case mod_odd:
+    {
+      assert(m.is_odd());
+
+      // fast inversion mod 2**k
+      //
+      // Based on the fact that
+      //
+      // XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
+      //                    =>  2*X*A - X*X*A*A = 1
+      //                    =>  2*(1) - (1)     = 1
+      const digit_type b = m[0];
+
+      static const size_type S = std::numeric_limits<digit_type>::digits;
+
+      digit_type x = (((b + 2) & 4) << 1) + b; // here x*a==1 mod 2**4
+      x *= 2 - b * x;                          // here x*a==1 mod 2**8
+      if (S != 8)
+        x *= 2 - b * x;                        // here x*a==1 mod 2**16
+      if (S == 64 || !(S == 8 || S == 16))
+        x *= 2 - b * x;                        // here x*a==1 mod 2**32
+      if (S == 64)
+        x *= 2 - b * x;                        // here x*a==1 mod 2**64
+
+      // rho = -1/m mod b
+      rho = traits_type::max_digit_value - x + 1U;
+      break;
+    }
+    case mod_generic:
+    {
+      // mu = b^2k/m
+      power<ApInt>::pow2(mu, m.size() * 2 * traits_type::digit_bits);
+      mu /= m;
+      break;
+    }
+  }
+
+  precalculated = true;
+}
+
+
+template<class ApInt>
+struct modular_power
+{
+  typedef typename ApInt::size_type   size_type;
+  typedef typename ApInt::digit_type  digit_type;
+  typedef typename ApInt::traits_type traits_type;
+
+  // computes z = base^exp % m
+  static void modpow(ApInt& z,
+                     const ApInt& base,
+                     const ApInt& exp,
+                     const ApInt& m,
+                     modpow_ctx<ApInt>* ctx);
+
+  static void modpow_with_ctx(ApInt& z,
+                              const ApInt& base,
+                              const ApInt& exp,
+                              const ApInt& m,
+                              const modpow_ctx<ApInt>& ctx);
+
+  static void barret_modpow(ApInt& z,
+                            const ApInt& base,
+                            const ApInt& exp,
+                            const ApInt& m,
+                            int redmode,
+                            const ApInt& mu);
+
+  static void montgomery_modpow(ApInt& z,
+                                const ApInt& base,
+                                const ApInt& exp,
+                                const ApInt& m,
+                                int redmode,
+                                digit_type mp);
+};
+
+
+template<class ApInt>
+void modular_power<ApInt>::modpow(ApInt& z,
+                                  const ApInt& base,
+                                  const ApInt& exp,
+                                  const ApInt& mod,
+                                  modpow_ctx<ApInt>* ctx = 0)
+{
+  if (mod.is_negative())
+    throw std::domain_error("modpow: modulus must be positive");
+
+  if (exp.is_negative())
+  {
+    //modpow(z, modinv(base, mod), abs(exp), mod, ctx);
+    return;
+  }
+
+  if (!ctx)
+  {
+    modpow_ctx<ApInt> tmp_ctx;
+    tmp_ctx.detect_modulus_type(mod);
+    tmp_ctx.precalculate(mod);
+    modpow_with_ctx(z, base, exp, mod, tmp_ctx);
+  }
+  else
+  {
+    if (!ctx->precalculated)
+    {
+      ctx->detect_modulus_type(mod);
+      ctx->precalculate(mod);
+    }
+    modpow_with_ctx(z, base, exp, mod, *ctx);
+  }
+}
+
+template<class ApInt>
+void modular_power<ApInt>::modpow_with_ctx(ApInt& z,
+                                           const ApInt& base,
+                                           const ApInt& exp,
+                                           const ApInt& mod,
+                                           const modpow_ctx<ApInt>& ctx)
+{
+  typedef modpow_ctx<ApInt> ctx_t;
+
+  switch (ctx.modulus_type)
+  {
+    case ctx_t::mod_restricted_dr:
+      montgomery_modpow(z, base, exp, mod, 1, ctx.rho); break;
+    case ctx_t::mod_unrestricted_dr:
+      montgomery_modpow(z, base, exp, mod, 2, ctx.rho); break;
+    case ctx_t::mod_unrestricted_dr_slow:
+      barret_modpow    (z, base, exp, mod, 1, ctx.mu); break;
+    case ctx_t::mod_odd:
+      montgomery_modpow(z, base, exp, mod, 0, ctx.rho); break;
+    case ctx_t::mod_generic:
+    default:
+      barret_modpow    (z, base, exp, mod, 0, ctx.mu); break;
+  }
+}
+
+template<class ApInt>
+void modular_power<ApInt>::barret_modpow(ApInt& z,
+                                         const ApInt& base,
+                                         const ApInt& exp,
+                                         const ApInt& m,
+                                         int redmode,
+                                         const ApInt& mu)
+{
+  void (*redux)(ApInt&, const ApInt&, const ApInt&);
 
   // find window size
   const size_type x = exp.precision();
@@ -46,13 +304,13 @@
     winsize = 8;
 
   if (redmode == 0)
-    redux = &barrett_reduce;
+    redux = &modular_reducer<ApInt>::barrett_reduce;
   else
-    redux = &unrestricted_dr_slow_reduce;
+    redux = &modular_reducer<ApInt>::unrestricted_dr_slow_reduce;
 
   // The M table contains powers of the base, e.g. M[i] = base**i % m
   // The first half of the table is not computed though except for M[0] and M[1]
-  mp_int<A,T> M[256];
+  ApInt M[256];
   M[1] = base % m;
 
   // compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times
@@ -61,7 +319,7 @@
   for (size_type i = 0; i < (winsize - 1); ++i)
   {
     const size_type offset = 1 << (winsize - 1);
-    M[offset].sqr();
+    multiplier<ApInt>::sqr(M[offset]);
     // reduce modulo m
     (*redux)(M[offset], m, mu);
   }
@@ -77,12 +335,12 @@
   }
 
   // setup result
-  mp_int<A,T> res = digit_type(1);
+  z = digit_type(1);
 
   int mode   = 0;
   int bitcnt = 1;
   digit_type buf = 0;
-  typename mp_int<A,T>::const_reverse_iterator exp_digit = exp.rbegin();
+  typename ApInt::const_reverse_iterator exp_digit = exp.rbegin();
   size_type bitcpy = 0;
   int bitbuf = 0;
 
@@ -93,14 +351,14 @@
     {
       if (exp_digit == exp.rend())
         break;
-      
+
       // read next digit and reset the bitcnt
       buf    = *exp_digit++;
-      bitcnt = mp_int<A,T>::valid_bits;
+      bitcnt = traits_type::radix_bits;
     }
 
     // grab the next msb from the exponent
-    int y = (buf >> static_cast<digit_type>(mp_int<A,T>::valid_bits - 1)) & 1;
+    int y = (buf >> static_cast<digit_type>(traits_type::radix_bits - 1)) & 1;
     buf <<= digit_type(1);
 
     // if the bit is zero and mode == 0 then we ignore it
@@ -113,8 +371,8 @@
     // if the bit is zero and mode == 1 then we square
     if (mode == 1 && y == 0)
     {
-      res.sqr();
-      (*redux)(res, m, mu);
+      multiplier<ApInt>::sqr(z);
+      (*redux)(z, m, mu);
       continue;
     }
 
@@ -128,13 +386,13 @@
       // square first
       for (size_type i = 0; i < winsize; ++i)
       {
-        res.sqr();
-        (*redux)(res, m, mu);
+        multiplier<ApInt>::sqr(z);
+        (*redux)(z, m, mu);
       }
 
       // then multiply
-      res *= M[bitbuf];
-      (*redux)(res, m, mu);
+      z *= M[bitbuf];
+      (*redux)(z, m, mu);
 
       // empty window and reset
       bitcpy = 0;
@@ -149,40 +407,35 @@
     // square then multiply if the bit is set
     for (size_type i = 0; i < bitcpy; ++i)
     {
-      res.sqr();
-      (*redux)(res, m, mu);
+      multiplier<ApInt>::sqr(z);
+      (*redux)(z, m, mu);
 
       bitbuf <<= 1;
       if ((bitbuf & (1 << winsize)) != 0)
       {
-        res *= M[1];
-        (*redux)(res, m, mu);
+        z *= M[1];
+        (*redux)(z, m, mu);
       }
     }
   }
-
-  return res;
 }
 
-/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
- *
- * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
- * The value of k changes based on the size of the exponent.
- *
- * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
- */
-template<class A, class T>
-mp_int<A,T> montgomery_modpow(const mp_int<A,T>& base,
-                              const mp_int<A,T>& exp,
-                              const mp_int<A,T>& m,
-                              int redmode,
-                              typename mp_int<A,T>::digit_type mp)
+// computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
+//
+// Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
+// The value of k changes based on the size of the exponent.
+//
+// Uses Montgomery or Diminished Radix reduction [whichever appropriate]
+template<class ApInt>
+void modular_power<ApInt>::montgomery_modpow(ApInt& z,
+                                             const ApInt& base,
+                                             const ApInt& exp,
+                                             const ApInt& m,
+                                             int redmode,
+                                             digit_type mp)
 {
-  typedef typename mp_int<A,T>::size_type size_type;
-  typedef typename mp_int<A,T>::digit_type digit_type;
+  void (*redux)(ApInt&, const ApInt&, digit_type);
 
-  void (*redux)(mp_int<A,T>&, const mp_int<A,T>&, digit_type);
-  
   // find window size
   const size_type x = exp.precision();
   size_type winsize;
@@ -200,32 +453,28 @@
     winsize = 7;
   else
     winsize = 8;
-  
-  //digit_type mp = ctx->mp;
-  
+
   if (redmode == 0)
-    redux = &montgomery_reduce;
+    redux = &modular_reducer<ApInt>::montgomery_reduce;
   else if (redmode == 1)
-    redux = &restricted_dr_reduce;
+    redux = &modular_reducer<ApInt>::restricted_dr_reduce;
   else
-    redux = &unrestricted_dr_reduce;
-
-  mp_int<A,T> res;
+    redux = &modular_reducer<ApInt>::unrestricted_dr_reduce;
 
   // create M table
   // The first half of the table is not computed though except for M[0] and M[1]
-  mp_int<A,T> M[256];
-  
+  ApInt M[256];
+
   if (redmode == 0)
   {
     // now we need R mod m
-    montgomery_normalize(res, m);
+    modular_reducer<ApInt>::montgomery_normalize(z, m);
     // now set M[1] to G * R mod m
-    M[1] = (base * res) % m;
+    M[1] = (base * z) % m;
   }
   else
   {
-    res = digit_type(1);
+    z = digit_type(1);
     M[1] = base % m;
   }
 
@@ -235,7 +484,7 @@
   for (size_type i = 0; i < (winsize - 1); ++i)
   {
     const size_type offset = 1 << (winsize - 1);
-    M[offset].sqr();
+    multiplier<ApInt>::sqr(M[offset]);
     (*redux)(M[offset], m, mp);
   }
 
@@ -243,15 +492,15 @@
   for (size_type i = (1 << (winsize - 1)) + 1;
        i < (size_type(1) << winsize); ++i)
   {
-    M[i] = M[i-1] * M[1];
+    multiplier<ApInt>::mul(M[i], M[i-1], M[1]);
     (*redux)(M[i], m, mp);
   }
 
-  /* set initial mode and bit cnt */
+  // set initial mode and bit cnt
   int mode   = 0;
   int bitcnt = 1;
   digit_type buf = 0;
-  typename mp_int<A,T>::const_reverse_iterator exp_digit = exp.rbegin();
+  typename ApInt::const_reverse_iterator exp_digit = exp.rbegin();
   size_type bitcpy = 0;
   unsigned int bitbuf = 0;
 
@@ -264,11 +513,11 @@
         break;
       // read next digit and reset bitcnt
       buf    = *exp_digit++;
-      bitcnt = mp_int<A,T>::valid_bits;
+      bitcnt = traits_type::radix_bits;
     }
 
     // grab the next msb from the exponent
-    int y = (buf >> (mp_int<A,T>::valid_bits - 1)) & 1;
+    int y = (buf >> (traits_type::radix_bits - 1)) & 1;
     buf <<= digit_type(1);
 
     // if the bit is zero and mode == 0 then we ignore it
@@ -281,8 +530,8 @@
     // if the bit is zero and mode == 1 then we square
     if (mode == 1 && y == 0)
     {
-      res.sqr();
-      (*redux)(res, m, mp);
+      multiplier<ApInt>::sqr(z);
+      (*redux)(z, m, mp);
       continue;
     }
 
@@ -293,16 +542,14 @@
     if (bitcpy == winsize)
     {
       // ok window is filled so square as required and multiply
-      // square first
       for (size_type i = 0; i < winsize; ++i)
       {
-        res.sqr();
-        (*redux)(res, m, mp);
+        multiplier<ApInt>::sqr(z);
+        (*redux)(z, m, mp);
       }
 
-      // then multiply
-      res *= M[bitbuf];
-      (*redux)(res, m, mp);
+      z *= M[bitbuf];
+      (*redux)(z, m, mp);
 
       // empty window and reset
       bitcpy = 0;
@@ -314,19 +561,17 @@
   // if bits remain then square/multiply
   if (mode == 2 && bitcpy > 0)
   {
-    // square then multiply if the bit is set
     for (size_type i = 0; i < bitcpy; ++i)
     {
-      res.sqr();
-      (*redux)(res, m, mp);
+      multiplier<ApInt>::sqr(z);
+      (*redux)(z, m, mp);
 
       // get next bit of the window
       bitbuf <<= 1;
       if ((bitbuf & (1 << winsize)) != 0)
       {
-        // then multiply
-        res *= M[1];
-        (*redux)(res, m, mp);
+        z *= M[1];
+        (*redux)(z, m, mp);
       }
     }
   }
@@ -335,9 +580,7 @@
   // Montgomery system is actually multiplied by R mod n. So we have to reduce
   // one more time to cancel out the factor of R.
   if (redmode == 0)
-    (*redux)(res, m, mp);
-
-  return res;
+    (*redux)(z, m, mp);
 }
 
 
Modified: sandbox/mp_math/boost/mp_math/integer/detail/modular_reduction.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/modular_reduction.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/modular_reduction.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,76 +1,108 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_DETAIL_MODULAR_REDUCTION_HPP
-#define BOOST_MP_MATH_MP_INT_DETAIL_MODULAR_REDUCTION_HPP
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_MODULAR_REDUCTION_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_MODULAR_REDUCTION_HPP
 
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
+#include <boost/mp_math/integer/detail/adder.hpp>
+#include <boost/mp_math/integer/detail/multiplier.hpp>
+#include <boost/mp_math/integer/detail/power.hpp>
+#include <boost/mp_math/integer/detail/shifter.hpp>
 
 namespace boost {
 namespace mp_math {
 namespace detail {
 
-// reduces x mod m, assumes 0 < x < m**2, mu is precomputed.
-// From HAC pp.604 Algorithm 14.42
-template<class A, class T>
-void barrett_reduce(mp_int<A,T>& x, const mp_int<A,T>& m, const mp_int<A,T>& mu)
+template<class ApInt>
+int compare_magnitude(const ApInt& lhs, const ApInt& rhs)
+{
+  return ApInt::traits_type::ops_type::compare_magnitude(
+      lhs.digits(), lhs.size(), rhs.digits(), rhs.size());
+}
+
+
+template<class ApInt>
+struct modular_reducer
 {
-  typedef typename mp_int<A,T>::digit_type digit_type;
+  typedef typename ApInt::digit_type     digit_type;
+  typedef typename ApInt::size_type      size_type;
+  typedef typename ApInt::traits_type    traits_type;
+  typedef typename traits_type::ops_type ops_type;
+
+  static void barrett_reduce        (ApInt& z, const ApInt& m, const ApInt& mu);
+  static void montgomery_reduce     (ApInt& z, const ApInt& m, digit_type rho);
+  static void montgomery_normalize  (ApInt& z, const ApInt& n);
+  static void restricted_dr_reduce  (ApInt& z, const ApInt& n, digit_type k);
+  static void unrestricted_dr_reduce(ApInt& z, const ApInt& n, digit_type d);
+  static void unrestricted_dr_slow_reduce(ApInt& z, const ApInt& n, const ApInt& d);
+};
+
 
-  const typename mp_int<A,T>::size_type k = m.size();
+// reduces x mod m, assumes 0 < x < m^2, mu is precomputed.
+// From HAC pp.604 Algorithm 14.42
+template<class ApInt>
+void modular_reducer<ApInt>::
+barrett_reduce(ApInt& x, const ApInt& m, const ApInt& mu)
+{
+  size_type k = m.size();
 
-  mp_int<A,T> q(x);
+  ApInt q(x);
 
-  // q = x / base**(k-1)
-  q.shift_digits_right(k - 1);
+  // q = x / radix^(k-1)
+  shifter<ApInt>::shift_digits_right(q, k-1);
 
   // according to HAC this optimization is ok
-  if (k > digit_type(1) << (mp_int<A,T>::valid_bits - 1))
+  if (k > digit_type(1) << (traits_type::radix_bits - 1))
     q *= mu;
   else
-    q.fast_mul_high_digits(mu, k);
+  {
+    //q.fast_mul_high_digits(mu, k);
+    ApInt tmp; tmp.reserve(k);
+    ops_type::comba_mul_hi(tmp.digits(), q.digits(), q.size(),
+                                         m.digits(), m.size(), k);
+    swap(tmp, q);
+  }
 
-  // q = q / base**(k+1)
-  q.shift_digits_right(k + 1);
+  // q = q / radix^(k+1)
+  shifter<ApInt>::shift_digits_right(q, k+1);
 
-  // r = x mod base**(k+1)
-  x.modulo_2_to_the_power_of(mp_int<A,T>::valid_bits * (k + 1));
+  // r = x mod radix^(k+1)
+  base::divider<ApInt>::modulo_pow2(x, traits_type::radix_bits * (k + 1));
 
-  // q = q * m mod base**(k+1)
-  q.mul_digits(m, k + 1);
+  // q = q * m mod radix^(k+1)
+  //q.mul_digits(m, k + 1);
+  ApInt tmp; tmp.reserve(k + 1);
+  ops_type::comba_mul_lo(tmp.digits(), q.digits(), q.size(),
+                                       m.digits(), m.size(), k + 1);
+  swap(tmp, q);
 
   x -= q;
 
-  // If x < 0, add base**(k+1) to it
+  // if x < 0, add radix^(k+1) to it
   if (x.is_negative())
   {
     q = digit_type(1);
-    q.shift_digits_left(k + 1);
+    shifter<ApInt>::shift_digits_left(q, k+1);
     x += q;
   }
 
   while (x >= m)
-    x.sub_smaller_magnitude(m);
+    base::adder<ApInt>::subtract_smaller_magnitude(x, m);
 }
 
-/* computes xR**-1 == x (mod m) via Montgomery Reduction */
-template<class A, class T>
-void montgomery_reduce(mp_int<A,T>& x,
-                       const mp_int<A,T>& m,
-                       typename mp_int<A,T>::digit_type rho)
+// computes xR^-1 == x (mod m) via Montgomery Reduction
+template<class ApInt>
+void modular_reducer<ApInt>::
+montgomery_reduce(ApInt& x, const ApInt& m, digit_type rho)
 {
-  typedef typename mp_int<A,T>::digit_type     digit_type;
-  typedef typename mp_int<A,T>::word_type      word_type;
-  typedef typename mp_int<A,T>::size_type      size_type;
-  typedef typename mp_int<A,T>::iterator       iterator;
-  typedef typename mp_int<A,T>::const_iterator const_iterator;
-
   const size_type num = m.size() * 2 + 1;
 
-  x.grow_capacity(num);
-  std::memset(x.digits() + x.size(), 0, (x.capacity() - x.size()) * sizeof(digit_type));
+  x.reserve(num);
+  std::memset(x.digits() + x.size(), 0,
+              (x.capacity() - x.size()) * sizeof(digit_type));
   x.set_size(num);
 
   for (size_type i = 0; i < m.size(); ++i)
@@ -80,62 +112,59 @@
     // this allows multiply_add_digits to reduce the input one digit at a time.
     const digit_type mu = x[i] * rho;
 
-    // x = x + mu * m * base**i
-  
+    // x = x + mu * m * base^i
+
     digit_type carry =
-      mp_int<A,T>::ops_type::multiply_add_digits(x.digits() + i,
-                                                 m.digits(),
-                                                 mu,
-                                                 x.digits() + i,
-                                                 m.size());
+      ops_type::multiply_add_digits(x.digits() + i,
+                                    m.digits(),
+                                    mu,
+                                    m.size());
 
     // At this point the i'th digit of x should be zero
 
-    mp_int<A,T>::ops_type::ripple_carry(x.digits() + i + m.size(),
-                                        x.digits() + i + m.size(),
-                                        num,
-                                        carry);
+    ops_type::ripple_carry(x.digits() + i + m.size(),
+                           x.digits() + i + m.size(), num, carry);
   }
 
-  // at this point the m.size least significant digits of x are all zero which
-  // means we can shift x to the right by m.size digits and the residue is
-  // unchanged.
-
-  // x = x/base**m.size()
   x.clamp();
 
   if (!x)
-    x.set_sign(1);
+    x.set_sign_bit(0);
 
-  x.shift_digits_right(m.size());
+  // at this point the m.size least significant digits of x are all zero which
+  // means we can shift x to the right by m.size digits and the residue is
+  // unchanged.
 
-  if (x.compare_magnitude(m) != -1)
-    x.sub_smaller_magnitude(m);
+  // x = x/radix^m.size()
+  shifter<ApInt>::shift_digits_right(x, m.size());
+
+  if (compare_magnitude(x, m) != -1)
+    base::adder<ApInt>::subtract_smaller_magnitude(x, m);
 }
 
 // shifts with subtractions when the result is greater than n.
 // The method is slightly modified to shift B unconditionally upto just under
 // the leading bit of n. This saves alot of multiple precision shifting.
-template<class A, class T>
-void montgomery_normalize(mp_int<A,T>& x, const mp_int<A,T>& n)
+template<class ApInt>
+void modular_reducer<ApInt>::montgomery_normalize(ApInt& x, const ApInt& n)
 {
   // how many bits of last digit does n use
-  typename mp_int<A,T>::size_type bits = n.precision() % mp_int<A,T>::valid_bits;
+  size_type bits = n.precision() % traits_type::radix_bits;
 
   if (n.size() > 1)
-    x.pow2((n.size() - 1) * mp_int<A,T>::valid_bits + bits - 1);
+    power<ApInt>::pow2(x, (n.size() - 1) * traits_type::radix_bits + bits - 1);
   else
   {
-    x = typename mp_int<A,T>::digit_type(1);
+    x = digit_type(1);
     bits = 1;
   }
 
   // now compute C = A * B mod n
-  for (int i = bits - 1; i < mp_int<A,T>::valid_bits; ++i)
+  for (size_type i = bits; i <= traits_type::radix_bits; ++i)
   {
-    x.multiply_by_2();
-    if (x.compare_magnitude(n) != -1)
-      x.sub_smaller_magnitude(n);
+    multiplier<ApInt>::multiply_by_2(x);
+    if (compare_magnitude(x, n) != -1)
+      base::adder<ApInt>::subtract_smaller_magnitude(x, n);
   }
 }
 
@@ -151,36 +180,23 @@
 // Has been modified to use algorithm 7.10 from the LTM book instead
 //
 // Input x must be in the range 0 <= x <= (n-1)**2
-template<class A, class T>
-void restricted_dr_reduce(mp_int<A,T>& x,
-                          const mp_int<A,T>& n,
-                          typename mp_int<A,T>::digit_type k)
+template<class ApInt>
+void modular_reducer<ApInt>::
+restricted_dr_reduce(ApInt& x, const ApInt& n, digit_type k)
 {
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  typedef typename mp_int<A,T>::word_type  word_type;
-  typedef typename mp_int<A,T>::size_type  size_type;
-  typedef typename mp_int<A,T>::iterator   iterator;
+  typedef typename ApInt::digit_type digit_type;
+  typedef typename ApInt::size_type  size_type;
+  typedef typename ApInt::iterator   iterator;
 
   const size_type m = n.size();
 
-  x.grow_capacity(m + m);
+  x.reserve(m + m);
   std::memset(x.digits() + x.size(), 0, (m + m - x.size()) * sizeof(digit_type));
 
 top:
-  // set carry to zero
-  digit_type mu = 0;
-
-  // compute (r mod B**m) + k * [r/B**m] inline and inplace
-  for (iterator d = x.begin(); d != x.begin() + m; ++d)
-  {
-    const word_type r = static_cast<word_type>(*(d + m))
-                      * static_cast<word_type>(k) + *d + mu;
-    *d = static_cast<digit_type>(r);
-    mu = static_cast<digit_type>(r >> static_cast<word_type>(mp_int<A,T>::digit_bits));
-  }
 
-  // set final carry
-  x[m] = mu;
+  // compute (r mod B**m) + k * [r/B**m]
+  x[m] = ops_type::multiply_add_digits(x.digits(), x.digits() + m, k, m);
 
   // zero words above m
   if (x.size() > m + 1) // guard against overflow
@@ -189,70 +205,69 @@
   x.clamp();
 
   if (!x)
-    x.set_sign(1);
+    x.set_sign_bit(0);
 
-  if (x.compare_magnitude(n) != -1)
+  if (compare_magnitude(x, n) != -1)
   {
-    x.sub_smaller_magnitude(n);
+    base::adder<ApInt>::subtract_smaller_magnitude(x, n);
     goto top;
   }
 }
 
-// reduces x modulo n where n is of the form 2**p - d
-template<class A, class T>
-void unrestricted_dr_reduce(mp_int<A,T>& x,
-                            const mp_int<A,T>& n,
-                            typename mp_int<A,T>::digit_type d)
+// reduces x modulo n where n is of the form 2^p - d
+template<class ApInt>
+void modular_reducer<ApInt>::
+unrestricted_dr_reduce(ApInt& x, const ApInt& n, digit_type d)
 {
-  const typename mp_int<A,T>::size_type p = n.precision();
+  const size_type p = n.precision();
 
 top:
 
-  mp_int<A,T> q(x);
-  
-  /* q = a/2**p, r = r mod 2**p */
-  q.shift_right(p, &x);
-
-  if (d != 1)
-    q.multiply_by_digit(d);
-  
-  x.add_magnitude(q);
+  ApInt q(x);
+
+  // q = x/2^p, x = x % 2^p
+  shifter<ApInt>::shift_bits_right(q, x, p);
+
+  q *= d;
 
-  if (x.compare_magnitude(n) != -1)
+  adder<ApInt>::add_magnitude(x, q);
+
+  if (compare_magnitude(x, n) != -1)
   {
-    x.sub_smaller_magnitude(n);
+    base::adder<ApInt>::subtract_smaller_magnitude(x, n);
     goto top;
   }
 }
 
-// reduces x modulo n where n is of the form 2**p - d. This differs from
+// reduces x modulo n where n is of the form 2^p - d. This differs from
 // unrestricted_dr_reduce since "d" can be larger than a single digit.
-template<class A, class T>
-void unrestricted_dr_slow_reduce(mp_int<A,T>& x,
-                                 const mp_int<A,T>& n,
-                                 const mp_int<A,T>& d)
+template<class ApInt>
+void modular_reducer<ApInt>::
+unrestricted_dr_slow_reduce(ApInt& x, const ApInt& n, const ApInt& d)
 {
-  const typename mp_int<A,T>::size_type p = n.precision();
+  const size_type p = n.precision();
 
 top:
 
-  mp_int<A,T> q(x);
+  ApInt q(x);
 
-  // q = x/2**p, r = r mod 2**p
-  q.shift_right(p, &x);
+  // q = x/2^p, x = x % 2^p
+  shifter<ApInt>::shift_bits_right(q, x, p);
 
   q *= d;
 
-  x.add_magnitude(q);
+  adder<ApInt>::add_magnitude(x, q);
 
-  if (x.compare_magnitude(n) != -1)
+  if (compare_magnitude(x, n) != -1)
   {
-    x.sub_smaller_magnitude(n);
+    base::adder<ApInt>::subtract_smaller_magnitude(x, n);
     goto top;
   }
 }
 
 
+
+
 } // namespace detail
 } // namespace mp_math
 } // namespace boost
Copied: sandbox/mp_math/boost/mp_math/integer/detail/multiplier.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/mul.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/mul.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/multiplier.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,135 +1,339 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
 
-// multiplies by a single digit
-template<class A, class T>
-void mp_int<A,T>::multiply_by_digit(digit_type x)
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_MULTIPLIER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_MULTIPLIER_HPP
+
+#include <boost/mp_math/integer/detail/shifter.hpp>
+#include <boost/mp_math/integer/detail/base/adder.hpp>
+#include <boost/mp_math/integer/detail/base/divider.hpp>
+#include <boost/mp_math/integer/detail/base/multiplier.hpp>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+template<
+  class ApInt,
+  bool IsSigned = ApInt::is_signed
+>
+struct multiplier;
+
+
+template<class ApInt>
+struct multiplier<ApInt, false>
 {
-  if (x == 0)
+  typedef ApInt                          int_type;
+  typedef typename int_type::traits_type traits_type;
+  typedef typename traits_type::ops_type ops_type;
+  typedef typename int_type::digit_type  digit_type;
+  typedef typename int_type::size_type   size_type;
+  typedef shifter<int_type>              shifter_type;
+  typedef base::adder<int_type>          base_adder_type;
+  typedef base::divider<int_type>        base_divider_type;
+  typedef base::multiplier<int_type>     base_multiplier_type;
+
+  static void multiply_or_square(ApInt& z, const ApInt& x);
+  static void multiply_or_square(ApInt& z, const ApInt& x, const ApInt& y);
+
+  static void mul          (ApInt& z, const ApInt& x, const ApInt& y);
+  static void long_mul     (ApInt& z, const ApInt& x, const ApInt& y);
+  static void comba_mul    (ApInt& z, const ApInt& x, const ApInt& y);
+  static void karatsuba_mul(ApInt& z, const ApInt& x, const ApInt& y);
+  static void toom3_mul    (ApInt& z, const ApInt& x, const ApInt& y);
+
+  static void multiply_by_2(ApInt& z);
+
+  static void sqr          (ApInt& z);
+  static void sqr          (ApInt& z, const ApInt& x);
+  static void comba_sqr    (ApInt& z, const ApInt& x);
+  static void karatsuba_sqr(ApInt& z, const ApInt& x);
+  static void toom3_sqr    (ApInt& z, const ApInt& x);
+
+private:
+
+/*  static void long_or_comba_mul(ApInt& z, const ApInt& x, const ApInt& y,
+                                bool_<false>)
   {
-    zero();
-    return;
+    long_mul(z, x, y);
   }
-  else if (x == 1)
-    return;
 
-  // make sure we can hold the result
-  grow_capacity(size_ + 1);
-  
-  const digit_type carry =
-    ops_type::multiply_by_digit(digits(), digits(), size(), x);
+  static void long_or_comba_mul(ApInt& z, const ApInt& x, const ApInt& y,
+                                bool_<true>)
+  {
+    comba_mul(z, x, y);
+  }*/
+};
 
-  if (carry)
-    push(carry);
+
+template<class ApInt>
+void multiplier<ApInt, false>::multiply_or_square(ApInt& z, const ApInt& x)
+{
+  if (&z == &x)
+    sqr(z);
+  else
+    mul(z, z, x);
 }
 
-/* *this *= 2 */
-template<class A, class T>
-void mp_int<A,T>::multiply_by_2()
+template<class ApInt>
+void
+multiplier<ApInt, false>::
+multiply_or_square(ApInt& z, const ApInt& x, const ApInt& y)
 {
-  grow_capacity(size_ + 1);
+  if (&x == &y)
+    sqr(z, x);
+  else
+    mul(z, x, y);
+}
 
-  const digit_type carry =
-    ops_type::multiply_by_two(digits(), digits(), size());
+template<class ApInt>
+void multiplier<ApInt, false>::mul(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  // always multiply larger by smaller number
+  const ApInt* a = &x;
+  const ApInt* b = &y;
+  if (a->size() < b->size())
+    std::swap(a, b);
 
-  if (carry)
-    push(carry);
+  if (b->size() == 1U)
+  {
+    if ((*b)[0] == 0U)
+    {
+      z.reserve(1);
+      z[0] = 0;
+      z.set_size(1);
+    }
+    else if ((*b)[0] == 1U)
+      z = *a;
+    else
+      ApInt::template integral_ops<digit_type>::multiply(z, *a, (*b)[0]);
+
+    return;
+  }
+
+  if (b->size() < traits_type::karatsuba_mul_threshold)
+    comba_mul(z, *a, *b);
+  else if (b->size() < traits_type::toom_mul_threshold)
+    karatsuba_mul(z, *a, *b);
+  else
+    toom3_mul(z, *a, *b);
 }
 
+template<class ApInt>
+inline
+void multiplier<ApInt, false>::
+long_mul(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  if ((&z != &x) && (&z != &y))
+  {
+    z.reserve(x.size() + y.size());
+    base_multiplier_type::long_mul(z, x, y);
+  }
+  else
+  {
+    ApInt tmp;
+    tmp.reserve(x.size() + y.size());
+    base_multiplier_type::long_mul(tmp, x, y);
+    swap(tmp, z);
+  }
+}
+
+template<class ApInt>
+inline
+void multiplier<ApInt, false>::
+comba_mul(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  if ((&z != &x) && (&z != &y))
+  {
+    z.reserve(x.size() + y.size());
+    base_multiplier_type::comba_mul(z, x, y);
+  }
+  else
+  {
+    ApInt tmp;
+    tmp.reserve(x.size() + y.size());
+    base_multiplier_type::comba_mul(tmp, x, y);
+    swap(tmp, z);
+  }
+}
+
+// Divide and conquer multiplication using the Karatsuba algorithm.
+//
+// Let B represent the radix [e.g. 2^radix_bits] and let n represent half of
+// the number of digits in min(a,b).
+//
+// a = x1 * B^n + x0
+// b = y1 * B^n + y0
+//
+// Then, a * b => x1y1 * B^2n + ((x1 + x0)(y1 + y0) - (x0y0 + x1y1)) * B + x0y0
+//
+// Note that x1y1 and x0y0 are used twice and only need to be computed once.  So
+// in total three half size (half # of digits) multiplications are performed,
+// x0y0, x1y1 and (x1+y1)(x0+y0).
+//
+// Note that a multiplication of half the digits requires 1/4th the number of
+// single precision multiplications so in total after one call 25% of the single
+// precision multiplications are saved. Note also that the call to operator *
+// can end up back in this function if x0, x1, y0, or y1 are above the
+// threshold. This leads to O(N^lg(3)) or O(N^1.584) complexity. Generally
+// though the overhead of this method doesn't pay off until a certain size
+// (N ~ 80) is reached.
+template<class ApInt>
+void multiplier<ApInt, false>::
+karatsuba_mul(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  assert(x.size() >= y.size());
+
+  ApInt x0, x1, y0, y1, x0y0, x1y1;
+
+  // B is the point at which we split both numbers
+  const size_type B = y.size() / 2;
+
+  // allocate memory
+  x0.reserve(B);
+  x1.reserve(x.size() + y.size());
+  y0.reserve(B);
+  y1.reserve(y.size() - B + 1);
+
+  x0.set_size(B);
+  y0.set_size(B);
+  x1.set_size(x.size() - B);
+  y1.set_size(y.size() - B);
+
+  // copy digits over
+  static const size_type s = sizeof(digit_type);
+  std::memcpy(x0.digits(), x.digits(), s * B);
+  std::memcpy(y0.digits(), y.digits(), s * B);
+  std::memcpy(x1.digits(), x.digits() + B, s * (x.size() - B));
+  std::memcpy(y1.digits(), y.digits() + B, s * (y.size() - B));
+
+  x0.clamp();
+  y0.clamp();
+
+  // now evaluate the term
+  // x1y1 * B**2n + ((x1 + x0)(y1 + y0) - (x0y0 + x1y1)) * B + x0y0
+
+  mul(x0y0, x0, y0);
+  mul(x1y1, x1, y1);
+
+  // tmp = (x1 + x0) * (y1 + y0)
+  x1 += x0;
+  y1 += y0;
+  // we don't need a tmp just reuse x1
+  mul(x1, x1, y1);
+
+  // tmp -= (x0y0 + x1y1);
+  base_adder_type::subtract_smaller_magnitude(x1, x0y0);
+  base_adder_type::subtract_smaller_magnitude(x1, x1y1);
+
+  // shift by B
+  if (x1 != digit_type(0))
+    shifter_type::shift_digits_left(x1, B);
+  if (x1 != digit_type(0))
+    shifter_type::shift_digits_left(x1y1, B * 2);
+
+  x1y1 += x1;
+  x1y1 += x0y0;
+  z.swap(x1y1);
+}
 
-// multiplication using the Toom-Cook 3-way algorithm 
+// multiplication using the Toom-Cook 3-way algorithm
 //
-// Much more complicated than Karatsuba but has a lower 
-// asymptotic running time of O(N**1.464). This algorithm is 
-// only particularly useful on VERY large inputs 
+// Much more complicated than Karatsuba but has a lower
+// asymptotic running time of O(N**1.464). This algorithm is
+// only particularly useful on VERY large inputs
 // (we're talking 1000s of digits here...).
-template<class A, class T>
-void mp_int<A,T>::toom_cook_mul(const mp_int& b)
+template<class ApInt>
+void multiplier<ApInt, false>::
+toom3_mul(ApInt& z, const ApInt& x, const ApInt& y)
 {
-  const size_type B = std::min(size_, b.size_) / 3;
-  
+  assert(x.size() >= y.size());
+
+  const size_type B = y.size() / 3;
+
   // a = a2 * B**2 + a1 * B + a0
-  mp_int a0(*this);
-  a0.modulo_2_to_the_power_of(valid_bits * B);
-  mp_int a1(*this);
-  a1.shift_digits_right(B);
-  a1.modulo_2_to_the_power_of(valid_bits * B);
-  mp_int a2(*this);
-  a2.shift_digits_right(B*2);
-  
+  ApInt a0(x);
+  base_divider_type::modulo_pow2(a0, traits_type::radix_bits * B);
+  ApInt a1(x);
+  shifter_type::shift_digits_right(a1, B);
+  base_divider_type::modulo_pow2(a1, traits_type::radix_bits * B);
+  ApInt a2(x);
+  shifter_type::shift_digits_right(a2, B*2);
+
   // b = b2 * B**2 + b1 * B + b0
-  mp_int b0(b);
-  b0.modulo_2_to_the_power_of(valid_bits * B);
-  mp_int b1(b);
-  b1.shift_digits_right(B);
-  b1.modulo_2_to_the_power_of(valid_bits * B);
-  mp_int b2(b);
-  b2.shift_digits_right(B*2);
+  ApInt b0(y);
+  base_divider_type::modulo_pow2(b0, traits_type::radix_bits * B);
+  ApInt b1(y);
+  shifter_type::shift_digits_right(b1, B);
+  base_divider_type::modulo_pow2(b1, traits_type::radix_bits * B);
+  ApInt b2(y);
+  shifter_type::shift_digits_right(b2, B*2);
 
   // w0 = a0*b0
-  const mp_int w0(a0 * b0);
-  
+  const ApInt w0(a0 * b0);
+
   // w4 = a2 * b2
-  mp_int w4 = a2 * b2;
-  
+  ApInt w4 = a2 * b2;
+
   // w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0))
-  mp_int tmp1 = a0;
-  tmp1.multiply_by_2();
+  ApInt tmp1 = a0;
+  multiply_by_2(tmp1);
   tmp1 += a1;
-  tmp1.multiply_by_2();
+  multiply_by_2(tmp1);
   tmp1 += a2;
-  
-  mp_int tmp2 = b0;
-  tmp2.multiply_by_2();
+
+  ApInt tmp2 = b0;
+  multiply_by_2(tmp2);
   tmp2 += b1;
-  tmp2.multiply_by_2();
+  multiply_by_2(tmp2);
   tmp2 += b2;
 
-  mp_int w1 = tmp1 * tmp2;
+  ApInt w1 = tmp1 * tmp2;
 
   // w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2))
   tmp1 = a2;
-  tmp1.multiply_by_2();
+  multiply_by_2(tmp1);
   tmp1 += a1;
-  tmp1.multiply_by_2();
+  multiply_by_2(tmp1);
   tmp1 += a0;
 
   tmp2 = b2;
-  tmp2.multiply_by_2();
+  multiply_by_2(tmp2);
   tmp2 += b1;
-  tmp2.multiply_by_2();
+  multiply_by_2(tmp2);
   tmp2 += b0;
 
-  mp_int w3 = tmp1 * tmp2;
+  ApInt w3 = tmp1 * tmp2;
 
   // w2 = (a2 + a1 + a0)(b2 + b1 + b0)
   tmp1 = a2 + a1;
   tmp1 += a0;
   tmp2 = b2 + b1;
   tmp2 += b0;
-  mp_int w2 = tmp1 * tmp2;
+  ApInt w2 = tmp1 * tmp2;
 
-  // now solve the matrix 
+  // now solve the matrix
   //
   // 0  0  0  0  1
   // 1  2  4  8  16
   // 1  1  1  1  1
   // 16 8  4  2  1
   // 1  0  0  0  0
-  //   
-  // using 12 subtractions, 4 shifts, 
-  // 2 small divisions and 1 small multiplication 
-   
+  //
+  // using 12 subtractions, 4 shifts,
+  // 2 small divisions and 1 small multiplication
+
   // r1 - r4
   w1 -= w4;
   // r3 - r0
   w3 -= w0;
   // r1/2
-  w1.divide_by_2();
+  base_divider_type::divide_by_2(w1);
   // r3/2
-  w3.divide_by_2();
+  base_divider_type::divide_by_2(w3);
   // r2 - r0 - r4
   w2 -= w0;
   w2 -= w4;
@@ -144,7 +348,7 @@
   tmp1 = w4 << 3;
   w3 -= tmp1;
   // 3r2 - r1 - r3
-  w2.multiply_by_digit(3);
+  w2 *= digit_type(3);
   w2 -= w1;
   w2 -= w3;
   // r1 - r2
@@ -152,210 +356,403 @@
   // r3 - r2
   w3 -= w2;
   // r1/3
-  w1.divide_by_3();
+  base_divider_type::divide_by_3(w1);
   // r3/3
-  w3.divide_by_3();
+  base_divider_type::divide_by_3(w3);
 
   // at this point shift W[n] by B*n
-  w1.shift_digits_left(1*B);
-  w2.shift_digits_left(2*B);
-  w3.shift_digits_left(3*B);
-  w4.shift_digits_left(4*B);
+  if (w1 != digit_type(0))
+    shifter_type::shift_digits_left(w1, 1 * B);
+  if (w2 != digit_type(0))
+    shifter_type::shift_digits_left(w2, 2 * B);
+  if (w3 != digit_type(0))
+    shifter_type::shift_digits_left(w3, 3 * B);
+  if (w4 != digit_type(0))
+    shifter_type::shift_digits_left(w4, 4 * B);
 
-  *this = w0 + w1;
+  z = w0 + w1;
   tmp1 = w2 + w3;
   tmp1 += w4;
-  *this += tmp1;
+  z += tmp1;
 }
 
-// c = |a| * |b| using Karatsuba Multiplication using 
-// three half size multiplications
-//
-// Let B represent the radix [e.g. 2**valid_bits] and 
-// let n represent half of the number of digits in 
-// the min(a,b)
-//
-// a = x1 * B**n + x0
-// b = y1 * B**n + y0
-//
-// Then, a * b => 
-// x1y1 * B**2n + ((x1 + x0)(y1 + y0) - (x0y0 + x1y1)) * B + x0y0
+template<class ApInt>
+void multiplier<ApInt, false>::multiply_by_2(ApInt& z)
+{
+  z.reserve(z.size() + 1);
+
+  const digit_type carry =
+    ops_type::multiply_by_two(z.digits(), z.digits(), z.size());
+
+  if (carry)
+    z.push(carry);
+}
+
+
+template<class ApInt>
+void multiplier<ApInt, false>::sqr(ApInt& z, const ApInt& x)
+{
+  if (x.size() < ApInt::traits_type::karatsuba_sqr_threshold)
+    comba_sqr(z, x);
+  else if (x.size() < ApInt::traits_type::toom_sqr_threshold)
+    karatsuba_sqr(z, x);
+  else
+    toom3_sqr(z, x);
+}
+
+template<class ApInt>
+void multiplier<ApInt, false>::sqr(ApInt& z)
+{
+  //TODO resurrect optimization here from mp_math_v04
+  // if (z.size() < 16)
+  //   comba_sqr to digit array on stack then memcpy over to z;
+  // else
+  //   ApInt tmp;
+  //   sqr(tmp, z);
+  ApInt tmp;
+  sqr(tmp, z);
+  z.swap(tmp);
+}
+
+template<class ApInt>
+inline
+void multiplier<ApInt, false>::comba_sqr(ApInt& z, const ApInt& x)
+{
+  z.reserve(x.size() + x.size());
+  base_multiplier_type::comba_sqr(z, x);
+}
+
+// Karatsuba squaring, computes b = a*a using three half size squarings
 //
-// Note that x1y1 and x0y0 are used twice and only need to be 
-// computed once.  So in total three half size (half # of 
-// digit) multiplications are performed, x0y0, x1y1 and 
-// (x1+y1)(x0+y0)
+// See comments of karatsuba_mul for details. It is essentially the same
+// algorithm but merely tuned to perform recursive squarings.
 //
-// Note that a multiplication of half the digits requires
-// 1/4th the number of single precision multiplications so in 
-// total after one call 25% of the single precision multiplications 
-// are saved.  Note also that the call to mp_mul can end up back 
-// in this function if the x0, x1, y0, or y1 are above the threshold.  
-// This is known as divide-and-conquer and leads to the famous 
-// O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than 
-// the standard O(N**2) that the baseline/comba methods use.  
-// Generally though the overhead of this method doesn't pay off 
-// until a certain size (N ~ 80) is reached.
-template<class A, class T>
-void mp_int<A,T>::karatsuba_mul(const mp_int& b)
+// a    = x1 * B**n + x0
+// a**2 = x1x1 * B**2n + 2*x0x1 * B**n + x0x0
+// where
+// 2*x0x1 = 1) x1x1 + x0x0 - (x1 - x0)**2   or
+//          2) (x0 + x1)**2 - (x0x0 + x1x1)
+// we use version 1)
+// version 2) may use one less temporary?
+// a**2 = x1x1 * B**2n + (x1x1 + x0x0 - (x1 - x0)**2) * B**n + x0x0
+// TODO revert!
+template<class ApInt>
+void multiplier<ApInt, false>::karatsuba_sqr(ApInt& z, const ApInt& x)
 {
-  mp_int x0, x1, y0, y1, /*tmp,*/ x0y0, x1y1;
+  typedef typename ApInt::digit_type digit_type;
 
-  // min # of digits
-  const size_type B = std::min(size_, b.size_) / 2;
+  ApInt x0, x1, tmp, tmp2, x0x0, x1x1;
 
-  // allocate memory
-  x0.grow_capacity(B);
-  x1.grow_capacity(size_ + b.size_);
-  y0.grow_capacity(B);
-  y1.grow_capacity(b.size_ - B + 1);
-
-  // set size_ count
-  x0.size_ = y0.size_ = B;
-  x1.size_ = size_ - B;
-  y1.size_ = b.size_ - B;
+  const typename ApInt::size_type B = x.size() / 2;
 
-  // copy digits over
-  static const size_type s = sizeof(digit_type);
-  std::memcpy(x0.digits_, digits_,   s * B);
-  std::memcpy(y0.digits_, b.digits_, s * B);
-  std::memcpy(x1.digits_, digits_ + B,   s * (  size_ - B));
-  std::memcpy(y1.digits_, b.digits_ + B, s * (b.size_ - B));
+  x0.reserve(B);
+  x1.reserve(x.size() - B);
+
+  x0x0.reserve(B * 2);
+  x1x1.reserve((x.size() - B) * 2);
+
+  // now shift the digits
+  std::memcpy(x0.digits(), x.digits(), B * sizeof(digit_type));
+  std::memcpy(x1.digits(), x.digits() + B, (x.size() - B) * sizeof(digit_type));
+
+  x0.set_size(B);
+  x1.set_size(x.size() - B);
+
+  x0.clamp();
+
+  sqr(x0x0, x0);
+  sqr(x1x1, x1);
+
+  tmp = x1x1;
+  tmp += x0x0;
+
+  tmp2 = x1;
+  tmp2 -= x0;
+  sqr(tmp2);
+
+  base_adder_type::subtract_smaller_magnitude(tmp, tmp2);
+
+  if (x1x1 != digit_type(0))
+    shifter_type::shift_digits_left(x1x1, B * 2);
+  if (tmp != digit_type(0))
+    shifter_type::shift_digits_left(tmp, B);
+
+  x1x1 += tmp;
+  x1x1 += x0x0;
+
+  z.swap(x1x1);
+}
+
+// squaring using Toom-Cook 3-way algorithm
+template<class ApInt>
+void multiplier<ApInt, false>::toom3_sqr(ApInt& z, const ApInt& x)
+{
+  ApInt w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
+
+  const typename ApInt::size_type B = x.size() / 3;
+
+  /* a = a2 * B**2 + a1 * B + a0 */
+  a0 = x;
+  base_divider_type::modulo_pow2(a0, traits_type::radix_bits * B);
+
+  a1 = x;
+  shifter_type::shift_digits_right(a1, B);
+  base_divider_type::modulo_pow2(a1, traits_type::radix_bits * B);
+
+  a2 = x;
+  shifter_type::shift_digits_right(a2, B * 2);
+
+  /* w0 = a0*a0 */
+  w0 = a0;
+  sqr(w0);
+
+  /* w4 = a2 * a2 */
+  w4 = a2;
+  sqr(w4);
+
+  /* w1 = (a2 + 2(a1 + 2a0))**2 */
+  w1 = a0;
+  multiply_by_2(w1);
+  w1 += a1;
+  multiply_by_2(w1);
+  w1 += a2;
+  sqr(w1);
+
+  /* w3 = (a0 + 2(a1 + 2a2))**2 */
+  w3 = a2;
+  multiply_by_2(w3);
+  w3 += a1;
+  multiply_by_2(w3);
+  w3 += a0;
+  sqr(w3);
+
+  /* w2 = (a2 + a1 + a0)**2 */
+  w2 = a1 + a2;
+  w2 += a0;
+  sqr(w2);
+
+  /* now solve the matrix
+
+     0  0  0  0  1
+     1  2  4  8  16
+     1  1  1  1  1
+     16 8  4  2  1
+     1  0  0  0  0
+
+     using 12 subtractions, 4 shifts, 2 small divisions and 1 small
+     multiplication.
+   */
+
+  /* r1 - r4 */
+  w1 -= w4;
+  /* r3 - r0 */
+  w3 -= w0;
+  /* r1/2 */
+  base_divider_type::divide_by_2(w1);
+  /* r3/2 */
+  base_divider_type::divide_by_2(w3);
+  /* r2 - r0 - r4 */
+  w2 -= w0;
+  w2 -= w4;
+  /* r1 - r2 */
+  w1 -= w2;
+  /* r3 - r2 */
+  w3 -= w2;
+  /* r1 - 8r0 */
+  tmp1 = w0;
+  tmp1 <<= 3;
+  w1 -= tmp1;
+  /* r3 - 8r4 */
+  tmp1 = w4;
+  tmp1 <<= 3;
+  w3 -= tmp1;
+  /* 3r2 - r1 - r3 */
+  w2 *= digit_type(3);
+  w2 -= w1;
+  w2 -= w3;
+  /* r1 - r2 */
+  w1 -= w2;
+  /* r3 - r2 */
+  w3 -= w2;
+  /* r1/3 */
+  base_divider_type::divide_by_3(w1);
+  /* r3/3 */
+  base_divider_type::divide_by_3(w3);
+  /* at this point shift W[n] by B*n */
+  if (w1 != digit_type(0))
+    shifter_type::shift_digits_left(w1, 1 * B);
+  if (w2 != digit_type(0))
+    shifter_type::shift_digits_left(w2, 2 * B);
+  if (w3 != digit_type(0))
+    shifter_type::shift_digits_left(w3, 3 * B);
+  if (w4 != digit_type(0))
+    shifter_type::shift_digits_left(w4, 4 * B);
+
+  z = w0 + w1;
+  tmp1 = w2 + w3;
+  tmp1 += w4;
+  z += tmp1;
+}
+
+/*template<typename D, typename W, typename S>
+void karatsuba_mul(mp_int_base<D,W,S>& z,
+                   const mp_int_base<D,W,S>& x,
+                   const mp_int_base<D,W,S>& y)
+{
+  typedef D digit_type;
+  typedef S size_type;
+
+  // B is the point at which we split both numbers
+  const size_type B = std::min(x.size(), y.size()) / 2;
+
+  mp_int_base_type x0(x.digits(), B, B);
+  mp_int_base_type y0(y.digits(), B, B);
+  mp_int_base_type x1(x.digits() + B, x.size() - B, x.size() - B);
+  mp_int_base_type y1(y.digits() + B, y.size() - B, y.size() - B);
 
-  // only need to clamp the lower words since by definition the 
-  // upper words x1/y1 must have a known number of digits
   x0.clamp();
   y0.clamp();
 
   // now evaluate the term
   // x1y1 * B**2n + ((x1 + x0)(y1 + y0) - (x0y0 + x1y1)) * B + x0y0
-  
-  // first calc the products x0y0 and x1y1
-  x0y0 = x0 * y0;
-  x1y1 = x1 * y1;
 
-  // tmp = (x1 + x0) * (y1 + y0)
-  x1.add_magnitude(x0);
-  y1.add_magnitude(y0);
-  // we don't need a tmp just reuse x1
-  x1 *= y1;
+  mp_int_base x0y0(memory, B + 1);
+  multiply(x0y0, x0, y0);
 
-  // tmp -= (x0y0 + x1y1);
-  x1.sub_smaller_magnitude(x0y0);
-  x1.sub_smaller_magnitude(x1y1);
+  mp_int_base x1y1(memory, B*2 + B + 1);
+  multiply(x1y1, x1, y1);
+
+  // c = (x1 + x0) * (y1 + y0)
+  add_magnitude(a, x1, x0);
+  add_magnitude(b, y1, y0);
+  multiply(c, a, b);
+
+  // c -= (x0y0 + x1y1);
+  sub_smaller_magnitude(c, x0y0);
+  sub_smaller_magnitude(c, x1y1);
 
   // shift by B
-  x1.shift_digits_left(B);
-  x1y1.shift_digits_left(B * 2);
+  shift_digits_left(x1, B);
+  shift_digits_left(x1y1, B * 2);
 
-  x1.add_magnitude(x0y0);
-  x1.add_magnitude(x1y1);
-  swap(x1);
-}
+  x1y1.add_magnitude(x1y1, x1);
+  x1y1.add_magnitude(x1y1, x0y0);
+  z.swap(x1y1);
 
+  //////////////////////////////////////////////////////////
 
-// multiplies |a| * |b| and only computes up to digs digits of result
-// HAC pp. 595, Algorithm 14.12  Modified so you can control how 
-// many digits of output are created.
-template<class A, class T>
-void mp_int<A,T>::mul_digits(const mp_int& b, size_type digs)
-{
-  mp_int tmp;
-  tmp.grow_capacity(digs);
-  // zero allocated digits
-  std::memset(tmp.digits_, 0, sizeof(digit_type) * digs);
-  tmp.size_ = digs;
+  size_type smallest_B = B;
+  while (smallest_B > karatsuba_mul_cutoff)
+    smallest_B /= 2;
 
-  // compute the digits of the product directly
-  for (size_type i = 0; i < size_; ++i)
+  for (size_type i = 0; i < std::min(x.size(), y.size()); i += smallest_B)
   {
-    digit_type carry = 0;
+    mp_int_base_type x0(x.digits() + B*i, B, B);
+    mp_int_base_type y0(y.digits() + B*i, B, B);
+    mp_int_base_type x1(x.digits() + B, x.size() - B, x.size() - B);
+    mp_int_base_type y1(y.digits() + B, y.size() - B, y.size() - B);
 
-    // limit ourselves to making digs digits of output
-    const size_type pb = std::min(b.size_, digs - i);
+  }
+}*/
 
-    // compute the columns of the output and propagate the carry
-    for (size_type j = 0; j < pb; ++j)
-    {
-      // compute the column as a word_type
-      const word_type r = static_cast<word_type>(tmp[i+j])
-                        + static_cast<word_type>(digits_[i])
-                        * static_cast<word_type>(b[j])
-                        + static_cast<word_type>(carry);
 
-      // the new column is the lower part of the result
-      tmp[i+j] = static_cast<digit_type>(r);
 
-      // get the carry word from the result
-      carry = static_cast<digit_type>(r >> static_cast<word_type>(valid_bits));
-    }
-    // set carry if it is placed below digs
-    if (i + pb < digs)
-      tmp[i+pb] = carry;
+template<class ApInt>
+struct multiplier<ApInt, true>
+{
+  typedef ApInt                          int_type;
+  typedef typename int_type::traits_type traits_type;
+  typedef typename traits_type::ops_type ops_type;
+  typedef typename int_type::digit_type  digit_type;
+  typedef typename int_type::size_type   size_type;
+
+  static void multiply_or_square(ApInt& z, const ApInt& x);
+  static void multiply_or_square(ApInt& z, const ApInt& x, const ApInt& y);
+
+  static void mul(ApInt& z, const ApInt& x, const ApInt& y);
+
+  static void multiply_by_2(ApInt& z)
+  {
+    multiplier<ApInt, false>::multiply_by_2(z);
+  }
+
+  static void sqr(ApInt& z)
+  {
+    multiplier<ApInt, false>::sqr(z);
+    z.set_sign_bit(0);
   }
 
-  tmp.clamp();
+  static void sqr(ApInt& z, const ApInt& x)
+  {
+    multiplier<ApInt, false>::sqr(z, x);
+    z.set_sign_bit(0);
+  }
+};
 
-  if (!tmp)
-    tmp.set_sign(1);
 
-  swap(tmp);
+template<class ApInt>
+void multiplier<ApInt, true>::multiply_or_square(ApInt& z, const ApInt& x)
+{
+  if (&z == &x)
+    sqr(z);
+  else
+    mul(z, z, x);
 }
 
-// FIXME no routine seems to use this
-//
-// multiplies |a| * |b| and does not compute the lower num digits
-// [meant to get the higher part of the product]
-template<class A, class T>
-void mp_int<A,T>::mul_high_digits(const mp_int& b, size_type num)
-{
-  mp_int tmp;
-  tmp.grow_capacity(size_ + b.size_ + 1);
-  tmp.size_ = size_ + b.size_ + 1;
-  std::memset(tmp.digits_, 0, sizeof(digit_type) * tmp.size_);
-
-  for (size_type i = 0; i < size_; ++i)
-  {
-    iterator dst     = tmp.begin() + num;
-    const_iterator z = b.begin() + (num - i);
-    digit_type carry = 0;
-
-    for (size_type j = num - i; j < b.size_; ++j)
-    {
-      const word_type r = static_cast<word_type>(*dst)
-                        + static_cast<word_type>(digits_[i])
-                        * static_cast<word_type>(*z++)
-                        + static_cast<word_type>(carry);
+template<class ApInt>
+void
+multiplier<ApInt, true>::
+multiply_or_square(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  if (&x == &y)
+    sqr(z, x);
+  else
+    mul(z, x, y);
+}
 
-      // get the lower part
-      *dst++ = static_cast<digit_type>(r);
+template<class ApInt>
+void multiplier<ApInt, true>::mul(ApInt& z, const ApInt& x, const ApInt& y)
+{
+  // always multiply larger by smaller number
+  const ApInt* a = &x;
+  const ApInt* b = &y;
+  if (a->size() < b->size())
+    std::swap(a, b);
 
-      // update carry
-      carry = static_cast<digit_type>(r >> valid_bits);
+  if (b->size() == 1U)
+  {
+    if ((*b)[0] == 0U)
+    {
+      z.reserve(1);
+      z[0] = 0;
+      z.set_size(1);
+      z.set_sign_bit(0);
     }
-    *dst = carry;
+    else if ((*b)[0] == 1U)
+      z = *a;
+    else
+      ApInt::template integral_ops<digit_type>::multiply(z, *a, (*b)[0]);
   }
+  else
+  {
+    const bool s = x.sign_bit() ^ y.sign_bit();
 
-  tmp.clamp();
-
-  if (!tmp)
-    tmp.set_sign(1);
+    if (b->size() < traits_type::karatsuba_mul_threshold)
+      multiplier<ApInt, false>::comba_mul(z, *a, *b);
+    else if (b->size() < traits_type::toom_mul_threshold)
+      multiplier<ApInt, false>::karatsuba_mul(z, *a, *b);
+    else
+      multiplier<ApInt, false>::toom3_mul(z, *a, *b);
 
-  swap(tmp);
+    z.set_sign_bit(s);
+  }
 }
 
 
-// this is a modified version of fast_s_mul_digs that only produces
-// output digits *above* num.  See the comments for fast_s_mul_digs
-// to see how it works.
-//
-// This is used in the Barrett reduction since for one of the multiplications
-// only the higher digits were needed. This essentially halves the work.
-//
-// Based on Algorithm 14.12 on pp.595 of HAC.
-template<class A, class T>
-void mp_int<A,T>::fast_mul_high_digits(const mp_int& b, size_type num)
-{
-  mul_high_digits(b, num);
-}
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
 
Copied: sandbox/mp_math/boost/mp_math/integer/detail/power.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/pow.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/pow.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/power.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,66 +1,144 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Tom St Denis 2002 - 2007.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
 
-// computes a = 2**b 
-// Simple algorithm which zeroes the int, grows it then just sets one bit
-// as required.
-template<class A, class T>
-void mp_int<A,T>::pow2(typename mp_int<A,T>::size_type b)
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_POWER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_POWER_HPP
+
+#include <boost/mp_math/integer/detail/multiplier.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+template<
+  class ApInt,
+  bool IsSigned = ApInt::is_signed
+>
+struct power;
+
+
+template<class ApInt>
+struct power<ApInt, false>
 {
-  grow_capacity(b / digit_bits + 1);
+  typedef typename ApInt::digit_type digit_type;
+  typedef typename ApInt::size_type  size_type;
 
-  // set size_ to where the bit will go
-  size_ = b / digit_bits + 1;
+  static void pow(ApInt& z, const ApInt& x, size_type y);
+  static void pow(ApInt& z, const ApInt& x, const ApInt& y);
+  static void pow2(ApInt& z, size_type n);
+};
 
-  // set all bits to zero
-  std::memset(digits_, 0, size_ * sizeof(digit_type));
-  
-  // put the single bit in its place
-  digits_[b / digit_bits] = digit_type(1) << (b % digit_bits);
-}
 
-// calculate c = x**y  using a square-multiply algorithm
-template<class A, class T>
-mp_int<A,T> pow(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type y)
+template<class ApInt>
+void power<ApInt, false>::pow(ApInt& z, const ApInt& x, size_type y)
 {
-  mp_int<A,T> result;  
+  z = digit_type(1);
 
-  result = typename mp_int<A,T>::digit_type(1);
+  if (y == 0U)
+    return;
 
-  const typename mp_int<A,T>::digit_type mask = 1 << (mp_int<A,T>::digit_bits - 1);
-  
-  for (int i = 0; i < mp_int<A,T>::digit_bits; ++i)
+  size_type mask = size_type(1) << (std::numeric_limits<size_type>::digits - 1);
+
+  int i = 0;
+  while (!(y & mask)) // skip leading zero bits
   {
-    result.sqr();
+    ++i;
+    mask >>= 1;
+  }
+
+  for (; i < std::numeric_limits<size_type>::digits; ++i)
+  {
+    multiplier<ApInt>::sqr(z);
 
     // if the bit is set multiply
     if (y & mask)
-      result *= x;
+      multiplier<ApInt>::mul(z, z, x);
 
     // shift to next bit
-    y <<= 1;
+    mask >>= 1;
   }
-
-  return result;
 }
 
-template<class A, class T>
-mp_int<A,T> pow(const mp_int<A,T>& x, const mp_int<A,T>& y)
+// calculate z = x^y using a square-multiply algorithm
+template<class ApInt>
+void power<ApInt, false>::pow(ApInt& z, const ApInt& x, const ApInt& y)
 {
   if (y.size() == 1)
-    return pow(x, y[0]);
+  {
+    pow(z, x, y[0]);
+    return;
+  }
+
+  z = digit_type(1);
 
-  mp_int<A,T> y0(y);
-  
-  y0.divide_by_2();
-  
-  mp_int<A,T> y1(y0);
+  ApInt mask(digit_type(1));
+  mask <<= y.precision() - 1; // TODO use pow2
 
-  if (y.is_odd())
-    ++y1;
+  for (size_type i = 0; i < y.precision(); ++i)
+  {
+    multiplier<ApInt>::sqr(z);
 
-  return pow(x, y0) * pow(x, y1);
+    // if the bit is set multiply
+    if (y & mask)
+      multiplier<ApInt>::mul(z, z, x);
+
+    // shift to next bit
+    mask >>= 1;
+  }
 }
 
+// computes z = 2^n
+template<class ApInt>
+void power<ApInt, false>::pow2(ApInt& z, size_type n)
+{
+  static const size_type db = ApInt::traits_type::digit_bits;
+  const size_type q = n / db + 1;
+  const size_type r = n % db;
+
+  z.reserve(q);
+
+  std::memset(z.digits(), 0, q * sizeof(digit_type));
+
+  z[q-1] = digit_type(1) << r;
+
+  z.set_size(q);
+}
+
+
+
+template<class ApInt>
+struct power<ApInt, true>
+{
+  typedef typename ApInt::size_type size_type;
+
+  static void pow(ApInt& z, const ApInt& x, size_type y)
+  {
+    power<ApInt, false>::pow(z, x, y);
+    z.set_sign_bit(y & 1 ? x.sign_bit() : 0);
+  }
+
+  static void pow(ApInt& z, const ApInt& x, const ApInt& y)
+  {
+    if (y.is_negative())
+      throw std::domain_error("pow: negative exponent");
+    power<ApInt, false>::pow(z, x, y);
+    z.set_sign_bit(y.is_odd() ? x.sign_bit() : 0);
+  }
+
+  static void pow2(ApInt& z, size_type n)
+  {
+    power<ApInt, false>::pow2(z, n);
+  }
+};
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Modified: sandbox/mp_math/boost/mp_math/integer/detail/prime_tab.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/prime_tab.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/prime_tab.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,10 +1,10 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_DETAIL_PRIME_TAB_HPP
-#define BOOST_MP_MATH_DETAIL_PRIME_TAB_HPP
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_PRIME_TAB_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_PRIME_TAB_HPP
 
 
 namespace boost {
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/detail/primitive_ops.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/primitive_ops.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,707 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_DETAIL_PRIMITIVE_OPS
-#define BOOST_MP_MATH_MP_INT_DETAIL_PRIMITIVE_OPS
-
-namespace boost {
-namespace mp_math {
-namespace detail {
-
-
-// this struct contains some basic arithmetic algorithms
-// which can be implemented via assembly rather easily
-
-template<typename DigitT, typename WordT, typename SizeT>
-struct basic_primitive_ops
-{
-  typedef DigitT digit_type;
-  typedef WordT  word_type;
-  typedef SizeT  size_type;
-
-  static const word_type digit_bits = std::numeric_limits<digit_type>::digits;
-
-  // ADD ------------------------------------
-
-  // add y to the digits in x and store result in z
-  // xlen must be > 0
-  // returns: the last carry (it will not get stored in z)
-  static digit_type add_single_digit(digit_type* z,
-                                     const digit_type* x, size_type xlen,
-                                     digit_type y);
-
-  // z = x + y, returns last carry
-  static digit_type add_digits(digit_type* z,
-                               const digit_type* x,
-                               const digit_type* y,
-                               size_type num);
-
-  // ripples the carry c up through n digits of x and stores results in z
-  // returns the number of digits the carry rippled through and stores the last
-  // carry in c. If there isn't a last carry then c will be 0.
-  static size_type ripple_carry(digit_type* z,
-                                const digit_type* x,
-                                size_type n,
-                                digit_type& c);
-
-  // z = x + y, where xlen >= ylen
-  // returns last carry
-  static digit_type add_smaller_magnitude(digit_type* z,
-                                          const digit_type* x, size_type xlen,
-                                          const digit_type* y, size_type ylen);
-
-  // SUB ------------------------------------
-
-  // subtracts x from the digits in y and store result in z
-  static void subtract_single_digit(digit_type* z,
-                                    const digit_type* x, size_type xlen,
-                                    digit_type y);
-
-  // z = x - y, returns last borrow
-  static digit_type subtract_digits(digit_type* z,
-                                    const digit_type* x,
-                                    const digit_type* y,
-                                    size_type num);
-
-  // ripples the borrow up through n digits of x and stores results in z
-  // returns the number of digits the borrow rippled through
-  static size_type ripple_borrow(digit_type* z,
-                                 const digit_type* x,
-                                 size_type n,
-                                 digit_type borrow);
-
-  // z = x - y, where x >= y
-  static void sub_smaller_magnitude(digit_type* z,
-                                    const digit_type* x, size_type xlen,
-                                    const digit_type* y, size_type ylen);
-
-  // MUL ------------------------------------
-
-  // multiply y of length ylen with x and store result in z
-  // returns: the last carry (it will not get stored in z)
-  static digit_type multiply_by_digit(digit_type* z,
-                                      const digit_type* x, size_type xlen,
-                                      digit_type y);
-
-  // z = x * 2
-  static digit_type multiply_by_two(digit_type* z,
-                                    const digit_type* x, size_type len);
-
-  // z = x * y
-  static void classic_mul(digit_type* z, const digit_type* x, size_type xlen,
-                                         const digit_type* y, size_type ylen);
-
-  // z = x * y; precondition: xlen >= ylen
-  static void comba_mul(digit_type* z, const digit_type* x, size_type xlen,
-                                       const digit_type* y, size_type ylen);
-
-  // z = x * y; for numbers of the same size
-  static void comba_mul(digit_type* z,
-                        const digit_type* x,
-                        const digit_type* y, size_type xylen);
-
-  // SQR ------------------------------------
-
-  // z = x * x;
-  static void comba_sqr(digit_type* z, const digit_type* x, size_type xlen);
-
-  // MADD ------------------------------------
-
-  // z = w * x + y
-  static digit_type multiply_add_digits(digit_type* z,
-                                        const digit_type* w,
-                                        digit_type x,
-                                        const digit_type* y,
-                                        size_type n);
-
-  // DIV -------------------------------------
-
-  // z = x / 2
-  static void divide_by_two(digit_type* z, const digit_type* x, size_type len);
-
-  // z = x / y
-  // returns remainder
-  static digit_type divide_by_digit(digit_type* z,
-                                    const digit_type* x, size_type xlen,
-                                    digit_type y);
-};
-
-
-
-template<typename D, typename W, typename S>
-inline
-D basic_primitive_ops<D,W,S>::add_single_digit(digit_type* z,
-                                               const digit_type* x,
-                                               size_type xlen,
-                                               digit_type y)
-{
-  word_type carry = static_cast<word_type>(*x++) + y;
-  *z++ = static_cast<digit_type>(carry);
-  carry >>= digit_bits;
-
-  while (carry && --xlen)
-  {
-    carry += static_cast<word_type>(*x++);
-    *z++ = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  return static_cast<digit_type>(carry);
-}
-
-
-template<typename D, typename W, typename S>
-inline
-D basic_primitive_ops<D,W,S>::add_digits(digit_type* z,
-                                         const digit_type* x,
-                                         const digit_type* y, size_type n)
-{
-  word_type carry = 0;
-
-  while (n--)
-  {
-    carry += static_cast<word_type>(*x++) + static_cast<word_type>(*y++);
-    *z++ = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  return static_cast<digit_type>(carry);
-}
-
-template<typename D, typename W, typename S>
-inline
-S basic_primitive_ops<D,W,S>::ripple_carry(digit_type* z,
-                                           const digit_type* x,
-                                           size_type n,
-                                           digit_type& carry)
-{
-  word_type c = carry;
-  size_type i = 0;
-
-  for (; c && (i < n); ++i)
-  {
-    c += static_cast<word_type>(*x++);
-    *z++ = static_cast<digit_type>(c);
-    c >>= digit_bits;
-  }
-
-  carry = static_cast<digit_type>(c);
-
-  return i;
-}
-
-template<typename D, typename W, typename S>
-inline
-D basic_primitive_ops<D,W,S>::add_smaller_magnitude(digit_type* z,
-                                                    const digit_type* x,
-                                                    size_type xlen,
-                                                    const digit_type* y,
-                                                    size_type ylen)
-{
-  digit_type carry = add_digits(z, x, y, ylen);
-
-  size_type n = ripple_carry(z + ylen, x + ylen, xlen - ylen, carry);
-
-  n += ylen;
-
-  if (n < xlen && z != x)
-    std::memcpy(z + n, x + n, sizeof(digit_type) * (xlen - n));
-
-  return carry;
-}
-
-template<typename D, typename W, typename S>
-inline
-void
-basic_primitive_ops<D,W,S>::subtract_single_digit(digit_type* z,
-                                                  const digit_type* y,
-                                                  size_type ylen,
-                                                  digit_type x)
-{
-  word_type borrow = static_cast<word_type>(*y++) - x;
-  *z++ = static_cast<digit_type>(borrow);
-  borrow >>= static_cast<word_type>(std::numeric_limits<word_type>::digits - 1);
-
-  while (borrow && --ylen)
-  {
-    borrow = static_cast<word_type>(*y++) - borrow;
-    *z++   = static_cast<digit_type>(borrow);
-    borrow >>= static_cast<word_type>(std::numeric_limits<word_type>::digits - 1);
-  }
-}
-
-template<typename D, typename W, typename S>
-inline
-D basic_primitive_ops<D,W,S>::subtract_digits(digit_type* z,
-                                              const digit_type* x,
-                                              const digit_type* y,
-                                              size_type n)
-{
-  word_type borrow = 0;
-
-  while (n--)
-  {
-    borrow = static_cast<word_type>(*x++) - static_cast<word_type>(*y++) - borrow;
-    *z++   = static_cast<digit_type>(borrow);
-    borrow >>= std::numeric_limits<word_type>::digits - 1;
-  }
-
-  return static_cast<digit_type>(borrow);
-}
-
-template<typename D, typename W, typename S>
-inline
-S basic_primitive_ops<D,W,S>::ripple_borrow(digit_type* z,
-                                            const digit_type* x,
-                                            size_type n,
-                                            digit_type borrow)
-{
-  word_type b = borrow;
-  size_type i = 0;
-  for (; b && (i < n); ++i)
-  {
-    b    = static_cast<word_type>(*x++) - b;
-    *z++ = static_cast<digit_type>(b);
-    b >>= std::numeric_limits<word_type>::digits - 1;
-  }
-
-  return i;
-}
-
-template<typename D, typename W, typename S>
-inline
-void basic_primitive_ops<D,W,S>::sub_smaller_magnitude(
-    digit_type* z,
-    const digit_type* x, size_type xlen,
-    const digit_type* y, size_type ylen)
-{
-  const digit_type borrow = subtract_digits(z, x, y, ylen);
-
-  size_type n = ripple_borrow(z + ylen, x + ylen, xlen - ylen, borrow);
-
-  if (z != x)
-  {
-    n += ylen;
-    std::memcpy(z + n, x + n, (xlen - n) * sizeof(digit_type));
-  }
-}
-
-template<typename D, typename W, typename S>
-inline
-D basic_primitive_ops<D,W,S>::multiply_by_digit(digit_type* z,
-                                                const digit_type* y,
-                                                size_type ylen,
-                                                digit_type x)
-{
-  digit_type carry = 0;
-
-  while (ylen--)
-  {
-    const word_type tmp = static_cast<word_type>(carry)
-                        + static_cast<word_type>(*y++)
-                        * static_cast<word_type>(x);
-    *z++ = static_cast<digit_type>(tmp);
-    carry = static_cast<digit_type>(tmp >> digit_bits);
-  }
-
-  return carry;
-}
-
-template<typename D, typename W, typename S>
-inline
-D basic_primitive_ops<D,W,S>::multiply_by_two(digit_type* z,
-                                              const digit_type* x, size_type n)
-{
-  static const digit_type one = 1U;
-
-  digit_type carry = 0;
-
-  while (n--)
-  {
-    // get carry bit for next iteration
-    const digit_type r = *x >> (static_cast<digit_type>(digit_bits) - one);
-
-    *z++ = (*x++ << one) | carry;
-
-    carry = r;
-  }
-
-  return carry;
-}
-
-template<typename D, typename W, typename S>
-void
-basic_primitive_ops<D,W,S>::classic_mul(
-    digit_type* z, const digit_type* x, size_type xlen,
-                   const digit_type* y, size_type ylen)
-{
-  // phase 1
-  word_type tmp = static_cast<word_type>(x[0]) * static_cast<word_type>(y[0]);
-  z[0] = static_cast<digit_type>(tmp);
-
-  for (size_type i = 1; i < xlen; ++i)
-  {
-    tmp = (tmp >> digit_bits)
-        + static_cast<word_type>(x[i])
-        * static_cast<word_type>(y[0]);
-    z[i] = static_cast<digit_type>(tmp);
-  }
-
-  tmp >>= digit_bits;
-  z[xlen] = static_cast<digit_type>(tmp);
-
-  // phase 2
-  for (size_type i = 1; i < ylen; ++i)
-  {
-    tmp = static_cast<word_type>(y[i])
-        * static_cast<word_type>(x[0])
-        + static_cast<word_type>(z[i]);
-    z[i] = static_cast<digit_type>(tmp);
-
-    for (size_type j = 1; j < xlen; ++j)
-    {
-      tmp = (tmp >> digit_bits)
-          + static_cast<word_type>(y[i]) * static_cast<word_type>(x[j])
-          + static_cast<word_type>(z[i+j]);
-      z[i+j] = static_cast<digit_type>(tmp);
-    }
-
-    tmp >>= digit_bits;
-    z[i + xlen] = static_cast<digit_type>(tmp);
-  }
-}
-
-
-// K = 2 ^ (alpha - (2*beta-1))
-// alpha = num bits of word_type, beta = num bits of digit_type
-// calculation works in 3 phases
-//                65432
-//              x   223
-//----------------------------------
-//              | 18  15 | 12  9  6
-//           12 | 10   8 |  6  4
-//        12 10 |  8   6 |  4
-//              |        |
-// phase:   3   |    2   |    1
-//
-// TODO handle too long columns => carry may overflow. This can happen if
-// digit_type is 8bit; in that case delegate to classic_mul routine in
-// operator *= (). Just check if (smaller number).used_ >= overflow_count.
-template<typename D, typename W, typename S>
-void
-basic_primitive_ops<D,W,S>::comba_mul(digit_type* z,
-                                      const digit_type* x, size_type xlen,
-                                      const digit_type* y, size_type ylen)
-{
-  assert(xlen >= ylen);
-
-  word_type acc = 0;  // accumulator for each column
-  word_type carry = 0;
-
-  // phase 1
-  for (size_type i = 0; i < ylen; ++i)
-  {
-    const digit_type* a = x;
-    const digit_type* b = y + i;
-
-    for (size_type j = 0; j <= i; ++j)
-    {
-      acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
-      carry += acc >> digit_bits;
-      acc = static_cast<digit_type>(acc);
-    }
-
-    *z++ = static_cast<digit_type>(acc);
-    acc  = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  // phase 2
-  for (size_type i = 0; i < xlen - ylen; ++i)
-  {
-    const digit_type* a = x + ylen + i;
-    const digit_type* b = y;
-
-    for (size_type j = 0; j < ylen; ++j)
-    {
-      acc += static_cast<word_type>(*a--) * static_cast<word_type>(*b++);
-      carry += acc >> digit_bits;
-      acc = static_cast<digit_type>(acc);
-    }
-
-    *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  // phase 3
-  for (size_type i = 0; i < ylen - 1; ++i)
-  {
-    const digit_type* a = x + xlen - 1;
-    const digit_type* b = y + i + 1;
-
-    for (size_type j = i + 1; j < ylen; ++j)
-    {
-      acc += static_cast<word_type>(*a--) * static_cast<word_type>(*b++);
-      carry += acc >> digit_bits;
-      acc = static_cast<digit_type>(acc);
-    }
-
-    *z++ = static_cast<digit_type>(acc);
-    acc  = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  *z = static_cast<digit_type>(acc);
-}
-
-template<typename D, typename W, typename S>
-void
-basic_primitive_ops<D,W,S>::comba_mul(digit_type* z,
-                                      const digit_type* x,
-                                      const digit_type* y, size_type xylen)
-{
-  word_type acc = 0;  // accumulator for each column
-  word_type carry = 0;
-
-  // phase 1
-  for (size_type i = 0; i < xylen; ++i)
-  {
-    const digit_type* a = x;
-    const digit_type* b = y + i;
-
-    for (size_type j = 0; j <= i; ++j)
-    {
-      acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
-      carry += acc >> digit_bits;
-      acc = static_cast<digit_type>(acc);
-    }
-
-    *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  // phase 2
-  for (size_type i = 1; i < xylen; ++i)
-  {
-    const digit_type* a = y + xylen - 1;
-    const digit_type* b = x + i;
-
-    for (size_type j = 0; j < xylen - i; ++j)
-    {
-      acc += static_cast<word_type>(*a--) * static_cast<word_type>(*b++);
-      carry += acc >> digit_bits;
-      acc = static_cast<digit_type>(acc);
-    }
-
-    *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  *z = static_cast<digit_type>(acc);
-}
-
-template<typename D, typename W, typename S>
-void
-basic_primitive_ops<D,W,S>::comba_sqr(digit_type* z,
-                                      const digit_type* x,
-                                      size_type xlen)
-{
-/*  word_type acc = 0;
-  word_type carry = 0;
-  word_type acc2;
-
-  for (size_type i = 0; i < xlen; ++i)
-  {
-    // even colum
-    acc += static_cast<word_type>(x[i]) * static_cast<word_type>(x[i]);
-
-    const digit_type* a = x + i;
-    const digit_type* b = x + i;
-
-    acc2 = 0;
-    for (size_type j = 0; j < (i - n&1) >> 1; ++j)
-    {
-      acc2 += static_cast<word_type>(*(--a)) * static_cast<word_type>(*(--b));
-      carry += acc2 >> digit_bits;
-      acc2 = static_cast<digit_type>(acc2);
-    }
-
-    acc += acc2 + acc2;
-
-    *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-
-    // odd column
-    const digit_type* a = x + i;
-    const digit_type* b = x + i + 1;
-
-    acc2 = 0;
-    for (size_type j = 0; j <= i; ++j)
-    {
-      acc2 += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
-      carry += acc2 >> digit_bits;
-      acc2 = static_cast<digit_type>(acc2);
-    }
-
-    acc += acc2 + acc2;
-
-    *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  *z = static_cast<digit_type>(acc);*/
-
-
-  word_type acc = 0;  // accumulator for each column
-  word_type carry = 0;
-
-  // phase 1
-  for (size_type i = 0; i < xlen; ++i)
-  {
-    const digit_type* a = x;
-    const digit_type* b = x + i;
-
-    for (size_type j = 0; j <= i; ++j)
-    {
-      acc += static_cast<word_type>(*a++) * static_cast<word_type>(*b--);
-      carry += acc >> digit_bits;
-      acc = static_cast<digit_type>(acc);
-    }
-
-    *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  // phase 2
-  for (size_type i = 1; i < xlen; ++i)
-  {
-    const digit_type* a = x + xlen - 1;
-    const digit_type* b = x + i;
-
-    for (size_type j = 0; j < xlen - i; ++j)
-    {
-      acc += static_cast<word_type>(*a--) * static_cast<word_type>(*b++);
-      carry += acc >> digit_bits;
-      acc = static_cast<digit_type>(acc);
-    }
-
-    *z++ = static_cast<digit_type>(acc);
-    acc = static_cast<digit_type>(carry);
-    carry >>= digit_bits;
-  }
-
-  *z = static_cast<digit_type>(acc);
-}
-
-template<typename D, typename W, typename S>
-D basic_primitive_ops<D,W,S>::multiply_add_digits(digit_type* z,
-                                                  const digit_type* w,
-                                                  digit_type x,
-                                                  const digit_type* y,
-                                                  size_type n)
-{
-  word_type carry = 0;
-  while (n--)
-  {
-    const word_type r = static_cast<word_type>(*w++)
-                      * static_cast<word_type>(x)
-                      + static_cast<word_type>(*y++)
-                      + carry;
-
-    *z++ = static_cast<digit_type>(r);
-    carry = r >> digit_bits;
-  }
-
-  return static_cast<digit_type>(carry);
-}
-
-
-template<typename D, typename W, typename S>
-inline
-void basic_primitive_ops<D,W,S>::divide_by_two(digit_type* z,
-                                               const digit_type* x, size_type n)
-{
-  z += n - 1;
-  x += n - 1;
-
-  digit_type carry = 0;
-
-  while (n--)
-  {
-    // get carry for next iteration
-    const digit_type r = *x & 1;
-
-    *z-- = (*x-- >> 1) | (carry << (digit_bits - 1));
-
-    carry = r;
-  }
-}
-
-template<typename D, typename W, typename S>
-D basic_primitive_ops<D,W,S>::divide_by_digit(digit_type* z,
-                                              const digit_type* x, size_type n,
-                                              digit_type y)
-{
-  z += n - 1;
-  x += n - 1;
-
-  word_type w = 0;
-
-  while (n--)
-  {
-    w = (w << digit_bits) | static_cast<word_type>(*x--);
-    digit_type tmp;
-    if (w >= y)
-    {
-      tmp = static_cast<digit_type>(w / y);
-      w -= tmp * y;
-    }
-    else
-      tmp = 0;
-    *z-- = tmp;
-  }
-
-  return static_cast<digit_type>(w);
-}
-
-
-
-
-// This exists to ease development of primitive_ops specializations. If a
-// specialized function isn't available yet, the compiler will just choose the
-// inherited one. It also means that whenever we add a new function to
-// basic_primitive_ops no code will break since it will be available to all
-// specializations as well.
-template<typename D, typename W, typename S>
-struct primitive_ops : basic_primitive_ops<D,W,S>
-{};
-
-
-// Here we include primitive_ops specializations that use assembler
-
-#if defined(BOOST_MP_MATH_MP_INT_USE_ASM)
-
-  #if defined(__GNU__)
-    #if defined(__386__)
-      #include <boost/mp_math/mp_int/detail/asm/x86/gnu_386_primitive_ops.hpp>
-    #endif
-  #endif
-
-#endif
-
-
-
-} // namespace detail
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Copied: sandbox/mp_math/boost/mp_math/integer/detail/root.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/root.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/root.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/root.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,202 +1,225 @@
+// Copyright Tom St Denis 2002 - 2007.
 // Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_ROOT_HPP
-#define BOOST_MP_MATH_MP_INT_ROOT_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_ROOT_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_ROOT_HPP
 
+#include <boost/mp_math/integer/detail/multiplier.hpp>
+#include <boost/type_traits/make_unsigned.hpp>
 
 namespace boost {
 namespace mp_math {
+namespace detail {
 
-template<class A, class T>
-mp_int<A,T> sqrt(const mp_int<A,T>& x)
+// Newton-Raphson approximation
+template<class ApInt, typename IntegerT>
+void
+newton_raphson_loop(ApInt& a, ApInt& b, const IntegerT& n, const ApInt& x)
 {
-  if (x.is_negative())
-    throw std::domain_error("sqrt: argument must be positive");
-
-  mp_int<A,T> t1;
-
-  if (!x)
-  {
-    t1.zero();
-    return t1;
-  }
-
-  t1 = x;
-
-  // First approx. (not very bad for large arg)
-  t1.shift_digits_right(t1.size()/2);
+  //std::cout << "initial = " << b.template to_string<std::string>(std::ios::hex) << std::endl;
+  // a is going to hold the result
+  // b holds the initial approximation
+  // c is just another temporary
+  ApInt c;
 
-  // t1 > 0
-  mp_int<A,T> t2 = x / t1;
-
-  t1 += t2;
-  t1.divide_by_2();
-  // And now t1 > sqrt(arg)
+  // improve the initial approximation b
   do
   {
-    t2 = x / t1;
-    t1 += t2;
-    t1.divide_by_2();
-    // t1 >= sqrt(arg) >= t2 at this point
-  } while (t1.compare_magnitude(t2) == 1);
-
-  return t1;
-}
+    a = b;
 
+    // b = a - (a^n - x) / (n * a^(n-1))
 
-// Uses Newton-Raphson approximation.
-template<class A, class T>
-mp_int<A,T> nth_root(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type n)
-{
-  if ((n & 1) == 0 && x.is_negative())
-    throw std::domain_error("nth_root: argument must be positive if n is even");
-
-  if (n == 0U)
-    throw std::domain_error("nth_root: n must not be zero");
-  else if (n == 1U)
-    return x;
-
-  // if x is negative fudge the sign but keep track
-  const int neg = x.sign();
-  const_cast<mp_int<A,T>*>(&x)->set_sign(1);
-
-  mp_int<A,T> t1, t2, t3;
-
-  typedef typename mp_int<A,T>::size_type size_type;
-
-  // initial approximation
-  const size_type result_precision = (x.precision() - 1) / n + 1;
-  t2.grow_capacity(1);
-  t2.set_size(1);
-  t2[0] = 0;
-  t2.set_bits(0, result_precision + 1);
-
-  do
-  {
-    t1 = t2;
-
-    // t2 = t1 - ((t1**n - x) / (n * t1**(n-1)))
-
-    // t3 = t1**(n-1)
-    t3 = pow(t1, n-1);
+    c = pow(a, n-1);
 
+    //std::cout << "c = " << c.template to_string<std::string>(std::ios::hex) << std::endl;
+    //std::cout << "a = " << a.template to_string<std::string>(std::ios::hex) << std::endl;
+    //std::cout << "x = " << x.template to_string<std::string>(std::ios::hex) << std::endl;
     // numerator
-    // t2 = t1**n
-    t2 = t3 * t1;
-
-    // t2 = t1**n - x
-    t2 -= x;
+    b = c * a;  // b = a^n
+    //std::cout << "b = " << b.template to_string<std::string>(std::ios::hex) << std::endl;
+    b -= x;     // b = a^n - x
+    //std::cout << "b = " << b.template to_string<std::string>(std::ios::hex) << std::endl;
 
     // denominator
-    // t3 = t1**(n-1) * n
-    t3.multiply_by_digit(n);
+    c *= n;     // c = a^(n-1) * n
+    c = b / c;  // c = (a^n - x) / (n * a^(n-1))
 
-    // t3 = (t1**n - x)/(n * t1**(n-1))
-    t3 = t2 / t3;
-
-    t2 = t1 - t3;
-  } while (t1 != t2);
+    //std::cout << "c = " << c.template to_string<std::string>(std::ios::hex) << std::endl;
+    //std::cout << " ok " << std::endl;
+    b = a - c;
+    //std::cout << " ok2 " << std::endl;
+  } while (a != b);
 
   // result can be off by a few so check
   for (;;)
   {
-    t2 = pow(t1, n);
+    b = pow(a, n);
 
-    if (t2 > x)
-      --t1;
+    if (b > x)
+      --a;
     else
       break;
   }
+}
 
-  // reset the sign of x first
-  const_cast<mp_int<A,T>*>(&x)->set_sign(neg);
 
-  // set the sign of the result
-  t1.set_sign(neg);
+template<
+  class ApInt,
+  bool IsApIntSigned = ApInt::is_signed
+>
+struct root;
 
-  return t1;
-}
 
-template<class A, class T>
-mp_int<A,T> nth_root(const mp_int<A,T>& x, const mp_int<A,T>& n)
+template<class ApInt>
+struct root<ApInt,false>
 {
-  if (n.is_odd() && x.is_negative())
-    throw std::domain_error("nth_root: argument must be positive if n is even");
-
-  if (n.size() == 1)
-    return nth_root(x, n[0]);
+  typedef typename ApInt::size_type size_type;
 
-  // if x is negative fudge the sign but keep track
-  const int neg = x.sign();
-  const_cast<mp_int<A,T>*>(&x)->set_sign(1);
+  static void sqrt    (ApInt& z, const ApInt& x);
+  template<typename IntegerT>
+  static void nth_root(ApInt& z, const IntegerT& n, const ApInt& x);
+};
 
-  mp_int<A,T> t1, t2, t3;
 
-  typedef typename mp_int<A,T>::size_type size_type;
+template<class ApInt>
+void
+root<ApInt,false>::sqrt(ApInt& z, const ApInt& x)
+{
+  if (!x)
+  {
+    z = typename ApInt::digit_type(0);
+    return;
+  }
 
-  static const size_type digit_bits = mp_int<A,T>::digit_bits;
+  z = x;
 
-  const size_type result_precision = (x.precision() - 1)
-                                   / n.template to_integral<size_type>() + 1;
+  // first approx. (not very bad for large arg)
+  shifter<ApInt>::shift_digits_right(z, z.size() / 2);
 
-  t2.grow_capacity((result_precision + digit_bits - 1) / digit_bits);
-  t2.set_size     ((result_precision + digit_bits - 1) / digit_bits);
+  ApInt a = x / z;
 
-  t2[t2.size()-1] = 0;
-  t2.set_bits(0, result_precision + 1);
+  z += a;
+  base::divider<ApInt>::divide_by_2(z);
 
+  // and now z > sqrt(x)
   do
   {
-    t1 = t2;
+    a = x / z;
+    z += a;
+    base::divider<ApInt>::divide_by_2(z);
+    // z >= sqrt(x) >= a at this point
+  } while (z > a);
+}
+
+template<class ApInt>
+template<typename IntegerT>
+void
+root<ApInt,false>::nth_root(ApInt& z, const IntegerT& n, const ApInt& x)
+{
+  if (n == 0U)
+    throw std::domain_error("nth_root: n must not be zero");
+  else if (n == 1U)
+  {
+    z = x;
+    return;
+  }
 
-    // t2 = t1 - ((t1**n - x) / (n * t1**(n-1)))
+  static const size_type digit_bits = ApInt::traits_type::digit_bits;
 
-    // t3 = t1**(n-1)
-    t3 = pow(t1, n-1);
+  // create initial approximation
+  z = x.precision() - 1;
+  z /= n;
+  const size_type result_precision = z.template to_integral<size_type>() + 1;
+
+  const size_type result_digits = (result_precision + (digit_bits - 1))
+                                / digit_bits;
+  ApInt initial_approximation;
+  initial_approximation.reserve (result_digits);
+  initial_approximation.set_size(result_digits);
 
-    // numerator
-    // t2 = t1**n
-    t2 = t3 * t1;
+  initial_approximation[result_digits - 1] = 0;
+  initial_approximation.set_bits(0, result_precision + 1);
 
-    // t2 = t1**n - x
-    t2 -= x;
+  newton_raphson_loop(z, initial_approximation, n, x);
+}
 
-    // denominator
-    // t3 = t1**(n-1) * n
-    t3 *= n;
 
-    // t3 = (t1**n - x)/(n * t1**(n-1))
-    t3 = t2 / t3;
+template<class ApInt>
+struct root<ApInt,true>
+{
+  typedef typename ApInt::size_type size_type;
 
-    t2 = t1 - t3;
-  } while (t1 != t2);
+  static void sqrt    (ApInt& z, const ApInt& x);
+  static void nth_root(ApInt& z, size_type n, const ApInt& x);
+  static void nth_root(ApInt& z, const ApInt& n, const ApInt& x);
+};
 
-  // result can be off by a few so check
-  for (;;)
-  {
-    t2 = pow(t1, n);
 
-    if (t2 > x)
-      --t1;
-    else
-      break;
+template<class ApInt>
+void
+root<ApInt,true>::sqrt(ApInt& z, const ApInt& x)
+{
+  if (x.is_negative())
+    throw std::domain_error("sqrt: radicand must be positive");
+
+  root<ApInt,false>::sqrt(z, x);
+}
+
+template<class ApInt>
+void
+root<ApInt,true>::nth_root(ApInt& z, size_type n, const ApInt& x)
+{
+  if ((n & 1) == 0 && x.is_negative())
+    throw std::domain_error("nth_root: radicand must be positive if n is even");
+
+  // x must be positive for the algorithm to work
+  const bool s = x.sign_bit();
+  const_cast<ApInt&>(x).set_sign_bit(0);
+
+  try
+  {
+    root<ApInt,false>::nth_root(z, n, x);
+  }
+  catch (const std::exception&)
+  {
+    const_cast<ApInt&>(x).set_sign_bit(s);
+    throw;
   }
 
-  // reset the sign of x first
-  const_cast<mp_int<A,T>*>(&x)->set_sign(neg);
+  const_cast<ApInt&>(x).set_sign_bit(s);
+  z.set_sign_bit(s);
+}
+
+template<class ApInt>
+void
+root<ApInt,true>::nth_root(ApInt& z, const ApInt& n, const ApInt& x)
+{
+  if (n.is_even() && x.is_negative())
+    throw std::domain_error("nth_root: radicand must be positive if n is even");
+
+  // x must be positive for the algorithm to work
+  const bool s = x.sign_bit();
+  const_cast<ApInt&>(x).set_sign_bit(0);
 
-  // set the sign of the result
-  t1.set_sign(neg);
+  try
+  {
+    root<ApInt,false>::nth_root(z, n, x);
+  }
+  catch (const std::exception&)
+  {
+    const_cast<ApInt&>(x).set_sign_bit(s);
+    throw;
+  }
 
-  return t1;
+  const_cast<ApInt&>(x).set_sign_bit(s);
+  z.set_sign_bit(s);
 }
 
 
+} // namespace detail
 } // namespace mp_math
 } // namespace boost
 
Copied: sandbox/mp_math/boost/mp_math/integer/detail/string_conversion.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/string_conversion.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/string_conversion.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/detail/string_conversion.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,314 +1,985 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
 
-namespace detail
+#ifndef BOOST_MP_MATH_INTEGER_DETAIL_STRING_CONVERTER_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_STRING_CONVERTER_HPP
+
+#include <algorithm>
+#include <iostream>
+#include <memory>
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+template<
+  typename T,
+  T Radix,
+  T Count = 0,
+  T Temp = Radix,
+  bool continue_recursion = true
+>
+struct max_power_impl
 {
-  template<typename charT>
-  inline int ascii_to_value(const charT c)
+  // continue recursion until Temp overflows
+  static const T a = static_cast<T>(Temp * Radix);
+  static const bool c = (a / Radix) == Temp;
+
+  typedef max_power_impl<T, Radix, Count + 1, c ? a : Temp, c> result;
+
+  static const T exponent = result::exponent;
+  static const T value    = result::value;
+};
+
+template<typename T, T Radix, T Count, T Temp>
+struct max_power_impl<T, Radix, Count, Temp, false>
+{
+  static const T exponent = Count;
+  static const T value    = Temp;
+};
+
+// T must be an unsigned integral type
+template<typename T, T Radix>
+struct max_power
+{
+  static const T exponent = max_power_impl<T, Radix>::exponent;
+  static const T value    = max_power_impl<T, Radix>::value;
+};
+
+
+// Supported radices are 2, 4, 8, 16, 32, 64 and 10
+template<class ApInt>
+struct sc_constants
+{
+  typedef typename ApInt::digit_type digit_type;
+
+//private:
+
+  const unsigned index_;
+
+  static unsigned map_radix_to_index(unsigned radix)
   {
-    switch (c)
+    switch (radix)       // map radix 2^x to index x-1
     {
-      case '0': case '1': case '2': case '3': case '4':
-      case '5': case '6': case '7': case '8': case '9':
-        return c - '0';
-      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-        return c - 'A' + 10;
-      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-        return c - 'a' + 10;
+      case  2: return 0;
+      case  4: return 1;
+      case  8: return 2;
+      case 16: return 3;
+      case 32: return 4;
+      case 64: return 5;
+      default: return 6; // map radix 10 to index 6
     }
-    return c;
   }
+
+  static const digit_type max_exponent_array_[7];
+  static const digit_type max_power_value_array_[7];
+  static const digit_type radix_storage_bits_array_[7];
+
+public:
+
+  explicit sc_constants(unsigned radix)
+  :
+    index_(map_radix_to_index(radix))
+  {}
+
+  // returns maximal exponent x so that radix^x still fits into a digit_type
+  digit_type max_exponent() const
+  {
+    return max_exponent_array_[index_];
+  }
+
+  // returns the corresponding value y = radix^max_power
+  digit_type max_power_value() const
+  {
+    return max_power_value_array_[index_];
+  }
+
+  // returns ceil(log2(radix))
+  digit_type radix_storage_bits() const
+  {
+    return radix_storage_bits_array_[index_];
+  }
+};
+
+template<class ApInt>
+const typename ApInt::digit_type
+sc_constants<ApInt>::max_exponent_array_[7] =
+{
+  max_power<digit_type,  2>::exponent,
+  max_power<digit_type,  4>::exponent,
+  max_power<digit_type,  8>::exponent,
+  max_power<digit_type, 16>::exponent,
+  max_power<digit_type, 32>::exponent,
+  max_power<digit_type, 64>::exponent,
+  max_power<digit_type, 10>::exponent
+};
+
+template<class ApInt>
+const typename ApInt::digit_type
+sc_constants<ApInt>::max_power_value_array_[7] =
+{
+  max_power<digit_type,  2>::value,
+  max_power<digit_type,  4>::value,
+  max_power<digit_type,  8>::value,
+  max_power<digit_type, 16>::value,
+  max_power<digit_type, 32>::value,
+  max_power<digit_type, 64>::value,
+  max_power<digit_type, 10>::value
+};
+
+template<class ApInt>
+const typename ApInt::digit_type
+sc_constants<ApInt>::radix_storage_bits_array_[7] = {1, 2, 3, 4, 5, 6, 4};
+
+
+// Always call detect_properties before calling convert, unless you're providing
+// the radix explicitly. In that case the number must not have a radix prefix.
+
+template<class ApInt>
+struct from_string_converter
+{
+  typedef typename ApInt::digit_type digit_type;
+  typedef typename ApInt::size_type  size_type;
+
+  // detect sign, radix, length
+  template<typename Iter>
+  void detect_properties(Iter& first, Iter last)
+  {
+    detect_properties(first, last,
+                      typename std::iterator_traits<Iter>::iterator_category());
+  }
+
+  // as above, additionally it checks if the number prefix is formatted
+  // according to the flags
+  template<typename Iter>
+  void detect_properties(Iter& first, Iter last, std::ios_base::fmtflags f);
+
+  // manual radix parameter for radices 2-64
+  template<typename Iter>
+  void convert(ApInt& x, Iter first, Iter last, unsigned radix) const
+  {
+    assert(x.is_uninitialized());
+    if (first != last)
+      convert(x, first, last, radix,
+            typename std::iterator_traits<Iter>::iterator_category());
+  }
+
+  // use the detected radix, can only be 8, 10 or 16
+  template<typename Iter>
+  void convert(ApInt& x, Iter first, Iter last) const
+  {
+    convert(x, first, last, radix);
+  }
+
+  template<typename InputIter>
+  void convert(ApInt& x, InputIter c) const;
+
+  // converts the string [first, last) to digits one at a time beginning with
+  // the most significant digit, works only for power of two radices
+  template<typename Iter>
+  digit_type get_next_digit(Iter& first, Iter last) const;
+
+  static bool is_power_of_two(unsigned radix)
+  {
+    return (radix & (radix - 1)) == 0;
+  }
+
+  // properties
+  std::size_t total_length;
+  unsigned    prefix_length;
+  std::size_t length;          // = total_length - prefix_length
+  unsigned    radix;
+  bool        is_positive;     // do we have a '-' as first character?
+
+private:
+
+  typedef sc_constants<ApInt> sc_type;
+  typedef typename ApInt::traits_type::ops_type ops_type;
+
+  static const unsigned radix_bits = ApInt::traits_type::radix_bits;
+
+  enum error_t
+  {
+    err_invalid_char,
+    err_bad_prefix,
+    err_no_number_after_prefix,
+    err_no_number_after_sign,
+    err_no_error
+  };
+
+  template<typename charT>
+  static digit_type ascii_to_value(charT c);
+
+  template<typename RandomAccessIterator>
+  void detect_properties(RandomAccessIterator& first,
+                         RandomAccessIterator last,
+                         std::random_access_iterator_tag);
+
+  template<typename InputIterator>
+  void detect_properties(InputIterator& first,
+                         InputIterator last,
+                         std::input_iterator_tag);
+
+  template<typename RandomAccessIterator>
+  void convert(ApInt& x,
+               RandomAccessIterator first, RandomAccessIterator last,
+               unsigned radix,
+               std::random_access_iterator_tag) const;
+
+  template<typename InputIterator>
+  void convert(ApInt& x,
+               InputIterator first, InputIterator last,
+               unsigned radix,
+               std::input_iterator_tag) const;
+
+  template<typename Iter>
+  void convert_pow2_radix(
+      ApInt& x, Iter first, Iter last, unsigned radix, const sc_type& sc) const
+  {
+    convert_pow2_radix(x, first, last, radix, sc,
+                       typename std::iterator_traits<Iter>::iterator_category());
+  }
+
+  template<typename Iter>
+  void convert_other_radix(ApInt& x,
+                           Iter first, Iter last,
+                           unsigned radix,
+                           const sc_type& sc) const
+  {
+    convert_other_radix(x, first, last, radix, sc,
+                        typename std::iterator_traits<Iter>::iterator_category());
+  }
+
+  template<typename RandomAccessIterator>
+  void convert_pow2_radix(ApInt& x,
+                          RandomAccessIterator first, RandomAccessIterator last,
+                          unsigned radix,
+                          const sc_type& sc,
+                          std::random_access_iterator_tag) const;
+
+  template<typename RandomAccessIterator>
+  void convert_other_radix(ApInt& x,
+                           RandomAccessIterator first, RandomAccessIterator last,
+                           unsigned radix,
+                           const sc_type& sc,
+                           std::random_access_iterator_tag) const;
+
+  template<typename InputIterator>
+  void convert_pow2_radix(ApInt& x,
+                          InputIterator first, InputIterator last,
+                          unsigned radix,
+                          const sc_type& sc,
+                          std::input_iterator_tag) const;
+
+  template<typename InputIterator>
+  void convert_other_radix(ApInt& x,
+                           InputIterator first, InputIterator last,
+                           unsigned radix,
+                           const sc_type& sc,
+                           std::input_iterator_tag) const;
+};
+
+
+template<class ApInt>
+template<typename charT>
+inline
+typename ApInt::digit_type
+from_string_converter<ApInt>::ascii_to_value(charT c)
+{
+  switch (c)
+  {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      c = c - '0';
+      break;
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+      c = c - 'A' + 10;
+      break;
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+      c = c - 'a' + 10;
+  }
+  return static_cast<digit_type>(c);
 }
 
-// low level from string conversion routine
-// Requires:
-// - size_ = 0
-// - first and last must point into string without sign prefix and without base
-//   prefix (like 0x)
-// - radix is 8, 10 or 16
-template<class A, class T>
-template<typename Iter>
-void mp_int<A,T>::from_string(Iter first, Iter last, unsigned radix)
+
+// pre: first <= last
+template<class ApInt>
+template<typename RandomAccessIterator>
+void from_string_converter<ApInt>::
+detect_properties(RandomAccessIterator& first, RandomAccessIterator last,
+                  std::random_access_iterator_tag)
 {
-  assert(size_ == 0);
-  assert(first != last);
+  const RandomAccessIterator beg = first;
 
-  const detail::string_conversion_constants<mp_int> sc(radix);
+  detect_properties(first, last, std::input_iterator_tag());
 
-  const size_type length = std::distance(first, last);
+  total_length = std::distance(beg, last);
+  prefix_length = std::distance(beg, first);
+  length = total_length - prefix_length;
+};
+
+// pre: first <= last
+template<class ApInt>
+template<typename InputIterator>
+void from_string_converter<ApInt>::
+detect_properties(InputIterator& first, InputIterator last,
+                  std::input_iterator_tag)
+{
+  if (first == last)
+  {
+    is_positive = true;
+    return;
+  }
 
-  static const char* inv_msg = "mp_int<>::from_string: invalid character";
-  
-  const bool is_power_of_two = (radix & (radix - 1)) == 0;
-  if (is_power_of_two)
+  if (*first == '-')
   {
-    const size_type required =
-      (length * sc.radix_storage_bits + (valid_bits - 1)) / valid_bits;
-    grow_capacity(required);
+    ++first;
+    is_positive = false;
+  }
+  else
+  {
+    if (*first == '+')
+      ++first;
+    is_positive = true;
+  }
 
-    digit_type result = 0;
-    int        offset = 0;
-    
-    typedef std::reverse_iterator<Iter> reverse_iter_type;
-    for (reverse_iter_type c(last); c != reverse_iter_type(first); ++c)
-    {
-      const digit_type x = static_cast<digit_type>(detail::ascii_to_value(*c));
-      
-      if (x >= radix)
-        throw std::invalid_argument(inv_msg);
-      
-      result |= x << offset;
-      offset += sc.radix_storage_bits;
-      
-      if (offset >= valid_bits)
+  // detect the radix
+  if (first != last)
+  {
+    if (*first == '0') // octal
+    {
+      ++first;
+      if (first != last && (*first == 'x' || *first == 'X')) // hex
       {
-        push(result);
-        offset -= valid_bits;
-        result = static_cast<digit_type>(x >> (sc.radix_storage_bits - offset));
+        radix = 16;
+        ++first;
+      }
+      else
+      {
+        radix = 8;
+        --first; // keep the zero, necessary for int_type("0")
       }
     }
-    
-    if (result || is_uninitialized())
-      push(result);
-    
-    clamp();
+    else // decimal
+      radix = 10;
+  }
+  else
+    throw std::invalid_argument(
+        "from_string_converter::detect_properties: malformed string");
+};
+
+template<class ApInt>
+template<typename Iter>
+void from_string_converter<ApInt>::
+detect_properties(Iter& first, Iter last, std::ios_base::fmtflags f)
+{
+  total_length = std::distance(first, last);
+
+  if (first == last)
+    return;
 
-    if (!*this)
-      set_sign(1);
+  const Iter beg = first;
+
+  if (*first == '-')
+  {
+    is_positive = false;
+    ++first;
   }
-  else // radix can only be 10 at this point
+  else
   {
-    size_type required;
-    // approximate log2(10) with 10/3
-    if (length < std::numeric_limits<size_type>::max()/10U)
-      required = (10U * length + 2U) / 3U;
+    if (f & std::ios_base::showpos)
+    {
+      if (*first == '+')
+        ++first;
+      else
+        throw std::invalid_argument(
+            "from_string_converter::detect_properties: expected a '+' sign");
+    }
+    is_positive = true;
+  }
+
+  // TODO should uppercase also mean that hex prefix must be 0X?
+  //const bool uppercase = f & std::ios_base::uppercase;
+  const bool showbase  = f & std::ios_base::showbase;
+
+  bool bad_prefix = false;
+
+  if (f & std::ios_base::hex)
+  {
+    if (showbase)
+    {
+      if (*first == '0')
+        ++first;
+      else
+        bad_prefix = true;
+      if (*first == 'x' || *first == 'X')
+        ++first;
+      else
+        bad_prefix = true;
+    }
+    radix = 16;
+  }
+  else if (f & std::ios_base::oct)
+  {
+    if (showbase)
+    {
+      if (*first != '0') // keep the zero, necessary for int_type("0")
+        bad_prefix = true;
+    }
+    radix = 8;
+  }
+  else if (f & std::ios_base::dec)
+    radix = 10;
+  else
+    throw std::invalid_argument(
+        "from_string_converter::detect_properties: unknown radix");
+
+  if (bad_prefix)
+    throw std::invalid_argument(
+        "from_string_converter::detect_properties: bad radix prefix");
+
+  prefix_length = std::distance(beg, first);
+  length = total_length - prefix_length;
+}
+
+template<class ApInt>
+template<typename RandomAccessIterator>
+void
+from_string_converter<ApInt>::
+convert_pow2_radix(ApInt& x,
+                   RandomAccessIterator first, RandomAccessIterator last,
+                   unsigned radix,
+                   const sc_type& sc,
+                   std::random_access_iterator_tag) const
+{
+  digit_type result = 0;
+  int        offset = 0;
+
+  typedef std::reverse_iterator<RandomAccessIterator> reverse_iter_type;
+  for (reverse_iter_type c(last); c != reverse_iter_type(first); ++c)
+  {
+    const digit_type y = static_cast<digit_type>(ascii_to_value(*c));
+
+    if (y >= radix)
+      throw std::invalid_argument("inv_msg");
+
+    result |= y << offset;
+    offset += sc.radix_storage_bits();
+
+    if (offset >= static_cast<int>(radix_bits))
+    {
+      x.push(result);
+      offset -= radix_bits;
+      result = static_cast<digit_type>(y >> (sc.radix_storage_bits() - offset));
+    }
+  }
+
+  if (result || x.is_uninitialized())
+    x.push(result);
+
+  x.clamp();
+}
+
+template<class ApInt>
+template<typename RandomAccessIterator>
+void
+from_string_converter<ApInt>::
+convert_other_radix(ApInt& x,
+                    RandomAccessIterator first, RandomAccessIterator last,
+                    unsigned radix,
+                    const sc_type& sc,
+                    std::random_access_iterator_tag) const
+{
+  for (size_type i = sc.max_exponent(); i < length; i += sc.max_exponent())
+  {
+    digit_type result = 0U;
+
+    // first convert a block of decimal digits to radix 10^sc.max_exponent
+    // which will still fit into a digit_type
+    for (unsigned int j = 0; j < sc.max_exponent(); ++j)
+    {
+      const digit_type y = *first++ - '0';
+      if (y >= 10U)
+        throw std::invalid_argument("inv_msg");
+      result = result * 10U + y;
+    }
+
+    // then use multi precision routines to convert this digit to binary
+    if (x.is_initialized())
+    {
+      digit_type carry =
+        ops_type::multiply_by_digit(x.digits(),
+                                    x.digits(), x.size(),
+                                    sc.max_power_value());
+
+      carry += ops_type::add_single_digit(x.digits(),
+                                          x.digits(), x.size(),
+                                          result);
+
+      if (carry)
+        x.push(carry);
+    }
     else
-      required = length / 3U * 10U;
-    required = (required + (valid_bits - 1)) / valid_bits;
-    
-    grow_capacity(required);
+      x.push(result);
+  }
+
+  // one last round for the remaining decimal digits
+  if (first != last)
+  {
+    digit_type radix_power = 1U;
+    digit_type result = 0U;
 
-    for (size_type i = sc.max_power; i < length; i += sc.max_power)
+    while (first != last)
     {
-      digit_type result = 0U;
+      const digit_type y = *first++ - '0';
+      if (y >= 10U)
+        throw std::invalid_argument("inv_msg");
+      result = result * 10U + y;
+      radix_power *= 10U;
+    }
 
-      // first convert a block of decimal digits to radix 10^sc.max_power
-      // which will still fit into a digit_type
-      for (unsigned int j = 0; j < sc.max_power; ++j)
-      {
-        const digit_type x = *first++ - '0';
-        if (x >= 10U)
-          throw std::invalid_argument(inv_msg);
-        result = result * 10U + x;
-      }
+    if (x.size())
+    {
+      digit_type carry =
+        ops_type::multiply_by_digit(x.digits(), x.digits(), x.size(),
+                                    static_cast<digit_type>(radix_power));
+
+      carry += ops_type::add_single_digit(x.digits(),
+                                          x.digits(), x.size(),
+                                          result);
 
-      // then use multi precision routines to convert this digit to binary
-      if (size_)
-      {
-        digit_type carry = ops_type::multiply_by_digit(digits_, digits_, size_,
-                                                            sc.max_power_value);
+      if (carry)
+        x.push(carry);
+    }
+    else
+      x.push(result);
+  }
+}
 
-        carry += ops_type::add_single_digit(digits_, digits_, size_, result);
-        
-        if (carry)
-          push(carry);
-      }
-      else
-        push(result);
+template<class ApInt>
+template<typename InputIterator>
+void
+from_string_converter<ApInt>::
+convert_pow2_radix(ApInt& x,
+                   InputIterator first, InputIterator last,
+                   unsigned radix,
+                   const sc_type& sc,
+                   std::input_iterator_tag) const
+{
+  digit_type result = 0;
+  int        offset = 0;
+  size_type  bits_read = 0;
+
+  for (; first != last; ++first)
+  {
+    const digit_type y = static_cast<digit_type>(ascii_to_value(*first));
+
+    if (y >= radix)
+      throw std::invalid_argument("inv_msg");
+
+    result |= y << offset;
+    offset += sc.radix_storage_bits();
+
+    if (offset >= static_cast<int>(radix_bits))
+    {
+      x.push(result);
+      offset -= radix_bits;
+      result = static_cast<digit_type>(y >> (sc.radix_storage_bits() - offset));
     }
 
-    // one last round for the remaining decimal digits
-    if (first != last)
+    bits_read += sc.radix_storage_bits();
+  }
+
+  if (result || x.is_uninitialized())
+    x.push(result);
+
+  // right shift bits and reverse the digits
+  const size_type n = bits_read % radix_bits;
+
+  if (n)
+  {
+    const size_type shift = radix_bits - n;
+    const digit_type mask = (digit_type(1) << n) - 1;
+    typename ApInt::iterator b = x.begin();
+    typename ApInt::iterator e = x.end();
+
+    if (b == e)
     {
-      digit_type radix_power = 1U;
-      digit_type result = 0U;
-      
-      while (first != last)
-      {
-        const digit_type x = *first++ - '0';
-        if (x >= 10U)
-          throw std::invalid_argument(inv_msg);
-        result = result * 10U + x;
-        radix_power *= 10U;
-      }
-      
-      if (size_)
-      {
-        digit_type carry = ops_type::multiply_by_digit(digits_, digits_, size_,
-                                          static_cast<digit_type>(radix_power));
+      x[0] >>= shift;
+      return;
+    }
 
-        carry += ops_type::add_single_digit(digits_, digits_, size_, result);
+    --e;
+    digit_type carry1 = 0;
 
-        if (carry)
-          push(carry);
-      }
-      else
-        push(result);
+    while (b < e)
+    {
+      const digit_type c1 = *b & mask;
+      digit_type d1 = (*b >> n) | (carry1 << shift);
+      carry1 = c1;
+
+      const digit_type carry2 = *(e-1) & mask;
+      digit_type d2 = (*e >> n) | (carry2 << shift);
+
+      *b = d2;
+      *e = d1;
+
+      ++b;
+      --e;
     }
+
+    // if the number of digits is odd, we need to shift the digit in the middle
+    if (x.size() & 1)
+      *b = (*b >> n) | (carry1 << shift);
   }
+  else
+    std::reverse(x.begin(), x.end());
+
+  x.clamp();
 }
 
+template<class ApInt>
+template<typename RandomAccessIterator>
+void
+from_string_converter<ApInt>::
+convert(ApInt& x,
+        RandomAccessIterator first, RandomAccessIterator last,
+        unsigned radix,
+        std::random_access_iterator_tag) const
+{
+  const sc_type sc(radix);
+
+  //static const char* inv_msg =
+  //  "from_string_converter::convert: invalid character";
 
-namespace detail
+  if (is_power_of_two(radix))
+  {
+    const size_type required =
+      (length * sc.radix_storage_bits() + (radix_bits - 1)) / radix_bits;
+
+    x.reserve(required);
+
+    convert_pow2_radix(x, first, last, radix, sc);
+  }
+  else
+  {
+    size_type required;
+
+    // approximate log2(10) = 3.32192809488736234787 with 10/3
+    if (length < std::numeric_limits<size_type>::max() / 10U)
+      required = (10U * length + 2U) / 3U;
+    else
+      required = length / 3U * 10U;
+
+    required = (required + (radix_bits - 1)) / radix_bits;
+
+    x.reserve(required);
+
+    convert_other_radix(x, first, last, radix, sc);
+  }
+}
+
+
+template<class ApInt, bool is_signed = ApInt::is_signed>
+struct sign_prefix;
+
+template<class ApInt> struct sign_prefix<ApInt,false>
+{
+  template<typename OutputIter>
+  static void write(const ApInt&, std::ios_base::fmtflags f, OutputIter& c)
+  {
+    if (f & std::ios_base::showpos)
+      *c++ = '+';
+  }
+};
+
+template<class ApInt> struct sign_prefix<ApInt,true>
+{
+  template<typename OutputIter>
+  static void write(const ApInt& x, std::ios_base::fmtflags f, OutputIter& c)
+  {
+    if (x.is_negative())
+      *c++ = '-';
+    else if (f & std::ios_base::showpos)
+      *c++ = '+';
+  }
+};
+
+
+template<class ApInt>
+struct to_string_converter
 {
-  template<typename T, class Alloc>
-  struct scoped_ptr : Alloc
+  typedef typename ApInt::size_type             size_type;
+  typedef typename ApInt::digit_type            digit_type;
+  typedef typename ApInt::traits_type::ops_type ops_type;
+
+  template<typename OutputIter>
+  void convert(const ApInt& x, std::ios_base::fmtflags f, OutputIter c);
+
+  template<class StringT>
+  void convert(StringT&, const ApInt& x, std::ios_base::fmtflags f);
+
+  static bool is_power_of_two(unsigned radix)
   {
-    T* ptr;
-    std::size_t size;
-    explicit scoped_ptr(std::size_t s) : size(s) { ptr = this->allocate(size); }
-    ~scoped_ptr() { this->deallocate(ptr,size); }
+    return (radix & (radix - 1)) == 0;
+  }
+
+  unsigned int radix;
+  size_type    total_bits_; // precision of the integer we're converting
+  size_type    prefix_length_;
+  size_type    number_length_;
+  size_type    total_length_;
+
+  enum error_t
+  {
+    err_unsupported_radix,
+    err_out_of_memory,
+    err_no_error
   };
-}
 
+  error_t err;
 
-// TODO use an output iterator then we can easily output to different string
-// types. But keep a high level to_string function to allocate string memory
-// only once.
-template<class A, class T>
-template<class StringT>
-StringT mp_int<A,T>::to_string(std::ios_base::fmtflags f) const
+  void check_fmtflags(std::ios_base::fmtflags f);
+
+private:
+
+  typedef sc_constants<ApInt> sc_type;
+
+  static const unsigned radix_bits = ApInt::traits_type::radix_bits;
+
+  static const char* const lowercase_tab_;
+  static const char* const uppercase_tab_;
+  const char* tab_;
+
+  template<typename OutputIter>
+  static void write_sign_prefix(const ApInt& x, std::ios_base::fmtflags f, OutputIter& c)
+  {
+    sign_prefix<ApInt>::write(x, f, c);
+  }
+
+  template<typename OutputIter>
+  void write_radix_prefix(std::ios_base::fmtflags f, OutputIter& c);
+
+  template<typename OutputIter>
+  void convert_pow2_radix(const ApInt& x, const sc_type& sc, OutputIter& c) const;
+
+  template<typename OutputIter>
+  void convert_other_radix(const ApInt& x, const sc_type& sc, OutputIter& c) const;
+
+  void estimate_number_length(const ApInt& x,
+                              const sc_type& sc);
+};
+
+
+template<class ApInt>
+const char* const
+to_string_converter<ApInt>::lowercase_tab_ = "0123456789abcdef";
+
+template<class ApInt>
+const char* const
+to_string_converter<ApInt>::uppercase_tab_ = "0123456789ABCDEF";
+
+
+template<class ApInt>
+void
+to_string_converter<ApInt>::
+estimate_number_length(const ApInt& x,
+                       const sc_type& sc)
 {
-  typedef typename StringT::value_type char_type;
+  total_bits_ = x.precision();
 
-  StringT s;
+  // round up to a multiple of sc.radix_storage_bits
+  if (total_bits_ % sc.radix_storage_bits())
+    total_bits_ = total_bits_ - total_bits_ % sc.radix_storage_bits()
+                + sc.radix_storage_bits();
+
+  if (is_power_of_two(radix))
+    number_length_ = (total_bits_ + (sc.radix_storage_bits() - 1))
+                   / sc.radix_storage_bits();
+  // approximate log2(10) with 13/4 = 3.25
+  else if (total_bits_ < std::numeric_limits<size_type>::max() / 4)
+    number_length_ = (total_bits_ * 4 + 12) / 13;
+  else
+    number_length_ = total_bits_ / 13 * 4;
 
-  if (is_uninitialized())
-    return s;
+  total_length_ = number_length_ + prefix_length_;
+}
 
-  digit_type radix;
+template<class ApInt>
+void
+to_string_converter<ApInt>::check_fmtflags(std::ios_base::fmtflags f)
+{
+  prefix_length_ = f & std::ios_base::showbase ? 1 : 0;
 
   if (f & std::ios_base::hex)
+  {
     radix = 16;
+    if (f & std::ios_base::showbase)
+      prefix_length_ += 2;
+  }
   else if (f & std::ios_base::oct)
+  {
     radix = 8;
+    if (f & std::ios_base::showbase)
+      prefix_length_ += 1;
+  }
   else if (f & std::ios_base::dec)
     radix = 10;
   else
-    throw std::invalid_argument("mp_int<>::to_string: unsupported radix");
+    err = err_unsupported_radix;
 
-  char_type prefix[3];
-  char_type* p = prefix;
-
-  if (is_negative())
-    *p++ = '-';
-  else if (f & std::ios_base::showpos)
-    *p++ = '+';
+  if (f & std::ios_base::uppercase)
+    tab_ = uppercase_tab_;
+  else
+    tab_ = lowercase_tab_;
+}
 
+template<class ApInt>
+template<typename OutputIter>
+void
+to_string_converter<ApInt>::
+write_radix_prefix(std::ios_base::fmtflags f, OutputIter& c)
+{
   if (f & std::ios_base::showbase)
   {
     if (radix == 16)
     {
-      *p++ = '0';
+      *c++ = '0';
       if (f & std::ios_base::uppercase)
-        *p++ = 'X';
+        *c++ = 'X';
       else
-        *p++ = 'x';
+        *c++ = 'x';
     }
     else if (radix == 8)
-      *p++ = '0';
+      *c++ = '0';
   }
+}
+
+template<class ApInt>
+template<typename OutputIter>
+void
+to_string_converter<ApInt>::
+convert_pow2_radix(const ApInt& x, const sc_type& sc, OutputIter& c) const
+{
+  const digit_type mask = (digit_type(1) << sc.radix_storage_bits()) - 1;
 
-  const int prefix_offset = p - prefix;
+  int offset = total_bits_ % radix_bits;
+  if (!offset)
+    offset = radix_bits;
 
-  if (!*this)
+  typename ApInt::const_reverse_iterator d = x.rbegin();
+  for (;;)
   {
-    s.reserve(prefix_offset + 1);
-    for (int i = 0; i < prefix_offset; ++i)
-      s.push_back(prefix[i]);
-    if (!(f & std::ios_base::oct))
-      s.push_back('0');
-    return s;
-  }
+    offset -= sc.radix_storage_bits();
+
+    while (offset >= 0)
+    {
+      *c++ = tab_[(*d >> offset) & mask];
+      offset -= sc.radix_storage_bits();
+    }
 
-  const detail::string_conversion_constants<mp_int> sc(radix);
-  const bool is_power_of_two = (radix & (radix - 1)) == 0;
+    const digit_type partial_value = (*d << -offset) & mask;
 
-  size_type total_bits = precision();
-  // round up to a multiple of sc.radix_storage_bits
-  if (total_bits % sc.radix_storage_bits)
-    total_bits = total_bits - total_bits % sc.radix_storage_bits
-               + sc.radix_storage_bits;
-  
-  size_type required;
-  if (is_power_of_two)
-    required = (total_bits + (sc.radix_storage_bits - 1))
-             / sc.radix_storage_bits;
-  // approximate log2(10) with 13/4
-  else if (total_bits < std::numeric_limits<size_type>::max() / 4)
-    required = (total_bits * 4 + 12) / 13;
-  else
-    required = total_bits / 13 * 4;
+    if (++d == x.rend())
+      break;
 
-  required += prefix_offset;
-  detail::scoped_ptr<char_type, typename StringT::allocator_type> sd(required);
+    offset += radix_bits;
+    *c++ = tab_[partial_value | (*d >> offset)];
+  }
+}
+
+template<class ApInt>
+template<typename OutputIter>
+void
+to_string_converter<ApInt>::
+convert_other_radix(const ApInt& x, const sc_type& sc, OutputIter& c) const
+{
+  ApInt tmp = abs(x);
+
+  while (tmp)
+  {
+    digit_type remainder = ops_type::divide_by_digit(tmp.digits(),
+                                                     tmp.digits(),
+                                                     tmp.size(),
+                                                     sc.max_power_value());
+    tmp.clamp_high_digit();
 
-  char_type* c = sd.ptr;
-  
-  for (int i = 0; i < prefix_offset; ++i)
-    *c++ = prefix[i];
-
-  if (is_power_of_two)
-  {
-    static const char* const lowercase_tab = "0123456789abcdef";
-    static const char* const uppercase_tab = "0123456789ABCDEF";
-
-    const char* const tab = (f & std::ios_base::uppercase)
-                          ? uppercase_tab
-                          : lowercase_tab;
-    
-    const digit_type mask = (digit_type(1) << sc.radix_storage_bits) - 1;
-
-    int offset = total_bits % valid_bits;
-    if (!offset)
-      offset = valid_bits;
-    
-    const_reverse_iterator d = rbegin();
-    for (;;)
+    for (digit_type i = 0; i < sc.max_exponent(); ++i)
     {
-      offset -= sc.radix_storage_bits;
-      while (offset >= 0)
-      {
-        *c++ = tab[(*d >> offset) & mask];
-        offset -= sc.radix_storage_bits;
-      }
-      const digit_type partial_value = (*d << -offset) & mask;
-      if (++d == rend())
-        break;
-      offset += valid_bits;
-      *c++ = tab[partial_value | (*d >> offset)];
+      if (remainder || tmp)
+        *c++ = static_cast<char>('0' + remainder % 10U);
+      remainder /= 10U;
     }
   }
+}
+
+template<class ApInt>
+template<typename OutputIter>
+void
+to_string_converter<ApInt>::convert(const ApInt& x,
+                                    std::ios_base::fmtflags f,
+                                    OutputIter c)
+{
+  if (x.is_uninitialized())
+    return;
+
+  write_sign_prefix(x, f, c);
+  write_radix_prefix(f, c);
+
+  if (!x)
+  {
+    if (!(f & std::ios_base::oct))
+      *c = '0';
+    return;
+  }
+
+  const sc_type sc(radix);
+
+  if (is_power_of_two(radix))
+    convert_pow2_radix(x, sc, c);
   else
   {
-    digit_type m = 2;
-    for (digit_type i = 100; i < sc.max_power_value; i *= 10)
-      ++m;
-    
-    mp_int tmp = abs(*this);
-    
-    while (tmp)
-    {
-      digit_type remainder = ops_type::divide_by_digit(tmp.digits(),
-                                                       tmp.digits(),
-                                                       tmp.size(),
-                                                       sc.max_power_value);
-      tmp.clamp_high_digit();
+    std::pair<char*, std::ptrdiff_t> buf =
+      std::get_temporary_buffer<char>(number_length_);
 
-      for (digit_type i = 0; i < m; ++i)
-      {
-        if (remainder || tmp)
-          *c++ = static_cast<char_type>('0' + remainder % 10U);
-        remainder /= 10U;
-      }
+    if (buf.first)
+    {
+      char* ptr = buf.first;
+      convert_other_radix(x, sc, ptr);
+
+      std::reverse_copy(buf.first, ptr, c);
+
+      std::return_temporary_buffer<char>(buf.first);
     }
-    std::reverse(sd.ptr + prefix_offset, c);
+    else
+      err = err_out_of_memory;
   }
+}
+
+template<class ApInt>
+template<class StringT>
+void
+to_string_converter<ApInt>::convert(StringT& s,
+                                    const ApInt& x,
+                                    std::ios_base::fmtflags f)
+{
+  check_fmtflags(f);
+
+  const sc_type sc(radix);
 
-  s.assign(sd.ptr, c);
+  estimate_number_length(x, sc);
+  s.reserve(total_length_);
 
-  return s;
+  convert(x, f, std::back_inserter(s));
 }
 
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/detail/string_conversion_constants.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/detail/string_conversion_constants.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,111 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_DETAIL_STRING_CONVERSION_CONSTANTS_HPP
-#define BOOST_MP_MATH_MP_INT_DETAIL_STRING_CONVERSION_CONSTANTS_HPP
-
-#include <boost/mp_math/mp_int/detail/meta_math.hpp>
-
-namespace boost {
-namespace mp_math {
-namespace detail {
-
-// radix 8, 10, 16
-
-
-template<
-  class MpInt,
-  typename MpInt::size_type Base,
-  typename MpInt::word_type Temp = 1,
-  typename MpInt::size_type Count = 0,
-  bool continue_loop = (Temp < MpInt::digit_max)
->
-struct max_power_impl
-{
-  typedef max_power_impl<MpInt, Base, Temp * Base, Count + 1> result;
-  static const typename MpInt::size_type  value     = result::value;
-  static const typename MpInt::digit_type max_value = result::max_value;
-};
-
-template<
-  class MpInt,
-  typename MpInt::size_type Base,
-  typename MpInt::word_type Temp,
-  typename MpInt::size_type Count
->
-struct max_power_impl<MpInt, Base, Temp, Count, false>
-{
-  static const typename MpInt::size_type  value     = Count - 1;
-  static const typename MpInt::digit_type max_value =
-    static_cast<typename MpInt::digit_type>(Temp / Base);
-};
-
-
-template<class MpInt, typename MpInt::size_type Base>
-struct max_power
-{
-  // convenience typedef ICEs on VC9 + SP1
-  //typedef max_power_impl<MpInt, Base> result;
-  static const typename MpInt::size_type  value     = max_power_impl<MpInt, Base>::value;
-  static const typename MpInt::digit_type max_value = max_power_impl<MpInt, Base>::max_value;
-};
-
-
-
-template<class MpInt, unsigned B>
-struct data
-{
-  typedef max_power<MpInt, B> x;
-  static const typename MpInt::size_type  max_power_          = x::value;
-  static const typename MpInt::digit_type max_power_value_    = x::max_value;
-  static const typename MpInt::size_type  radix_storage_bits_ =
-    binary_log<typename MpInt::size_type, B - 1>::value;
-};
-
-
-template<class MpInt>
-struct string_conversion_constants
-{
-  // maximum power of radix that fits into a digit_type
-  typename MpInt::size_type  max_power;
-  // the corresponding power value (=radix**max_power)
-  typename MpInt::digit_type max_power_value;
-  // how many bits do we need to store the value radix
-  typename MpInt::size_type  radix_storage_bits;
-
-  explicit string_conversion_constants(unsigned radix)
-  {
-    switch (radix)
-    {
-      case  8: *this = data<MpInt,  8>(); break;
-      case 10: *this = data<MpInt, 10>(); break;
-      case 16: *this = data<MpInt, 16>(); break;
-      default:
-        throw std::invalid_argument(
-            "mp_int<>::string_conversion_constants: unsupported radix used");
-    }
-  }
-
-  template<unsigned B>
-  string_conversion_constants& operator = (const data<MpInt, B>&)
-  {
-    max_power          = data<MpInt, B>::max_power_;
-    max_power_value    = data<MpInt, B>::max_power_value_;
-    radix_storage_bits = data<MpInt, B>::radix_storage_bits_;
-    return *this;
-  }
-};
-
-
-
-
-
-
-} // namespace detail
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Added: sandbox/mp_math/boost/mp_math/integer/detail/unbounded_int_integral.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/unbounded_int_integral.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,788 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_UNBOUNDED_INT_INTEGRAL_OPS_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_UNBOUNDED_INT_INTEGRAL_OPS_HPP
+
+#include <boost/mp_math/integer/detail/base/unbounded_int_integral.hpp>
+#include <boost/mp_math/integer/detail/unbounded_uint_integral.hpp>
+#include <boost/mp_math/integer/unbounded_uint.hpp>
+
+// Here we optimize interaction with built in integral types.
+// This code is even hairier and more subtle.
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+template<
+  class UnboundedInt,
+  typename IntegralT,
+  bool is_signed = std::numeric_limits<IntegralT>::is_signed
+>
+struct unbounded_int_integral_ops_impl;
+
+
+// 1)
+template<class UnboundedInt>
+struct unbounded_int_integral_ops_impl<
+  UnboundedInt,
+  typename UnboundedInt::digit_type,
+  false
+>
+{
+  typedef UnboundedInt                             unbounded_int_type;
+  typedef typename unbounded_int_type::digit_type  integral_type;
+  typedef typename unbounded_int_type::traits_type traits_type;
+
+  typedef base::unbounded_int_integral_ops<
+    unbounded_int_type, integral_type
+  >                                                base_type;
+
+  typedef unbounded_uint_integral_ops<
+    unbounded_int_type, integral_type
+  >                                                magnitude_type_integral_ops;
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(1);
+    base_type::assign(lhs, rhs);
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return base_type::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return base_type::less(lhs, rhs);
+  }
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(lhs.size() + 1);
+    base_type::add(lhs, rhs);
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(lhs.size() + 1);
+    base_type::subtract(lhs, rhs);
+  }
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs);
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y);
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_type::divide(lhs, rhs);
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_type::modulo(lhs, rhs);
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_type::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_type::bitwise_and(lhs, rhs);
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_type::bitwise_xor(lhs, rhs);
+  }
+};
+
+
+template<class UnboundedInt>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt, typename UnboundedInt::digit_type, false
+>::multiply(unbounded_int_type& lhs, integral_type rhs)
+{
+  if (rhs == 0)
+  {
+    assign(lhs, integral_type(0));
+    return;
+  }
+  else if (rhs == 1)
+    return;
+
+  lhs.reserve(lhs.size() + 1);
+
+  const integral_type carry =
+    traits_type::ops_type::multiply_by_digit(
+        lhs.digits(), lhs.digits(), lhs.size(), rhs);
+
+  if (carry)
+    lhs.push(carry);
+}
+
+template<class UnboundedInt>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt, typename UnboundedInt::digit_type, false
+>::multiply(unbounded_int_type& z,
+            const unbounded_int_type& x, integral_type y)
+{
+  if (y == 0)
+  {
+    assign(z, integral_type(0));
+    return;
+  }
+  else if (y == 1)
+  {
+    z = x;
+    return;
+  }
+
+  z.reserve(x.size() + 1);
+
+  const integral_type carry =
+    traits_type::ops_type::multiply_by_digit(
+        z.digits(), x.digits(), x.size(), y);
+
+  z.set_size(x.size());
+  z.set_sign_bit(x.sign_bit());
+
+  if (carry)
+    z.push(carry);
+}
+
+
+// 2)
+template<class UnboundedInt>
+struct unbounded_int_integral_ops_impl<
+  UnboundedInt,
+  typename make_signed<typename UnboundedInt::digit_type>::type,
+  true
+>
+{
+  typedef UnboundedInt                            unbounded_int_type;
+  typedef typename make_signed<
+    typename unbounded_int_type::digit_type
+  >::type                                         integral_type;
+
+  typedef typename unbounded_int_type::digit_type unsigned_integral_type;
+
+  typedef base::unbounded_int_integral_ops<
+    unbounded_int_type,
+    integral_type
+  >                                               base_integral_ops_type;
+
+  static bool get_sign_bit(integral_type x)
+  {
+    if (x >= 0)
+      return 0;
+    else
+      return 1;
+  }
+
+  static unsigned_integral_type get_absolute(integral_type x)
+  {
+    if (x >= 0)
+      return static_cast<unsigned_integral_type>(x);
+    else
+      return static_cast<unsigned_integral_type>(-x);
+  }
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(1);
+    base_integral_ops_type::assign(lhs, rhs);
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return base_integral_ops_type::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return base_integral_ops_type::less(lhs, rhs);
+  }
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (rhs >= 0)
+    {
+      lhs.reserve(lhs.size() + 1);
+      base::unbounded_int_integral_ops<
+        unbounded_int_type,
+        unsigned_integral_type
+      >::add(lhs, static_cast<unsigned_integral_type>(rhs));
+    }
+    else
+      base::unbounded_int_integral_ops<
+        unbounded_int_type,
+        unsigned_integral_type
+      >::subtract(lhs, static_cast<unsigned_integral_type>(-rhs));
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (rhs >= 0)
+      base_integral_ops_type::subtract(lhs, static_cast<unsigned_integral_type>(rhs));
+    else
+      base_integral_ops_type::add(lhs, static_cast<unsigned_integral_type>(-rhs));
+  }
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    unbounded_int_integral_ops_impl<
+      unbounded_int_type,
+      unsigned_integral_type
+    >::multiply(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(lhs.sign_bit() ^ get_sign_bit(rhs));
+  }
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y)
+  {
+    unbounded_int_integral_ops_impl<
+      unbounded_int_type,
+      unsigned_integral_type
+    >::multiply(z, x, get_absolute(y));
+    z.set_sign_bit(x.sign_bit() ^ get_sign_bit(y));
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_integral_ops_type::divide(lhs, rhs);
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_integral_ops_type::modulo(lhs, rhs);
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_integral_ops_type::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_integral_ops_type::bitwise_and(lhs, rhs);
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_integral_ops_type::bitwise_xor(lhs, rhs);
+  }
+};
+
+
+// 3
+template<class UnboundedInt, typename IntegralT>
+struct unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, false
+>
+{
+  typedef UnboundedInt                             unbounded_int_type;
+  typedef typename unbounded_int_type::traits_type traits_type;
+  typedef IntegralT                                integral_type;
+  typedef std::numeric_limits<integral_type>       integral_type_limits;
+
+  typedef base::unbounded_int_integral_ops<
+    unbounded_int_type, integral_type
+  >                                          base_unbounded_int_integral_ops_type;
+
+  typedef base::unbounded_uint_integral_ops<
+    unbounded_int_type, integral_type
+  >                                          magnitude_type_integral_ops;
+
+  static const unsigned radix_bits      = traits_type::radix_bits;
+  static const unsigned max_digit_value = traits_type::max_digit_value;
+
+  static const unsigned q =
+    (integral_type_limits::digits + (radix_bits - 1))
+    / radix_bits;
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(q);
+    magnitude_type_integral_ops::assign(lhs, rhs);
+    lhs.set_sign_bit(0);
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return base_unbounded_int_integral_ops_type::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return base_unbounded_int_integral_ops_type::less(lhs, rhs);
+  }
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(std::max(lhs.size(), q) + 1);
+    base_unbounded_int_integral_ops_type::add(lhs, rhs);
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs)
+  {
+    base_unbounded_int_integral_ops_type::subtract(lhs, rhs);
+  }
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(lhs.size() + q);
+    base_unbounded_int_integral_ops_type::multiply(lhs, rhs);
+  }
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y)
+  {
+    z.reserve(x.size() + q);
+    base_unbounded_int_integral_ops_type::multiply(z, x, y);
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs /= unbounded_int_type(rhs);
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs %= unbounded_int_type(rhs);
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(q);
+    base_unbounded_int_integral_ops_type::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(q);
+    base_unbounded_int_integral_ops_type::bitwise_and(lhs, rhs);
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(q);
+    base_unbounded_int_integral_ops_type::bitwise_xor(lhs, rhs);
+  }
+};
+
+
+template<class UnboundedInt, typename IntegralT>
+const unsigned unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, false>::q;
+
+
+// 4)
+template<class UnboundedInt, typename IntegralT>
+struct unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, true
+>
+{
+  typedef UnboundedInt                             unbounded_int_type;
+  typedef typename unbounded_int_type::traits_type traits_type;
+  typedef IntegralT                                integral_type;
+  typedef typename make_unsigned<
+    integral_type
+  >::type                                    unsigned_integral_type;
+
+  typedef base::unbounded_int<traits_type>   unbounded_int_base_type;
+
+  typedef unbounded_uint_integral_ops<
+    unbounded_int_type,
+    unsigned_integral_type
+  >                                          unbounded_uint_integral_ops_type;
+
+  typedef base::unbounded_int_integral_ops<
+    unbounded_int_type,
+    integral_type
+  >                                          base_unbounded_int_integral_ops_type;
+
+  typedef std::numeric_limits<integral_type> integral_type_limits;
+  static const unsigned radix_bits      = traits_type::radix_bits;
+  static const unsigned max_digit_value = traits_type::max_digit_value;
+
+  static const unsigned q =
+    (integral_type_limits::digits + (radix_bits - 1))
+    / radix_bits;
+
+  static bool get_sign_bit(integral_type x)
+  {
+    if (x >= 0)
+      return 0;
+    else
+      return 1;
+  }
+
+  static unsigned_integral_type get_absolute(integral_type x)
+  {
+    if (x >= 0)
+      return static_cast<unsigned_integral_type>(x);
+    else
+      return static_cast<unsigned_integral_type>(-x);
+  }
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    unbounded_uint_integral_ops_type::assign(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(get_sign_bit(rhs));
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return base::unbounded_int_integral_ops<
+      unbounded_int_type, integral_type>::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return base::unbounded_int_integral_ops<
+      unbounded_int_type, integral_type>::less(lhs, rhs);
+  }
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.sign_bit() == get_sign_bit(rhs))
+      unbounded_uint_integral_ops_type::add(lhs, get_absolute(rhs));
+    else
+      subtract_smaller(lhs, get_absolute(rhs), get_sign_bit(rhs));
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs)
+  {
+    if (lhs.sign_bit() != get_sign_bit(rhs))
+      unbounded_uint_integral_ops_type::add(lhs, get_absolute(rhs));
+    else
+      subtract_smaller(lhs, get_absolute(rhs), ~lhs.sign_bit());
+  }
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(lhs.size() + q);
+    base_unbounded_int_integral_ops_type::multiply(lhs, rhs);
+  }
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y)
+  {
+    z.reserve(x.size() + q);
+    base_unbounded_int_integral_ops_type::multiply(z, x, y);
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs /= unbounded_int_type(rhs);
+    //unbounded_uint_integral_ops_type::divide(lhs, get_absolute(rhs));
+    //lhs.set_sign_bit(lhs.sign_bit() ^ get_sign_bit(rhs));
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    lhs %= unbounded_int_type(rhs);
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    unbounded_int_integral_ops_impl<
+      UnboundedInt, unsigned_integral_type
+    >::bitwise_or(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(lhs.sign_bit() | get_sign_bit(rhs));
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    unbounded_int_integral_ops_impl<
+      UnboundedInt, unsigned_integral_type
+    >::bitwise_and(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(lhs.sign_bit() & get_sign_bit(rhs));
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    unbounded_int_integral_ops_impl<
+      UnboundedInt, unsigned_integral_type
+    >::bitwise_xor(lhs, get_absolute(rhs));
+    lhs.set_sign_bit(lhs.sign_bit() ^ get_sign_bit(rhs));
+  }
+
+  static void subtract_smaller(unbounded_int_type& lhs,
+                               unsigned_integral_type rhs,
+                               bool final_sign);
+};
+
+
+template<class UnboundedInt, typename IntegralT>
+const unsigned unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, true>::q;
+
+
+template<class UnboundedInt, typename IntegralT>
+void
+unbounded_int_integral_ops_impl<
+  UnboundedInt, IntegralT, true
+>::subtract_smaller(unbounded_int_type& lhs,
+                    unsigned_integral_type rhs,
+                    bool final_sign)
+{
+  static const unsigned radix_bits = traits_type::radix_bits;
+
+  static const unsigned q =
+    (std::numeric_limits<integral_type>::digits + (radix_bits - 1))
+    / radix_bits;
+
+  typedef base::unbounded_uint<traits_type> unbounded_uint_base_type;
+
+  typename traits_type::digit_type tmp_digits[q];
+
+  unbounded_uint_base_type tmp(tmp_digits, q, q);
+
+  base::from_integral_converter<
+    unbounded_uint_base_type, unsigned_integral_type
+  >::convert(tmp, rhs);
+
+  const unbounded_uint_base_type* x;
+  const unbounded_uint_base_type* y;
+
+  if (static_cast<const unbounded_uint_base_type&>(lhs) >= tmp)
+  {
+    x = &lhs;
+    y = &tmp;
+  }
+  else
+  {
+    x = &tmp;
+    y = &lhs;
+    lhs.reserve(tmp.size());
+    lhs.set_sign_bit(final_sign);
+  }
+
+  traits_type::ops_type::sub_smaller_magnitude(
+      lhs.digits(), x->digits(), x->size(),
+                    y->digits(), y->size());
+
+  lhs.set_size(x->size());
+  lhs.clamp();
+
+  if (!lhs)
+    lhs.set_sign_bit(0);
+}
+
+
+template<
+  class UnboundedInt,
+  typename IntegralT,
+  bool less_equal =
+      std::numeric_limits<IntegralT>::is_signed ?
+      (
+        std::numeric_limits<IntegralT>::digits <=
+        std::numeric_limits<
+          typename make_signed<
+            typename UnboundedInt::traits_type::digit_type
+          >::type
+        >::digits
+      ):
+      (
+        std::numeric_limits<IntegralT>::digits <=
+        std::numeric_limits<
+          typename UnboundedInt::traits_type::digit_type
+        >::digits
+      )
+>
+struct unbounded_int_integral_ops;
+
+
+// Dispatches integral types that fit into a digit_type by casting it to
+// digit_type or signed digit_type and using the specialization at the top.
+template<
+  class UnboundedInt,
+  typename IntegralT
+>
+struct unbounded_int_integral_ops<UnboundedInt,IntegralT,true>
+{
+  BOOST_STATIC_ASSERT(is_integral<IntegralT>::value);
+
+  typedef UnboundedInt                             unbounded_int_type;
+  typedef IntegralT                                integral_type;
+  typedef typename unbounded_int_type::traits_type traits_type;
+
+  typedef typename mpl::if_<
+    is_signed<IntegralT>,
+    unbounded_int_integral_ops_impl<
+      unbounded_int_type,
+      typename make_signed<
+        typename unbounded_int_type::digit_type
+      >::type
+    >,
+    unbounded_int_integral_ops_impl<
+      unbounded_int_type,
+      typename unbounded_int_type::digit_type
+    >
+  >::type                                          impl_type;
+
+  typedef typename impl_type::integral_type        to_integral_type;
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, static_cast<to_integral_type>(y));
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, static_cast<to_integral_type>(rhs));
+  }
+};
+
+
+template<
+  class UnboundedInt,
+  typename IntegralT
+>
+struct unbounded_int_integral_ops<UnboundedInt,IntegralT,false>
+{
+  BOOST_STATIC_ASSERT(is_integral<IntegralT>::value);
+
+  typedef UnboundedInt                             unbounded_int_type;
+  typedef IntegralT                                integral_type;
+  typedef typename unbounded_int_type::traits_type traits_type;
+
+  typedef unbounded_int_integral_ops_impl<
+      unbounded_int_type, integral_type
+  >                                                impl_type;
+
+  static void assign(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, rhs);
+  }
+
+  static bool equal(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_int_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, rhs);
+  }
+
+  static void add(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, rhs);
+  }
+
+  static void subtract(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, rhs);
+  }
+
+  static void multiply(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, rhs);
+  }
+
+  static void multiply(unbounded_int_type& z,
+                       const unbounded_int_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, y);
+  }
+
+  static void divide(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, rhs);
+  }
+
+  static void modulo(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, rhs);
+  }
+
+  static void bitwise_or(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, rhs);
+  }
+
+  static void bitwise_xor(unbounded_int_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, rhs);
+  }
+};
+
+
+
+
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/detail/unbounded_uint_integral.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/unbounded_uint_integral.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,657 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_DETAIL_UNBOUNDED_UINT_INTEGRAL_OPS_HPP
+#define BOOST_MP_MATH_INTEGER_DETAIL_UNBOUNDED_UINT_INTEGRAL_OPS_HPP
+
+#include <boost/mp_math/integer/detail/base/unbounded_uint_integral.hpp>
+
+// Here we optimize interaction with built in integral types.
+// This code is even hairier and more subtle.
+
+namespace boost {
+namespace mp_math {
+namespace detail {
+
+// Generally we will try to dispatch calls to unbounded_uint_integral_ops
+// possibly with a call to reserve() before that. If more optimization is
+// possible by calling reserve() only at certain points inside a function then
+// we reimplement the functionality of the corresponding
+// unbounded_uint_integral_ops function here. That means in any case the
+// functions closely correlate and improvements should be applied to both.
+
+template<
+  class UnboundedUint,
+  typename IntegralT,
+  bool is_signed = std::numeric_limits<IntegralT>::is_signed
+>
+struct unbounded_uint_integral_ops_impl;
+
+
+// 1)
+template<class UnboundedUint>
+struct unbounded_uint_integral_ops_impl<
+  UnboundedUint,
+  typename UnboundedUint::digit_type,
+  false
+>
+{
+  typedef UnboundedUint                             unbounded_uint_type;
+  typedef typename unbounded_uint_type::traits_type traits_type;
+  typedef typename unbounded_uint_type::digit_type  integral_type;
+
+  typedef base::unbounded_uint_integral_ops<
+    base::unbounded_uint<traits_type>,
+    integral_type
+  >                                                 base_type;
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(1);
+    base_type::assign(lhs, rhs);
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return base_type::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return base_type::less(lhs, rhs);
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(lhs.size() + 1);
+    base_type::add(lhs, rhs);
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    base_type::subtract(lhs, rhs);
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs);
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y);
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    base_type::divide(lhs, rhs);
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    base_type::modulo(lhs, rhs);
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    base_type::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    base_type::bitwise_and(lhs, rhs);
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    base_type::bitwise_xor(lhs, rhs);
+  }
+};
+
+
+template<class UnboundedUint>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUint, typename UnboundedUint::digit_type, false
+>::multiply(unbounded_uint_type& lhs, integral_type rhs)
+{
+  if (rhs == 0)
+  {
+    assign(lhs, integral_type(0));
+    return;
+  }
+  else if (rhs == 1)
+    return;
+
+  lhs.reserve(lhs.size() + 1);
+
+  const integral_type carry =
+    traits_type::ops_type::multiply_by_digit(
+        lhs.digits(), lhs.digits(), lhs.size(), rhs);
+
+  if (carry)
+    lhs.push(carry);
+}
+
+template<class UnboundedUint>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUint, typename UnboundedUint::digit_type, false
+>::multiply(unbounded_uint_type& z,
+            const unbounded_uint_type& x, integral_type y)
+{
+  if (y == 0)
+  {
+    assign(z, integral_type(0));
+    return;
+  }
+  else if (y == 1)
+  {
+    z = x;
+    return;
+  }
+
+  z.reserve(x.size() + 1);
+
+  const integral_type carry =
+    traits_type::ops_type::multiply_by_digit(
+        z.digits(), x.digits(), x.size(), y);
+
+  z.set_size(x.size());
+
+  if (carry)
+    z.push(carry);
+}
+
+
+// 2)
+// just casts to digit_type and dispatches to above specialization
+template<class UnboundedUint>
+struct unbounded_uint_integral_ops_impl<
+  UnboundedUint,
+  typename make_signed<typename UnboundedUint::digit_type>::type,
+  true
+>
+{
+  typedef UnboundedUint                             unbounded_uint_type;
+  typedef typename unbounded_uint_type::traits_type traits_type;
+  typedef typename make_signed<
+    typename unbounded_uint_type::digit_type
+  >::type                                            integral_type;
+
+  typedef typename unbounded_uint_type::digit_type   unsigned_integral_type;
+  typedef unbounded_uint_integral_ops_impl<
+    unbounded_uint_type,
+    unsigned_integral_type
+  >                                                  impl_type;
+
+  static unsigned_integral_type get_absolute(integral_type x)
+  {
+    if (x >= 0)
+      return static_cast<unsigned_integral_type>(x);
+    else
+      return static_cast<unsigned_integral_type>(-x);
+  }
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, get_absolute(rhs));
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, get_absolute(rhs));
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, get_absolute(rhs));
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, get_absolute(rhs));
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, get_absolute(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, get_absolute(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, get_absolute(y));
+  }
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, get_absolute(rhs));
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, get_absolute(rhs));
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, get_absolute(rhs));
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, get_absolute(rhs));
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, get_absolute(rhs));
+  }
+};
+
+
+// 3
+template<class UnboundedUint, typename IntegralT>
+struct unbounded_uint_integral_ops_impl<
+  UnboundedUint, IntegralT, false
+>
+{
+  typedef UnboundedUint                             unbounded_uint_type;
+  typedef typename unbounded_uint_type::traits_type traits_type;
+  typedef IntegralT                                 integral_type;
+  typedef std::numeric_limits<integral_type>        integral_type_limits;
+
+  typedef base::unbounded_uint_integral_ops_impl<
+    base::unbounded_uint<traits_type>,
+    integral_type
+  >                                                 impl_type;
+
+  static const unsigned radix_bits      = traits_type::radix_bits;
+  static const unsigned max_digit_value = traits_type::max_digit_value;
+
+  static const unsigned q =
+    (integral_type_limits::digits + (radix_bits - 1))
+    / radix_bits;
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs);
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, rhs);
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(std::max(lhs.size(), q) + 1);
+    impl_type::add(lhs, rhs);
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, rhs);
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(lhs.size() + q);
+    impl_type::multiply(lhs, rhs);
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y)
+  {
+    z.reserve(x.size() + q);
+    impl_type::multiply(z, x, y);
+  }
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs /= unbounded_uint_type(rhs);
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs %= unbounded_uint_type(rhs);
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(q);
+    impl_type::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(q);
+    impl_type::bitwise_and(lhs, rhs);
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    lhs.reserve(q);
+    impl_type::bitwise_xor(lhs, rhs);
+  }
+};
+
+
+template<class UnboundedUint, typename IntegralT>
+const unsigned unbounded_uint_integral_ops_impl<
+  UnboundedUint, IntegralT, false>::q;
+
+
+template<class UnboundedUint, typename IntegralT>
+void
+unbounded_uint_integral_ops_impl<
+  UnboundedUint, IntegralT, false>::assign(unbounded_uint_type& lhs,
+                                           integral_type rhs)
+{
+  if (rhs <= max_digit_value)
+  {
+    lhs.reserve(1);
+    lhs[0] = static_cast<typename traits_type::digit_type>(rhs);
+    lhs.set_size(1);
+  }
+  else
+  {
+    lhs.reserve(q);
+
+    base::from_integral_converter<
+      unbounded_uint_type, integral_type
+    >::convert(lhs, rhs);
+  }
+}
+
+
+// 4)
+template<class UnboundedUint, typename IntegralT>
+struct unbounded_uint_integral_ops_impl<
+  UnboundedUint, IntegralT, true
+>
+{
+  typedef UnboundedUint                               unbounded_uint_type;
+  typedef IntegralT                                   integral_type;
+  typedef typename make_unsigned<integral_type>::type unsigned_integral_type;
+  // this is spec 3
+  typedef unbounded_uint_integral_ops_impl<
+    unbounded_uint_type,
+    unsigned_integral_type
+  > impl_type;
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, static_cast<unsigned_integral_type>(y));
+  }
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, static_cast<unsigned_integral_type>(rhs));
+  }
+};
+
+
+
+
+template<
+  class UnboundedUint,
+  typename IntegralT,
+  bool less_equal =
+      std::numeric_limits<IntegralT>::is_signed ?
+      (
+        std::numeric_limits<IntegralT>::digits <=
+        std::numeric_limits<
+          typename make_signed<
+            typename UnboundedUint::traits_type::digit_type
+          >::type
+        >::digits
+      ):
+      (
+        std::numeric_limits<IntegralT>::digits <=
+        std::numeric_limits<
+          typename UnboundedUint::traits_type::digit_type
+        >::digits
+      )
+>
+struct unbounded_uint_integral_ops
+{};
+
+
+// Dispatches integral types that fit into a digit_type by casting it to
+// digit_type or signed digit_type and calling the specializations 1) and 2).
+template<
+  class UnboundedUint,
+  typename IntegralT
+>
+struct unbounded_uint_integral_ops<UnboundedUint,IntegralT,true>
+{
+  BOOST_STATIC_ASSERT(is_integral<IntegralT>::value);
+
+  typedef UnboundedUint                             unbounded_uint_type;
+  typedef IntegralT                                 integral_type;
+  typedef typename unbounded_uint_type::traits_type traits_type;
+
+  typedef typename mpl::if_<
+    is_signed<IntegralT>,
+    unbounded_uint_integral_ops_impl<
+      unbounded_uint_type,
+      typename make_signed<
+        typename unbounded_uint_type::digit_type
+      >::type
+    >,
+    unbounded_uint_integral_ops_impl<
+      unbounded_uint_type,
+      typename unbounded_uint_type::digit_type
+    >
+  >::type                                           impl_type;
+
+  typedef typename impl_type::integral_type  to_integral_type;
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, static_cast<to_integral_type>(y));
+  }
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, static_cast<to_integral_type>(rhs));
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, static_cast<to_integral_type>(rhs));
+  }
+};
+
+
+template<
+  class UnboundedUint,
+  typename IntegralT
+>
+struct unbounded_uint_integral_ops<UnboundedUint,IntegralT,false>
+{
+  BOOST_STATIC_ASSERT(is_integral<IntegralT>::value);
+
+  typedef UnboundedUint                             unbounded_uint_type;
+  typedef IntegralT                                 integral_type;
+
+  typedef unbounded_uint_integral_ops_impl<
+      unbounded_uint_type, IntegralT
+  >                                                 impl_type;
+
+  static void assign(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::assign(lhs, rhs);
+  }
+
+  static bool equal(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::equal(lhs, rhs);
+  }
+
+  static bool less(const unbounded_uint_type& lhs, integral_type rhs)
+  {
+    return impl_type::less(lhs, rhs);
+  }
+
+  static void add(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::add(lhs, rhs);
+  }
+
+  static void subtract(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::subtract(lhs, rhs);
+  }
+
+  static void multiply(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::multiply(lhs, rhs);
+  }
+
+  static void multiply(unbounded_uint_type& z,
+                       const unbounded_uint_type& x, integral_type y)
+  {
+    impl_type::multiply(z, x, y);
+  }
+
+  static void divide(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::divide(lhs, rhs);
+  }
+
+  static void modulo(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::modulo(lhs, rhs);
+  }
+
+  static void bitwise_or(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_or(lhs, rhs);
+  }
+
+  static void bitwise_and(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_and(lhs, rhs);
+  }
+
+  static void bitwise_xor(unbounded_uint_type& lhs, integral_type rhs)
+  {
+    impl_type::bitwise_xor(lhs, rhs);
+  }
+};
+
+
+
+
+
+
+} // namespace detail
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/div.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/div.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,149 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-template<class A, class T>
-typename mp_int<A,T>::digit_type
-mp_int<A,T>::divide_by_digit(digit_type b)
-{
-  if (b == 0)
-    throw std::domain_error("mp_int::divide_by_digit: division by zero");
-
-  if (b == 1 || !*this)
-    return 0;
-
-  const bool is_power_of_two = (b & (b-1)) == 0;
-
-  if (!is_power_of_two)
-  {
-    const digit_type remainder =
-      ops_type::divide_by_digit(digits(), digits(), size(), b);
-
-    clamp_high_digit();
-
-    if (!*this)
-      set_sign(1);
-
-    return remainder;
-  }
-
-  int i = 0;
-  while ((i < valid_bits) && (b != digit_type(1) << i))
-    ++i;
-
-  const digit_type remainder = digits_[0] & ((digit_type(1) << i) - 1);
-  *this >>= i;
-  return remainder;
-}
-
-// *this /= 2
-template<class A, class T>
-void mp_int<A,T>::divide_by_2()
-{
-  ops_type::divide_by_two(digits(), digits(), size());
-
-  clamp_high_digit();
-
-  if (!*this)
-    set_sign(1);
-}
-
-// divide by three (based on routine from MPI and the GMP manual)
-template<class A, class T>
-typename mp_int<A,T>::digit_type
-mp_int<A,T>::divide_by_3()
-{
-  // b = 2**valid_bits / 3
-  const word_type b = (word_type(1) << static_cast<word_type>(valid_bits))
-                    / word_type(3);
-
-  word_type w = 0;
-  for (reverse_iterator d = rbegin(); d != rend(); ++d)
-  {
-    w = (w << static_cast<word_type>(valid_bits)) | static_cast<word_type>(*d);
-    
-    word_type t;
-    if (w >= 3)
-    {
-      // multiply w by [1/3]
-      t = (w * b) >> static_cast<word_type>(valid_bits);
-
-      // now subtract 3 * [w/3] from w, to get the remainder
-      w -= t+t+t;
-
-      // fixup the remainder as required since the optimization is not exact.
-      while (w >= 3)
-      {
-        t += 1;
-        w -= 3;
-      }
-    }
-    else
-      t = 0;
-
-    *d = static_cast<digit_type>(t);
-  }  
-
-  // *this is now the quotient
-  // return remainder
-  return static_cast<digit_type>(w);
-}
-
-// shift right by a certain bit count
-template<class A, class T>
-void mp_int<A,T>::shift_right(size_type b, mp_int* remainder)
-{
-  if (b == 0)
-  {
-    if (remainder)
-      remainder->zero();
-    return;
-  }
-
-  // get the remainder
-  mp_int t;
-  if (remainder)
-  {
-    *remainder = *this;
-    remainder->modulo_2_to_the_power_of(b);
-  }
-
-  // shift by as many digits in the bit count
-  if (b >= static_cast<size_type>(valid_bits))
-    shift_digits_right(b / valid_bits);
-
-  // shift any bit count < valid_bits
-  const digit_type D = b % valid_bits;
-  if (D)
-  {
-    const digit_type mask = (digit_type(1) << D) - 1;
-
-    // shift for lsb
-    const digit_type shift = valid_bits - D;
-
-    digit_type carry = 0;
-    for (reverse_iterator d = rbegin(); d != rend(); ++d)
-    {
-      // get the lower bits of this word in a temp
-      const digit_type rr = *d & mask;
-
-      // shift the current word and mix in the carry bits from the previous word
-      *d = (*d >> D) | (carry << shift);
-
-      // set the carry to the carry bits of the current word found above
-      carry = rr;
-    }
-  }
-
-  clamp();
-
-  if (!*this)
-    set_sign(1);
-}
-
-template<class A, class T>
-void divide(const mp_int<A,T>& x, const mp_int<A,T>& y, mp_int<A,T>& q, mp_int<A,T>& r)
-{
-  detail::classic_divide(x, y, q, &r);
-}
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/gcd.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/gcd.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,70 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_GCD_HPP
-#define BOOST_MP_MATH_MP_INT_GCD_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-
-
-namespace boost {
-namespace mp_math {
-
-// Greatest Common Divisor using the binary method
-template<class A, class T>
-mp_int<A,T> gcd(const mp_int<A,T>& a, const mp_int<A,T>& b)
-{
-  // either zero then gcd is the largest
-  if (!a)
-    return abs(b);
-  if (!b)
-    return abs(a);
-
-  // get copies of a and b we can modify
-  mp_int<A,T> u = abs(a);
-  mp_int<A,T> v = abs(b);
-
-  typedef typename mp_int<A,T>::size_type size_type;
-
-  // Find the common power of two for u and v
-  const size_type u_lsb = u.count_lsb();
-  const size_type v_lsb = v.count_lsb();
-  const size_type     k = std::min(u_lsb, v_lsb);
-
-  // divide out powers of two
-  u >>= u_lsb;
-  v >>= v_lsb;
-
-  while (v)
-  {
-    if (u > v)
-      u.swap(v);
-     
-    v.sub_smaller_magnitude(u);
-
-    // Divide out all factors of two
-    v >>= v.count_lsb();
-  } 
-
-  // multiply by 2**k which we divided out at the beginning
-  u <<= k;
-
-  return u;
-}
-
-#ifdef BOOST_HAS_VARIADIC_TMPL
-template<class A, class T, class... MpInts>
-mp_int<A,T> gcd(const mp_int<A,T>& a, const mp_int<A,T>& b, const MpInts&... args)
-{
-  return gcd(gcd(a, b), args...);
-}
-#endif
-
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Added: sandbox/mp_math/boost/mp_math/integer/gmp_integer.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/gmp_integer.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,1449 @@
+// Copyright Kevin Sopp 2009.
+// 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_MP_MATH_INTEGER_GMP_INTEGER_HPP
+#define BOOST_MP_MATH_INTEGER_GMP_INTEGER_HPP
+
+#include <gmp.h>
+#include <boost/config.hpp>
+#include <boost/mp_math/integer/contexts.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <cstring> // strlen
+#include <iostream>
+#include <limits>
+#include <stdexcept>
+
+namespace boost {
+namespace mp_math {
+
+struct boost_behavior
+{
+  static void bitwise_or(mpz_ptr z, mpz_srcptr x, mpz_srcptr y);
+  static void bitwise_and(mpz_ptr z, mpz_srcptr x, mpz_srcptr y);
+  static void bitwise_xor(mpz_ptr z, mpz_srcptr x, mpz_srcptr y);
+};
+
+
+struct gmp_behavior
+{
+  static void bitwise_or(mpz_ptr z, mpz_srcptr x, mpz_srcptr y)
+  {
+    mpz_ior(z, x, y);
+  }
+
+  static void bitwise_and(mpz_ptr z, mpz_srcptr x, mpz_srcptr y)
+  {
+    mpz_and(z, x, y);
+  }
+
+  static void bitwise_xor(mpz_ptr z, mpz_srcptr x, mpz_srcptr y)
+  {
+    mpz_xor(z, x, y);
+  }
+};
+
+
+template<class Behavior = gmp_behavior>
+class gmp_integer;
+
+
+namespace detail {
+
+template<
+  class B,
+  typename IntegralT,
+  bool IsSigned = std::numeric_limits<IntegralT>::is_signed,
+  bool FitsIntoLongInt =
+    IsSigned ? (std::numeric_limits<IntegralT>::digits <=
+                std::numeric_limits<signed long int>::digits)
+             : (std::numeric_limits<IntegralT>::digits <=
+                std::numeric_limits<unsigned long int>::digits)
+>
+struct gmp_integer_integral_ops;
+
+
+template<
+  class B,
+  typename IntegralT
+>
+struct gmp_integer_integral_ops<gmp_integer<B>, IntegralT, false, true>
+{
+  typedef gmp_integer<B> gmp_integer_type;
+  typedef IntegralT      integral_type;
+
+  static void init(gmp_integer_type& z, integral_type x)
+  {
+    mpz_init_set_ui(z.get_mpz_t(), x);
+  }
+
+  static void assign(gmp_integer_type& z, integral_type x)
+  {
+    mpz_set_ui(z.get_mpz_t(), x);
+  }
+
+  static bool equal(const gmp_integer_type& z, integral_type x)
+  {
+    return mpz_cmp_ui(z.get_mpz_t(), x) == 0;
+  }
+
+  static bool less(const gmp_integer_type& z, integral_type x)
+  {
+    return mpz_cmp_ui(z.get_mpz_t(), x) < 0;
+  }
+
+  static void add(gmp_integer_type& z, integral_type x)
+  {
+    mpz_add_ui(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void subtract(gmp_integer_type& z, integral_type x)
+  {
+    mpz_sub_ui(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void multiply(gmp_integer_type& z, integral_type x)
+  {
+    mpz_mul_ui(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void divide(gmp_integer_type& z, integral_type x)
+  {
+    mpz_tdiv_q_ui(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void modulo(gmp_integer_type& z, integral_type x)
+  {
+    mpz_mod_ui(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void bitwise_or(gmp_integer_type& z, integral_type x);
+  static void bitwise_and(gmp_integer_type& z, integral_type x);
+  static void bitwise_xor(gmp_integer_type& z, integral_type x);
+};
+
+
+template<
+  class B,
+  typename IntegralT
+>
+struct gmp_integer_integral_ops<gmp_integer<B>, IntegralT, true, true>
+{
+  typedef gmp_integer<B> gmp_integer_type;
+  typedef IntegralT      integral_type;
+
+  static void init(gmp_integer_type& z, integral_type x)
+  {
+    mpz_init_set_si(z.get_mpz_t(), x);
+  }
+
+  static void assign(gmp_integer_type& z, integral_type x)
+  {
+    mpz_set_si(z.get_mpz_t(), x);
+  }
+
+  static bool equal(const gmp_integer_type& z, integral_type x)
+  {
+    return mpz_cmp_si(z.get_mpz_t(), x) == 0;
+  }
+
+  static bool less(const gmp_integer_type& z, integral_type x)
+  {
+    return mpz_cmp_si(z.get_mpz_t(), x) < 0;
+  }
+
+  static void add(gmp_integer_type& z, integral_type x)
+  {
+    mpz_add_ui(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void subtract(gmp_integer_type& z, integral_type x)
+  {
+    mpz_sub_ui(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void multiply(gmp_integer_type& z, integral_type x)
+  {
+    mpz_mul_si(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void divide(gmp_integer_type& z, integral_type x)
+  {
+    mpz_tdiv_q_ui(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void modulo(gmp_integer_type& z, integral_type x)
+  {
+    mpz_mod_ui(z.get_mpz_t(), z.get_mpz_t(), x);
+  }
+
+  static void bitwise_or(gmp_integer_type& z, integral_type x);
+  static void bitwise_and(gmp_integer_type& z, integral_type x);
+  static void bitwise_xor(gmp_integer_type& z, integral_type x);
+};
+
+
+template<
+  class B,
+  typename IntegralT,
+  bool IsSigned = std::numeric_limits<IntegralT>::is_signed,
+  bool FitsIntoLongInt =
+    IsSigned ? (std::numeric_limits<IntegralT>::digits <=
+                std::numeric_limits<signed long int>::digits)
+             : (std::numeric_limits<IntegralT>::digits <=
+                std::numeric_limits<unsigned long int>::digits)
+>
+struct gmp_integer_to_integral;
+
+
+template<class B, typename IntegralT>
+struct gmp_integer_to_integral<B, IntegralT, false, true>
+{
+  static IntegralT convert(const gmp_integer<B>& x)
+  {
+    return static_cast<IntegralT>(mpz_get_ui(x.get_mpz_t()));
+  }
+};
+
+
+template<class B, typename IntegralT>
+struct gmp_integer_to_integral<B, IntegralT, true, true>
+{
+  static IntegralT convert(const gmp_integer<B>& x)
+  {
+    return static_cast<IntegralT>(mpz_get_si(x.get_mpz_t()));
+  }
+};
+
+
+
+struct gmp_integer_traits
+{
+  typedef mp_limb_t   digit_type;
+  typedef std::size_t size_type;
+
+  static const size_type  digit_bits      = GMP_LIMB_BITS;
+  static const size_type  radix_bits      = GMP_NUMB_BITS;
+  static const digit_type max_digit_value = GMP_NUMB_MAX;
+};
+
+
+// Same as gmp_allocated_string in gmp-impl.h, but we can't use it because
+// gmp-impl.h is an internal GMP header and is probably not installed.
+extern "C"
+{
+  typedef void (*gmp_free_func)(void *, size_t);
+}
+
+struct gmp_allocated_string
+{
+  char*             str;
+  const std::size_t len;
+
+  gmp_allocated_string(char *s)
+  :
+    str(s), len(std::strlen(s) + 1)
+  {}
+
+  ~gmp_allocated_string()
+  {
+    gmp_free_func f;
+    mp_get_memory_functions (0, 0, &f);
+    (*f)(str, len);
+  }
+};
+
+
+
+} // namespace detail
+
+
+// gmp_original or gmp_boost
+// differences: bitwise ops
+template<class Behavior>
+class gmp_integer
+{
+  mpz_t val_;
+
+public:
+
+  static const bool is_signed = true;
+  static const bool is_bounded = false;
+
+  typedef Behavior behavior_type;
+
+  template<typename IntegralT>
+  struct integral_ops
+  :
+    detail::gmp_integer_integral_ops<gmp_integer<Behavior>, IntegralT>
+  {};
+
+  typedef detail::gmp_integer_traits traits_type;
+
+  typedef traits_type::digit_type digit_type;
+  typedef traits_type::size_type  size_type;
+
+  typedef digit_type*                           iterator;
+  typedef const digit_type*                     const_iterator;
+  typedef std::reverse_iterator<iterator>       reverse_iterator;
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+  gmp_integer()
+  {
+    mpz_init(val_);
+  }
+
+  template<typename IntegralT>
+  gmp_integer(IntegralT x,
+              typename enable_if<is_integral<IntegralT> >::type* dummy = 0)
+  {
+    integral_ops<IntegralT>::init(*this, x);
+  }
+
+  gmp_integer(const mpz_t& x)
+  {
+    mpz_init_set(val_, x);
+  }
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  gmp_integer(mpz_t&& x)
+  :
+    val_(x)
+  {}
+  #endif
+
+  explicit gmp_integer(const char* s);
+  explicit gmp_integer(const std::string& s);
+
+  gmp_integer(const char* s,        std::ios_base::fmtflags);
+  gmp_integer(const std::string& s, std::ios_base::fmtflags);
+
+  gmp_integer(const gmp_integer& copy)
+  {
+    mpz_init_set(val_, copy.val_);
+  }
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  gmp_integer(gmp_integer&& copy)
+  {
+    val_->_mp_alloc = copy.val_->_mp_alloc;
+    val_->_mp_size  = copy.val_->_mp_size;
+    val_->_mp_d     = copy.val_->_mp_d;
+    copy.val_->_mp_alloc = 0;
+    copy.val_->_mp_size  = 0;
+    copy.val_->_mp_d     = 0;
+  }
+  #endif
+
+  ~gmp_integer()
+  {
+    mpz_clear(val_);
+  }
+
+  gmp_integer& operator = (const gmp_integer& rhs)
+  {
+    mpz_set(val_, rhs.val_);
+    return *this;
+  }
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  gmp_integer& operator = (gmp_integer&& rhs)
+  {
+    mpz_clear(val_);
+    swap(rhs);
+    return *this;
+  }
+  #endif
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, gmp_integer&>::type
+  operator = (IntegralT x)
+  {
+    integral_ops<IntegralT>::assign(*this, x);
+    return *this;
+  }
+
+  template<typename charT>
+  gmp_integer& operator = (const charT* s)
+  {
+    if (mpz_set_str(val_, s, 0) == 0)
+      return *this;
+    else
+      throw std::invalid_argument(
+          "boost::mp_math::gmp_integer: operator = (const charT*)");
+  }
+
+  template<typename charT, class traits, class alloc>
+  gmp_integer& operator = (const std::basic_string<charT,traits,alloc>& s)
+  {
+    if (mpz_set_str(val_, s.c_str(), 0) == 0)
+      return *this;
+    else
+      throw std::invalid_argument(
+          "boost::mp_math::gmp_integer: operator = (const charT*)");
+  }
+
+  template<typename charT>
+  void assign(const charT* s, std::ios_base::fmtflags f)
+  {
+    unsigned radix;
+    if (f & std::ios_base::hex)
+      radix = 16;
+    else if (f & std::ios_base::oct)
+      radix = 8;
+    else
+      radix = 10;
+    if (mpz_set_str(val_, s, radix) == -1)
+      throw std::invalid_argument(
+          "boost::mp_math::gmp_integer::assign: illformatted string)");
+  }
+
+  // TODO dispatch std::string to mpz_set_string, but dispatch other string
+  // types to detail/string_converter? Could do that but would need support for
+  // NAIL bits.
+  template<typename charT, class traits, class alloc>
+  void assign(const std::basic_string<charT,traits,alloc>& s,
+              std::ios_base::fmtflags f)
+  {
+    unsigned radix;
+    if (f & std::ios_base::hex)
+      radix = 16;
+    else if (f & std::ios_base::oct)
+      radix = 8;
+    else
+      radix = 10;
+    if (mpz_set_str(val_, s.c_str(), radix) == -1)
+      throw std::invalid_argument(
+          "boost::mp_math::gmp_integer::assign: illformatted string)");
+  }
+
+
+  template<typename RandomAccessIterator>
+  void assign(RandomAccessIterator first, RandomAccessIterator last,
+              std::ios_base::fmtflags);
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  void swap(gmp_integer&& other)
+  #else
+  void swap(gmp_integer& other)
+  #endif
+  {
+    mpz_swap(val_, other.val_);
+  }
+
+#ifdef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
+private:
+
+  typedef mpz_t gmp_integer::*unspecified_bool_type;
+
+public:
+
+  operator unspecified_bool_type() const
+  {
+	  return mpz_sgn(val_) ? &gmp_integer::val_ : 0;
+  }
+#else
+  explicit operator bool() const { return static_cast<bool>(mpz_sgn(val_)); }
+#endif
+
+  bool is_even() const { return mpz_even_p(val_); }
+  bool is_odd () const { return mpz_odd_p(val_); }
+
+  bool is_positive() const { return mpz_sgn(val_) >= 0; }
+  bool is_negative() const { return mpz_sgn(val_) < 0; }
+
+  // These two functions use the same signature as GMP's mpz_class
+  mpz_ptr    get_mpz_t()       { return val_; }
+  mpz_srcptr get_mpz_t() const { return val_; }
+
+  size_type size() const { return mpz_size(val_); }
+
+  digit_type*       digits()       { return val_->_mp_d; }
+  const digit_type* digits() const { return val_->_mp_d; }
+
+  iterator begin() { return digits(); }
+  iterator end  () { return digits(); }
+  const_iterator begin() const { return digits(); }
+  const_iterator end  () const { return digits() + size(); }
+  const_iterator cbegin() const { return digits(); }
+  const_iterator cend  () const { return digits() + size(); }
+  reverse_iterator rbegin() { return reverse_iterator(end  ()); }
+  reverse_iterator rend  () { return reverse_iterator(begin()); }
+  const_reverse_iterator rbegin() const { return const_reverse_iterator(end  ()); }
+  const_reverse_iterator rend  () const { return const_reverse_iterator(begin()); }
+  const_reverse_iterator crbegin() const { return const_reverse_iterator(end  ()); }
+  const_reverse_iterator crend  () const { return const_reverse_iterator(begin()); }
+
+  digit_type&       operator [] (size_type i)       { return val_->_mp_d[i]; }
+  const digit_type& operator [] (size_type i) const { return val_->_mp_d[i]; }
+
+  gmp_integer& operator ++() { mpz_add_ui(val_, val_, 1); return *this; }
+  gmp_integer& operator --() { mpz_sub_ui(val_, val_, 1); return *this; }
+
+  gmp_integer operator ++(int)
+  {
+    gmp_integer tmp;
+    mpz_add_ui(tmp.val_, val_, 1);
+    return tmp;
+  }
+
+  gmp_integer operator --(int)
+  {
+    gmp_integer tmp;
+    mpz_sub_ui(tmp.val_, val_, 1);
+    return tmp;
+  }
+
+  gmp_integer& operator <<= (size_type n)
+  {
+    mpz_mul_2exp(val_, val_, n);
+    return *this;
+  }
+
+  gmp_integer& operator >>= (size_type n)
+  {
+    mpz_tdiv_q_2exp(val_, val_, n);
+    return *this;
+  }
+
+  gmp_integer& operator - () { mpz_neg(val_, val_); return *this; }
+
+  gmp_integer& operator ~ () { mpz_cmp(val_, val_); return *this; }
+
+  gmp_integer& operator += (const gmp_integer& rhs)
+  {
+    mpz_add(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  gmp_integer& operator -= (const gmp_integer& rhs)
+  {
+    mpz_sub(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  gmp_integer& operator *= (const gmp_integer& rhs)
+  {
+    mpz_mul(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  gmp_integer& operator /= (const gmp_integer& rhs)
+  {
+    mpz_tdiv_q(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  gmp_integer& operator %= (const gmp_integer& rhs)
+  {
+    mpz_tdiv_r(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  gmp_integer& operator |= (const gmp_integer& rhs)
+  {
+    behavior_type::bitwise_or(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  gmp_integer& operator &= (const gmp_integer& rhs)
+  {
+    behavior_type::bitwise_and(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  gmp_integer& operator ^= (const gmp_integer& rhs)
+  {
+    behavior_type::bitwise_xor(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, gmp_integer&>::type
+  operator += (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, gmp_integer&>::type
+  operator -= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, gmp_integer&>::type
+  operator *= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, gmp_integer&>::type
+  operator /= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, gmp_integer&>::type
+  operator %= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, gmp_integer&>::type
+  operator |= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, gmp_integer&>::type
+  operator &= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, gmp_integer&>::type
+  operator ^= (IntegralT);
+
+  template<typename IntegralT>
+  IntegralT to_integral() const
+  {
+    return detail::gmp_integer_to_integral<behavior_type, IntegralT>::
+      convert(*this);
+  }
+
+  template<class StringT>
+  StringT to_string(std::ios_base::fmtflags f =  std::ios_base::fmtflags()) const
+  {
+    int radix;
+    if (f & std::ios_base::hex)
+      radix = 16;
+    else if (f & std::ios_base::oct)
+      radix = 8;
+    else
+      radix = 10;
+
+    const detail::gmp_allocated_string tmp(mpz_get_str(0, radix, val_));
+    return StringT(tmp.str, tmp.str + tmp.len - 1);
+  }
+};
+
+
+template<class B>
+gmp_integer<B>::gmp_integer(const char* s)
+{
+  if (*s != '\0')
+  {
+    if (mpz_init_set_str(val_, s, 0))
+    {
+      if (val_->_mp_d)
+        mpz_clear(val_);
+      throw std::invalid_argument(
+          "boost::mp_math::gmp_integer::gmp_integer(const char*)");
+    }
+  }
+  else
+    mpz_init(val_);
+}
+
+template<class B>
+gmp_integer<B>::gmp_integer(const char* s, std::ios_base::fmtflags f)
+{
+  unsigned radix;
+  if (f & std::ios_base::hex)
+    radix = 16;
+  else if (f & std::ios_base::oct)
+    radix = 8;
+  else
+    radix = 10;
+
+  if (*s != '\0')
+  {
+    if (mpz_init_set_str(val_, s, radix))
+    {
+      if (val_->_mp_d)
+        mpz_clear(val_);
+      throw std::invalid_argument(
+          "boost::mp_math::gmp_integer::"
+          "gmp_integer(const char*, std::ios_base::fmtflags)");
+    }
+  }
+  else
+    mpz_init(val_);
+}
+
+template<class B>
+gmp_integer<B>::gmp_integer(const std::string& s)
+{
+  if (!s.empty())
+  {
+    if (mpz_init_set_str(val_, s.c_str(), 0))
+    {
+      if (val_->_mp_d)
+        mpz_clear(val_);
+      throw std::invalid_argument(
+          "boost::mp_math::gmp_integer::gmp_integer(const std::string&)");
+    }
+  }
+  else
+    mpz_init(val_);
+}
+
+template<class B>
+gmp_integer<B>::gmp_integer(const std::string& s, std::ios_base::fmtflags f)
+{
+  unsigned radix;
+  if (f & std::ios_base::hex)
+    radix = 16;
+  else if (f & std::ios_base::oct)
+    radix = 8;
+  else
+    radix = 10;
+
+  if (!s.empty())
+  {
+    if (mpz_init_set_str(val_, s.c_str(), radix))
+    {
+      if (val_->_mp_d)
+        mpz_clear(val_);
+      throw std::invalid_argument(
+          "boost::mp_math::gmp_integer::"
+          "gmp_integer(const std::string&, std::ios_base::fmtflags)");
+    }
+  }
+  else
+    mpz_init(val_);
+}
+
+template<class B>
+inline void swap(gmp_integer<B>& lhs, gmp_integer<B>& rhs)
+{
+  lhs.swap(rhs);
+}
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+template<class B>
+inline void swap(gmp_integer<B>&& lhs, gmp_integer<B>& rhs)
+{
+  lhs.swap(rhs);
+}
+template<class B>
+inline void swap(gmp_integer<B>& lhs, gmp_integer<B>&& rhs)
+{
+  lhs.swap(rhs);
+}
+#endif
+
+
+template<class B>
+inline gmp_integer<B>
+operator << (const gmp_integer<B>& x,
+             typename gmp_integer<B>::size_type n)
+{
+  gmp_integer<B> nrv;
+  mpz_mul_2exp(nrv.get_mpz_t(), x.get_mpz_t(), n);
+  return nrv;
+}
+
+template<class B>
+inline gmp_integer<B>
+operator >> (const gmp_integer<B>& x,
+             typename gmp_integer<B>::size_type n)
+{
+  gmp_integer<B> nrv;
+  mpz_tdiv_q_2exp(nrv.get_mpz_t(), x.get_mpz_t(), n);
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+operator + (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  gmp_integer<B> nrv;
+  mpz_add(nrv.get_mpz_t(), lhs.get_mpz_t(), rhs.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+operator - (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  gmp_integer<B> nrv;
+  mpz_sub(nrv.get_mpz_t(), lhs.get_mpz_t(), rhs.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+operator * (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  gmp_integer<B> nrv;
+  mpz_mul(nrv.get_mpz_t(), lhs.get_mpz_t(), rhs.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+operator / (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  gmp_integer<B> nrv;
+  mpz_tdiv_q(nrv.get_mpz_t(), lhs.get_mpz_t(), rhs.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+operator % (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  gmp_integer<B> nrv;
+  mpz_tdiv_r(nrv.get_mpz_t(), lhs.get_mpz_t(), rhs.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+operator | (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  gmp_integer<B> nrv;
+  B::bitwise_or(nrv.get_mpz_t(), lhs.get_mpz_t(), rhs.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+operator & (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  gmp_integer<B> nrv;
+  B::bitwise_and(nrv.get_mpz_t(), lhs.get_mpz_t(), rhs.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+operator ^ (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  gmp_integer<B> nrv;
+  B::bitwise_xor(nrv.get_mpz_t(), lhs.get_mpz_t(), rhs.get_mpz_t());
+  return nrv;
+}
+
+// Arithmetic and bitwise operators involving integral types
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B>&>::type
+gmp_integer<B>::operator += (IntegralT rhs)
+{
+  integral_ops<IntegralT>::add(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B>&>::type
+gmp_integer<B>::operator -= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::subtract(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B>&>::type
+gmp_integer<B>::operator *= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::multiply(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B>&>::type
+gmp_integer<B>::operator /= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::divide(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B>&>::type
+gmp_integer<B>::operator %= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::modulo(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B>&>::type
+gmp_integer<B>::operator |= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_or(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B>&>::type
+gmp_integer<B>::operator &= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_and(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B>&>::type
+gmp_integer<B>::operator ^= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_xor(*this, rhs);
+  return *this;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B> >::type
+operator + (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  gmp_integer<B> nrv(lhs);
+  nrv += rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B> >::type
+operator - (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  gmp_integer<B> nrv(lhs);
+  nrv -= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B> >::type
+operator * (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  gmp_integer<B> nrv(lhs);
+  nrv *= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B> >::type
+operator / (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  gmp_integer<B> nrv(lhs);
+  nrv /= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B> >::type
+operator % (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  gmp_integer<B> nrv(lhs);
+  nrv %= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B> >::type
+operator | (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  gmp_integer<B> nrv(lhs);
+  nrv |= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B> >::type
+operator & (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  gmp_integer<B> nrv(lhs);
+  nrv &= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, gmp_integer<B> >::type
+operator ^ (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  gmp_integer<B> nrv(lhs);
+  nrv ^= rhs;
+  return nrv;
+}
+
+
+template<class B>
+inline bool operator == (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  return mpz_cmp(lhs.get_mpz_t(), rhs.get_mpz_t()) == 0;
+}
+
+template<class B>
+inline bool operator != (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  return mpz_cmp(lhs.get_mpz_t(), rhs.get_mpz_t()) != 0;
+}
+
+template<class B>
+inline bool operator < (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  return mpz_cmp(lhs.get_mpz_t(), rhs.get_mpz_t()) < 0;
+}
+
+template<class B>
+inline bool operator > (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  return mpz_cmp(lhs.get_mpz_t(), rhs.get_mpz_t()) > 0;
+}
+
+template<class B>
+inline bool operator <= (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  return mpz_cmp(lhs.get_mpz_t(), rhs.get_mpz_t()) <= 0;
+}
+
+template<class B>
+inline bool operator >= (const gmp_integer<B>& lhs, const gmp_integer<B>& rhs)
+{
+  return mpz_cmp(lhs.get_mpz_t(), rhs.get_mpz_t()) >= 0;
+}
+
+// compare unbounded_int to integral
+/*template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  return detail::unbounded_int_integral_ops<
+    gmp_integer<B>, IntegralT>::equal(lhs, rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  return detail::unbounded_int_integral_ops<
+    gmp_integer<B>, IntegralT>::less(lhs, rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  return rhs < lhs;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  return (lhs < rhs) || (lhs == rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (const gmp_integer<B>& lhs, IntegralT rhs)
+{
+  return !(lhs < rhs);
+}
+
+// compare integral to unbounded_int
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (IntegralT lhs, const gmp_integer<B>& rhs)
+{
+  return rhs == lhs;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (IntegralT lhs, const gmp_integer<B>& rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (IntegralT lhs, const gmp_integer<B>& rhs)
+{
+  return !(rhs <= lhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (IntegralT lhs, const gmp_integer<B>& rhs)
+{
+  return rhs < lhs;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (IntegralT lhs, const gmp_integer<B>& rhs)
+{
+  return !(rhs < lhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (IntegralT lhs, const gmp_integer<B>& rhs)
+{
+  return rhs <= lhs;
+}*/
+
+// compare unbounded_int to const charT*
+template<class B, typename charT>
+inline bool
+operator == (const gmp_integer<B>& lhs, const charT* rhs)
+{
+  return lhs == gmp_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator != (const gmp_integer<B>& lhs, const charT* rhs)
+{
+  return lhs != gmp_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator < (const gmp_integer<B>& lhs, const charT* rhs)
+{
+  return lhs < gmp_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator > (const gmp_integer<B>& lhs, const charT* rhs)
+{
+  return lhs > gmp_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator <= (const gmp_integer<B>& lhs, const charT* rhs)
+{
+  return lhs <= gmp_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator >= (const gmp_integer<B>& lhs, const charT* rhs)
+{
+  return lhs >= gmp_integer<B>(rhs);
+}
+
+// comparison const charT* to unbounded_int
+template<class B, typename charT>
+inline bool
+operator == (const charT* lhs, const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) == rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator != (const charT* lhs, const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) != rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator < (const charT* lhs, const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) < rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator > (const charT* lhs, const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) > rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator <= (const charT* lhs, const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) <= rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator >= (const charT* lhs, const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) >= rhs;
+}
+
+// compare unbounded_int to basic_string
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator == (const gmp_integer<B>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs == gmp_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator != (const gmp_integer<B>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs != gmp_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator < (const gmp_integer<B>& lhs,
+            const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs < gmp_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator > (const gmp_integer<B>& lhs,
+            const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs > gmp_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const gmp_integer<B>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs <= gmp_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const gmp_integer<B>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs >= gmp_integer<B>(rhs);
+}
+
+// compare basic_string to unbounded_int
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator == (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) == rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator != (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) != rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator < (const std::basic_string<charT,Traits,Alloc>& lhs,
+            const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) < rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator > (const std::basic_string<charT,Traits,Alloc>& lhs,
+            const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) > rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) <= rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const gmp_integer<B>& rhs)
+{
+  return gmp_integer<B>(lhs) >= rhs;
+}
+
+// Input/Output
+template<class B, typename charT, class traits>
+std::basic_istream<charT, traits>&
+operator >> (std::basic_istream<charT, traits>& is, gmp_integer<B>&)
+{
+  return is;
+}
+
+template<class B, typename charT, class traits>
+std::basic_ostream<charT, traits>&
+operator << (std::basic_ostream<charT, traits>& os, const gmp_integer<B>& x)
+{
+  return os << x.template to_string<std::string>(os.flags());
+}
+
+
+
+template<class B>
+inline gmp_integer<B> abs(const gmp_integer<B>& x)
+{
+  gmp_integer<B> nrv;
+  mpz_abs(nrv.get_mpz_t(), x.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline gmp_integer<B> gcd(const gmp_integer<B>& x, const gmp_integer<B>& y)
+{
+  gmp_integer<B> nrv;
+  mpz_gcd(nrv.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
+  return nrv;
+}
+
+#ifndef BOOST_NO_VARIADIC_TEMPLATES
+template<class B, class... GMPInteger>
+gmp_integer<B> gcd(const gmp_integer<B>& a,
+                   const gmp_integer<B>& b,
+                   const GMPInteger&... args)
+{
+  return gcd(gcd(a, b), args...);
+}
+#endif
+
+template<class B>
+inline gmp_integer<B> lcm(const gmp_integer<B>& x, const gmp_integer<B>& y)
+{
+  gmp_integer<B> nrv;
+  mpz_lcm(nrv.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
+  return nrv;
+}
+
+#ifndef BOOST_NO_VARIADIC_TEMPLATES
+template<class B, class... GMPInteger>
+gmp_integer<B> lcm(const gmp_integer<B>& a,
+                   const gmp_integer<B>& b,
+                   const GMPInteger&... args)
+{
+  return lcm(lcm(a, b), args...);
+}
+#endif
+
+template<class B>
+inline
+gmp_integer<B>
+pow(const gmp_integer<B>& x, typename gmp_integer<B>::size_type y)
+{
+  gmp_integer<B> nrv;
+  mpz_pow_ui(nrv.get_mpz_t(), x.get_mpz_t(), y);
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B> pow(const gmp_integer<B>& x, const gmp_integer<B>& y)
+{
+  gmp_integer<B> nrv;
+  mpz_pow_ui(nrv.get_mpz_t(), x.get_mpz_t(),
+             y.template to_integral<unsigned long>());
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+sqrt(const gmp_integer<B>& x)
+{
+  gmp_integer<B> nrv;
+  mpz_sqrt(nrv.get_mpz_t(), x.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+nth_root(typename gmp_integer<B>::size_type n, const gmp_integer<B>& x)
+{
+  gmp_integer<B> nrv;
+  mpz_root(nrv.get_mpz_t(), x.get_mpz_t(), n);
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+nth_root(const gmp_integer<B>& n, const gmp_integer<B>& x)
+{
+  gmp_integer<B> nrv;
+  mpz_root(nrv.get_mpz_t(), x.get_mpz_t(), n);
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B>
+modinv(const gmp_integer<B>& x, const gmp_integer<B>& m)
+{
+  gmp_integer<B> nrv;
+  if (mpz_invert(nrv.get_mpz_t(), x.get_mpz_t(), m.get_mpz_t()) == 0)
+    throw std::domain_error(
+        "boost::mp_math::modinv: modular inverse does not exist");
+  return nrv;
+}
+
+template<class B>
+inline
+gmp_integer<B> modpow(const gmp_integer<B>& base,
+                     const gmp_integer<B>& exp,
+                     const gmp_integer<B>& mod,
+                     modpow_ctx<gmp_integer<B> >* ctx = 0)
+{
+  gmp_integer<B> nrv;
+  mpz_powm(nrv.get_mpz_t(), base.get_mpz_t(), exp.get_mpz_t(), mod.get_mpz_t());
+  return nrv;
+}
+
+template<class B>
+inline
+int jacobi(const gmp_integer<B>& x, const gmp_integer<B>& y)
+{
+  return mpz_jacobi(x.get_mpz_t(), y.get_mpz_t());
+}
+
+
+
+
+
+} // namespace mp_math
+} // namespace boost
+
+#endif
Copied: sandbox/mp_math/boost/mp_math/integer/integer.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/mp_int.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/mp_int.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/integer.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -3,910 +3,94 @@
 // (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef BOOST_MP_MATH_MP_INT_MP_INT_HPP
-#define BOOST_MP_MATH_MP_INT_MP_INT_HPP
-
-#include <algorithm>
-#include <cassert>
-#include <cstring>
-#include <iosfwd>
-#include <iterator> // reverse_iterator
-#include <limits>
-#include <stdexcept>
-#include <sstream>
-#include <string>
+#ifndef BOOST_MP_MATH_INTEGER_INTEGER_HPP
+#define BOOST_MP_MATH_INTEGER_INTEGER_HPP
 
 #include <boost/config.hpp>
-#include <boost/random.hpp>
-#include <boost/type_traits/is_integral.hpp>
-#include <boost/utility/enable_if.hpp>
-#include <boost/mp_math/mp_int/detail/div.hpp>
-#include <boost/mp_math/mp_int/detail/string_conversion_constants.hpp>
-#include <boost/mp_math/mp_int/detail/integral_ops.hpp>
-#include <boost/mp_math/mp_int/detail/meta_math.hpp>
-#include <boost/mp_math/mp_int/detail/primitive_ops.hpp>
-
 
 namespace boost {
 namespace mp_math {
 
-template<
-  class Allocator,
-  class Traits
->
-struct mp_int
-:
-  Allocator::template rebind<typename Traits::digit_type>::other
+template<class Type>
+struct integer : Type
 {
-private:
-
-  typedef typename Allocator::template
-    rebind<typename Traits::digit_type>::other base_allocator_type;
-
-public:
-
-  typedef Allocator                               allocator_type;
-  typedef Traits                                  traits_type;
-  typedef typename base_allocator_type::size_type size_type;
-
-  mp_int();
-
-  explicit mp_int(const allocator_type& a);
-
-  template<typename IntegralT>
-  mp_int(IntegralT,
-         const allocator_type& a = allocator_type(),
-         typename enable_if<is_integral<IntegralT> >::type* dummy = 0);
-
-  template<typename charT>
-  mp_int(const charT*, const allocator_type& a = allocator_type());
-
-  template<typename charT>
-  mp_int(const charT*,
-         std::ios_base::fmtflags,
-         const allocator_type& a = allocator_type());
-
-  template<typename charT, class traits, class Alloc>
-  mp_int(const std::basic_string<charT,traits,Alloc>&,
-         const allocator_type& a = allocator_type());
-
-  template<typename charT, class traits, class Alloc>
-  mp_int(const std::basic_string<charT,traits,Alloc>&,
-         std::ios_base::fmtflags,
-         const allocator_type& a = allocator_type());
-
-  template<typename RandomAccessIterator>
-  mp_int(RandomAccessIterator first,
-         RandomAccessIterator last,
-         const allocator_type& a = allocator_type());
-
-  template<typename RandomAccessIterator>
-  mp_int(RandomAccessIterator first,
-         RandomAccessIterator last,
-         std::ios_base::fmtflags f,
-         const allocator_type& a = allocator_type());
-
-  mp_int(const mp_int& copy);
+  typedef Type type;
+  typedef typename type::traits_type            traits_type;
+  typedef typename type::digit_type             digit_type;
+  typedef typename type::size_type              size_type;
+  typedef typename type::iterator               iterator;
+  typedef typename type::const_iterator         const_iterator;
+  typedef typename type::reverse_iterator       reverse_iterator;
+  typedef typename type::const_reverse_iterator const_reverse_iterator;
+
+  integer(){}
+
+  #if !defined(BOOST_NO_VARIADIC_TEMPLATES) && !defined(BOOST_NO_RVALUE_REFERENCES)
+  template<typename... Args>
+  integer(Args&&... args)
+  :
+    type(args...)
+  {}
 
-  #ifdef BOOST_HAS_RVALUE_REFS
-  mp_int(mp_int&& copy);
-  #endif
-
-  ~mp_int();
-
-  mp_int& operator = (const mp_int& rhs);
+  #else
 
-  #ifdef BOOST_HAS_RVALUE_REFS
-  mp_int& operator = (mp_int&& rhs);
+  template<typename T1>
+  integer(const T1& t1)
+  : type(t1) {}
+
+  template<typename T1, typename T2>
+  integer(const T1& t1, const T2& t2)
+  : type(t1, t2) {}
+
+  template<typename T1, typename T2, typename T3>
+  integer(const T1& t1, const T2& t2, const T3& t3)
+  : type(t1, t2, t3) {}
+
+  template<typename T1, typename T2, typename T3, typename T4>
+  integer(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
+  : type(t1, t2, t3, t4) {}
+
+  template<typename T1, typename T2, typename T3, typename T4, typename T5>
+  integer(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
+  : type(t1, t2, t3, t4, t5) {}
   #endif
 
-  template<typename IntegralT>
-  mp_int& operator = (IntegralT rhs);
-
-  template<typename charT>
-  mp_int& operator = (const charT*);
-
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator = (const std::basic_string<charT,traits,Alloc>&);
-
-  template<typename charT>
-  void assign(const charT*, std::ios_base::fmtflags);
-
-  template<typename charT, class traits, class Alloc>
-  void assign(const std::basic_string<charT,traits,Alloc>&,
-              std::ios_base::fmtflags);
-
-  template<typename RandomAccessIterator>
-  void assign(RandomAccessIterator first, RandomAccessIterator last,
-              std::ios_base::fmtflags);
-
-  #ifdef BOOST_HAS_RVALUE_REFS
-  void swap(mp_int&& other);
+  template<typename T>
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  integer& operator = (T&& t)
   #else
-  void swap(mp_int& other);
+  integer& operator = (const T& t)
   #endif
-
-  mp_int& operator ++();
-  mp_int& operator --();
-  mp_int  operator ++(int);
-  mp_int  operator --(int);
-  mp_int& operator <<= (size_type);
-  mp_int& operator >>= (size_type);
-  mp_int& operator - ();
-
-  mp_int& operator += (const mp_int&);
-  mp_int& operator -= (const mp_int&);
-  mp_int& operator *= (const mp_int&);
-  mp_int& operator /= (const mp_int&);
-  mp_int& operator %= (const mp_int&);
-  mp_int& operator |= (const mp_int&);
-  mp_int& operator &= (const mp_int&);
-  mp_int& operator ^= (const mp_int&);
-
-  template<typename IntegralT> mp_int& operator += (IntegralT);
-  template<typename IntegralT> mp_int& operator -= (IntegralT);
-  template<typename IntegralT> mp_int& operator *= (IntegralT);
-  template<typename IntegralT> mp_int& operator /= (IntegralT);
-  template<typename IntegralT> mp_int& operator %= (IntegralT);
-  template<typename IntegralT> mp_int& operator |= (IntegralT);
-  template<typename IntegralT> mp_int& operator &= (IntegralT);
-  template<typename IntegralT> mp_int& operator ^= (IntegralT);
-
-  template<typename charT> mp_int& operator += (const charT*);
-  template<typename charT> mp_int& operator -= (const charT*);
-  template<typename charT> mp_int& operator *= (const charT*);
-  template<typename charT> mp_int& operator /= (const charT*);
-  template<typename charT> mp_int& operator %= (const charT*);
-  template<typename charT> mp_int& operator |= (const charT*);
-  template<typename charT> mp_int& operator &= (const charT*);
-  template<typename charT> mp_int& operator ^= (const charT*);
-
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator += (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator -= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator *= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator /= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator %= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator |= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator &= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator ^= (const std::basic_string<charT,traits,Alloc>&);
-
-  allocator_type get_allocator() const { return allocator_type(); }
-
-private:
-
-  typedef size_type mp_int::*unspecified_bool_type;
-
-public:
-
-  operator unspecified_bool_type() const
   {
-	  return !(size_ == 1 && digits_[0] == 0) ? &mp_int::size_ : 0;
+    type::operator=(t);
+    return *this;
   }
 
-  bool is_even() const { return (digits_[0] & digit_type(1)) == 0; }
-  bool is_odd () const { return (digits_[0] & digit_type(1)) == 1; }
-
-  bool is_positive() const { return sign() ==  1; }
-  bool is_negative() const { return sign() == -1; }
-
-  template<class StringT>
-  StringT to_string(std::ios_base::fmtflags f = std::ios_base::dec) const;
-
-  template<typename IntegralT>
-  IntegralT to_integral() const;
-
-public: // low level interface
-
-  typedef typename traits_type::digit_type        digit_type;
-  typedef typename traits_type::word_type         word_type;
-  typedef typename traits_type::digit_type*       iterator;
-  typedef const typename traits_type::digit_type* const_iterator;
-  typedef std::reverse_iterator<iterator>         reverse_iterator;
-  typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
-  typedef detail::primitive_ops<digit_type, word_type, size_type> ops_type;
-
-  // bits per digit, we subtract one because we count from 0
-  static const int valid_bits = std::numeric_limits<digit_type>::digits;
-  static const int digit_bits = std::numeric_limits<digit_type>::digits;
-  // used to mask off the most significant bit(s)
-  static const digit_type mp_mask = (word_type(1) << valid_bits) - 1;
-  static const size_type mp_warray = 512;
-    //1 << (std::numeric_limits<word_type>::digits - 2 * valid_bits + 1);
-  static const digit_type digit_max = static_cast<digit_type>(-1);
-
-  static const size_type sign_bit =
-    size_type(1) << (std::numeric_limits<size_type>::digits - 1U);
-
-  template<typename RandomAccessIterator>
-  void init(RandomAccessIterator first, RandomAccessIterator last);
-
-  template<typename RandomAccessIterator>
-  void init(RandomAccessIterator first, RandomAccessIterator last,
-            std::ios_base::fmtflags f);
-
-  iterator       begin()       { return digits_;         }
-  iterator       end  ()       { return digits_ + size_; }
-  const_iterator begin() const { return digits_;         }
-  const_iterator end  () const { return digits_ + size_; }
-  reverse_iterator       rbegin()       { return reverse_iterator(end());   }
-  reverse_iterator       rend  ()       { return reverse_iterator(begin()); }
-  const_reverse_iterator rbegin() const { return const_reverse_iterator(end());   }
-  const_reverse_iterator rend  () const { return const_reverse_iterator(begin()); }
-
-  digit_type&       operator[](size_type i)       { return digits_[i]; }
-  const digit_type& operator[](size_type i) const { return digits_[i]; }
-
-  digit_type&       at(size_type i)
-  {
-    if (i >= size_)
-      throw std::out_of_range("mp_int::at: array subscript out of range");
-    return digits_[i];
-  }
-
-  const digit_type& at(size_type i) const
-  {
-    if (i >= size_)
-      throw std::out_of_range("mp_int::at: array subscript out of range");
-    return digits_[i];
-  }
-
-  void push(digit_type x) { digits_[size_++] = x; }
-  void pop() { --size_; }
-
-  void zero();
-
-  // debug functionality
-  void print(bool all=false) const;
-  bool test_invariants() const;
-
-  bool is_uninitialized() const { return !size_; }
-
-  size_type size() const { return size_; }
-  size_type capacity() const
-  {
-    return capacity_ & ~sign_bit;
-  }
-
-  void set_capacity(size_type c)
-  {
-    capacity_ &= sign_bit;
-    capacity_ |= c;
-  }
-
-  void set_size(size_type s) { size_ = s; }
-
-  int sign() const
-  {
-    return (capacity_ & sign_bit) ? -1 : 1;
-  }
-
-  void set_sign(int s)
-  {
-    if (s == 1)
-      capacity_ &= ~sign_bit;
-    else
-      capacity_ |= sign_bit;
-  }
-
-  digit_type*       digits()       { return digits_; }
-  const digit_type* digits() const { return digits_; }
-
-  void grow_capacity(size_type n);
-  void clamp();
-  void clamp_high_digit();
-
-  int compare_magnitude(const mp_int& rhs) const;
-  int compare_to_digit(digit_type) const;
-  int compare(const mp_int& rhs) const;
-
-  void add_magnitude(const mp_int& rhs);
-  void sub_smaller_magnitude(const mp_int& rhs);
-
-  bool is_power_of_two() const;
-  void add_digit(digit_type);
-  void sub_digit(digit_type);
-
-  void shift_digits_left(size_type);
-  void shift_digits_right(size_type);
-
-  void multiply_by_digit(digit_type);
-  void karatsuba_mul(const mp_int&);
-  void toom_cook_mul(const mp_int&);
-  void multiply_by_2();
-  void mul_digits(const mp_int&, size_type num_digits);
-  void mul_high_digits(const mp_int&, size_type num_digits);
-  void fast_mul_digits(const mp_int&, size_type num_digits);
-  void fast_mul_high_digits(const mp_int&, size_type num_digits);
-
-  void sqr();
-  void toom_sqr();
-  void karatsuba_sqr();
-  void comba_sqr();
-
-  digit_type divide_by_digit(digit_type); // returns remainder
-  void divide_by_2();
-  digit_type divide_by_3();
-  void modulo_2_to_the_power_of(size_type);
-  size_type count_lsb() const;
-  void shift_right(size_type b, mp_int* remainder);
-
-  void pow2(size_type b);
-
-  void set_least_significant_bit()
-  {
-    digits_[0] |= digit_type(1);
-  }
-
-  void set_bit(size_type bit)
-  {
-    digits_[bit / valid_bits] |= digit_type(1) << (bit % valid_bits);
-  }
-
-  void clear_bit(size_type bit)
-  {
-    digits_[bit / valid_bits] &= ~(digit_type(1) << (bit % valid_bits));
-  }
-
-  void set_bits(size_type beg, size_type end);
-  void clear_bits(size_type beg, size_type end);
-
-  void truncate(size_type prec);
-
-  size_type precision() const;
-
-  void set_precision(size_type bits)
-  {
-    size_ = (bits + (valid_bits - 1)) / valid_bits;
-  }
-
-  template<class A, class T>
-  friend bool operator == (const mp_int<A,T>&, const mp_int<A,T>&);
-
-  template<class A, class T>
-  friend bool operator < (const mp_int<A,T>&, const mp_int<A,T>&);
-
-  template<typename Iter>
-  void from_string(Iter first, Iter last, unsigned radix);
-
-private:
-
-  digit_type* digits_;
-  size_type size_, capacity_;
+  operator type&       ()       { return *this; }
+  operator const type& () const { return *this; }
 };
 
 
+template<class Type>
+struct modpow_ctx<integer<Type> >
+:
+  modpow_ctx<Type>
+{};
 
-template<class A, class T>
-void mp_int<A,T>::print(bool all) const
-{
-  using std::cout;
-  if (is_negative())
-  cout << '-';
-  cout << size_ << "{";
-  for (size_type i = 0; i < size_; ++i)
-  {
-    cout << static_cast<word_type>(digits_[i]);
-    if (i < size_  - 1)
-      cout << ",";
-  }
-  cout << "}";
-
-  if (all)
-  {
-    cout << capacity() - size_ << "{";
-    for (size_type i = size_; i < capacity(); ++i)
-    {
-      cout << static_cast<word_type>(digits_[i]);
-      if (i < capacity()  - 1)
-        cout << ",";
-    }
-    cout << "}";
-  }
-  cout << "\n";
-}
-
-template<class A, class T>
-bool mp_int<A,T>::test_invariants() const
-{
-  if (size_) // don't test uninitialized mp_ints
-  {
-    if (size_ > capacity())
-      return false;
-    if (digits_[size_-1] == 0U)
-      return false;
-    if (!*this && sign() != 1)
-      return false;
-  }
-  return true;
-}
-
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator = (const mp_int<A,T>& rhs)
-{
-  if (this != &rhs)
-  {
-    if ((capacity() == 0) || (capacity() < rhs.capacity()))
-      mp_int(rhs).swap(*this);
-    else
-    {
-      std::memcpy(digits_, rhs.digits_, rhs.size_ * sizeof(digit_type));
-      size_ = rhs.size_;
-      set_sign(rhs.sign());
-    }
-  }
-  return *this;
-}
-
-#ifdef BOOST_HAS_RVALUE_REFS
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator = (mp_int<A,T>&& rhs)
-{
-  if (this != &rhs)
-  {
-    if (digits_)
-      this->deallocate(digits_, capacity());
-    digits_ = 0;
-    size_ = 0;
-    capacity_ = 0;
-    swap(rhs);
-  }
-  return *this;
-}
-#endif
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator = (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::assign(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename charT>
-mp_int<A,T>& mp_int<A,T>::operator = (const charT* s)
-{
-  size_ = 0;
-  init(s, s + std::char_traits<charT>::length(s));
-  return *this;
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-mp_int<A,T>& mp_int<A,T>::operator = (const std::basic_string<charT,traits,Alloc>& s)
-{
-  size_ = 0;
-  init(s.begin(), s.end());
-  return *this;
-}
-
-template<class A, class T>
-template<typename charT>
-inline void
-mp_int<A,T>::assign(const charT* s, std::ios_base::fmtflags f)
-{
-  assign(s, s + std::char_traits<charT>::length(s), f);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline void
-mp_int<A,T>::assign(const std::basic_string<charT,traits,Alloc>& s,
-                    std::ios_base::fmtflags f)
-{
-  assign(s.begin(), s.end(), f);
-}
-
-template<class A, class T>
-template<typename RandomAccessIterator>
-inline void
-mp_int<A,T>::assign(RandomAccessIterator first, RandomAccessIterator last,
-                    std::ios_base::fmtflags f)
-{
-  size_ = 0;
-  init(first, last, f);
-}
-
-
-template<class A, class T>
-#ifdef BOOST_HAS_RVALUE_REFS
-void mp_int<A,T>::swap(mp_int&& other)
-#else
-void mp_int<A,T>::swap(mp_int& other)
-#endif
-{
-  std::swap(digits_, other.digits_);
-  std::swap(size_, other.size_);
-  std::swap(capacity_, other.capacity_);
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator += (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::add(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator -= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::subtract(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator *= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::multiply(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator /= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::divide(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator %= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::modulo(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator |= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::bitwise_or(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator &= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::bitwise_and(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator ^= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::bitwise_xor(*this, rhs);
-  return *this;
-}
-
-
-template<class A, class T>
-void mp_int<A,T>::zero()
-{
-  grow_capacity(1);
-  digits_[0] = 0;
-  size_ = 1;
-  set_sign(1);
-}
-
-template<class A, class T>
-void mp_int<A,T>::grow_capacity(size_type n)
-{
-  if (capacity() < n)
-  {
-    if (n < sign_bit)
-    {
-      const size_type new_cap = capacity() + capacity();
-      if (new_cap > n)
-        n = new_cap;
-      digit_type* d = this->allocate(n, digits_);
-      std::memcpy(d, digits_, sizeof(digit_type) * size_);
-      this->deallocate(digits_, capacity());
-      digits_ = d;
-      set_capacity(n);
-    }
-    else
-      throw std::bad_alloc();
-  }
-}
-
-// This is used to ensure that leading zero digits are trimmed.
-template<class A, class T>
-void mp_int<A,T>::clamp()
-{
-  while (size_ > 1 && digits_[size_-1] == 0)
-    --size_;
-}
-
-// For when we know that only one leading zero digit may exist.
-template<class A, class T>
-inline void mp_int<A,T>::clamp_high_digit()
-{
-  if (size_ > 1 && digits_[size_-1] == 0)
-    --size_;
-}
-
-// disregards the sign of the numbers
-// return 1 if *this is greater
-// returns 0 if both are equal
-// return -1 if *this is smaller
-template<class A, class T>
-int mp_int<A,T>::compare_magnitude(const mp_int& rhs) const
-{
-  // compare based on # of non-zero digits
-  if (size_ > rhs.size_)
-    return 1;
-
-  if (size_ < rhs.size_)
-    return -1;
-
-  // compare based on digits
-  const_reverse_iterator d = rbegin();
-  const_reverse_iterator d2 = rhs.rbegin();
-  for (; d != rend(); ++d, ++d2)
-  {
-    if (*d > *d2)
-      return 1;
-    if (*d < *d2)
-      return -1;
-  }
-  return 0;
-}
-
-template<class A, class T>
-int mp_int<A,T>::compare_to_digit(digit_type d) const
-{
-  // compare based on sign
-  if (is_negative())
-    return -1;
-
-  // compare based on magnitude
-  if (size_ > 1)
-    return 1;
-
-  // compare the only digit of *this to d
-  if (digits_[0] > d)
-    return 1;
-  else if (digits_[0] < d)
-    return -1;
-  else
-    return 0;
-}
-
-template<class A, class T>
-int mp_int<A,T>::compare(const mp_int& rhs) const
-{
-  if (sign() != rhs.sign())
-  {
-    if (is_negative())
-      return -1;
-    else
-      return 1;
-  }
-
-  if (is_negative())
-    // if negative compare opposite direction
-    return rhs.compare_magnitude(*this);
-  else
-    return compare_magnitude(rhs);
-}
-
-// {A,B,C,D,E} shifted left by 2 digits becomes
-// {0,0,A,B,C,D,E}
-template<class A, class T>
-void mp_int<A,T>::shift_digits_left(size_type b)
-{
-  if (b <= 0)
-    return;
-
-  grow_capacity(size_ + b);
-
-  std::memmove(digits_ + b, digits_, size_ * sizeof(digit_type));
-
-  // zero the lower digits
-  std::memset(digits_, 0, b * sizeof(digit_type));
-
-  size_ += b;
-}
-
-// {A,B,C,D,E} shifted right by 2 digits becomes
-// {C,D,E}
-template<class A, class T>
-void mp_int<A,T>::shift_digits_right(size_type b)
-{
-  if (b <= 0)
-    return;
-
-  if (size_ <= b)
-  {
-    zero();
-    return;
-  }
-
-  // shift the digits down
-  std::memmove(digits_, digits_ + b, (size_ - b) * sizeof(digit_type));
-
-  // zero the top digits
-  std::memset(digits_ + size_ - b, 0, b * sizeof(digit_type));
-
-  // remove excess digits
-  size_ -= b;
-}
-
-template<class A, class T>
-typename mp_int<A,T>::size_type
-mp_int<A,T>::precision() const
-{
-  // get number of digits and add that
-  size_type p = (size_ - 1) * valid_bits;
-
-  // take the last digit and count the bits in it
-  digit_type q = digits_[size_ - 1];
-  while (q > 0U)
-  {
-    ++p;
-    q >>= 1;
-  }
-  return p;
-}
-
-// Counts the number of lsbs which are zero before the first one bit
-template<class A, class T>
-typename mp_int<A,T>::size_type
-mp_int<A,T>::count_lsb() const
-{
-  static const size_type lnz[16] = {
-    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
-  };
-
-  if (!*this)
-    return 0;
-
-  // scan lower digits until non-zero
-  size_type x = 0;
-  while (x < size_ && digits_[x] == 0)
-    ++x;
-  digit_type q = digits_[x];
-  x *= valid_bits;
-
-  // now scan this digit until a 1 is found
-  if ((q & 1) == 0)
-  {
-    digit_type qq;
-    do
-    {
-      qq  = q & 15;
-      x  += lnz[qq];
-      q >>= 4;
-    } while (qq == 0);
-  }
-  return x;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline IntegralT mp_int<A,T>::to_integral() const
-{
-  return detail::integral_ops<IntegralT>::convert(*this);
-}
-
-template<class A, class T>
-void mp_int<A,T>::set_bits(size_type beg, size_type end)
-{
-  const size_type beg_index  = beg / digit_bits;
-  const size_type end_index  = end / digit_bits;
-  const size_type first_bits = beg % digit_bits;
-  const size_type last_bits  = end % digit_bits;
-
-  static const digit_type z = ~digit_type(0);
-
-  digit_type mask = z << first_bits;
-  if (beg_index == end_index && last_bits)
-    mask &= z >> (digit_bits - last_bits);
-
-  digits_[beg_index] |= mask;
-
-  for (size_type i = beg_index + ((beg % digit_bits) ? 1 : 0); i < end_index; ++i)
-    digits_[i] = digit_max;
-
-  if (beg_index != end_index && last_bits)
-    digits_[end_index] |= z >> (digit_bits - last_bits);
-}
-
-template<class A, class T>
-void mp_int<A,T>::clear_bits(size_type beg, size_type end)
-{
-  const size_type beg_index  = beg / digit_bits;
-  const size_type end_index  = end / digit_bits;
-  const size_type first_bits = beg % digit_bits;
-  const size_type last_bits  = end % digit_bits;
-
-  static const digit_type z = ~digit_type(0);
-
-  digit_type mask;
-  if (first_bits)
-    mask = z >> (digit_bits - first_bits);
-  else
-    mask = 0;
-
-  if (beg_index == end_index)
-    mask |= z << last_bits;
-
-  digits_[beg_index] &= mask;
-
-  if (beg_index != end_index)
-  {
-    std::memset(digits_ + beg_index + 1, 0,
-        sizeof(digit_type) * (end_index - beg_index - 1));
-
-    digits_[end_index] &= z << last_bits;
-  }
-}
-
-// don't forget to clamp() after truncating!
-template<class A, class T>
-void mp_int<A,T>::truncate(size_type prec)
-{
-  set_precision(prec);
-  const size_type last_bits = prec % valid_bits;
-  if (last_bits)
-  {
-    static const digit_type z = ~digit_type(0);
-    const digit_type mask = z >> (valid_bits - last_bits);
-    digits_[size_ - 1] &= mask;
-  }
-}
-
-
-template<class A, class T>
-inline void swap(mp_int<A,T>& lhs, mp_int<A,T>& rhs)
-{
-  lhs.swap(rhs);
-}
-
-#ifdef BOOST_HAS_RVALUE_REFS
-template<class A, class T>
-inline void swap(mp_int<A,T>&& lhs, mp_int<A,T>& rhs)
-{
-  lhs.swap(rhs);
+// returns base^exp % mod
+template<class Type>
+inline
+integer<Type> modpow(const integer<Type>& base,
+                     const integer<Type>& exp,
+                     const integer<Type>& mod,
+                     modpow_ctx<integer<Type> >* ctx = 0)
+{
+  return modpow(static_cast<const Type&>(base),
+                static_cast<const Type&>(exp),
+                static_cast<const Type&>(mod),
+                static_cast<modpow_ctx<Type>*>(ctx));
 }
-template<class A, class T>
-inline void swap(mp_int<A,T>& lhs, mp_int<A,T>&& rhs)
-{
-  lhs.swap(rhs);
-}
-#endif
-
-
-
-
-
 
-#include <boost/mp_math/mp_int/abs.hpp>
-#include <boost/mp_math/mp_int/add.hpp>
-#include <boost/mp_math/mp_int/ctors.hpp>
-#include <boost/mp_math/mp_int/div.hpp>
-#include <boost/mp_math/mp_int/mod.hpp>
-#include <boost/mp_math/mp_int/mul.hpp>
-#include <boost/mp_math/mp_int/operators.hpp>
-#include <boost/mp_math/mp_int/pow.hpp>
-#include <boost/mp_math/mp_int/random.hpp>
-#include <boost/mp_math/mp_int/sqr.hpp>
-#include <boost/mp_math/mp_int/sub.hpp>
-#include <boost/mp_math/mp_int/string_conversion.hpp>
 
 } // namespace mp_math
 } // namespace boost
Copied: sandbox/mp_math/boost/mp_math/integer/integer_fwd.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/mp_int_fwd.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/mp_int_fwd.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/integer_fwd.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,23 +1,18 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_MP_INT_FWD_HPP
-#define BOOST_MP_MATH_MP_INT_MP_INT_FWD_HPP
-
-#include <memory>
-#include <boost/mp_math/mp_int/traits.hpp>
+#ifndef BOOST_MP_MATH_MP_INT_INTEGER_FWD_HPP
+#define BOOST_MP_MATH_MP_INT_INTEGER_FWD_HPP
 
+#include <boost/mp_math/integer/unbounded.hpp>
 
 namespace boost {
 namespace mp_math {
 
-template<
-  class Allocator = std::allocator<void>,
-  class Traits = mp_int_traits<>
->
-struct mp_int;
+template<class Type = unbounded<> >
+struct integer;
 
 } // namespace mp_math
 } // namespace boost
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/jacobi.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/jacobi.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,75 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_JACOBI_HPP
-#define BOOST_MP_MATH_MP_INT_JACOBI_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-
-
-namespace boost {
-namespace mp_math {
-
-// computes the jacobi c = (a | p) (or Legendre if p is prime)
-// HAC pp. 73 Algorithm 2.149
-template<class A, class T>
-int jacobi(const mp_int<A,T>& a, const mp_int<A,T>& p)
-{
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  typedef typename mp_int<A,T>::size_type  size_type;
-
-  if (p <= digit_type(0))
-    throw std::domain_error("jacobi: p must be greater than 0");
-
-  if (!a)
-    return 0;
-  
-  if (a == digit_type(1))
-    return 1;
-
-  // default
-  int s = 0;
-
-  // write a = a1 * 2**k
-  mp_int<A,T> a1(a);
-
-  // find largest power of two that divides a1
-  const size_type k = a1.count_lsb();
-  // now divide by it
-  a1.shift_right(k,0);
-
-  // if k is even set s=1
-  if ((k & 1) == 0)
-    s = 1;
-  else
-  {
-    // calculate p.digits_[0] mod 8
-    const digit_type residue = p[0] & 7;
-
-    if (residue == 1 || residue == 7)
-      s = 1;
-    else if (residue == 3 || residue == 5)
-      s = -1;
-  }
-
-  // if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s
-  if (((p[0] & 3) == 3) && ((a1[0] & 3) == 3))
-    s = -s;
-
-  if (a1 == digit_type(1))
-    return s;
-  else
-  {
-    const mp_int<A,T> p1(p % a1);
-    return s * jacobi(p1, a1);
-  }
-}
-
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/lcm.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/lcm.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,47 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_LCM_HPP
-#define BOOST_MP_MATH_MP_INT_LCM_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-
-
-namespace boost {
-namespace mp_math {
-
-// computes least common multiple as |a*b|/gcd(a,b)
-template<class A, class T>
-mp_int<A,T> lcm(const mp_int<A,T>& a, const mp_int<A,T>& b)
-{
-  mp_int<A,T> result;
-    
-  if (!a || !b)
-  {
-    result.zero();
-    return result;
-  }
-  
-  result = a / gcd(a, b) * b;
-
-  result.set_sign(1);
-  
-  return result;
-}
-
-#ifdef BOOST_HAS_VARIADIC_TMPL
-template<class A, class T, class... MpInts>
-mp_int<A,T> lcm(const mp_int<A,T>& a, const mp_int<A,T>& b, const MpInts&... args)
-{
-  return lcm(lcm(a, b), args...);
-}
-#endif
-
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Added: sandbox/mp_math/boost/mp_math/integer/libtom_integer.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/libtom_integer.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,1445 @@
+// Copyright Kevin Sopp 2009.
+// 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_MP_MATH_INTEGER_LIBTOM_INTEGER_HPP
+#define BOOST_MP_MATH_INTEGER_LIBTOM_INTEGER_HPP
+
+#include <tommath.h>
+#include <boost/config.hpp>
+#include <boost/mp_math/integer/contexts.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <cstring> // strlen
+#include <iostream>
+#include <limits>
+#include <stdexcept>
+
+namespace boost {
+namespace mp_math {
+
+struct boost_behavior
+{
+  static void bitwise_or(mp_int* z, mp_int* x, mp_int* y);
+  static void bitwise_and(mp_int* z, mp_int* x, mp_int* y);
+  static void bitwise_xor(mp_int* z, mp_int* x, mp_int* y);
+};
+
+
+struct libtom_behavior
+{
+  static void bitwise_or(mp_int* z, mp_int* x, mp_int* y)
+  {
+    mp_or(x, y, z);
+  }
+
+  static void bitwise_and(mp_int* z, mp_int* x, mp_int* y)
+  {
+    mp_and(x, y, z);
+  }
+
+  static void bitwise_xor(mp_int* z, mp_int* x, mp_int* y)
+  {
+    mp_xor(x, y, z);
+  }
+};
+
+
+template<class Behavior = libtom_behavior>
+class libtom_integer;
+
+
+namespace detail {
+
+template<
+  class B,
+  typename IntegralT,
+  bool IsSigned = std::numeric_limits<IntegralT>::is_signed,
+  bool FitsIntoLongInt =
+    IsSigned ? (std::numeric_limits<IntegralT>::digits <=
+                std::numeric_limits<signed long int>::digits)
+             : (std::numeric_limits<IntegralT>::digits <=
+                std::numeric_limits<unsigned long int>::digits)
+>
+struct libtom_integer_integral_ops;
+
+
+template<
+  class B,
+  typename IntegralT
+>
+struct libtom_integer_integral_ops<libtom_integer<B>, IntegralT, false, true>
+{
+  typedef libtom_integer<B> libtom_integer_type;
+  typedef IntegralT      integral_type;
+
+  static void init(libtom_integer_type& z, integral_type x)
+  {
+    mpz_init_set_ui(z.get_mp_int(), x);
+  }
+
+  static void assign(libtom_integer_type& z, integral_type x)
+  {
+    mpz_set_ui(z.get_mp_int(), x);
+  }
+
+  static bool equal(const libtom_integer_type& z, integral_type x)
+  {
+    return mpz_cmp_ui(z.get_mp_int(), x) == 0;
+  }
+
+  static bool less(const libtom_integer_type& z, integral_type x)
+  {
+    return mpz_cmp_ui(z.get_mp_int(), x) < 0;
+  }
+
+  static void add(libtom_integer_type& z, integral_type x)
+  {
+    mpz_add_ui(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void subtract(libtom_integer_type& z, integral_type x)
+  {
+    mpz_sub_ui(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void multiply(libtom_integer_type& z, integral_type x)
+  {
+    mpz_mul_ui(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void divide(libtom_integer_type& z, integral_type x)
+  {
+    mp_intdiv_q_ui(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void modulo(libtom_integer_type& z, integral_type x)
+  {
+    mpz_mod_ui(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void bitwise_or(libtom_integer_type& z, integral_type x);
+  static void bitwise_and(libtom_integer_type& z, integral_type x);
+  static void bitwise_xor(libtom_integer_type& z, integral_type x);
+};
+
+
+template<
+  class B,
+  typename IntegralT
+>
+struct libtom_integer_integral_ops<libtom_integer<B>, IntegralT, true, true>
+{
+  typedef libtom_integer<B> libtom_integer_type;
+  typedef IntegralT      integral_type;
+
+  static void init(libtom_integer_type& z, integral_type x)
+  {
+    mpz_init_set_si(z.get_mp_int(), x);
+  }
+
+  static void assign(libtom_integer_type& z, integral_type x)
+  {
+    mpz_set_si(z.get_mp_int(), x);
+  }
+
+  static bool equal(const libtom_integer_type& z, integral_type x)
+  {
+    return mpz_cmp_si(z.get_mp_int(), x) == 0;
+  }
+
+  static bool less(const libtom_integer_type& z, integral_type x)
+  {
+    return mpz_cmp_si(z.get_mp_int(), x) < 0;
+  }
+
+  static void add(libtom_integer_type& z, integral_type x)
+  {
+    mpz_add_ui(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void subtract(libtom_integer_type& z, integral_type x)
+  {
+    mpz_sub_ui(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void multiply(libtom_integer_type& z, integral_type x)
+  {
+    mpz_mul_si(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void divide(libtom_integer_type& z, integral_type x)
+  {
+    mp_intdiv_q_ui(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void modulo(libtom_integer_type& z, integral_type x)
+  {
+    mpz_mod_ui(z.get_mp_int(), z.get_mp_int(), x);
+  }
+
+  static void bitwise_or(libtom_integer_type& z, integral_type x);
+  static void bitwise_and(libtom_integer_type& z, integral_type x);
+  static void bitwise_xor(libtom_integer_type& z, integral_type x);
+};
+
+
+template<
+  class B,
+  typename IntegralT,
+  bool IsSigned = std::numeric_limits<IntegralT>::is_signed,
+  bool FitsIntoLongInt =
+    IsSigned ? (std::numeric_limits<IntegralT>::digits <=
+                std::numeric_limits<signed long int>::digits)
+             : (std::numeric_limits<IntegralT>::digits <=
+                std::numeric_limits<unsigned long int>::digits)
+>
+struct libtom_integer_to_integral;
+
+
+template<class B, typename IntegralT>
+struct libtom_integer_to_integral<B, IntegralT, false, true>
+{
+  static IntegralT convert(const libtom_integer<B>& x)
+  {
+    return static_cast<IntegralT>(mpz_get_ui(x.get_mp_int()));
+  }
+};
+
+
+template<class B, typename IntegralT>
+struct libtom_integer_to_integral<B, IntegralT, true, true>
+{
+  static IntegralT convert(const libtom_integer<B>& x)
+  {
+    return static_cast<IntegralT>(mpz_get_si(x.get_mp_int()));
+  }
+};
+
+
+
+struct libtom_integer_traits
+{
+  typedef mp_digit    digit_type;
+  typedef std::size_t size_type;
+
+  static const size_type  digit_bits      = GMP_LIMB_BITS;
+  static const size_type  radix_bits      = GMP_NUMB_BITS;
+  static const digit_type max_digit_value = GMP_NUMB_MAX;
+};
+
+
+// Same as libtom_allocated_string in libtom-impl.h, but we can't use it because
+// libtom-impl.h is an internal GMP header and is probably not installed.
+extern "C"
+{
+  typedef void (*libtom_free_func)(void *, size_t);
+}
+
+struct libtom_allocated_string
+{
+  char*             str;
+  const std::size_t len;
+
+  libtom_allocated_string(char *s)
+  :
+    str(s), len(std::strlen(s) + 1)
+  {}
+
+  ~libtom_allocated_string()
+  {
+    libtom_free_func f;
+    mp_get_memory_functions (0, 0, &f);
+    (*f)(str, len);
+  }
+};
+
+
+
+} // namespace detail
+
+
+// libtom_original or libtom_boost
+// differences: bitwise ops
+template<class Behavior>
+class libtom_integer
+{
+  mp_int val_;
+
+public:
+
+  static const bool is_signed = true;
+  static const bool is_bounded = false;
+
+  typedef Behavior behavior_type;
+
+  template<typename IntegralT>
+  struct integral_ops
+  :
+    detail::libtom_integer_integral_ops<libtom_integer<Behavior>, IntegralT>
+  {};
+
+  typedef detail::libtom_integer_traits traits_type;
+
+  typedef traits_type::digit_type digit_type;
+  typedef traits_type::size_type  size_type;
+
+  typedef digit_type*                           iterator;
+  typedef const digit_type*                     const_iterator;
+  typedef std::reverse_iterator<iterator>       reverse_iterator;
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+  libtom_integer()
+  {
+    mp_init(&val_);
+  }
+
+  template<typename IntegralT>
+  libtom_integer(IntegralT x,
+              typename enable_if<is_integral<IntegralT> >::type* dummy = 0)
+  {
+    integral_ops<IntegralT>::init(*this, x);
+  }
+
+  libtom_integer(const mp_int& x)
+  {
+    mp_init_copy(&val_, &x);
+  }
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  libtom_integer(mp_int&& x)
+  :
+    val_(x)
+  {}
+  #endif
+
+  explicit libtom_integer(const char* s);
+  explicit libtom_integer(const std::string& s);
+
+  libtom_integer(const char* s,        std::ios_base::fmtflags);
+  libtom_integer(const std::string& s, std::ios_base::fmtflags);
+
+  libtom_integer(const libtom_integer& copy)
+  {
+    mp_init_copy(&val_, ©.val_);
+  }
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  libtom_integer(libtom_integer&& copy)
+  {
+    val_.alloc = copy.val_.alloc;
+    val_.used  = copy.val_.used;
+    val_.dp    = copy.val_.dp;
+    copy.val_.alloc = 0;
+    copy.val_.used  = 0;
+    copy.val_.dp    = 0;
+  }
+  #endif
+
+  ~libtom_integer()
+  {
+    mp_clear(&val_);
+  }
+
+  libtom_integer& operator = (const libtom_integer& rhs)
+  {
+    mp_copy(&rhs.val_, &val);
+    return *this;
+  }
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  libtom_integer& operator = (libtom_integer&& rhs)
+  {
+    mp_clear(&val_);
+    swap(rhs);
+    return *this;
+  }
+  #endif
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, libtom_integer&>::type
+  operator = (IntegralT x)
+  {
+    integral_ops<IntegralT>::assign(*this, x);
+    return *this;
+  }
+
+  template<typename charT>
+  libtom_integer& operator = (const charT* s)
+  {
+    if (mpz_set_str(val_, s, 0) == 0)
+      return *this;
+    else
+      throw std::invalid_argument(
+          "boost::mp_math::libtom_integer: operator = (const charT*)");
+  }
+
+  template<typename charT, class traits, class alloc>
+  libtom_integer& operator = (const std::basic_string<charT,traits,alloc>& s)
+  {
+    if (mpz_set_str(val_, s.c_str(), 0) == 0)
+      return *this;
+    else
+      throw std::invalid_argument(
+          "boost::mp_math::libtom_integer: operator = (const charT*)");
+  }
+
+  template<typename charT>
+  void assign(const charT* s, std::ios_base::fmtflags f)
+  {
+    unsigned radix;
+    if (f & std::ios_base::hex)
+      radix = 16;
+    else if (f & std::ios_base::oct)
+      radix = 8;
+    else
+      radix = 10;
+    if (mp_read_radix(&val_, s, radix) == -1)
+      throw std::invalid_argument(
+          "boost::mp_math::libtom_integer::assign: illformatted string)");
+  }
+
+  // TODO dispatch std::string to mpz_set_string, but dispatch other string
+  // types to detail/string_converter? Could do that but would need support for
+  // NAIL bits.
+  template<typename charT, class traits, class alloc>
+  void assign(const std::basic_string<charT,traits,alloc>& s,
+              std::ios_base::fmtflags f)
+  {
+    unsigned radix;
+    if (f & std::ios_base::hex)
+      radix = 16;
+    else if (f & std::ios_base::oct)
+      radix = 8;
+    else
+      radix = 10;
+    if (mp_read_radix(&val_, s.c_str(), radix) == -1)
+      throw std::invalid_argument(
+          "boost::mp_math::libtom_integer::assign: illformatted string)");
+  }
+
+
+  template<typename RandomAccessIterator>
+  void assign(RandomAccessIterator first, RandomAccessIterator last,
+              std::ios_base::fmtflags);
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  void swap(libtom_integer&& other)
+  #else
+  void swap(libtom_integer& other)
+  #endif
+  {
+    mp_exch(&val_, &other.val_);
+  }
+
+#ifdef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
+private:
+
+  typedef mp_int libtom_integer::*unspecified_bool_type;
+
+public:
+
+  operator unspecified_bool_type() const
+  {
+	  return mp_iszero(&val_) ? 0 : &libtom_integer::val_;
+  }
+#else
+  explicit operator bool() const { return static_cast<bool>(mp_iszero(&val_)); }
+#endif
+
+  bool is_even() const { return mp_iseven(&val_); }
+  bool is_odd () const { return mp_isodd(&val_); }
+
+  bool is_positive() const { return val_.sign >= 0; }
+  bool is_negative() const { return val_.sign < 0; }
+
+  // These two functions use the same signature as GMP's mpz_class
+  mp_int&       get_mp_int()       { return val_; }
+  const mp_int& get_mp_int() const { return val_; }
+
+  size_type size() const { return statc_cast<size_type>(val_.used); }
+
+  digit_type*       digits()       { return val_.dp; }
+  const digit_type* digits() const { return val_.dp; }
+
+  iterator begin() { return digits(); }
+  iterator end  () { return digits(); }
+  const_iterator begin() const { return digits(); }
+  const_iterator end  () const { return digits() + size(); }
+  const_iterator cbegin() const { return digits(); }
+  const_iterator cend  () const { return digits() + size(); }
+  reverse_iterator rbegin() { return reverse_iterator(end  ()); }
+  reverse_iterator rend  () { return reverse_iterator(begin()); }
+  const_reverse_iterator rbegin() const { return const_reverse_iterator(end  ()); }
+  const_reverse_iterator rend  () const { return const_reverse_iterator(begin()); }
+  const_reverse_iterator crbegin() const { return const_reverse_iterator(end  ()); }
+  const_reverse_iterator crend  () const { return const_reverse_iterator(begin()); }
+
+  digit_type&       operator [] (size_type i)       { return val_.dp[i]; }
+  const digit_type& operator [] (size_type i) const { return val_.dp[i]; }
+
+  libtom_integer& operator ++() { mp_add_d(&val_, 1, &val_); return *this; }
+  libtom_integer& operator --() { mp_sub_d(&val_, 1, &val_); return *this; }
+
+  libtom_integer operator ++(int)
+  {
+    libtom_integer tmp;
+    mp_add_d(&val_, 1, &tmp.val_);
+    return tmp;
+  }
+
+  libtom_integer operator --(int)
+  {
+    libtom_integer tmp;
+    mp_sub_d(&val_, 1, &tmp.val_);
+    return tmp;
+  }
+
+  libtom_integer& operator <<= (size_type n)
+  {
+    mp_mul_2d(&val_, n, &val_);
+    return *this;
+  }
+
+  libtom_integer& operator >>= (size_type n)
+  {
+    mp_mul_2d(&val_, n, &val_, 0);
+    return *this;
+  }
+
+  libtom_integer& operator - () { mp_neg(&val_, &val_); return *this; }
+
+  libtom_integer& operator ~ () { mpz_cmp(val_, val_); return *this; }
+
+  libtom_integer& operator += (const libtom_integer& rhs)
+  {
+    mp_add(&val_, &rhs.val_, &val_);
+    return *this;
+  }
+
+  libtom_integer& operator -= (const libtom_integer& rhs)
+  {
+    mp_sub(&val_, &rhs.val_, &val_);
+    return *this;
+  }
+
+  libtom_integer& operator *= (const libtom_integer& rhs)
+  {
+    mp_mul(&val_, &rhs.val_, &val_);
+    return *this;
+  }
+
+  libtom_integer& operator /= (const libtom_integer& rhs)
+  {
+    mp_div(&val_, &rhs.val_, &val_, 0);
+    return *this;
+  }
+
+  libtom_integer& operator %= (const libtom_integer& rhs)
+  {
+    mp_div(&val_, &rhs.val_, 0, &val_);
+    return *this;
+  }
+
+  libtom_integer& operator |= (const libtom_integer& rhs)
+  {
+    behavior_type::bitwise_or(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  libtom_integer& operator &= (const libtom_integer& rhs)
+  {
+    behavior_type::bitwise_and(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  libtom_integer& operator ^= (const libtom_integer& rhs)
+  {
+    behavior_type::bitwise_xor(val_, val_, rhs.val_);
+    return *this;
+  }
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, libtom_integer&>::type
+  operator += (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, libtom_integer&>::type
+  operator -= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, libtom_integer&>::type
+  operator *= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, libtom_integer&>::type
+  operator /= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, libtom_integer&>::type
+  operator %= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, libtom_integer&>::type
+  operator |= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, libtom_integer&>::type
+  operator &= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, libtom_integer&>::type
+  operator ^= (IntegralT);
+
+  template<typename IntegralT>
+  IntegralT to_integral() const
+  {
+    return detail::libtom_integer_to_integral<behavior_type, IntegralT>::
+      convert(*this);
+  }
+
+  template<class StringT>
+  StringT to_string(std::ios_base::fmtflags f =  std::ios_base::fmtflags()) const
+  {
+    int radix;
+    if (f & std::ios_base::hex)
+      radix = 16;
+    else if (f & std::ios_base::oct)
+      radix = 8;
+    else
+      radix = 10;
+
+    const detail::libtom_allocated_string tmp(mpz_get_str(0, radix, val_));
+    return StringT(tmp.str, tmp.str + tmp.len - 1);
+  }
+};
+
+
+template<class B>
+libtom_integer<B>::libtom_integer(const char* s)
+{
+  mp_init(&val_);
+  if (*s != '\0')
+  {
+    if (mpz_init_set_str(val_, s, 0))
+    {
+      if (val_->_mp_d)
+        mpz_clear(val_);
+      throw std::invalid_argument(
+          "boost::mp_math::libtom_integer::libtom_integer(const char*)");
+    }
+  }
+}
+
+template<class B>
+libtom_integer<B>::libtom_integer(const char* s, std::ios_base::fmtflags f)
+{
+  mp_init(&val_);
+  unsigned radix;
+  if (f & std::ios_base::hex)
+    radix = 16;
+  else if (f & std::ios_base::oct)
+    radix = 8;
+  else
+    radix = 10;
+
+  if (*s != '\0')
+  {
+    if (mpz_init_set_str(val_, s, radix))
+    {
+      if (val_->_mp_d)
+        mpz_clear(val_);
+      throw std::invalid_argument(
+          "boost::mp_math::libtom_integer::"
+          "libtom_integer(const char*, std::ios_base::fmtflags)");
+    }
+  }
+}
+
+template<class B>
+libtom_integer<B>::libtom_integer(const std::string& s)
+{
+  mp_init(&val_);
+  if (!s.empty())
+  {
+    if (mpz_init_set_str(val_, s.c_str(), 0))
+    {
+      if (val_->_mp_d)
+        mpz_clear(val_);
+      throw std::invalid_argument(
+          "boost::mp_math::libtom_integer::libtom_integer(const std::string&)");
+    }
+  }
+}
+
+template<class B>
+libtom_integer<B>::libtom_integer(const std::string& s, std::ios_base::fmtflags f)
+{
+  mp_init(&val_);
+  unsigned radix;
+  if (f & std::ios_base::hex)
+    radix = 16;
+  else if (f & std::ios_base::oct)
+    radix = 8;
+  else
+    radix = 10;
+
+  if (!s.empty())
+  {
+    if (mpz_init_set_str(val_, s.c_str(), radix))
+    {
+      if (val_->_mp_d)
+        mpz_clear(val_);
+      throw std::invalid_argument(
+          "boost::mp_math::libtom_integer::"
+          "libtom_integer(const std::string&, std::ios_base::fmtflags)");
+    }
+  }
+}
+
+template<class B>
+inline void swap(libtom_integer<B>& lhs, libtom_integer<B>& rhs)
+{
+  lhs.swap(rhs);
+}
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+template<class B>
+inline void swap(libtom_integer<B>&& lhs, libtom_integer<B>& rhs)
+{
+  lhs.swap(rhs);
+}
+template<class B>
+inline void swap(libtom_integer<B>& lhs, libtom_integer<B>&& rhs)
+{
+  lhs.swap(rhs);
+}
+#endif
+
+
+template<class B>
+inline libtom_integer<B>
+operator << (const libtom_integer<B>& x,
+             typename libtom_integer<B>::size_type n)
+{
+  libtom_integer<B> nrv;
+  mpz_mul_2exp(nrv.get_mp_int(), x.get_mp_int(), n);
+  return nrv;
+}
+
+template<class B>
+inline libtom_integer<B>
+operator >> (const libtom_integer<B>& x,
+             typename libtom_integer<B>::size_type n)
+{
+  libtom_integer<B> nrv;
+  mp_intdiv_q_2exp(nrv.get_mp_int(), x.get_mp_int(), n);
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+operator + (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  libtom_integer<B> nrv;
+  mp_add(&lhs.get_mp_int(), &rhs.get_mp_int(), &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+operator - (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  libtom_integer<B> nrv;
+  mp_sub(&lhs.get_mp_int(), &rhs.get_mp_int(), &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+operator * (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  libtom_integer<B> nrv;
+  mp_mul(&lhs.get_mp_int(), &rhs.get_mp_int(), &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+operator / (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  libtom_integer<B> nrv;
+  mp_div(&lhs.get_mp_int(), &rhs.get_mp_int(), &nrv.get_mp_int(), 0);
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+operator % (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  libtom_integer<B> nrv;
+  mp_div(&lhs.get_mp_int(), &rhs.get_mp_int(), 0, &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+operator | (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  libtom_integer<B> nrv;
+  B::bitwise_or(nrv.get_mp_int(), lhs.get_mp_int(), rhs.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+operator & (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  libtom_integer<B> nrv;
+  B::bitwise_and(nrv.get_mp_int(), lhs.get_mp_int(), rhs.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+operator ^ (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  libtom_integer<B> nrv;
+  B::bitwise_xor(nrv.get_mp_int(), lhs.get_mp_int(), rhs.get_mp_int());
+  return nrv;
+}
+
+// Arithmetic and bitwise operators involving integral types
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B>&>::type
+libtom_integer<B>::operator += (IntegralT rhs)
+{
+  integral_ops<IntegralT>::add(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B>&>::type
+libtom_integer<B>::operator -= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::subtract(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B>&>::type
+libtom_integer<B>::operator *= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::multiply(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B>&>::type
+libtom_integer<B>::operator /= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::divide(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B>&>::type
+libtom_integer<B>::operator %= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::modulo(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B>&>::type
+libtom_integer<B>::operator |= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_or(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B>&>::type
+libtom_integer<B>::operator &= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_and(*this, rhs);
+  return *this;
+}
+
+template<class B>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B>&>::type
+libtom_integer<B>::operator ^= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_xor(*this, rhs);
+  return *this;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B> >::type
+operator + (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  libtom_integer<B> nrv(lhs);
+  nrv += rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B> >::type
+operator - (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  libtom_integer<B> nrv(lhs);
+  nrv -= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B> >::type
+operator * (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  libtom_integer<B> nrv(lhs);
+  nrv *= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B> >::type
+operator / (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  libtom_integer<B> nrv(lhs);
+  nrv /= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B> >::type
+operator % (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  libtom_integer<B> nrv(lhs);
+  nrv %= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B> >::type
+operator | (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  libtom_integer<B> nrv(lhs);
+  nrv |= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B> >::type
+operator & (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  libtom_integer<B> nrv(lhs);
+  nrv &= rhs;
+  return nrv;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, libtom_integer<B> >::type
+operator ^ (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  libtom_integer<B> nrv(lhs);
+  nrv ^= rhs;
+  return nrv;
+}
+
+
+template<class B>
+inline bool operator == (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  return mp_cmp(&lhs.get_mp_int(), &rhs.get_mp_int()) == MP_EQ;
+}
+
+template<class B>
+inline bool operator != (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  return mp_cmp(&lhs.get_mp_int(), &rhs.get_mp_int()) != MP_EQ;
+}
+
+template<class B>
+inline bool operator < (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  return mp_cmp(&lhs.get_mp_int(), &rhs.get_mp_int()) == MP_LT;
+}
+
+template<class B>
+inline bool operator > (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  return mp_cmp(&lhs.get_mp_int(), &rhs.get_mp_int()) == MP_GT;
+}
+
+template<class B>
+inline bool operator <= (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  return mp_cmp(&lhs.get_mp_int(), &rhs.get_mp_int()) <= 0;
+}
+
+template<class B>
+inline bool operator >= (const libtom_integer<B>& lhs, const libtom_integer<B>& rhs)
+{
+  return mp_cmp(&lhs.get_mp_int(), &rhs.get_mp_int()) >= 0;
+}
+
+// compare unbounded_int to integral
+/*template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  return detail::unbounded_int_integral_ops<
+    libtom_integer<B>, IntegralT>::equal(lhs, rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  return detail::unbounded_int_integral_ops<
+    libtom_integer<B>, IntegralT>::less(lhs, rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  return rhs < lhs;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  return (lhs < rhs) || (lhs == rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (const libtom_integer<B>& lhs, IntegralT rhs)
+{
+  return !(lhs < rhs);
+}
+
+// compare integral to unbounded_int
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (IntegralT lhs, const libtom_integer<B>& rhs)
+{
+  return rhs == lhs;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (IntegralT lhs, const libtom_integer<B>& rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (IntegralT lhs, const libtom_integer<B>& rhs)
+{
+  return !(rhs <= lhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (IntegralT lhs, const libtom_integer<B>& rhs)
+{
+  return rhs < lhs;
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (IntegralT lhs, const libtom_integer<B>& rhs)
+{
+  return !(rhs < lhs);
+}
+
+template<class B, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (IntegralT lhs, const libtom_integer<B>& rhs)
+{
+  return rhs <= lhs;
+}*/
+
+// compare unbounded_int to const charT*
+template<class B, typename charT>
+inline bool
+operator == (const libtom_integer<B>& lhs, const charT* rhs)
+{
+  return lhs == libtom_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator != (const libtom_integer<B>& lhs, const charT* rhs)
+{
+  return lhs != libtom_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator < (const libtom_integer<B>& lhs, const charT* rhs)
+{
+  return lhs < libtom_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator > (const libtom_integer<B>& lhs, const charT* rhs)
+{
+  return lhs > libtom_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator <= (const libtom_integer<B>& lhs, const charT* rhs)
+{
+  return lhs <= libtom_integer<B>(rhs);
+}
+
+template<class B, typename charT>
+inline bool
+operator >= (const libtom_integer<B>& lhs, const charT* rhs)
+{
+  return lhs >= libtom_integer<B>(rhs);
+}
+
+// comparison const charT* to unbounded_int
+template<class B, typename charT>
+inline bool
+operator == (const charT* lhs, const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) == rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator != (const charT* lhs, const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) != rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator < (const charT* lhs, const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) < rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator > (const charT* lhs, const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) > rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator <= (const charT* lhs, const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) <= rhs;
+}
+
+template<class B, typename charT>
+inline bool
+operator >= (const charT* lhs, const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) >= rhs;
+}
+
+// compare unbounded_int to basic_string
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator == (const libtom_integer<B>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs == libtom_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator != (const libtom_integer<B>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs != libtom_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator < (const libtom_integer<B>& lhs,
+            const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs < libtom_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator > (const libtom_integer<B>& lhs,
+            const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs > libtom_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const libtom_integer<B>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs <= libtom_integer<B>(rhs);
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const libtom_integer<B>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs >= libtom_integer<B>(rhs);
+}
+
+// compare basic_string to unbounded_int
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator == (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) == rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator != (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) != rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator < (const std::basic_string<charT,Traits,Alloc>& lhs,
+            const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) < rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator > (const std::basic_string<charT,Traits,Alloc>& lhs,
+            const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) > rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) <= rhs;
+}
+
+template<class B, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const libtom_integer<B>& rhs)
+{
+  return libtom_integer<B>(lhs) >= rhs;
+}
+
+// Input/Output
+template<class B, typename charT, class traits>
+std::basic_istream<charT, traits>&
+operator >> (std::basic_istream<charT, traits>& is, libtom_integer<B>&)
+{
+  return is;
+}
+
+template<class B, typename charT, class traits>
+std::basic_ostream<charT, traits>&
+operator << (std::basic_ostream<charT, traits>& os, const libtom_integer<B>& x)
+{
+  return os << x.template to_string<std::string>(os.flags());
+}
+
+
+
+template<class B>
+inline libtom_integer<B> abs(const libtom_integer<B>& x)
+{
+  libtom_integer<B> nrv;
+  mp_abs(&x.get_mp_int(), &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline libtom_integer<B> gcd(const libtom_integer<B>& x, const libtom_integer<B>& y)
+{
+  libtom_integer<B> nrv;
+  mp_gcd(&x.get_mp_int(), &y.get_mp_int(), &nrv.get_mp_int());
+  return nrv;
+}
+
+#ifndef BOOST_NO_VARIADIC_TEMPLATES
+template<class B, class... LTMInteger>
+libtom_integer<B> gcd(const libtom_integer<B>& a,
+                   const libtom_integer<B>& b,
+                   const LTMInteger&... args)
+{
+  return gcd(gcd(a, b), args...);
+}
+#endif
+
+template<class B>
+inline libtom_integer<B> lcm(const libtom_integer<B>& x, const libtom_integer<B>& y)
+{
+  libtom_integer<B> nrv;
+  mp_lcm(&x.get_mp_int(), &y.get_mp_int(), &nrv.get_mp_int());
+  return nrv;
+}
+
+#ifndef BOOST_NO_VARIADIC_TEMPLATES
+template<class B, class... LTMInteger>
+libtom_integer<B> lcm(const libtom_integer<B>& a,
+                   const libtom_integer<B>& b,
+                   const LTMInteger&... args)
+{
+  return lcm(lcm(a, b), args...);
+}
+#endif
+
+template<class B>
+inline
+libtom_integer<B>
+pow(const libtom_integer<B>& x, typename libtom_integer<B>::digit_type y)
+{
+  libtom_integer<B> nrv;
+  mp_expt_d(&x.get_mp_int(), y, &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B> pow(const libtom_integer<B>& x, const libtom_integer<B>& y)
+{
+  libtom_integer<B> nrv;
+  mp_expt_d(&x.get_mp_int(),
+            y.template to_integral<unsigned long>(),
+            &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+sqrt(const libtom_integer<B>& x)
+{
+  libtom_integer<B> nrv;
+  mp_sqrt(&x.get_mp_int(), &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+nth_root(typename libtom_integer<B>::digit_type n, const libtom_integer<B>& x)
+{
+  libtom_integer<B> nrv;
+  mp_n_root(&x.get_mp_int(), n, &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+nth_root(const libtom_integer<B>& n, const libtom_integer<B>& x)
+{
+  libtom_integer<B> nrv;
+  mp_n_root(&x.get_mp_int(), n, &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B>
+modinv(const libtom_integer<B>& x, const libtom_integer<B>& m)
+{
+  libtom_integer<B> nrv;
+  mp_invmod(&x.get_mp_int(), &m.get_mp_int(), &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+libtom_integer<B> modpow(const libtom_integer<B>& base,
+                         const libtom_integer<B>& exp,
+                         const libtom_integer<B>& mod,
+                         modpow_ctx<libtom_integer<B> >* ctx = 0)
+{
+  libtom_integer<B> nrv;
+  mp_exptmod(&base.get_mp_int(), &exp.get_mp_int(), &mod.get_mp_int(),
+             &nrv.get_mp_int());
+  return nrv;
+}
+
+template<class B>
+inline
+int jacobi(const libtom_integer<B>& x, const libtom_integer<B>& y)
+{
+  int j;
+  mp_jacobi(&x.get_mp_int(), &y.get_mp_int(), &j);
+  return j;
+}
+
+
+
+} // namespace mp_math
+} // namespace boost
+
+#endif
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/mod.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/mod.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,27 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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 % 2**b
-template<class A, class T>
-void mp_int<A,T>::modulo_2_to_the_power_of(size_type b)
-{
-  // if modulus >= *this then return
-  if (b >= size_ * valid_bits)
-    return;
-
-  // zero digits above the last digit of the modulus
-  const size_type offset = (b / valid_bits) + ((b % valid_bits) == 0 ? 0 : 1);
-  std::memset(digits_ + offset, 0, sizeof(digit_type) * (size_ - offset));
-
-  // clear remaining high bits
-  const digit_type mask = (1 << (static_cast<digit_type>(b % valid_bits))) - 1;
-  digits_[b / valid_bits] &= mask;
-  
-  clamp();
-
-  if (!*this)
-    set_sign(1);
-}
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/modinv.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/modinv.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,41 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_MODINV_HPP
-#define BOOST_MP_MATH_MP_INT_MODINV_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-#include <boost/mp_math/mp_int/detail/modinv.hpp>
-
-
-namespace boost {
-namespace mp_math {
-
-
-// hac 14.61, pp608
-// returns the modular multiplicative inverse x of a (mod m) such that
-//  x*a = 1 (mod m)  =>
-// a^-1 = x (mod m)
-// The inverse exists only if a and m are coprime (i.e. gcd(a,m) = 1).
-// If no inverse exists this function will throw std::domain_error.
-template<class A, class T>
-mp_int<A,T> modinv(const mp_int<A,T>& a, const mp_int<A,T>& m)
-{
-  if (m.is_negative() || !m)
-    throw std::domain_error("modinv: modulus is negative or zero");
-
-  // if the modulus is odd we can use a faster routine
-  if (m.is_odd())
-    return detail::odd_modinv(a, m);
-  else
-    return detail::even_modinv(a, m);
-}
-
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/modpow.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/modpow.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,70 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_MODPOW_HPP
-#define BOOST_MP_MATH_MP_INT_MODPOW_HPP
-
-#include <boost/mp_math/mp_int/modpow_ctx.hpp>
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-#include <boost/mp_math/mp_int/detail/modpow.hpp>
-#include <boost/mp_math/mp_int/detail/modular_reduction.hpp>
-
-namespace boost {
-namespace mp_math {
-
-// z = base^exp % mod
-template<class A, class T>
-mp_int<A,T> modpow(const mp_int<A,T>& base,
-                   const mp_int<A,T>& exp,
-                   const mp_int<A,T>& mod,
-                   modpow_ctx<A,T>*   ctx = 0)
-{
-  if (mod.is_negative())
-    throw std::domain_error("modpow: modulus must be positive");
-
-  typedef modpow_ctx<A,T> ctx_t;
-  
-  ctx_t tmp_ctx;
-  
-  if (!ctx)
-  {
-    tmp_ctx.detect_modulus_type(mod);
-    tmp_ctx.precalculate(mod);
-    ctx = &tmp_ctx;
-  }
-  else
-  {
-    if (!ctx->precalculated)
-    {
-      ctx->detect_modulus_type(mod);
-      ctx->precalculate(mod);
-    }
-  }
-
-  if (exp.is_negative())
-    return modpow(modinv(base, mod), abs(exp), mod, ctx);
-
-  switch (ctx->modulus_type)
-  {
-    case ctx_t::mod_restricted_dr:
-      return detail::montgomery_modpow(base, exp, mod, 1, ctx->rho);
-    case ctx_t::mod_unrestricted_dr:
-      return detail::montgomery_modpow(base, exp, mod, 2, ctx->rho);
-    case ctx_t::mod_unrestricted_dr_slow:
-      return detail::barret_modpow    (base, exp, mod, 1, ctx->mu);
-    case ctx_t::mod_odd:
-      return detail::montgomery_modpow(base, exp, mod, 0, ctx->rho);
-    case ctx_t::mod_generic:
-    default:
-      return detail::barret_modpow    (base, exp, mod, 0, ctx->mu);
-  }
-}
-
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/modpow_ctx.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/modpow_ctx.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,185 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_MODPOW_CTX_HPP
-#define BOOST_MP_MATH_MP_INT_MODPOW_CTX_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-
-namespace boost {
-namespace mp_math {
-
-
-// r = x mod m given x and m
-template<class A, class T>
-struct modpow_ctx
-{
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  typedef typename mp_int<A,T>::word_type  word_type;
-  typedef typename mp_int<A,T>::size_type  size_type;
-
-  // dr means diminished radix
-  enum modulus_type_t
-  {                           // R is our radix, i.e. digit_max
-    mod_restricted_dr,        // m = R**k - d; d <= R
-    mod_unrestricted_dr,      // m = 2**k - d; d <= R
-    mod_unrestricted_dr_slow, // m = 2**k - d; d <  d**(k/2)
-    mod_odd,
-    mod_generic
-  }modulus_type;
-
-  modpow_ctx() : precalculated(false){}
-
-  modulus_type_t do_detect(const mp_int<A,T>& m) const;
-
-  void detect_modulus_type(const mp_int<A,T>& m)
-  {
-    modulus_type = do_detect(m);
-  }
-  
-  void precalculate(const mp_int<A,T>& m);
-
-  mp_int<A,T> mu;
-  digit_type rho;
-  bool precalculated;
-};
-
-
-template<class A, class T>
-typename modpow_ctx<A,T>::modulus_type_t
-modpow_ctx<A,T>::do_detect(const mp_int<A,T>& m) const
-{
-  if (m.size() == 1)
-    return mod_unrestricted_dr;
-
-  typename mp_int<A,T>::size_type count = 0;
-
-  const int bits = m.precision() % mp_int<A,T>::valid_bits;
-  
-  if (!bits && m[m.size()-1] == mp_int<A,T>::digit_max)
-    ++count;
-
-  for (typename mp_int<A,T>::const_reverse_iterator d = m.rbegin() + 1;
-       d != m.rend(); ++d)
-  {
-    if (*d != mp_int<A,T>::digit_max)
-      break;
-    else
-      ++count;
-  }
-
-  // if all bits are set
-  if (count == m.size() - 1)
-    return mod_restricted_dr;
-  
-  // if all bits until the most significant digit are set
-  if (count == m.size() - 2)
-  {
-    bool all_bits_set = true;
-    
-    // handle the remaining bits in the most significant digit
-    typename mp_int<A,T>::digit_type mask = 1;
-    for (int i = 0; i < bits; ++i)
-    {
-      if ((m[m.size()-1] & mask) == 0)
-      {
-        all_bits_set = false;
-        break;
-      }
-      mask <<= 1;
-    }
-    if (all_bits_set)
-      return mod_unrestricted_dr;
-  }
-
-  // if more than half of the bits are set
-  if (count >= m.size() / 2)
-    return mod_unrestricted_dr_slow;
-
-  if (m.is_odd())
-    return mod_odd;
-
-  return mod_generic;
-}
-
-template<class A, class T>
-void modpow_ctx<A,T>::precalculate(const mp_int<A,T>& m)
-{
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  typedef typename mp_int<A,T>::word_type  word_type;
-
-  switch (modulus_type)
-  {
-    case mod_restricted_dr:
-    {
-      rho = (word_type(1) << static_cast<word_type>(mp_int<A,T>::valid_bits))
-          - static_cast<word_type>(m[0]);
-      break;
-    }
-    case mod_unrestricted_dr:
-    {
-      const size_type p = m.precision();
-
-      mp_int<A,T> tmp;
-      tmp.pow2(p);
-      tmp.sub_smaller_magnitude(m);
-
-      rho = tmp[0];
-      break;
-    }
-    case mod_unrestricted_dr_slow:
-    {
-      mp_int<A,T> tmp;
-
-      tmp.pow2(m.precision());
-      mu = tmp - m;
-      break;
-    }
-    case mod_odd:
-    {
-      assert(m.is_odd());
-
-      // fast inversion mod 2**k
-      //
-      // Based on the fact that
-      //
-      // XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
-      //                    =>  2*X*A - X*X*A*A = 1
-      //                    =>  2*(1) - (1)     = 1
-      const digit_type b = m[0];
-
-      static const typename mp_int<A,T>::size_type S = 
-        sizeof(digit_type) * std::numeric_limits<unsigned char>::digits;
-
-      digit_type x = (((b + 2) & 4) << 1) + b; // here x*a==1 mod 2**4
-      x *= 2 - b * x;                          // here x*a==1 mod 2**8
-      if (S != 8)
-        x *= 2 - b * x;                        // here x*a==1 mod 2**16
-      if (S == 64 || !(S == 8 || S == 16))
-        x *= 2 - b * x;                        // here x*a==1 mod 2**32
-      if (S == 64)
-        x *= 2 - b * x;                        // here x*a==1 mod 2**64
-
-      // rho = -1/m mod b
-      rho = (word_type(1) << (static_cast<word_type>(mp_int<A,T>::valid_bits))) - x;
-      break;
-    }
-    case mod_generic:
-    {
-      // mu = b**2k/m
-      mu.pow2(m.size() * 2 * mp_int<A,T>::digit_bits);
-      mu /= m;
-      break;
-    }
-  }
-  precalculated = true;
-}
-
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/mp_int.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/mp_int.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,914 +0,0 @@
-// Copyright Kevin Sopp 2008 - 2009.
-// 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_MP_MATH_MP_INT_MP_INT_HPP
-#define BOOST_MP_MATH_MP_INT_MP_INT_HPP
-
-#include <algorithm>
-#include <cassert>
-#include <cstring>
-#include <iosfwd>
-#include <iterator> // reverse_iterator
-#include <limits>
-#include <stdexcept>
-#include <sstream>
-#include <string>
-
-#include <boost/config.hpp>
-#include <boost/random.hpp>
-#include <boost/type_traits/is_integral.hpp>
-#include <boost/utility/enable_if.hpp>
-#include <boost/mp_math/mp_int/detail/div.hpp>
-#include <boost/mp_math/mp_int/detail/string_conversion_constants.hpp>
-#include <boost/mp_math/mp_int/detail/integral_ops.hpp>
-#include <boost/mp_math/mp_int/detail/meta_math.hpp>
-#include <boost/mp_math/mp_int/detail/primitive_ops.hpp>
-
-
-namespace boost {
-namespace mp_math {
-
-template<
-  class Allocator,
-  class Traits
->
-struct mp_int
-:
-  Allocator::template rebind<typename Traits::digit_type>::other
-{
-private:
-
-  typedef typename Allocator::template
-    rebind<typename Traits::digit_type>::other base_allocator_type;
-
-public:
-
-  typedef Allocator                               allocator_type;
-  typedef Traits                                  traits_type;
-  typedef typename base_allocator_type::size_type size_type;
-
-  mp_int();
-
-  explicit mp_int(const allocator_type& a);
-
-  template<typename IntegralT>
-  mp_int(IntegralT,
-         const allocator_type& a = allocator_type(),
-         typename enable_if<is_integral<IntegralT> >::type* dummy = 0);
-
-  template<typename charT>
-  mp_int(const charT*, const allocator_type& a = allocator_type());
-
-  template<typename charT>
-  mp_int(const charT*,
-         std::ios_base::fmtflags,
-         const allocator_type& a = allocator_type());
-
-  template<typename charT, class traits, class Alloc>
-  mp_int(const std::basic_string<charT,traits,Alloc>&,
-         const allocator_type& a = allocator_type());
-
-  template<typename charT, class traits, class Alloc>
-  mp_int(const std::basic_string<charT,traits,Alloc>&,
-         std::ios_base::fmtflags,
-         const allocator_type& a = allocator_type());
-
-  template<typename RandomAccessIterator>
-  mp_int(RandomAccessIterator first,
-         RandomAccessIterator last,
-         const allocator_type& a = allocator_type());
-
-  template<typename RandomAccessIterator>
-  mp_int(RandomAccessIterator first,
-         RandomAccessIterator last,
-         std::ios_base::fmtflags f,
-         const allocator_type& a = allocator_type());
-
-  mp_int(const mp_int& copy);
-
-  #ifdef BOOST_HAS_RVALUE_REFS
-  mp_int(mp_int&& copy);
-  #endif
-
-  ~mp_int();
-
-  mp_int& operator = (const mp_int& rhs);
-
-  #ifdef BOOST_HAS_RVALUE_REFS
-  mp_int& operator = (mp_int&& rhs);
-  #endif
-
-  template<typename IntegralT>
-  mp_int& operator = (IntegralT rhs);
-
-  template<typename charT>
-  mp_int& operator = (const charT*);
-
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator = (const std::basic_string<charT,traits,Alloc>&);
-
-  template<typename charT>
-  void assign(const charT*, std::ios_base::fmtflags);
-
-  template<typename charT, class traits, class Alloc>
-  void assign(const std::basic_string<charT,traits,Alloc>&,
-              std::ios_base::fmtflags);
-
-  template<typename RandomAccessIterator>
-  void assign(RandomAccessIterator first, RandomAccessIterator last,
-              std::ios_base::fmtflags);
-
-  #ifdef BOOST_HAS_RVALUE_REFS
-  void swap(mp_int&& other);
-  #else
-  void swap(mp_int& other);
-  #endif
-
-  mp_int& operator ++();
-  mp_int& operator --();
-  mp_int  operator ++(int);
-  mp_int  operator --(int);
-  mp_int& operator <<= (size_type);
-  mp_int& operator >>= (size_type);
-  mp_int& operator - ();
-
-  mp_int& operator += (const mp_int&);
-  mp_int& operator -= (const mp_int&);
-  mp_int& operator *= (const mp_int&);
-  mp_int& operator /= (const mp_int&);
-  mp_int& operator %= (const mp_int&);
-  mp_int& operator |= (const mp_int&);
-  mp_int& operator &= (const mp_int&);
-  mp_int& operator ^= (const mp_int&);
-
-  template<typename IntegralT> mp_int& operator += (IntegralT);
-  template<typename IntegralT> mp_int& operator -= (IntegralT);
-  template<typename IntegralT> mp_int& operator *= (IntegralT);
-  template<typename IntegralT> mp_int& operator /= (IntegralT);
-  template<typename IntegralT> mp_int& operator %= (IntegralT);
-  template<typename IntegralT> mp_int& operator |= (IntegralT);
-  template<typename IntegralT> mp_int& operator &= (IntegralT);
-  template<typename IntegralT> mp_int& operator ^= (IntegralT);
-
-  template<typename charT> mp_int& operator += (const charT*);
-  template<typename charT> mp_int& operator -= (const charT*);
-  template<typename charT> mp_int& operator *= (const charT*);
-  template<typename charT> mp_int& operator /= (const charT*);
-  template<typename charT> mp_int& operator %= (const charT*);
-  template<typename charT> mp_int& operator |= (const charT*);
-  template<typename charT> mp_int& operator &= (const charT*);
-  template<typename charT> mp_int& operator ^= (const charT*);
-
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator += (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator -= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator *= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator /= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator %= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator |= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator &= (const std::basic_string<charT,traits,Alloc>&);
-  template<typename charT, class traits, class Alloc>
-  mp_int& operator ^= (const std::basic_string<charT,traits,Alloc>&);
-
-  allocator_type get_allocator() const { return allocator_type(); }
-
-private:
-
-  typedef size_type mp_int::*unspecified_bool_type;
-
-public:
-
-  operator unspecified_bool_type() const
-  {
-	  return !(size_ == 1 && digits_[0] == 0) ? &mp_int::size_ : 0;
-  }
-
-  bool is_even() const { return (digits_[0] & digit_type(1)) == 0; }
-  bool is_odd () const { return (digits_[0] & digit_type(1)) == 1; }
-
-  bool is_positive() const { return sign() ==  1; }
-  bool is_negative() const { return sign() == -1; }
-
-  template<class StringT>
-  StringT to_string(std::ios_base::fmtflags f = std::ios_base::dec) const;
-
-  template<typename IntegralT>
-  IntegralT to_integral() const;
-
-public: // low level interface
-
-  typedef typename traits_type::digit_type        digit_type;
-  typedef typename traits_type::word_type         word_type;
-  typedef typename traits_type::digit_type*       iterator;
-  typedef const typename traits_type::digit_type* const_iterator;
-  typedef std::reverse_iterator<iterator>         reverse_iterator;
-  typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
-  typedef detail::primitive_ops<digit_type, word_type, size_type> ops_type;
-
-  // bits per digit, we subtract one because we count from 0
-  static const int valid_bits = std::numeric_limits<digit_type>::digits;
-  static const int digit_bits = std::numeric_limits<digit_type>::digits;
-  // used to mask off the most significant bit(s)
-  static const digit_type mp_mask = (word_type(1) << valid_bits) - 1;
-  static const size_type mp_warray = 512;
-    //1 << (std::numeric_limits<word_type>::digits - 2 * valid_bits + 1);
-  static const digit_type digit_max = static_cast<digit_type>(-1);
-
-  static const size_type sign_bit =
-    size_type(1) << (std::numeric_limits<size_type>::digits - 1U);
-
-  template<typename RandomAccessIterator>
-  void init(RandomAccessIterator first, RandomAccessIterator last);
-
-  template<typename RandomAccessIterator>
-  void init(RandomAccessIterator first, RandomAccessIterator last,
-            std::ios_base::fmtflags f);
-
-  iterator       begin()       { return digits_;         }
-  iterator       end  ()       { return digits_ + size_; }
-  const_iterator begin() const { return digits_;         }
-  const_iterator end  () const { return digits_ + size_; }
-  reverse_iterator       rbegin()       { return reverse_iterator(end());   }
-  reverse_iterator       rend  ()       { return reverse_iterator(begin()); }
-  const_reverse_iterator rbegin() const { return const_reverse_iterator(end());   }
-  const_reverse_iterator rend  () const { return const_reverse_iterator(begin()); }
-
-  digit_type&       operator[](size_type i)       { return digits_[i]; }
-  const digit_type& operator[](size_type i) const { return digits_[i]; }
-
-  digit_type&       at(size_type i)
-  {
-    if (i >= size_)
-      throw std::out_of_range("mp_int::at: array subscript out of range");
-    return digits_[i];
-  }
-
-  const digit_type& at(size_type i) const
-  {
-    if (i >= size_)
-      throw std::out_of_range("mp_int::at: array subscript out of range");
-    return digits_[i];
-  }
-
-  void push(digit_type x) { digits_[size_++] = x; }
-  void pop() { --size_; }
-
-  void zero();
-
-  // debug functionality
-  void print(bool all=false) const;
-  bool test_invariants() const;
-
-  bool is_uninitialized() const { return !size_; }
-
-  size_type size() const { return size_; }
-  size_type capacity() const
-  {
-    return capacity_ & ~sign_bit;
-  }
-
-  void set_capacity(size_type c)
-  {
-    capacity_ &= sign_bit;
-    capacity_ |= c;
-  }
-
-  void set_size(size_type s) { size_ = s; }
-
-  int sign() const
-  {
-    return (capacity_ & sign_bit) ? -1 : 1;
-  }
-
-  void set_sign(int s)
-  {
-    if (s == 1)
-      capacity_ &= ~sign_bit;
-    else
-      capacity_ |= sign_bit;
-  }
-
-  digit_type*       digits()       { return digits_; }
-  const digit_type* digits() const { return digits_; }
-
-  void grow_capacity(size_type n);
-  void clamp();
-  void clamp_high_digit();
-
-  int compare_magnitude(const mp_int& rhs) const;
-  int compare_to_digit(digit_type) const;
-  int compare(const mp_int& rhs) const;
-
-  void add_magnitude(const mp_int& rhs);
-  void sub_smaller_magnitude(const mp_int& rhs);
-
-  bool is_power_of_two() const;
-  void add_digit(digit_type);
-  void sub_digit(digit_type);
-
-  void shift_digits_left(size_type);
-  void shift_digits_right(size_type);
-
-  void multiply_by_digit(digit_type);
-  void karatsuba_mul(const mp_int&);
-  void toom_cook_mul(const mp_int&);
-  void multiply_by_2();
-  void mul_digits(const mp_int&, size_type num_digits);
-  void mul_high_digits(const mp_int&, size_type num_digits);
-  void fast_mul_digits(const mp_int&, size_type num_digits);
-  void fast_mul_high_digits(const mp_int&, size_type num_digits);
-
-  void sqr();
-  void toom_sqr();
-  void karatsuba_sqr();
-  void comba_sqr();
-
-  digit_type divide_by_digit(digit_type); // returns remainder
-  void divide_by_2();
-  digit_type divide_by_3();
-  void modulo_2_to_the_power_of(size_type);
-  size_type count_lsb() const;
-  void shift_right(size_type b, mp_int* remainder);
-
-  void pow2(size_type b);
-
-  void set_least_significant_bit()
-  {
-    digits_[0] |= digit_type(1);
-  }
-
-  void set_bit(size_type bit)
-  {
-    digits_[bit / valid_bits] |= digit_type(1) << (bit % valid_bits);
-  }
-
-  void clear_bit(size_type bit)
-  {
-    digits_[bit / valid_bits] &= ~(digit_type(1) << (bit % valid_bits));
-  }
-
-  void set_bits(size_type beg, size_type end);
-  void clear_bits(size_type beg, size_type end);
-
-  void truncate(size_type prec);
-
-  size_type precision() const;
-
-  void set_precision(size_type bits)
-  {
-    size_ = (bits + (valid_bits - 1)) / valid_bits;
-  }
-
-  template<class A, class T>
-  friend bool operator == (const mp_int<A,T>&, const mp_int<A,T>&);
-
-  template<class A, class T>
-  friend bool operator < (const mp_int<A,T>&, const mp_int<A,T>&);
-
-  template<typename Iter>
-  void from_string(Iter first, Iter last, unsigned radix);
-
-private:
-
-  digit_type* digits_;
-  size_type size_, capacity_;
-};
-
-
-
-template<class A, class T>
-void mp_int<A,T>::print(bool all) const
-{
-  using std::cout;
-  if (is_negative())
-  cout << '-';
-  cout << size_ << "{";
-  for (size_type i = 0; i < size_; ++i)
-  {
-    cout << static_cast<word_type>(digits_[i]);
-    if (i < size_  - 1)
-      cout << ",";
-  }
-  cout << "}";
-
-  if (all)
-  {
-    cout << capacity() - size_ << "{";
-    for (size_type i = size_; i < capacity(); ++i)
-    {
-      cout << static_cast<word_type>(digits_[i]);
-      if (i < capacity()  - 1)
-        cout << ",";
-    }
-    cout << "}";
-  }
-  cout << "\n";
-}
-
-template<class A, class T>
-bool mp_int<A,T>::test_invariants() const
-{
-  if (size_) // don't test uninitialized mp_ints
-  {
-    if (size_ > capacity())
-      return false;
-    if (digits_[size_-1] == 0U)
-      return false;
-    if (!*this && sign() != 1)
-      return false;
-  }
-  return true;
-}
-
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator = (const mp_int<A,T>& rhs)
-{
-  if (this != &rhs)
-  {
-    if ((capacity() == 0) || (capacity() < rhs.capacity()))
-      mp_int(rhs).swap(*this);
-    else
-    {
-      std::memcpy(digits_, rhs.digits_, rhs.size_ * sizeof(digit_type));
-      size_ = rhs.size_;
-      set_sign(rhs.sign());
-    }
-  }
-  return *this;
-}
-
-#ifdef BOOST_HAS_RVALUE_REFS
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator = (mp_int<A,T>&& rhs)
-{
-  if (this != &rhs)
-  {
-    if (digits_)
-      this->deallocate(digits_, capacity());
-    digits_ = 0;
-    size_ = 0;
-    capacity_ = 0;
-    swap(rhs);
-  }
-  return *this;
-}
-#endif
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator = (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::assign(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename charT>
-mp_int<A,T>& mp_int<A,T>::operator = (const charT* s)
-{
-  size_ = 0;
-  init(s, s + std::char_traits<charT>::length(s));
-  return *this;
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-mp_int<A,T>& mp_int<A,T>::operator = (const std::basic_string<charT,traits,Alloc>& s)
-{
-  size_ = 0;
-  init(s.begin(), s.end());
-  return *this;
-}
-
-template<class A, class T>
-template<typename charT>
-inline void
-mp_int<A,T>::assign(const charT* s, std::ios_base::fmtflags f)
-{
-  assign(s, s + std::char_traits<charT>::length(s), f);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline void
-mp_int<A,T>::assign(const std::basic_string<charT,traits,Alloc>& s,
-                    std::ios_base::fmtflags f)
-{
-  assign(s.begin(), s.end(), f);
-}
-
-template<class A, class T>
-template<typename RandomAccessIterator>
-inline void
-mp_int<A,T>::assign(RandomAccessIterator first, RandomAccessIterator last,
-                    std::ios_base::fmtflags f)
-{
-  size_ = 0;
-  init(first, last, f);
-}
-
-
-template<class A, class T>
-#ifdef BOOST_HAS_RVALUE_REFS
-void mp_int<A,T>::swap(mp_int&& other)
-#else
-void mp_int<A,T>::swap(mp_int& other)
-#endif
-{
-  std::swap(digits_, other.digits_);
-  std::swap(size_, other.size_);
-  std::swap(capacity_, other.capacity_);
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator += (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::add(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator -= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::subtract(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator *= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::multiply(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator /= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::divide(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator %= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::modulo(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator |= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::bitwise_or(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator &= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::bitwise_and(*this, rhs);
-  return *this;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline mp_int<A,T>& mp_int<A,T>::operator ^= (IntegralT rhs)
-{
-  detail::integral_ops<IntegralT>::bitwise_xor(*this, rhs);
-  return *this;
-}
-
-
-template<class A, class T>
-void mp_int<A,T>::zero()
-{
-  grow_capacity(1);
-  digits_[0] = 0;
-  size_ = 1;
-  set_sign(1);
-}
-
-template<class A, class T>
-void mp_int<A,T>::grow_capacity(size_type n)
-{
-  if (capacity() < n)
-  {
-    if (n < sign_bit)
-    {
-      const size_type new_cap = capacity() + capacity();
-      if (new_cap > n)
-        n = new_cap;
-      digit_type* d = this->allocate(n, digits_);
-      std::memcpy(d, digits_, sizeof(digit_type) * size_);
-      this->deallocate(digits_, capacity());
-      digits_ = d;
-      set_capacity(n);
-    }
-    else
-      throw std::bad_alloc();
-  }
-}
-
-// This is used to ensure that leading zero digits are trimmed.
-template<class A, class T>
-void mp_int<A,T>::clamp()
-{
-  while (size_ > 1 && digits_[size_-1] == 0)
-    --size_;
-}
-
-// For when we know that only one leading zero digit may exist.
-template<class A, class T>
-inline void mp_int<A,T>::clamp_high_digit()
-{
-  if (size_ > 1 && digits_[size_-1] == 0)
-    --size_;
-}
-
-// disregards the sign of the numbers
-// return 1 if *this is greater
-// returns 0 if both are equal
-// return -1 if *this is smaller
-template<class A, class T>
-int mp_int<A,T>::compare_magnitude(const mp_int& rhs) const
-{
-  // compare based on # of non-zero digits
-  if (size_ > rhs.size_)
-    return 1;
-
-  if (size_ < rhs.size_)
-    return -1;
-
-  // compare based on digits
-  const_reverse_iterator d = rbegin();
-  const_reverse_iterator d2 = rhs.rbegin();
-  for (; d != rend(); ++d, ++d2)
-  {
-    if (*d > *d2)
-      return 1;
-    if (*d < *d2)
-      return -1;
-  }
-  return 0;
-}
-
-template<class A, class T>
-int mp_int<A,T>::compare_to_digit(digit_type d) const
-{
-  // compare based on sign
-  if (is_negative())
-    return -1;
-
-  // compare based on magnitude
-  if (size_ > 1)
-    return 1;
-
-  // compare the only digit of *this to d
-  if (digits_[0] > d)
-    return 1;
-  else if (digits_[0] < d)
-    return -1;
-  else
-    return 0;
-}
-
-template<class A, class T>
-int mp_int<A,T>::compare(const mp_int& rhs) const
-{
-  if (sign() != rhs.sign())
-  {
-    if (is_negative())
-      return -1;
-    else
-      return 1;
-  }
-
-  if (is_negative())
-    // if negative compare opposite direction
-    return rhs.compare_magnitude(*this);
-  else
-    return compare_magnitude(rhs);
-}
-
-// {A,B,C,D,E} shifted left by 2 digits becomes
-// {0,0,A,B,C,D,E}
-template<class A, class T>
-void mp_int<A,T>::shift_digits_left(size_type b)
-{
-  if (b <= 0)
-    return;
-
-  grow_capacity(size_ + b);
-
-  std::memmove(digits_ + b, digits_, size_ * sizeof(digit_type));
-
-  // zero the lower digits
-  std::memset(digits_, 0, b * sizeof(digit_type));
-
-  size_ += b;
-}
-
-// {A,B,C,D,E} shifted right by 2 digits becomes
-// {C,D,E}
-template<class A, class T>
-void mp_int<A,T>::shift_digits_right(size_type b)
-{
-  if (b <= 0)
-    return;
-
-  if (size_ <= b)
-  {
-    zero();
-    return;
-  }
-
-  // shift the digits down
-  std::memmove(digits_, digits_ + b, (size_ - b) * sizeof(digit_type));
-
-  // zero the top digits
-  std::memset(digits_ + size_ - b, 0, b * sizeof(digit_type));
-
-  // remove excess digits
-  size_ -= b;
-}
-
-template<class A, class T>
-typename mp_int<A,T>::size_type
-mp_int<A,T>::precision() const
-{
-  // get number of digits and add that
-  size_type p = (size_ - 1) * valid_bits;
-
-  // take the last digit and count the bits in it
-  digit_type q = digits_[size_ - 1];
-  while (q > 0U)
-  {
-    ++p;
-    q >>= 1;
-  }
-  return p;
-}
-
-// Counts the number of lsbs which are zero before the first one bit
-template<class A, class T>
-typename mp_int<A,T>::size_type
-mp_int<A,T>::count_lsb() const
-{
-  static const size_type lnz[16] = {
-    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
-  };
-
-  if (!*this)
-    return 0;
-
-  // scan lower digits until non-zero
-  size_type x = 0;
-  while (x < size_ && digits_[x] == 0)
-    ++x;
-  digit_type q = digits_[x];
-  x *= valid_bits;
-
-  // now scan this digit until a 1 is found
-  if ((q & 1) == 0)
-  {
-    digit_type qq;
-    do
-    {
-      qq  = q & 15;
-      x  += lnz[qq];
-      q >>= 4;
-    } while (qq == 0);
-  }
-  return x;
-}
-
-template<class A, class T>
-template<typename IntegralT>
-inline IntegralT mp_int<A,T>::to_integral() const
-{
-  return detail::integral_ops<IntegralT>::convert(*this);
-}
-
-template<class A, class T>
-void mp_int<A,T>::set_bits(size_type beg, size_type end)
-{
-  const size_type beg_index  = beg / digit_bits;
-  const size_type end_index  = end / digit_bits;
-  const size_type first_bits = beg % digit_bits;
-  const size_type last_bits  = end % digit_bits;
-
-  static const digit_type z = ~digit_type(0);
-
-  digit_type mask = z << first_bits;
-  if (beg_index == end_index && last_bits)
-    mask &= z >> (digit_bits - last_bits);
-
-  digits_[beg_index] |= mask;
-
-  for (size_type i = beg_index + ((beg % digit_bits) ? 1 : 0); i < end_index; ++i)
-    digits_[i] = digit_max;
-
-  if (beg_index != end_index && last_bits)
-    digits_[end_index] |= z >> (digit_bits - last_bits);
-}
-
-template<class A, class T>
-void mp_int<A,T>::clear_bits(size_type beg, size_type end)
-{
-  const size_type beg_index  = beg / digit_bits;
-  const size_type end_index  = end / digit_bits;
-  const size_type first_bits = beg % digit_bits;
-  const size_type last_bits  = end % digit_bits;
-
-  static const digit_type z = ~digit_type(0);
-
-  digit_type mask;
-  if (first_bits)
-    mask = z >> (digit_bits - first_bits);
-  else
-    mask = 0;
-
-  if (beg_index == end_index)
-    mask |= z << last_bits;
-
-  digits_[beg_index] &= mask;
-
-  if (beg_index != end_index)
-  {
-    std::memset(digits_ + beg_index + 1, 0,
-        sizeof(digit_type) * (end_index - beg_index - 1));
-
-    digits_[end_index] &= z << last_bits;
-  }
-}
-
-// don't forget to clamp() after truncating!
-template<class A, class T>
-void mp_int<A,T>::truncate(size_type prec)
-{
-  set_precision(prec);
-  const size_type last_bits = prec % valid_bits;
-  if (last_bits)
-  {
-    static const digit_type z = ~digit_type(0);
-    const digit_type mask = z >> (valid_bits - last_bits);
-    digits_[size_ - 1] &= mask;
-  }
-}
-
-
-template<class A, class T>
-inline void swap(mp_int<A,T>& lhs, mp_int<A,T>& rhs)
-{
-  lhs.swap(rhs);
-}
-
-#ifdef BOOST_HAS_RVALUE_REFS
-template<class A, class T>
-inline void swap(mp_int<A,T>&& lhs, mp_int<A,T>& rhs)
-{
-  lhs.swap(rhs);
-}
-template<class A, class T>
-inline void swap(mp_int<A,T>& lhs, mp_int<A,T>&& rhs)
-{
-  lhs.swap(rhs);
-}
-#endif
-
-
-
-
-
-
-#include <boost/mp_math/mp_int/abs.hpp>
-#include <boost/mp_math/mp_int/add.hpp>
-#include <boost/mp_math/mp_int/ctors.hpp>
-#include <boost/mp_math/mp_int/div.hpp>
-#include <boost/mp_math/mp_int/mod.hpp>
-#include <boost/mp_math/mp_int/mul.hpp>
-#include <boost/mp_math/mp_int/operators.hpp>
-#include <boost/mp_math/mp_int/pow.hpp>
-#include <boost/mp_math/mp_int/random.hpp>
-#include <boost/mp_math/mp_int/sqr.hpp>
-#include <boost/mp_math/mp_int/sub.hpp>
-#include <boost/mp_math/mp_int/string_conversion.hpp>
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/mp_int_fwd.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/mp_int_fwd.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,26 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_MP_INT_FWD_HPP
-#define BOOST_MP_MATH_MP_INT_MP_INT_FWD_HPP
-
-#include <memory>
-#include <boost/mp_math/mp_int/traits.hpp>
-
-
-namespace boost {
-namespace mp_math {
-
-template<
-  class Allocator = std::allocator<void>,
-  class Traits = mp_int_traits<>
->
-struct mp_int;
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/mul.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/mul.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,361 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-// multiplies by a single digit
-template<class A, class T>
-void mp_int<A,T>::multiply_by_digit(digit_type x)
-{
-  if (x == 0)
-  {
-    zero();
-    return;
-  }
-  else if (x == 1)
-    return;
-
-  // make sure we can hold the result
-  grow_capacity(size_ + 1);
-  
-  const digit_type carry =
-    ops_type::multiply_by_digit(digits(), digits(), size(), x);
-
-  if (carry)
-    push(carry);
-}
-
-/* *this *= 2 */
-template<class A, class T>
-void mp_int<A,T>::multiply_by_2()
-{
-  grow_capacity(size_ + 1);
-
-  const digit_type carry =
-    ops_type::multiply_by_two(digits(), digits(), size());
-
-  if (carry)
-    push(carry);
-}
-
-
-// multiplication using the Toom-Cook 3-way algorithm 
-//
-// Much more complicated than Karatsuba but has a lower 
-// asymptotic running time of O(N**1.464). This algorithm is 
-// only particularly useful on VERY large inputs 
-// (we're talking 1000s of digits here...).
-template<class A, class T>
-void mp_int<A,T>::toom_cook_mul(const mp_int& b)
-{
-  const size_type B = std::min(size_, b.size_) / 3;
-  
-  // a = a2 * B**2 + a1 * B + a0
-  mp_int a0(*this);
-  a0.modulo_2_to_the_power_of(valid_bits * B);
-  mp_int a1(*this);
-  a1.shift_digits_right(B);
-  a1.modulo_2_to_the_power_of(valid_bits * B);
-  mp_int a2(*this);
-  a2.shift_digits_right(B*2);
-  
-  // b = b2 * B**2 + b1 * B + b0
-  mp_int b0(b);
-  b0.modulo_2_to_the_power_of(valid_bits * B);
-  mp_int b1(b);
-  b1.shift_digits_right(B);
-  b1.modulo_2_to_the_power_of(valid_bits * B);
-  mp_int b2(b);
-  b2.shift_digits_right(B*2);
-
-  // w0 = a0*b0
-  const mp_int w0(a0 * b0);
-  
-  // w4 = a2 * b2
-  mp_int w4 = a2 * b2;
-  
-  // w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0))
-  mp_int tmp1 = a0;
-  tmp1.multiply_by_2();
-  tmp1 += a1;
-  tmp1.multiply_by_2();
-  tmp1 += a2;
-  
-  mp_int tmp2 = b0;
-  tmp2.multiply_by_2();
-  tmp2 += b1;
-  tmp2.multiply_by_2();
-  tmp2 += b2;
-
-  mp_int w1 = tmp1 * tmp2;
-
-  // w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2))
-  tmp1 = a2;
-  tmp1.multiply_by_2();
-  tmp1 += a1;
-  tmp1.multiply_by_2();
-  tmp1 += a0;
-
-  tmp2 = b2;
-  tmp2.multiply_by_2();
-  tmp2 += b1;
-  tmp2.multiply_by_2();
-  tmp2 += b0;
-
-  mp_int w3 = tmp1 * tmp2;
-
-  // w2 = (a2 + a1 + a0)(b2 + b1 + b0)
-  tmp1 = a2 + a1;
-  tmp1 += a0;
-  tmp2 = b2 + b1;
-  tmp2 += b0;
-  mp_int w2 = tmp1 * tmp2;
-
-  // now solve the matrix 
-  //
-  // 0  0  0  0  1
-  // 1  2  4  8  16
-  // 1  1  1  1  1
-  // 16 8  4  2  1
-  // 1  0  0  0  0
-  //   
-  // using 12 subtractions, 4 shifts, 
-  // 2 small divisions and 1 small multiplication 
-   
-  // r1 - r4
-  w1 -= w4;
-  // r3 - r0
-  w3 -= w0;
-  // r1/2
-  w1.divide_by_2();
-  // r3/2
-  w3.divide_by_2();
-  // r2 - r0 - r4
-  w2 -= w0;
-  w2 -= w4;
-  // r1 - r2
-  w1 -= w2;
-  // r3 - r2
-  w3 -= w2;
-  // r1 - 8r0
-  tmp1 = w0 << 3;
-  w1 -= tmp1;
-  // r3 - 8r4
-  tmp1 = w4 << 3;
-  w3 -= tmp1;
-  // 3r2 - r1 - r3
-  w2.multiply_by_digit(3);
-  w2 -= w1;
-  w2 -= w3;
-  // r1 - r2
-  w1 -= w2;
-  // r3 - r2
-  w3 -= w2;
-  // r1/3
-  w1.divide_by_3();
-  // r3/3
-  w3.divide_by_3();
-
-  // at this point shift W[n] by B*n
-  w1.shift_digits_left(1*B);
-  w2.shift_digits_left(2*B);
-  w3.shift_digits_left(3*B);
-  w4.shift_digits_left(4*B);
-
-  *this = w0 + w1;
-  tmp1 = w2 + w3;
-  tmp1 += w4;
-  *this += tmp1;
-}
-
-// c = |a| * |b| using Karatsuba Multiplication using 
-// three half size multiplications
-//
-// Let B represent the radix [e.g. 2**valid_bits] and 
-// let n represent half of the number of digits in 
-// the min(a,b)
-//
-// a = x1 * B**n + x0
-// b = y1 * B**n + y0
-//
-// Then, a * b => 
-// x1y1 * B**2n + ((x1 + x0)(y1 + y0) - (x0y0 + x1y1)) * B + x0y0
-//
-// Note that x1y1 and x0y0 are used twice and only need to be 
-// computed once.  So in total three half size (half # of 
-// digit) multiplications are performed, x0y0, x1y1 and 
-// (x1+y1)(x0+y0)
-//
-// Note that a multiplication of half the digits requires
-// 1/4th the number of single precision multiplications so in 
-// total after one call 25% of the single precision multiplications 
-// are saved.  Note also that the call to mp_mul can end up back 
-// in this function if the x0, x1, y0, or y1 are above the threshold.  
-// This is known as divide-and-conquer and leads to the famous 
-// O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than 
-// the standard O(N**2) that the baseline/comba methods use.  
-// Generally though the overhead of this method doesn't pay off 
-// until a certain size (N ~ 80) is reached.
-template<class A, class T>
-void mp_int<A,T>::karatsuba_mul(const mp_int& b)
-{
-  mp_int x0, x1, y0, y1, /*tmp,*/ x0y0, x1y1;
-
-  // min # of digits
-  const size_type B = std::min(size_, b.size_) / 2;
-
-  // allocate memory
-  x0.grow_capacity(B);
-  x1.grow_capacity(size_ + b.size_);
-  y0.grow_capacity(B);
-  y1.grow_capacity(b.size_ - B + 1);
-
-  // set size_ count
-  x0.size_ = y0.size_ = B;
-  x1.size_ = size_ - B;
-  y1.size_ = b.size_ - B;
-
-  // copy digits over
-  static const size_type s = sizeof(digit_type);
-  std::memcpy(x0.digits_, digits_,   s * B);
-  std::memcpy(y0.digits_, b.digits_, s * B);
-  std::memcpy(x1.digits_, digits_ + B,   s * (  size_ - B));
-  std::memcpy(y1.digits_, b.digits_ + B, s * (b.size_ - B));
-
-  // only need to clamp the lower words since by definition the 
-  // upper words x1/y1 must have a known number of digits
-  x0.clamp();
-  y0.clamp();
-
-  // now evaluate the term
-  // x1y1 * B**2n + ((x1 + x0)(y1 + y0) - (x0y0 + x1y1)) * B + x0y0
-  
-  // first calc the products x0y0 and x1y1
-  x0y0 = x0 * y0;
-  x1y1 = x1 * y1;
-
-  // tmp = (x1 + x0) * (y1 + y0)
-  x1.add_magnitude(x0);
-  y1.add_magnitude(y0);
-  // we don't need a tmp just reuse x1
-  x1 *= y1;
-
-  // tmp -= (x0y0 + x1y1);
-  x1.sub_smaller_magnitude(x0y0);
-  x1.sub_smaller_magnitude(x1y1);
-
-  // shift by B
-  x1.shift_digits_left(B);
-  x1y1.shift_digits_left(B * 2);
-
-  x1.add_magnitude(x0y0);
-  x1.add_magnitude(x1y1);
-  swap(x1);
-}
-
-
-// multiplies |a| * |b| and only computes up to digs digits of result
-// HAC pp. 595, Algorithm 14.12  Modified so you can control how 
-// many digits of output are created.
-template<class A, class T>
-void mp_int<A,T>::mul_digits(const mp_int& b, size_type digs)
-{
-  mp_int tmp;
-  tmp.grow_capacity(digs);
-  // zero allocated digits
-  std::memset(tmp.digits_, 0, sizeof(digit_type) * digs);
-  tmp.size_ = digs;
-
-  // compute the digits of the product directly
-  for (size_type i = 0; i < size_; ++i)
-  {
-    digit_type carry = 0;
-
-    // limit ourselves to making digs digits of output
-    const size_type pb = std::min(b.size_, digs - i);
-
-    // compute the columns of the output and propagate the carry
-    for (size_type j = 0; j < pb; ++j)
-    {
-      // compute the column as a word_type
-      const word_type r = static_cast<word_type>(tmp[i+j])
-                        + static_cast<word_type>(digits_[i])
-                        * static_cast<word_type>(b[j])
-                        + static_cast<word_type>(carry);
-
-      // the new column is the lower part of the result
-      tmp[i+j] = static_cast<digit_type>(r);
-
-      // get the carry word from the result
-      carry = static_cast<digit_type>(r >> static_cast<word_type>(valid_bits));
-    }
-    // set carry if it is placed below digs
-    if (i + pb < digs)
-      tmp[i+pb] = carry;
-  }
-
-  tmp.clamp();
-
-  if (!tmp)
-    tmp.set_sign(1);
-
-  swap(tmp);
-}
-
-// FIXME no routine seems to use this
-//
-// multiplies |a| * |b| and does not compute the lower num digits
-// [meant to get the higher part of the product]
-template<class A, class T>
-void mp_int<A,T>::mul_high_digits(const mp_int& b, size_type num)
-{
-  mp_int tmp;
-  tmp.grow_capacity(size_ + b.size_ + 1);
-  tmp.size_ = size_ + b.size_ + 1;
-  std::memset(tmp.digits_, 0, sizeof(digit_type) * tmp.size_);
-
-  for (size_type i = 0; i < size_; ++i)
-  {
-    iterator dst     = tmp.begin() + num;
-    const_iterator z = b.begin() + (num - i);
-    digit_type carry = 0;
-
-    for (size_type j = num - i; j < b.size_; ++j)
-    {
-      const word_type r = static_cast<word_type>(*dst)
-                        + static_cast<word_type>(digits_[i])
-                        * static_cast<word_type>(*z++)
-                        + static_cast<word_type>(carry);
-
-      // get the lower part
-      *dst++ = static_cast<digit_type>(r);
-
-      // update carry
-      carry = static_cast<digit_type>(r >> valid_bits);
-    }
-    *dst = carry;
-  }
-
-  tmp.clamp();
-
-  if (!tmp)
-    tmp.set_sign(1);
-
-  swap(tmp);
-}
-
-
-// this is a modified version of fast_s_mul_digs that only produces
-// output digits *above* num.  See the comments for fast_s_mul_digs
-// to see how it works.
-//
-// This is used in the Barrett reduction since for one of the multiplications
-// only the higher digits were needed. This essentially halves the work.
-//
-// Based on Algorithm 14.12 on pp.595 of HAC.
-template<class A, class T>
-void mp_int<A,T>::fast_mul_high_digits(const mp_int& b, size_type num)
-{
-  mul_high_digits(b, num);
-}
-
Modified: sandbox/mp_math/boost/mp_math/integer/numeric_limits.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/numeric_limits.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/numeric_limits.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,28 +1,146 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_INTEGER_NUMERIC_LIMITS_HPP
+#define BOOST_MP_MATH_INTEGER_NUMERIC_LIMITS_HPP
+
+#include <limits>
+
 namespace std
 {
 
+template<class Alloc, class Traits>
+class numeric_limits<
+  boost::mp_math::unbounded_uint<Alloc,Traits>
+>
+{
+  typedef boost::mp_math::unbounded_uint<Alloc,Traits> int_type;
+
+public:
+
+  static const bool is_specialized = true;
+
+  static int_type min() throw() { return int_type(0U); }
+  static int_type max() throw() { return int_type(0U); }
+
+  static const int  digits   = 0;
+  static const int  digits10 = 0;
+  static const bool is_signed  = false;
+  static const bool is_integer = true;
+  static const bool is_exact   = true;
+  static const int  radix      = 0;
+
+  // This is a Boost extension since the radix member above cannot hold the true
+  // radix.
+  static const typename int_type::digit_type max_radix_value =
+    int_type::max_digit_value;
+
+  static int_type epsilon    () throw() { return int_type(0U); }
+  static int_type round_error() throw() { return int_type(0U); }
+
+  static const int  min_exponent   = 0;
+  static const int  min_exponent10 = 0;
+  static const int  max_exponent   = 0;
+  static const int  max_exponent10 = 0;
+
+  static const bool has_infinity      = false;
+  static const bool has_quiet_NaN     = false;
+  static const bool has_signaling_NaN = false;
+  static const float_denorm_style has_denorm = denorm_absent;
+  static const bool has_denorm_loss   = false;
+
+  static int_type infinity     () throw() { return int_type(0U); }
+  static int_type quiet_NaN    () throw() { return int_type(0U); }
+  static int_type signaling_NaN() throw() { return int_type(0U); }
+  static int_type denorm_min   () throw() { return int_type(0U); }
+
+  static const bool is_iec559  = false;
+  static const bool is_bounded = false;
+  static const bool is_modulo  = false;
+
+  static const bool traps           = false;
+  static const bool tinyness_before = false;
+  static const float_round_style round_style = round_toward_zero;
+};
+
+
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::is_specialized;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_uint<A,T> >::digits;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_uint<A,T> >::digits10;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::is_signed;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::is_integer;
 template<class A, class T>
-class numeric_limits<boost::mp_math::mp_int<A,T> >
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::is_exact;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_uint<A,T> >::radix;
+template<class A, class T>
+const typename boost::mp_math::unbounded_uint<A,T>::digit_type
+numeric_limits<boost::mp_math::unbounded_uint<A,T> >::max_radix_value;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_uint<A,T> >::min_exponent;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_uint<A,T> >::min_exponent10;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_uint<A,T> >::max_exponent;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_uint<A,T> >::max_exponent10;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::has_infinity;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::has_quiet_NaN;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::has_signaling_NaN;
+template<class A, class T>
+const float_denorm_style numeric_limits<boost::mp_math::unbounded_uint<A,T> >::has_denorm;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::is_iec559;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::is_bounded;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::is_modulo;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::traps;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_uint<A,T> >::tinyness_before;
+template<class A, class T>
+const float_round_style numeric_limits<boost::mp_math::unbounded_uint<A,T> >::round_style;
+
+
+template<class Alloc, class Traits>
+class numeric_limits<
+  boost::mp_math::unbounded_int<Alloc,Traits>
+>
 {
+  typedef boost::mp_math::unbounded_int<Alloc,Traits> int_type;
+
 public:
 
   static const bool is_specialized = true;
-  static boost::mp_math::mp_int<A,T> min() throw() { return boost::mp_math::mp_int<A,T>(0U); }
-  static boost::mp_math::mp_int<A,T> max() throw() { return boost::mp_math::mp_int<A,T>(0U); }
+
+  static int_type min() throw() { return int_type(0U); }
+  static int_type max() throw() { return int_type(0U); }
 
   static const int  digits   = 0;
   static const int  digits10 = 0;
   static const bool is_signed  = true;
   static const bool is_integer = true;
   static const bool is_exact   = true;
-  static const int  radix      = 2;
-  static boost::mp_math::mp_int<A,T> epsilon    () throw() { return boost::mp_math::mp_int<A,T>(0U); }
-  static boost::mp_math::mp_int<A,T> round_error() throw() { return boost::mp_math::mp_int<A,T>(0U); }
+  static const int  radix      = 0;
+
+  // This is a Boost extension since the radix member above cannot hold the true
+  // radix.
+  static const typename int_type::digit_type max_radix_value =
+    int_type::max_digit_value;
+
+  static int_type epsilon    () throw() { return int_type(0U); }
+  static int_type round_error() throw() { return int_type(0U); }
 
   static const int  min_exponent   = 0;
   static const int  min_exponent10 = 0;
@@ -34,19 +152,278 @@
   static const bool has_signaling_NaN = false;
   static const float_denorm_style has_denorm = denorm_absent;
   static const bool has_denorm_loss   = false;
-  static boost::mp_math::mp_int<A,T> infinity     () throw() { return boost::mp_math::mp_int<A,T>(0U); }
-  static boost::mp_math::mp_int<A,T> quiet_NaN    () throw() { return boost::mp_math::mp_int<A,T>(0U); }
-  static boost::mp_math::mp_int<A,T> signaling_NaN() throw() { return boost::mp_math::mp_int<A,T>(0U); }
-  static boost::mp_math::mp_int<A,T> denorm_min   () throw() { return boost::mp_math::mp_int<A,T>(0U); }
+
+  static int_type infinity     () throw() { return int_type(0U); }
+  static int_type quiet_NaN    () throw() { return int_type(0U); }
+  static int_type signaling_NaN() throw() { return int_type(0U); }
+  static int_type denorm_min   () throw() { return int_type(0U); }
 
   static const bool is_iec559  = false;
   static const bool is_bounded = false;
   static const bool is_modulo  = false;
 
-  static const bool traps = false;
+  static const bool traps           = false;
   static const bool tinyness_before = false;
   static const float_round_style round_style = round_toward_zero;
 };
 
+
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::is_specialized;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_int<A,T> >::digits;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_int<A,T> >::digits10;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::is_signed;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::is_integer;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::is_exact;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_int<A,T> >::radix;
+template<class A, class T>
+const typename boost::mp_math::unbounded_int<A,T>::digit_type
+numeric_limits<boost::mp_math::unbounded_int<A,T> >::max_radix_value;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_int<A,T> >::min_exponent;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_int<A,T> >::min_exponent10;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_int<A,T> >::max_exponent;
+template<class A, class T>
+const int numeric_limits<boost::mp_math::unbounded_int<A,T> >::max_exponent10;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::has_infinity;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::has_quiet_NaN;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::has_signaling_NaN;
+template<class A, class T>
+const float_denorm_style numeric_limits<boost::mp_math::unbounded_int<A,T> >::has_denorm;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::is_iec559;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::is_bounded;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::is_modulo;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::traps;
+template<class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded_int<A,T> >::tinyness_before;
+template<class A, class T>
+const float_round_style numeric_limits<boost::mp_math::unbounded_int<A,T> >::round_style;
+
+
+template<bool Signed, class Alloc, class Traits>
+class numeric_limits<
+  boost::mp_math::unbounded<Signed,Alloc,Traits>
+>
+{
+  typedef boost::mp_math::unbounded<Signed,Alloc,Traits> int_type;
+
+public:
+
+  static const bool is_specialized = true;
+
+  static int_type min() throw() { return int_type(0U); }
+  static int_type max() throw() { return int_type(0U); }
+
+  static const int  digits   = 0;
+  static const int  digits10 = 0;
+  static const bool is_signed  = Signed;
+  static const bool is_integer = true;
+  static const bool is_exact   = true;
+  static const int  radix      = 0;
+
+  // This is a Boost extension since the radix member above cannot hold the true
+  // radix.
+  static const typename int_type::digit_type max_radix_value =
+    int_type::max_digit_value;
+
+  static int_type epsilon    () throw() { return int_type(0U); }
+  static int_type round_error() throw() { return int_type(0U); }
+
+  static const int  min_exponent   = 0;
+  static const int  min_exponent10 = 0;
+  static const int  max_exponent   = 0;
+  static const int  max_exponent10 = 0;
+
+  static const bool has_infinity      = false;
+  static const bool has_quiet_NaN     = false;
+  static const bool has_signaling_NaN = false;
+  static const float_denorm_style has_denorm = denorm_absent;
+  static const bool has_denorm_loss   = false;
+
+  static int_type infinity     () throw() { return int_type(0U); }
+  static int_type quiet_NaN    () throw() { return int_type(0U); }
+  static int_type signaling_NaN() throw() { return int_type(0U); }
+  static int_type denorm_min   () throw() { return int_type(0U); }
+
+  static const bool is_iec559  = false;
+  static const bool is_bounded = false;
+  static const bool is_modulo  = false;
+
+  static const bool traps           = false;
+  static const bool tinyness_before = false;
+  static const float_round_style round_style = round_toward_zero;
+};
+
+
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::is_specialized;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::unbounded<S,A,T> >::digits;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::unbounded<S,A,T> >::digits10;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::is_signed;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::is_integer;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::is_exact;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::unbounded<S,A,T> >::radix;
+template<bool S, class A, class T>
+const typename boost::mp_math::unbounded<S,A,T>::digit_type
+numeric_limits<boost::mp_math::unbounded<S,A,T> >::max_radix_value;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::unbounded<S,A,T> >::min_exponent;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::unbounded<S,A,T> >::min_exponent10;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::unbounded<S,A,T> >::max_exponent;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::unbounded<S,A,T> >::max_exponent10;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::has_infinity;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::has_quiet_NaN;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::has_signaling_NaN;
+template<bool S, class A, class T>
+const float_denorm_style numeric_limits<boost::mp_math::unbounded<S,A,T> >::has_denorm;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::is_iec559;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::is_bounded;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::is_modulo;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::traps;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::unbounded<S,A,T> >::tinyness_before;
+template<bool S, class A, class T>
+const float_round_style numeric_limits<boost::mp_math::unbounded<S,A,T> >::round_style;
+
+
+template<bool Signed, class Alloc, class Traits>
+class numeric_limits<
+  boost::mp_math::integer<
+    boost::mp_math::unbounded<Signed,Alloc,Traits>
+  >
+>
+{
+  typedef boost::mp_math::integer<
+    boost::mp_math::unbounded<Signed,Alloc,Traits>
+  > int_type;
+
+public:
+
+  static const bool is_specialized = true;
+
+  static int_type min() throw() { return int_type(0U); }
+  static int_type max() throw() { return int_type(0U); }
+
+  static const int  digits   = 0;
+  static const int  digits10 = 0;
+  static const bool is_signed  = Signed;
+  static const bool is_integer = true;
+  static const bool is_exact   = true;
+  static const int  radix      = 0;
+
+  // This is a Boost extension since the radix member above cannot hold the true
+  // radix.
+  static const typename int_type::digit_type max_radix_value =
+    int_type::max_digit_value;
+
+  static int_type epsilon    () throw() { return int_type(0U); }
+  static int_type round_error() throw() { return int_type(0U); }
+
+  static const int  min_exponent   = 0;
+  static const int  min_exponent10 = 0;
+  static const int  max_exponent   = 0;
+  static const int  max_exponent10 = 0;
+
+  static const bool has_infinity      = false;
+  static const bool has_quiet_NaN     = false;
+  static const bool has_signaling_NaN = false;
+  static const float_denorm_style has_denorm = denorm_absent;
+  static const bool has_denorm_loss   = false;
+
+  static int_type infinity     () throw() { return int_type(0U); }
+  static int_type quiet_NaN    () throw() { return int_type(0U); }
+  static int_type signaling_NaN() throw() { return int_type(0U); }
+  static int_type denorm_min   () throw() { return int_type(0U); }
+
+  static const bool is_iec559  = false;
+  static const bool is_bounded = false;
+  static const bool is_modulo  = false;
+
+  static const bool traps           = false;
+  static const bool tinyness_before = false;
+  static const float_round_style round_style = round_toward_zero;
+};
+
+
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::is_specialized;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::digits;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::digits10;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::is_signed;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::is_integer;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::is_exact;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::radix;
+template<bool S, class A, class T>
+const typename boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> >::digit_type
+numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::max_radix_value;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::min_exponent;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::min_exponent10;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::max_exponent;
+template<bool S, class A, class T>
+const int numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::max_exponent10;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::has_infinity;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::has_quiet_NaN;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::has_signaling_NaN;
+template<bool S, class A, class T>
+const float_denorm_style numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::has_denorm;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::is_iec559;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::is_bounded;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::is_modulo;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::traps;
+template<bool S, class A, class T>
+const bool numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::tinyness_before;
+template<bool S, class A, class T>
+const float_round_style numeric_limits<boost::mp_math::integer<boost::mp_math::unbounded<S,A,T> > >::round_style;
+
 } // namespace std
 
+
+#endif
+
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/operators.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/operators.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,1019 +0,0 @@
-// Copyright Kevin Sopp 2008 - 2009.
-// 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)
-
-// compare mp_int to mp_int
-template<class A, class T>
-inline bool
-operator == (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  return lhs.sign() == rhs.sign() && lhs.size() == rhs.size() &&
-    std::equal(lhs.begin(), lhs.end(), rhs.begin());
-}
-
-template<class A, class T>
-inline bool
-operator != (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)  { return !(lhs == rhs); }
-
-template<class A, class T>
-bool
-operator < (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  if (lhs.sign() != rhs.sign())
-  {
-    if (lhs.is_negative())
-      return true;
-    else
-      return false;
-  }
-
-  if (lhs.size() < rhs.size())
-    return true;
-  if (lhs.size() > rhs.size())
-    return false;
-
-  if (lhs.is_negative())
-    return std::lexicographical_compare(
-      rhs.rbegin(), rhs.rend(), lhs.rbegin(), lhs.rend());
-  else
-    return std::lexicographical_compare(
-      lhs.rbegin(), lhs.rend(), rhs.rbegin(), rhs.rend());
-}
-
-template<class A, class T>
-inline bool
-operator > (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs) { return rhs < lhs; }
-
-template<class A, class T>
-inline bool
-operator <= (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)  { return !(rhs < lhs);  }
-
-template<class A, class T>
-inline bool
-operator >= (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)  { return !(lhs < rhs);  }
-
-
-// compare mp_int to integral
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator == (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  return detail::integral_ops<IntegralT>::equal(lhs, rhs);
-}
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator != (const mp_int<A,T>& lhs, IntegralT rhs) { return !(lhs == rhs); }
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator < (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  return detail::integral_ops<IntegralT>::less(lhs, rhs);
-}
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator > (const mp_int<A,T>& lhs, IntegralT rhs)  { return rhs < lhs; }
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator <= (const mp_int<A,T>& lhs, IntegralT rhs) { return (lhs < rhs) || (lhs == rhs);  }
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator >= (const mp_int<A,T>& lhs, IntegralT rhs) { return !(lhs < rhs);  }
-
-// compare integral to mp_int
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator == (IntegralT lhs, const mp_int<A,T>& rhs) { return rhs == lhs;  }
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator != (IntegralT lhs, const mp_int<A,T>& rhs) { return !(lhs == rhs); }
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator < (IntegralT lhs, const mp_int<A,T>& rhs)  { return !(rhs <= lhs); }
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator > (IntegralT lhs, const mp_int<A,T>& rhs)  { return rhs < lhs; }
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator <= (IntegralT lhs, const mp_int<A,T>& rhs) { return !(rhs < lhs);  }
-
-template<class A, class T, typename IntegralT>
-inline typename enable_if<is_integral<IntegralT>, bool>::type
-operator >= (IntegralT lhs, const mp_int<A,T>& rhs) { return rhs <= lhs;  }
-
-
-// compare mp_int to character string
-template<class A, class T, typename charT>
-inline bool
-operator == (const mp_int<A,T>& lhs, const charT* rhs) { return lhs == mp_int<A,T>(rhs); }
-
-template<class A, class T, typename charT>
-inline bool
-operator != (const mp_int<A,T>& lhs, const charT* rhs) { return lhs != mp_int<A,T>(rhs); }
-
-template<class A, class T, typename charT>
-inline bool
-operator < (const mp_int<A,T>& lhs, const charT* rhs) { return lhs < mp_int<A,T>(rhs); }
-
-template<class A, class T, typename charT>
-inline bool
-operator > (const mp_int<A,T>& lhs, const charT* rhs) { return lhs > mp_int<A,T>(rhs); }
-
-template<class A, class T, typename charT>
-inline bool
-operator <= (const mp_int<A,T>& lhs, const charT* rhs) { return lhs <= mp_int<A,T>(rhs); }
-
-template<class A, class T, typename charT>
-inline bool
-operator >= (const mp_int<A,T>& lhs, const charT* rhs) { return lhs >= mp_int<A,T>(rhs); }
-
-// compare const charT* to mp_int
-template<class A, class T, typename charT>
-inline bool
-operator == (const charT* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) == rhs; }
-
-template<class A, class T, typename charT>
-inline bool
-operator != (const charT* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) != rhs; }
-
-template<class A, class T, typename charT>
-inline bool
-operator < (const charT* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) < rhs; }
-
-template<class A, class T, typename charT>
-inline bool
-operator > (const charT* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) > rhs; }
-
-template<class A, class T, typename charT>
-inline bool
-operator <= (const charT* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) <= rhs; }
-
-template<class A, class T, typename charT>
-inline bool
-operator >= (const charT* lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) >= rhs; }
-
-
-// compare mp_int to basic_string
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator == (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs == mp_int<A,T>(rhs); }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator != (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs != mp_int<A,T>(rhs); }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator < (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs < mp_int<A,T>(rhs); }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator > (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs > mp_int<A,T>(rhs); }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator <= (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs <= mp_int<A,T>(rhs); }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator >= (const mp_int<A,T>& lhs, const std::basic_string<charT,Traits,Alloc>& rhs) { return lhs >= mp_int<A,T>(rhs); }
-
-// compare basic_string to mp_int
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator == (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) == rhs; }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator != (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) != rhs; }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator < (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) < rhs; }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator > (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) > rhs; }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator <= (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) <= rhs; }
-
-template<class A, class T, class charT, class Traits, class Alloc>
-inline bool
-operator >= (const std::basic_string<charT,Traits,Alloc>& lhs, const mp_int<A,T>& rhs) { return mp_int<A,T>(lhs) >= rhs; }
-
-
-
-
-// prefix ops
-template<class A, class T>
-inline mp_int<A,T>& mp_int<A,T>::operator ++()
-{
-  add_digit(1);
-  return *this;
-}
-
-template<class A, class T>
-inline mp_int<A,T>& mp_int<A,T>::operator --()
-{
-  sub_digit(1);
-  return *this;
-}
-
-// postfix ops
-template<class A, class T>
-inline mp_int<A,T> mp_int<A,T>::operator ++(int)
-{
-  mp_int<A,T> tmp(*this);
-  ++(*this);
-  return tmp;
-}
-
-template<class A, class T>
-inline mp_int<A,T> mp_int<A,T>::operator --(int)
-{
-  mp_int<A,T> tmp(*this);
-  --(*this);
-  return tmp;
-}
-
-// shift ops
-// this function corresponds to mp_mul_2d()
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator <<= (size_type b)
-{
-  grow_capacity(size_ + b/valid_bits + 1);
-
-  /* shift by as many digits in the bit count */
-  if (b >= static_cast<size_type>(valid_bits))
-    shift_digits_left(b / valid_bits);
-
-  /* shift any bit count < valid_bits */
-  const digit_type d = static_cast<digit_type>(b % valid_bits);
-
-  if (d)
-  {
-    /* bitmask for carries */
-    const digit_type mask = (digit_type(1) << d) - 1;
-
-    /* shift for msbs */
-    const digit_type shift = valid_bits - d;
-
-    digit_type carry = 0;
-    for (size_type i = 0; i < size_; ++i)
-    {
-      /* get the higher bits of the current word */
-      const digit_type carry_cur = (digits_[i] >> shift) & mask;
-
-      /* shift the current word and OR in the carry */
-      digits_[i] = (digits_[i] << d) | carry;
-
-      /* set the carry to the carry bits of the current word */
-      carry = carry_cur;
-    }
-
-    if (carry)
-      push(carry);
-  }
-
-  clamp();
-  return *this;
-}
-
-template<class A, class T>
-inline mp_int<A,T>& mp_int<A,T>::operator >>= (size_type b)
-{
-  shift_right(b, 0);
-  return *this;
-}
-
-// unary negate
-template<class A, class T>
-inline mp_int<A,T>& mp_int<A,T>::operator - ()
-{
-  if (*this)
-    set_sign(sign() == 1 ? -1 : 1);
-  return *this;
-}
-
-
-// arithmetic
-
-
-// this is the high level addition function
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator += (const mp_int<A,T>& rhs)
-{
-  if (sign() == rhs.sign())
-    add_magnitude(rhs);
-  else
-  {
-    // subtract the one with the lesser magnitude from
-    // the one of the greater magnitude. The result gets
-    // the sign of the one with the greater magnitude.
-    const mp_int* x;
-    const mp_int* y;
-    if (compare_magnitude(rhs) != -1) // |*this| >= |rhs|
-    {
-      x = this;
-      y = &rhs;
-    }
-    else // |*this| < |rhs|
-    {
-      grow_capacity(rhs.size_);
-      set_sign(rhs.sign());
-      x = &rhs;
-      y = this;
-    }
-
-    ops_type::sub_smaller_magnitude(digits_, x->digits_, x->size_,
-                                             y->digits_, y->size_);
-    size_ = x->size_;
-
-    clamp();
-
-    if (!*this)
-      set_sign(1);
-  }
-  return *this;
-}
-
-// high level subtraction (handles signs)
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator -= (const mp_int<A,T>& rhs)
-{
-  if (sign() != rhs.sign())
-    // add magnitudes, and use the sign of *this.
-    add_magnitude(rhs);
-  else
-  {
-    const mp_int* x;
-    const mp_int* y;
-    if (compare_magnitude(rhs) != -1) // [*this] >= rhs
-    {
-      x = this;
-      y = &rhs;
-    }
-    else // |*this| < |rhs|
-    {
-      grow_capacity(rhs.size_);
-      // result has opposite sign from *this
-      set_sign(is_positive() ? -1 : 1);
-      x = &rhs;
-      y = this;
-    }
-
-    ops_type::sub_smaller_magnitude(digits_, x->digits_, x->size_,
-                                             y->digits_, y->size_);
-
-    size_ = x->size_;
-
-    clamp();
-
-    if (!*this)
-      set_sign(1);
-  }
-  return *this;
-}
-
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator *= (const mp_int<A,T>& rhs)
-{
-  if (this == &rhs)
-  {
-    sqr();
-    return *this;
-  }
-
-  const int neg = (sign() == rhs.sign()) ? 1 : -1;
-  const size_type min = std::min(size_, rhs.size_);
-
-  if (min >= traits_type::toom_mul_cutoff)
-    toom_cook_mul(rhs);
-  else if (min >= traits_type::karatsuba_mul_cutoff)
-    karatsuba_mul(rhs);
-  else
-  {
-    mp_int tmp;
-    tmp.grow_capacity(size_ + rhs.size_);
-
-    if (size_ == rhs.size_)
-      ops_type::comba_mul(tmp.digits(), digits(), rhs.digits(), size_);
-    else
-    {
-      // always multiply larger by smaller number
-      const mp_int* a = this;
-      const mp_int* b = &rhs;
-      if (a->size_ < b->size_)
-        std::swap(a, b);
-
-      ops_type::comba_mul(tmp.digits(), a->digits(), a->size_, b->digits(), b->size_);
-    }
-
-    tmp.size_ = size_ + rhs.size_;
-    tmp.clamp();
-    *this = tmp;
-  }
-
-  set_sign(!*this ? 1 : neg);
-
-  return *this;
-}
-
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator /= (const mp_int<A,T>& rhs)
-{
-  const mp_int<A,T> tmp(*this);
-  detail::classic_divide(tmp, rhs, *this);
-  return *this;
-}
-
-// The sign of the result is the sign of the dividend, i.e. *this.
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator %= (const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> quotient;
-  detail::classic_divide(*this, rhs, quotient, this);
-  return *this;
-}
-
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator |= (const mp_int<A,T>& rhs)
-{
-  size_type px;
-  mp_int tmp;
-  const mp_int* x;
-
-  if (size_ > rhs.size_)
-  {
-    tmp = *this;
-    px = rhs.size_;
-    x = &rhs;
-  }
-  else
-  {
-    tmp = rhs;
-    px = size_;
-    x = this;
-  }
-
-  for (size_type i = 0; i < px; ++i)
-    tmp[i] |= (*x)[i];
-
-  tmp.clamp();
-  swap(tmp);
-
-  return *this;
-}
-
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator &= (const mp_int<A,T>& rhs)
-{
-  size_type px;
-  mp_int tmp;
-  const mp_int *x;
-
-  if (size_ > rhs.size_)
-  {
-    tmp = *this;
-    px = rhs.size_;
-    x = &rhs;
-  }
-  else
-  {
-    tmp = rhs;
-    px = size_;
-    x = this;
-  }
-
-  for (size_type i = 0; i < px; ++i)
-    tmp[i] &= (*x)[i];
-
-  /* zero digits above the last from the smallest mp_int */
-  std::memset(tmp.digits_ + px, 0, (tmp.size_ - px) * sizeof(digit_type));
-  tmp.clamp();
-  swap(tmp);
-
-  return *this;
-}
-
-template<class A, class T>
-mp_int<A,T>& mp_int<A,T>::operator ^= (const mp_int<A,T>& rhs)
-{
-  size_type px;
-  mp_int tmp;
-  const mp_int *x;
-
-  if (size_ > rhs.size_)
-  {
-    tmp = *this;
-    px = rhs.size_;
-    x = &rhs;
-  }
-  else
-  {
-    tmp = rhs;
-    px = size_;
-    x = this;
-  }
-
-  for (size_type i = 0; i < px; ++i)
-    tmp[i] ^= (*x)[i];
-
-  tmp.clamp();
-  swap(tmp);
-
-  return *this;
-}
-
-template<class A, class T>
-inline mp_int<A,T>
-operator << (const mp_int<A,T>& lhs, typename mp_int<A,T>::size_type b)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv <<= b;
-  return nrv;
-}
-
-template<class A, class T>
-inline mp_int<A,T>
-operator >> (const mp_int<A,T>& lhs, typename mp_int<A,T>::size_type b)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv >>= b;
-  return nrv;
-}
-
-
-template<class A, class T>
-inline mp_int<A,T> operator - (const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> nrv(rhs);
-  -nrv;
-  return nrv;
-}
-
-
-
-template<class A, class T>
-inline mp_int<A,T> operator + (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv += rhs;
-  return nrv;
-}
-
-template<class A, class T>
-inline mp_int<A,T> operator - (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv -= rhs;
-  return nrv;
-}
-
-template<class A, class T>
-inline mp_int<A,T> operator * (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  if (&lhs != &rhs)
-    nrv *= rhs;
-  else
-    nrv *= nrv; // this uses special squaring code in operator *=
-  return nrv;
-}
-
-template<class A, class T>
-inline mp_int<A,T> operator / (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv /= rhs;
-  return nrv;
-}
-
-template<class A, class T>
-inline mp_int<A,T> operator % (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv %= rhs;
-  return nrv;
-}
-
-template<class A, class T>
-inline mp_int<A,T> operator | (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv |= rhs;
-  return nrv;
-}
-
-template<class A, class T>
-inline mp_int<A,T> operator & (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv &= rhs;
-  return nrv;
-}
-
-template<class A, class T>
-inline mp_int<A,T> operator ^ (const mp_int<A,T>& lhs, const mp_int<A,T>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv ^= rhs;
-  return nrv;
-}
-
-template<class A, class T, typename IntegralT>
-inline mp_int<A,T> operator + (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv += rhs;
-  return nrv;
-}
-
-template<class A, class T, typename IntegralT>
-inline mp_int<A,T> operator - (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv -= rhs;
-  return nrv;
-}
-
-template<class A, class T, typename IntegralT>
-inline mp_int<A,T> operator * (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv *= rhs;
-  return nrv;
-}
-
-template<class A, class T, typename IntegralT>
-inline mp_int<A,T> operator / (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv /= rhs;
-  return nrv;
-}
-
-template<class A, class T, typename IntegralT>
-inline mp_int<A,T> operator % (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv %= rhs;
-  return nrv;
-}
-
-template<class A, class T, typename IntegralT>
-inline mp_int<A,T> operator | (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv |= rhs;
-  return nrv;
-}
-
-template<class A, class T, typename IntegralT>
-inline mp_int<A,T> operator & (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv &= rhs;
-  return nrv;
-}
-
-template<class A, class T, typename IntegralT>
-inline mp_int<A,T> operator ^ (const mp_int<A,T>& lhs, IntegralT rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv ^= rhs;
-  return nrv;
-}
-
-
-// Arithmetic and bitwise operators involving character strings
-template<class A, class T>
-template<typename charT>
-inline mp_int<A,T>& mp_int<A,T>::operator += (const charT* s) { return *this += mp_int<A,T>(s); }
-template<class A, class T>
-template<typename charT>
-inline mp_int<A,T>& mp_int<A,T>::operator -= (const charT* s) { return *this -= mp_int<A,T>(s); }
-template<class A, class T>
-template<typename charT>
-inline mp_int<A,T>& mp_int<A,T>::operator *= (const charT* s) { return *this *= mp_int<A,T>(s); }
-template<class A, class T>
-template<typename charT>
-inline mp_int<A,T>& mp_int<A,T>::operator /= (const charT* s) { return *this /= mp_int<A,T>(s); }
-template<class A, class T>
-template<typename charT>
-inline mp_int<A,T>& mp_int<A,T>::operator %= (const charT* s) { return *this %= mp_int<A,T>(s); }
-template<class A, class T>
-template<typename charT>
-inline mp_int<A,T>& mp_int<A,T>::operator |= (const charT* s) { return *this |= mp_int<A,T>(s); }
-template<class A, class T>
-template<typename charT>
-inline mp_int<A,T>& mp_int<A,T>::operator &= (const charT* s) { return *this &= mp_int<A,T>(s); }
-template<class A, class T>
-template<typename charT>
-inline mp_int<A,T>& mp_int<A,T>::operator ^= (const charT* s) { return *this ^= mp_int<A,T>(s); }
-
-template<class A, class T, typename charT>
-inline mp_int<A,T> operator + (const mp_int<A,T>& lhs, const charT* rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv += mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT>
-inline mp_int<A,T> operator - (const mp_int<A,T>& lhs, const charT* rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv -= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT>
-inline mp_int<A,T> operator * (const mp_int<A,T>& lhs, const charT* rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv *= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT>
-inline mp_int<A,T> operator / (const mp_int<A,T>& lhs, const charT* rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv /= mp_int<A,T>(rhs);
-  return nrv;
-}
-template<class A, class T, typename charT>
-inline mp_int<A,T> operator % (const mp_int<A,T>& lhs, const charT* rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv %= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT>
-inline mp_int<A,T> operator | (const mp_int<A,T>& lhs, const charT* rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv |= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT>
-inline mp_int<A,T> operator & (const mp_int<A,T>& lhs, const charT* rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv &= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT>
-inline mp_int<A,T> operator ^ (const mp_int<A,T>& lhs, const charT* rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv ^= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-
-// Arithmetic and bitwise operators involving basic_string
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline mp_int<A,T>&
-mp_int<A,T>::operator += (const std::basic_string<charT,traits,Alloc>& s)
-{
-  return *this += mp_int<A,T>(s);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline mp_int<A,T>&
-mp_int<A,T>::operator -= (const std::basic_string<charT,traits,Alloc>& s)
-{
-  return *this -= mp_int<A,T>(s);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline mp_int<A,T>&
-mp_int<A,T>::operator *= (const std::basic_string<charT,traits,Alloc>& s)
-{
-  return *this *= mp_int<A,T>(s);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline mp_int<A,T>&
-mp_int<A,T>::operator /= (const std::basic_string<charT,traits,Alloc>& s)
-{
-  return *this /= mp_int<A,T>(s);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline mp_int<A,T>&
-mp_int<A,T>::operator %= (const std::basic_string<charT,traits,Alloc>& s)
-{
-  return *this %= mp_int<A,T>(s);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline mp_int<A,T>&
-mp_int<A,T>::operator |= (const std::basic_string<charT,traits,Alloc>& s)
-{
-  return *this |= mp_int<A,T>(s);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline mp_int<A,T>&
-mp_int<A,T>::operator &= (const std::basic_string<charT,traits,Alloc>& s)
-{
-  return *this &= mp_int<A,T>(s);
-}
-
-template<class A, class T>
-template<typename charT, class traits, class Alloc>
-inline mp_int<A,T>&
-mp_int<A,T>::operator ^= (const std::basic_string<charT,traits,Alloc>& s)
-{
-  return *this ^= mp_int<A,T>(s);
-}
-
-template<class A, class T, typename charT, class traits, class Alloc>
-inline mp_int<A,T>
-operator + (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv += mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT, class traits, class Alloc>
-inline mp_int<A,T>
-operator - (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv -= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT, class traits, class Alloc>
-inline mp_int<A,T>
-operator * (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv *= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT, class traits, class Alloc>
-inline mp_int<A,T>
-operator / (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv /= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT, class traits, class Alloc>
-inline mp_int<A,T>
-operator % (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv %= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT, class traits, class Alloc>
-inline mp_int<A,T>
-operator | (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv |= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT, class traits, class Alloc>
-inline mp_int<A,T>
-operator & (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv &= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-template<class A, class T, typename charT, class traits, class Alloc>
-inline mp_int<A,T>
-operator ^ (const mp_int<A,T>& lhs, const std::basic_string<charT,traits,Alloc>& rhs)
-{
-  mp_int<A,T> nrv(lhs);
-  nrv ^= mp_int<A,T>(rhs);
-  return nrv;
-}
-
-
-
-
-// Input/Output
-template<class A, class T, typename charT, class traits>
-std::basic_istream<charT, traits>&
-operator >> (std::basic_istream<charT, traits>& is, mp_int<A,T>& x)
-{
-  typename std::basic_istream<charT, traits>::sentry sentry(is);
-  if (!sentry)
-    return is;
-
-  std::string s;
-
-  const std::istreambuf_iterator<charT, traits> end;
-  std::istreambuf_iterator<charT, traits> c(is);
-
-  if (*c == '+' || *c == '-')
-  {
-    s.push_back(*c);
-    ++c;
-  }
-
-  int base;
-  if (*c == '0')
-  {
-    base = 8;
-    s.push_back(*c);
-    ++c;
-    if (*c == 'x' || *c == 'X')
-    {
-      base = 16;
-      s.push_back(*c);
-      ++c;
-    }
-  }
-  else if (*c >= '0' && *c <= '9')
-    base = 10;
-  else
-  {
-    is.setstate(std::ios_base::failbit);
-    return is;
-  }
-
-  switch (base)
-  {
-    case 8:
-      while (c != end)
-      {
-        if (*c >= '0' && *c <= '7')
-          s.push_back(*c);
-        else
-          break;
-        ++c;
-      }
-      break;
-    case 10:
-      while (c != end)
-      {
-        if (*c >= '0' && *c <= '9')
-          s.push_back(*c);
-        else
-          break;
-        ++c;
-      }
-      break;
-    case 16:
-      while (c != end)
-      {
-        if ((*c >= '0' && *c <= '9') ||
-            (*c >= 'A' && *c <= 'F') ||
-            (*c >= 'a' && *c <= 'f'))
-          s.push_back(*c);
-        else
-          break;
-        ++c;
-      }
-      break;
-  }
-
-  const mp_int<A,T> tmp(s.begin(), s.end());
-  x = tmp;
-
-  return is;
-}
-
-template<class A, class T, typename charT, class traits>
-std::basic_ostream<charT, traits>&
-operator << (std::basic_ostream<charT, traits>& os, const mp_int<A,T>& x)
-{
-  return os << x.template to_string<std::string>(os.flags());
-}
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/pow.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/pow.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,66 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-// computes a = 2**b 
-// Simple algorithm which zeroes the int, grows it then just sets one bit
-// as required.
-template<class A, class T>
-void mp_int<A,T>::pow2(typename mp_int<A,T>::size_type b)
-{
-  grow_capacity(b / digit_bits + 1);
-
-  // set size_ to where the bit will go
-  size_ = b / digit_bits + 1;
-
-  // set all bits to zero
-  std::memset(digits_, 0, size_ * sizeof(digit_type));
-  
-  // put the single bit in its place
-  digits_[b / digit_bits] = digit_type(1) << (b % digit_bits);
-}
-
-// calculate c = x**y  using a square-multiply algorithm
-template<class A, class T>
-mp_int<A,T> pow(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type y)
-{
-  mp_int<A,T> result;  
-
-  result = typename mp_int<A,T>::digit_type(1);
-
-  const typename mp_int<A,T>::digit_type mask = 1 << (mp_int<A,T>::digit_bits - 1);
-  
-  for (int i = 0; i < mp_int<A,T>::digit_bits; ++i)
-  {
-    result.sqr();
-
-    // if the bit is set multiply
-    if (y & mask)
-      result *= x;
-
-    // shift to next bit
-    y <<= 1;
-  }
-
-  return result;
-}
-
-template<class A, class T>
-mp_int<A,T> pow(const mp_int<A,T>& x, const mp_int<A,T>& y)
-{
-  if (y.size() == 1)
-    return pow(x, y[0]);
-
-  mp_int<A,T> y0(y);
-  
-  y0.divide_by_2();
-  
-  mp_int<A,T> y1(y0);
-
-  if (y.is_odd())
-    ++y1;
-
-  return pow(x, y0) * pow(x, y1);
-}
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/root.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/root.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,204 +0,0 @@
-// Copyright Kevin Sopp 2008 - 2009.
-// 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_MP_MATH_MP_INT_ROOT_HPP
-#define BOOST_MP_MATH_MP_INT_ROOT_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-
-
-namespace boost {
-namespace mp_math {
-
-template<class A, class T>
-mp_int<A,T> sqrt(const mp_int<A,T>& x)
-{
-  if (x.is_negative())
-    throw std::domain_error("sqrt: argument must be positive");
-
-  mp_int<A,T> t1;
-
-  if (!x)
-  {
-    t1.zero();
-    return t1;
-  }
-
-  t1 = x;
-
-  // First approx. (not very bad for large arg)
-  t1.shift_digits_right(t1.size()/2);
-
-  // t1 > 0
-  mp_int<A,T> t2 = x / t1;
-
-  t1 += t2;
-  t1.divide_by_2();
-  // And now t1 > sqrt(arg)
-  do
-  {
-    t2 = x / t1;
-    t1 += t2;
-    t1.divide_by_2();
-    // t1 >= sqrt(arg) >= t2 at this point
-  } while (t1.compare_magnitude(t2) == 1);
-
-  return t1;
-}
-
-
-// Uses Newton-Raphson approximation.
-template<class A, class T>
-mp_int<A,T> nth_root(const mp_int<A,T>& x, typename mp_int<A,T>::digit_type n)
-{
-  if ((n & 1) == 0 && x.is_negative())
-    throw std::domain_error("nth_root: argument must be positive if n is even");
-
-  if (n == 0U)
-    throw std::domain_error("nth_root: n must not be zero");
-  else if (n == 1U)
-    return x;
-
-  // if x is negative fudge the sign but keep track
-  const int neg = x.sign();
-  const_cast<mp_int<A,T>*>(&x)->set_sign(1);
-
-  mp_int<A,T> t1, t2, t3;
-
-  typedef typename mp_int<A,T>::size_type size_type;
-
-  // initial approximation
-  const size_type result_precision = (x.precision() - 1) / n + 1;
-  t2.grow_capacity(1);
-  t2.set_size(1);
-  t2[0] = 0;
-  t2.set_bits(0, result_precision + 1);
-
-  do
-  {
-    t1 = t2;
-
-    // t2 = t1 - ((t1**n - x) / (n * t1**(n-1)))
-
-    // t3 = t1**(n-1)
-    t3 = pow(t1, n-1);
-
-    // numerator
-    // t2 = t1**n
-    t2 = t3 * t1;
-
-    // t2 = t1**n - x
-    t2 -= x;
-
-    // denominator
-    // t3 = t1**(n-1) * n
-    t3.multiply_by_digit(n);
-
-    // t3 = (t1**n - x)/(n * t1**(n-1))
-    t3 = t2 / t3;
-
-    t2 = t1 - t3;
-  } while (t1 != t2);
-
-  // result can be off by a few so check
-  for (;;)
-  {
-    t2 = pow(t1, n);
-
-    if (t2 > x)
-      --t1;
-    else
-      break;
-  }
-
-  // reset the sign of x first
-  const_cast<mp_int<A,T>*>(&x)->set_sign(neg);
-
-  // set the sign of the result
-  t1.set_sign(neg);
-
-  return t1;
-}
-
-template<class A, class T>
-mp_int<A,T> nth_root(const mp_int<A,T>& x, const mp_int<A,T>& n)
-{
-  if (n.is_odd() && x.is_negative())
-    throw std::domain_error("nth_root: argument must be positive if n is even");
-
-  if (n.size() == 1)
-    return nth_root(x, n[0]);
-
-  // if x is negative fudge the sign but keep track
-  const int neg = x.sign();
-  const_cast<mp_int<A,T>*>(&x)->set_sign(1);
-
-  mp_int<A,T> t1, t2, t3;
-
-  typedef typename mp_int<A,T>::size_type size_type;
-
-  static const size_type digit_bits = mp_int<A,T>::digit_bits;
-
-  const size_type result_precision = (x.precision() - 1)
-                                   / n.template to_integral<size_type>() + 1;
-
-  t2.grow_capacity((result_precision + digit_bits - 1) / digit_bits);
-  t2.set_size     ((result_precision + digit_bits - 1) / digit_bits);
-
-  t2[t2.size()-1] = 0;
-  t2.set_bits(0, result_precision + 1);
-
-  do
-  {
-    t1 = t2;
-
-    // t2 = t1 - ((t1**n - x) / (n * t1**(n-1)))
-
-    // t3 = t1**(n-1)
-    t3 = pow(t1, n-1);
-
-    // numerator
-    // t2 = t1**n
-    t2 = t3 * t1;
-
-    // t2 = t1**n - x
-    t2 -= x;
-
-    // denominator
-    // t3 = t1**(n-1) * n
-    t3 *= n;
-
-    // t3 = (t1**n - x)/(n * t1**(n-1))
-    t3 = t2 / t3;
-
-    t2 = t1 - t3;
-  } while (t1 != t2);
-
-  // result can be off by a few so check
-  for (;;)
-  {
-    t2 = pow(t1, n);
-
-    if (t2 > x)
-      --t1;
-    else
-      break;
-  }
-
-  // reset the sign of x first
-  const_cast<mp_int<A,T>*>(&x)->set_sign(neg);
-
-  // set the sign of the result
-  t1.set_sign(neg);
-
-  return t1;
-}
-
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/sqr.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/sqr.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,220 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-/* squaring using Toom-Cook 3-way algorithm */
-template<class A, class T>
-void mp_int<A,T>::toom_sqr()
-{
-  mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
-
-  const size_type B = size_ / 3;
-
-  /* a = a2 * B**2 + a1 * B + a0 */
-  a0 = *this;
-  a0.modulo_2_to_the_power_of(valid_bits * B);
-
-  a1 = *this;
-  a1.shift_digits_right(B);
-  a1.modulo_2_to_the_power_of(valid_bits * B);
-
-  a2 = *this;
-  a2.shift_digits_right(B * 2);
-
-  /* w0 = a0*a0 */
-  w0 = a0;
-  w0.sqr();
-
-  /* w4 = a2 * a2 */
-  w4 = a2;
-  w4.sqr();
-
-  /* w1 = (a2 + 2(a1 + 2a0))**2 */
-  w1 = a0;
-  w1.multiply_by_2();
-  w1 += a1;
-  w1.multiply_by_2();
-  w1 += a2;
-  w1.sqr();
-
-  /* w3 = (a0 + 2(a1 + 2a2))**2 */
-  w3 = a2;
-  w3.multiply_by_2();
-  w3 += a1;
-  w3.multiply_by_2();
-  w3 += a0;
-  w3.sqr();
-
-  /* w2 = (a2 + a1 + a0)**2 */
-  w2 = a1 + a2;
-  w2 += a0;
-  w2.sqr();
-
-  /* now solve the matrix
-
-     0  0  0  0  1
-     1  2  4  8  16
-     1  1  1  1  1
-     16 8  4  2  1
-     1  0  0  0  0
-
-     using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
-   */
-
-  /* r1 - r4 */
-  w1 -= w4;
-  /* r3 - r0 */
-  w3 -= w0;
-  /* r1/2 */
-  w1.divide_by_2();
-  /* r3/2 */
-  w3.divide_by_2();
-  /* r2 - r0 - r4 */
-  w2 -= w0;
-  w2 -= w4;
-  /* r1 - r2 */
-  w1 -= w2;
-  /* r3 - r2 */
-  w3 -= w2;
-  /* r1 - 8r0 */
-  tmp1 = w0;
-  tmp1 <<= 3;
-  w1 -= tmp1;
-  /* r3 - 8r4 */
-  tmp1 = w4;
-  tmp1 <<= 3;
-  w3 -= tmp1;
-  /* 3r2 - r1 - r3 */
-  w2.multiply_by_digit(3);
-  w2 -= w1;
-  w2 -= w3;
-  /* r1 - r2 */
-  w1 -= w2;
-  /* r3 - r2 */
-  w3 -= w2;
-  /* r1/3 */
-  w1.divide_by_3();
-  /* r3/3 */
-  w3.divide_by_3();
-  /* at this point shift W[n] by B*n */
-  w1.shift_digits_left(1 * B);
-  w2.shift_digits_left(2 * B);
-  w3.shift_digits_left(3 * B);
-  w4.shift_digits_left(4 * B);
-  *this = w0 + w1;
-  tmp1 = w2 + w3;
-  tmp1 += w4;
-  *this += tmp1;
-}
-
-/* Karatsuba squaring, computes b = a*a using three 
- * half size squarings
- *
- * See comments of karatsuba_mul for details.  It 
- * is essentially the same algorithm but merely 
- * tuned to perform recursive squarings.
- */
-// a    = x1 * B**n + x0
-// a**2 = x1x1 * B**2n + 2*x0x1 * B**n + x0x0
-// where
-// 2*x0x1 = 1) x1x1 + x0x0 - (x1 - x0)**2   or
-//          2) (x0 + x1)**2 - (x0x0 + x1x1)
-// we use version 1)
-// version 2) may use one less temporary?
-// a**2 = x1x1 * B**2n + (x1x1 + x0x0 - (x1 - x0)**2) * B**n + x0x0
-// TODO revert!
-template<class A, class T>
-void mp_int<A,T>::karatsuba_sqr()
-{
-  mp_int x0, x1, tmp, tmp2, x0x0, x1x1;
-
-  /* min # of digits divided in two */
-  const size_type B = size_ >> 1;
-
-  /* init copy all the temps */
-  x0.grow_capacity(B);
-  x1.grow_capacity(size_ - B);
-
-  /* init temps */
-  x0x0.grow_capacity(B * 2);
-  x1x1.grow_capacity((size_ - B) * 2);
-
-  /* now shift the digits */
-  std::memcpy(x0.digits_, digits_, B * sizeof(digit_type));
-  std::memcpy(x1.digits_, digits_ + B, (size_ - B) * sizeof(digit_type));
-
-  x0.size_ = B;
-  x1.size_ = size_ - B;
-
-  x0.clamp();
-
-  x0x0 = x0;
-  x0x0.sqr();
-  x1x1 = x1;
-  x1x1.sqr();
-
-  tmp = x1x1;
-  tmp.add_magnitude(x0x0);
-
-  tmp2 = x1;
-  tmp2 -= x0;
-  tmp2.sqr();
-
-  tmp.sub_smaller_magnitude(tmp2);
-
-  x1x1.shift_digits_left(B * 2);
-  tmp.shift_digits_left(B);
-
-  x1x1.add_magnitude(tmp);
-  x1x1.add_magnitude(x0x0);
-  swap(x1x1);
-}
-
-template<class A, class T>
-void mp_int<A,T>::comba_sqr()
-{
-  if (size() < 16U)
-  {
-    grow_capacity(size() + size());
-    
-    digit_type Z[32];
-    
-    ops_type::comba_sqr(Z, digits(), size());
-    
-    std::memcpy(digits(), Z, (size() + size()) * sizeof(digit_type));
-    
-    set_size(size() + size());
-    
-    if (!digits()[size()-1])
-      pop();
-  }
-  else
-  {
-    mp_int tmp;
-    tmp.grow_capacity(size() + size());
-
-    ops_type::comba_sqr(tmp.digits(), digits(), size());
-
-    tmp.set_size(size() + size());
-
-    if (!tmp[tmp.size()-1])
-      tmp.pop();
-
-    *this = tmp;
-  }
-}
-
-// computes *this = *this * *this
-template<class A, class T>
-void mp_int<A,T>::sqr()
-{
-  if (size_ >= traits_type::toom_sqr_cutoff)
-    toom_sqr();
-  else if (size_ >= traits_type::karatsuba_sqr_cutoff)
-    karatsuba_sqr();
-  else
-    comba_sqr();
-  set_sign(1);
-}
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/string_conversion.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/string_conversion.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,314 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-namespace detail
-{
-  template<typename charT>
-  inline int ascii_to_value(const charT c)
-  {
-    switch (c)
-    {
-      case '0': case '1': case '2': case '3': case '4':
-      case '5': case '6': case '7': case '8': case '9':
-        return c - '0';
-      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-        return c - 'A' + 10;
-      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-        return c - 'a' + 10;
-    }
-    return c;
-  }
-}
-
-// low level from string conversion routine
-// Requires:
-// - size_ = 0
-// - first and last must point into string without sign prefix and without base
-//   prefix (like 0x)
-// - radix is 8, 10 or 16
-template<class A, class T>
-template<typename Iter>
-void mp_int<A,T>::from_string(Iter first, Iter last, unsigned radix)
-{
-  assert(size_ == 0);
-  assert(first != last);
-
-  const detail::string_conversion_constants<mp_int> sc(radix);
-
-  const size_type length = std::distance(first, last);
-
-  static const char* inv_msg = "mp_int<>::from_string: invalid character";
-  
-  const bool is_power_of_two = (radix & (radix - 1)) == 0;
-  if (is_power_of_two)
-  {
-    const size_type required =
-      (length * sc.radix_storage_bits + (valid_bits - 1)) / valid_bits;
-    grow_capacity(required);
-
-    digit_type result = 0;
-    int        offset = 0;
-    
-    typedef std::reverse_iterator<Iter> reverse_iter_type;
-    for (reverse_iter_type c(last); c != reverse_iter_type(first); ++c)
-    {
-      const digit_type x = static_cast<digit_type>(detail::ascii_to_value(*c));
-      
-      if (x >= radix)
-        throw std::invalid_argument(inv_msg);
-      
-      result |= x << offset;
-      offset += sc.radix_storage_bits;
-      
-      if (offset >= valid_bits)
-      {
-        push(result);
-        offset -= valid_bits;
-        result = static_cast<digit_type>(x >> (sc.radix_storage_bits - offset));
-      }
-    }
-    
-    if (result || is_uninitialized())
-      push(result);
-    
-    clamp();
-
-    if (!*this)
-      set_sign(1);
-  }
-  else // radix can only be 10 at this point
-  {
-    size_type required;
-    // approximate log2(10) with 10/3
-    if (length < std::numeric_limits<size_type>::max()/10U)
-      required = (10U * length + 2U) / 3U;
-    else
-      required = length / 3U * 10U;
-    required = (required + (valid_bits - 1)) / valid_bits;
-    
-    grow_capacity(required);
-
-    for (size_type i = sc.max_power; i < length; i += sc.max_power)
-    {
-      digit_type result = 0U;
-
-      // first convert a block of decimal digits to radix 10^sc.max_power
-      // which will still fit into a digit_type
-      for (unsigned int j = 0; j < sc.max_power; ++j)
-      {
-        const digit_type x = *first++ - '0';
-        if (x >= 10U)
-          throw std::invalid_argument(inv_msg);
-        result = result * 10U + x;
-      }
-
-      // then use multi precision routines to convert this digit to binary
-      if (size_)
-      {
-        digit_type carry = ops_type::multiply_by_digit(digits_, digits_, size_,
-                                                            sc.max_power_value);
-
-        carry += ops_type::add_single_digit(digits_, digits_, size_, result);
-        
-        if (carry)
-          push(carry);
-      }
-      else
-        push(result);
-    }
-
-    // one last round for the remaining decimal digits
-    if (first != last)
-    {
-      digit_type radix_power = 1U;
-      digit_type result = 0U;
-      
-      while (first != last)
-      {
-        const digit_type x = *first++ - '0';
-        if (x >= 10U)
-          throw std::invalid_argument(inv_msg);
-        result = result * 10U + x;
-        radix_power *= 10U;
-      }
-      
-      if (size_)
-      {
-        digit_type carry = ops_type::multiply_by_digit(digits_, digits_, size_,
-                                          static_cast<digit_type>(radix_power));
-
-        carry += ops_type::add_single_digit(digits_, digits_, size_, result);
-
-        if (carry)
-          push(carry);
-      }
-      else
-        push(result);
-    }
-  }
-}
-
-
-namespace detail
-{
-  template<typename T, class Alloc>
-  struct scoped_ptr : Alloc
-  {
-    T* ptr;
-    std::size_t size;
-    explicit scoped_ptr(std::size_t s) : size(s) { ptr = this->allocate(size); }
-    ~scoped_ptr() { this->deallocate(ptr,size); }
-  };
-}
-
-
-// TODO use an output iterator then we can easily output to different string
-// types. But keep a high level to_string function to allocate string memory
-// only once.
-template<class A, class T>
-template<class StringT>
-StringT mp_int<A,T>::to_string(std::ios_base::fmtflags f) const
-{
-  typedef typename StringT::value_type char_type;
-
-  StringT s;
-
-  if (is_uninitialized())
-    return s;
-
-  digit_type radix;
-
-  if (f & std::ios_base::hex)
-    radix = 16;
-  else if (f & std::ios_base::oct)
-    radix = 8;
-  else if (f & std::ios_base::dec)
-    radix = 10;
-  else
-    throw std::invalid_argument("mp_int<>::to_string: unsupported radix");
-
-  char_type prefix[3];
-  char_type* p = prefix;
-
-  if (is_negative())
-    *p++ = '-';
-  else if (f & std::ios_base::showpos)
-    *p++ = '+';
-
-  if (f & std::ios_base::showbase)
-  {
-    if (radix == 16)
-    {
-      *p++ = '0';
-      if (f & std::ios_base::uppercase)
-        *p++ = 'X';
-      else
-        *p++ = 'x';
-    }
-    else if (radix == 8)
-      *p++ = '0';
-  }
-
-  const int prefix_offset = p - prefix;
-
-  if (!*this)
-  {
-    s.reserve(prefix_offset + 1);
-    for (int i = 0; i < prefix_offset; ++i)
-      s.push_back(prefix[i]);
-    if (!(f & std::ios_base::oct))
-      s.push_back('0');
-    return s;
-  }
-
-  const detail::string_conversion_constants<mp_int> sc(radix);
-  const bool is_power_of_two = (radix & (radix - 1)) == 0;
-
-  size_type total_bits = precision();
-  // round up to a multiple of sc.radix_storage_bits
-  if (total_bits % sc.radix_storage_bits)
-    total_bits = total_bits - total_bits % sc.radix_storage_bits
-               + sc.radix_storage_bits;
-  
-  size_type required;
-  if (is_power_of_two)
-    required = (total_bits + (sc.radix_storage_bits - 1))
-             / sc.radix_storage_bits;
-  // approximate log2(10) with 13/4
-  else if (total_bits < std::numeric_limits<size_type>::max() / 4)
-    required = (total_bits * 4 + 12) / 13;
-  else
-    required = total_bits / 13 * 4;
-
-  required += prefix_offset;
-  detail::scoped_ptr<char_type, typename StringT::allocator_type> sd(required);
-
-  char_type* c = sd.ptr;
-  
-  for (int i = 0; i < prefix_offset; ++i)
-    *c++ = prefix[i];
-
-  if (is_power_of_two)
-  {
-    static const char* const lowercase_tab = "0123456789abcdef";
-    static const char* const uppercase_tab = "0123456789ABCDEF";
-
-    const char* const tab = (f & std::ios_base::uppercase)
-                          ? uppercase_tab
-                          : lowercase_tab;
-    
-    const digit_type mask = (digit_type(1) << sc.radix_storage_bits) - 1;
-
-    int offset = total_bits % valid_bits;
-    if (!offset)
-      offset = valid_bits;
-    
-    const_reverse_iterator d = rbegin();
-    for (;;)
-    {
-      offset -= sc.radix_storage_bits;
-      while (offset >= 0)
-      {
-        *c++ = tab[(*d >> offset) & mask];
-        offset -= sc.radix_storage_bits;
-      }
-      const digit_type partial_value = (*d << -offset) & mask;
-      if (++d == rend())
-        break;
-      offset += valid_bits;
-      *c++ = tab[partial_value | (*d >> offset)];
-    }
-  }
-  else
-  {
-    digit_type m = 2;
-    for (digit_type i = 100; i < sc.max_power_value; i *= 10)
-      ++m;
-    
-    mp_int tmp = abs(*this);
-    
-    while (tmp)
-    {
-      digit_type remainder = ops_type::divide_by_digit(tmp.digits(),
-                                                       tmp.digits(),
-                                                       tmp.size(),
-                                                       sc.max_power_value);
-      tmp.clamp_high_digit();
-
-      for (digit_type i = 0; i < m; ++i)
-      {
-        if (remainder || tmp)
-          *c++ = static_cast<char_type>('0' + remainder % 10U);
-        remainder /= 10U;
-      }
-    }
-    std::reverse(sd.ptr + prefix_offset, c);
-  }
-
-  s.assign(sd.ptr, c);
-
-  return s;
-}
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/sub.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/sub.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,44 +0,0 @@
-// Copyright Kevin Sopp 2008 - 2009.
-// 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)
-
-template<class A, class T>
-void mp_int<A,T>::sub_digit(digit_type b)
-{
-  if (is_negative())
-  {
-    const digit_type carry =
-      ops_type::add_single_digit(digits_, digits_, size_, b);
-    if (carry)
-      push(carry);
-    return;
-  }
-
-  if (size_ == 1)
-  {
-    if (digits_[0] < b) // example: 2 - 6 = -4
-    {
-      digits_[0] = b - digits_[0];
-      set_sign(-1);
-    }
-    else // example: 8 - 7 = 1 or 5 - 5 = 0
-      digits_[0] -= b;
-  }
-  else
-  {
-    ops_type::subtract_single_digit(digits_, digits_, size_, b);
-    if (!digits_[size_-1])
-      --size_;
-  }
-}
-
-// low level subtraction (assumes |*this| >= |rhs|), HAC pp.595 Algorithm 14.9
-template<class A, class T>
-inline void mp_int<A,T>::sub_smaller_magnitude(const mp_int& rhs)
-{
-  ops_type::sub_smaller_magnitude(digits_, digits_, size_, rhs.digits_, rhs.size_);
-
-  clamp();
-}
-
Deleted: /sandbox/mp_math/boost/mp_math/mp_int/traits.hpp
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/traits.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,99 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_TRAITS_HPP
-#define BOOST_MP_MATH_MP_INT_TRAITS_HPP
-
-#include <cstddef> // size_t
-#include <limits>
-#include <boost/config.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/mpl/back.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/mpl/deref.hpp>
-#include <boost/mpl/lower_bound.hpp>
-#include <boost/mpl/vector.hpp>
-
-
-namespace boost {
-namespace mp_math {
-
-namespace detail {
-
-typedef mpl::vector<
-  unsigned char,
-  unsigned short,
-  unsigned int,
-  unsigned long int
-  #ifdef BOOST_HAS_LONG_LONG
-  ,
-  unsigned long long int
-  #endif
-> unsigned_type_vec;
-
-template<typename T1, typename T2>
-struct cmp_digits
-:
-mpl::bool_<
-  std::numeric_limits<T1>::digits < std::numeric_limits<T2>::digits/2
->
-{
-};
-
-// we could also choose unsigned int (since this is propably the
-// fastest unsigned integer type) as digit_type then
-// try to find a larger type as word_type
-// if none exists set unsigned int as word_type and choose next
-// smaller type as digit_type
-struct choose
-{
-  typedef mpl::back<unsigned_type_vec>::type word_type;
-  typedef mpl::deref<
-      mpl::lower_bound<
-        unsigned_type_vec, word_type, cmp_digits<mpl::_1,mpl::_2>
-        >::type
-      >::type digit_type;
-};
-
-} // namespace detail
-
-
-template<
-  typename Digit = detail::choose::digit_type,
-  typename Word = detail::choose::word_type/*,
-  bool debug = false*/
->
-struct mp_int_traits
-{
-  BOOST_STATIC_ASSERT(
-    std::numeric_limits<Digit>::digits <= std::numeric_limits<Word>::digits/2
-  );
-
-  typedef Digit digit_type;
-  typedef Word  word_type;
-
-  static std::size_t toom_mul_cutoff;
-  static std::size_t toom_sqr_cutoff;
-  static std::size_t karatsuba_mul_cutoff;
-  static std::size_t karatsuba_sqr_cutoff;
-};
-
-
-#define BMPINT_init(S) template<typename D, typename W>\
-  S mp_int_traits<D,W>::
-BMPINT_init(std::size_t)toom_mul_cutoff = 350;
-BMPINT_init(std::size_t)toom_sqr_cutoff = 400;
-BMPINT_init(std::size_t)karatsuba_mul_cutoff = 80;
-BMPINT_init(std::size_t)karatsuba_sqr_cutoff = 120;
-
-#undef BMPINT_init
-
-
-
-} // namespace mp_math
-} // namespace boost
-
-#endif
-
Added: sandbox/mp_math/boost/mp_math/integer/unbounded.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/unbounded.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,118 @@
+// Copyright Kevin Sopp 2009.
+// 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_MP_MATH_INTEGER_UNBOUNDED_HPP
+#define BOOST_MP_MATH_INTEGER_UNBOUNDED_HPP
+
+#include <boost/config.hpp>
+#include <boost/mp_math/integer/unbounded_int.hpp>
+#include <boost/mp_math/integer/unbounded_uint.hpp>
+#include <boost/mp_math/integer/unbounded_traits.hpp>
+
+namespace boost {
+namespace mp_math {
+
+template<
+  bool IsSigned = true,
+  class Alloc = std::allocator<void>,
+  class Traits = unbounded_traits<>
+>
+struct unbounded
+:
+  mpl::if_c<
+    IsSigned,
+    unbounded_int<Alloc,Traits>,
+    unbounded_uint<Alloc,Traits>
+  >::type
+{
+  typedef typename mpl::if_c<
+    IsSigned,
+    unbounded_int<Alloc,Traits>,
+    unbounded_uint<Alloc,Traits>
+  >::type base_type;
+
+  // these constants are used by the numeric_limits specialization
+  static const bool is_signed = IsSigned;
+  static const bool is_bounded = false;
+
+  typedef typename base_type::traits_type traits_type;
+  typedef typename base_type::digit_type  digit_type;
+  typedef typename base_type::size_type   size_type;
+
+  unbounded(){}
+
+  #if !defined(BOOST_NO_VARIADIC_TEMPLATES) &&\
+      !defined(BOOST_NO_RVALUE_REFERENCES)
+  template<typename... Args>
+  unbounded(Args&&... args)
+  :
+    base_type(args...)
+  {}
+
+  #else
+
+  template<typename T1>
+  unbounded(const T1& t1)
+  : base_type(t1) {}
+
+  template<typename T1, typename T2>
+  unbounded(const T1& t1, const T2& t2)
+  : base_type(t1, t2) {}
+
+  template<typename T1, typename T2, typename T3>
+  unbounded(const T1& t1, const T2& t2, const T3& t3)
+  : base_type(t1, t2, t3) {}
+
+  template<typename T1, typename T2, typename T3, typename T4>
+  unbounded(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
+  : base_type(t1, t2, t3, t4) {}
+
+  template<typename T1, typename T2, typename T3, typename T4, typename T5>
+  unbounded(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
+  : base_type(t1, t2, t3, t4, t5) {}
+  #endif
+
+  template<typename T>
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  unbounded& operator = (T&& t)
+  #else
+  unbounded& operator = (const T& t)
+  #endif
+  {
+    base_type::operator=(t);
+    return *this;
+  }
+
+  operator base_type&       ()       { return *this; }
+  operator const base_type& () const { return *this; }
+};
+
+
+template<bool S, class A, class T>
+struct modpow_ctx<unbounded<S,A,T> >
+:
+  modpow_ctx<typename unbounded<S,A,T>::base_type>
+{};
+
+// returns base^exp % mod
+template<bool S, class A, class T>
+inline
+unbounded<S,A,T> modpow(const unbounded<S,A,T>& base,
+                        const unbounded<S,A,T>& exp,
+                        const unbounded<S,A,T>& mod,
+                        modpow_ctx<unbounded<S,A,T> >* ctx = 0)
+{
+  return modpow(static_cast<const typename unbounded<S,A,T>::base_type&>(base),
+                static_cast<const typename unbounded<S,A,T>::base_type&>(exp),
+                static_cast<const typename unbounded<S,A,T>::base_type&>(mod),
+                static_cast<modpow_ctx<typename unbounded<S,A,T>::base_type>*>(ctx));
+}
+
+
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Added: sandbox/mp_math/boost/mp_math/integer/unbounded_int.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/unbounded_int.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,1469 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_UNBOUNDED_INT_HPP
+#define BOOST_MP_MATH_INTEGER_UNBOUNDED_INT_HPP
+
+#include <boost/config.hpp>
+#include <boost/mp_math/integer/contexts.hpp>
+#include <boost/mp_math/integer/unbounded_traits.hpp>
+#include <boost/mp_math/integer/detail/adder.hpp>
+#include <boost/mp_math/integer/detail/bitwise_ops.hpp>
+#include <boost/mp_math/integer/detail/divider.hpp>
+#include <boost/mp_math/integer/detail/gcd.hpp>
+#include <boost/mp_math/integer/detail/jacobi.hpp>
+#include <boost/mp_math/integer/detail/lcm.hpp>
+#include <boost/mp_math/integer/detail/modinv.hpp>
+#include <boost/mp_math/integer/detail/modpow.hpp>
+#include <boost/mp_math/integer/detail/power.hpp>
+#include <boost/mp_math/integer/detail/root.hpp>
+#include <boost/mp_math/integer/detail/string_conversion.hpp>
+#include <boost/mp_math/integer/detail/unbounded_int_integral.hpp>
+#include <boost/mp_math/integer/detail/base/unbounded_int.hpp>
+
+namespace boost {
+namespace mp_math {
+
+template<
+  class Alloc = std::allocator<void>,
+  class Traits = unbounded_traits<>
+>
+struct unbounded_int
+:
+  /*typename*/ Alloc::template rebind<typename Traits::digit_type>::other,
+  detail::base::unbounded_int<Traits>
+{
+protected:
+
+  typedef detail::base::unbounded_int<Traits> base_type;
+
+  typedef typename Alloc::template
+    rebind<typename Traits::digit_type>::other base_allocator_type;
+
+public:
+
+  template<typename IntegralT>
+  struct integral_ops
+  :
+    detail::unbounded_int_integral_ops<unbounded_int, IntegralT>
+  {};
+
+  typedef Alloc                              allocator_type;
+  typedef Traits                             traits_type;
+  typedef typename traits_type::digit_type   digit_type;
+  typedef typename allocator_type::size_type size_type;
+
+  typedef typename base_type::iterator               iterator;
+  typedef typename base_type::const_iterator         const_iterator;
+  typedef typename base_type::reverse_iterator       reverse_iterator;
+  typedef typename base_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename base_type::magnitude_type         magnitude_type;
+
+  unbounded_int();
+
+  explicit unbounded_int(const allocator_type& a);
+
+  template<typename IntegralT>
+  unbounded_int(IntegralT,
+         const allocator_type& a = allocator_type(),
+         typename enable_if<is_integral<IntegralT> >::type* dummy = 0);
+
+  template<typename charT>
+  unbounded_int(const charT*, const allocator_type& a = allocator_type());
+
+  template<typename charT>
+  unbounded_int(const charT*,
+                std::ios_base::fmtflags,
+                const allocator_type& a = allocator_type());
+
+  template<typename charT, class traits, class alloc>
+  unbounded_int(const std::basic_string<charT,traits,alloc>&,
+                const allocator_type& a = allocator_type());
+
+  template<typename charT, class traits, class alloc>
+  unbounded_int(const std::basic_string<charT,traits,alloc>&,
+                std::ios_base::fmtflags,
+                const allocator_type& a = allocator_type());
+
+  template<typename RandomAccessIterator>
+  unbounded_int(RandomAccessIterator first,
+                RandomAccessIterator last,
+                const allocator_type& a = allocator_type());
+
+  template<typename RandomAccessIterator>
+  unbounded_int(RandomAccessIterator first,
+                RandomAccessIterator last,
+                std::ios_base::fmtflags f,
+                const allocator_type& a = allocator_type());
+
+  unbounded_int(const unbounded_int& copy);
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  unbounded_int(unbounded_int&& copy);
+  #endif
+
+  ~unbounded_int();
+
+  unbounded_int& operator = (const unbounded_int& rhs);
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  unbounded_int& operator = (unbounded_int&& rhs);
+  #endif
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator = (IntegralT rhs);
+
+  template<typename charT>
+  unbounded_int& operator = (const charT*);
+
+  template<typename charT, class traits, class alloc>
+  unbounded_int& operator = (const std::basic_string<charT,traits,alloc>&);
+
+  template<typename charT>
+  void assign(const charT*, std::ios_base::fmtflags);
+
+  template<typename charT, class traits, class alloc>
+  void assign(const std::basic_string<charT,traits,alloc>&,
+              std::ios_base::fmtflags);
+
+  template<typename RandomAccessIterator>
+  void assign(RandomAccessIterator first, RandomAccessIterator last,
+              std::ios_base::fmtflags);
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  void swap(unbounded_int&& other)
+  #else
+  void swap(unbounded_int& other)
+  #endif
+  {
+    base_type::swap(other);
+  }
+
+  allocator_type get_allocator() const { return allocator_type(); }
+
+  void reserve(size_type n);
+
+  unbounded_int& operator ++();
+  unbounded_int& operator --();
+  unbounded_int  operator ++(int);
+  unbounded_int  operator --(int);
+  unbounded_int& operator <<= (size_type);
+  unbounded_int& operator >>= (size_type);
+  unbounded_int& operator - ();
+
+  unbounded_int& operator += (const unbounded_int&);
+  unbounded_int& operator -= (const unbounded_int&);
+  unbounded_int& operator *= (const unbounded_int&);
+  unbounded_int& operator /= (const unbounded_int&);
+  unbounded_int& operator %= (const unbounded_int&);
+  unbounded_int& operator |= (const unbounded_int&);
+  unbounded_int& operator &= (const unbounded_int&);
+  unbounded_int& operator ^= (const unbounded_int&);
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator += (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator -= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator *= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator /= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator %= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator |= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator &= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_int&>::type
+  operator ^= (IntegralT);
+
+  template<typename charT> unbounded_int& operator += (const charT*);
+  template<typename charT> unbounded_int& operator -= (const charT*);
+  template<typename charT> unbounded_int& operator *= (const charT*);
+  template<typename charT> unbounded_int& operator /= (const charT*);
+  template<typename charT> unbounded_int& operator %= (const charT*);
+  template<typename charT> unbounded_int& operator |= (const charT*);
+  template<typename charT> unbounded_int& operator &= (const charT*);
+  template<typename charT> unbounded_int& operator ^= (const charT*);
+
+  template<typename charT, class traits, class alloc>
+  unbounded_int& operator += (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_int& operator -= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_int& operator *= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_int& operator /= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_int& operator %= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_int& operator |= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_int& operator &= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_int& operator ^= (const std::basic_string<charT,traits,alloc>&);
+
+  template<class StringT>
+  StringT to_string(std::ios_base::fmtflags f = std::ios_base::dec) const
+  {
+    StringT tmp;
+    detail::to_string_converter<unbounded_int> conv;
+    conv.convert(tmp, *this, f);
+    return tmp;
+  }
+
+protected:
+
+  template<typename Iter>
+  void init_from_string(Iter first, Iter last)
+  {
+    detail::from_string_converter<unbounded_int> conv;
+    conv.detect_properties(first, last);
+    conv.convert(*this, first, last);
+    if (*this)
+      base_type::set_sign_bit(conv.is_positive ? 0 : 1);
+  }
+
+  template<typename Iter>
+  void init_from_string(Iter first, Iter last, std::ios_base::fmtflags f)
+  {
+    detail::from_string_converter<unbounded_int> conv;
+    conv.detect_properties(first, last, f);
+    conv.convert(*this, first, last);
+    if (*this)
+      base_type::set_sign_bit(conv.is_positive ? 0 : 1);
+  }
+};
+
+
+template<class A, class T>
+inline void swap(unbounded_int<A,T>& lhs, unbounded_int<A,T>& rhs)
+{
+  lhs.swap(rhs);
+}
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+template<class A, class T>
+inline void swap(unbounded_int<A,T>&& lhs, unbounded_int<A,T>& rhs)
+{
+  lhs.swap(rhs);
+}
+template<class A, class T>
+inline void swap(unbounded_int<A,T>& lhs, unbounded_int<A,T>&& rhs)
+{
+  lhs.swap(rhs);
+}
+#endif
+
+
+template<class A, class T>
+unbounded_int<A,T>::unbounded_int()
+:
+  base_type(0, 0, 0)
+{
+}
+
+template<class A, class T>
+unbounded_int<A,T>::unbounded_int(const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+}
+
+template<class A, class T>
+template<typename IntegralT>
+unbounded_int<A,T>::unbounded_int(
+    IntegralT b,
+    const allocator_type& a,
+    typename enable_if<is_integral<IntegralT> >::type*)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  integral_ops<IntegralT>::assign(*this, b);
+}
+
+template<class A, class T>
+template<typename RandomAccessIterator>
+unbounded_int<A,T>::unbounded_int(RandomAccessIterator first,
+                                  RandomAccessIterator last,
+                                  const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(first, last);
+}
+
+template<class A, class T>
+template<typename charT>
+unbounded_int<A,T>::unbounded_int(const charT* s, const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(s, s + std::char_traits<charT>::length(s));
+}
+
+template<class A, class T>
+template<typename charT>
+unbounded_int<A,T>::unbounded_int(const charT* s,
+                                  std::ios_base::fmtflags f,
+                                  const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(s, s + std::char_traits<charT>::length(s), f);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+unbounded_int<A,T>::unbounded_int(
+    const std::basic_string<charT,traits,Alloc>& s,
+    const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(s.begin(), s.end());
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+unbounded_int<A,T>::unbounded_int(
+    const std::basic_string<charT,traits,Alloc>& s,
+    std::ios_base::fmtflags f,
+    const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(s.begin(), s.end(), f);
+}
+
+
+template<class A, class T>
+unbounded_int<A,T>::unbounded_int(const unbounded_int& copy)
+:
+  base_allocator_type(copy.get_allocator())
+{
+  base_type::digits_ = this->allocate(copy.size());
+  std::memcpy(base_type::digits_,
+              copy.digits(), copy.size() * sizeof(digit_type));
+  base_type::set_size(copy.size());
+  base_type::set_capacity(copy.size());
+  base_type::set_sign_bit(copy.sign_bit());
+}
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+template<class A, class T>
+unbounded_int<A,T>::unbounded_int(unbounded_int&& copy)
+:
+  base_type(copy.digits(), copy.size(), copy.capacity_)
+{
+  copy.digits_   = 0;
+  copy.size_     = 0;
+  copy.capacity_ = 0;
+}
+#endif
+
+
+template<class A, class T>
+unbounded_int<A,T>::~unbounded_int()
+{
+  base_type::assert_invariants();
+  if (base_type::digits())
+    this->deallocate(base_type::digits(), base_type::capacity());
+}
+
+template<class A, class T>
+unbounded_int<A,T>&
+unbounded_int<A,T>::operator = (const unbounded_int<A,T>& rhs)
+{
+  if (this != &rhs)
+  {
+    if ((base_type::capacity() == 0) || (base_type::capacity() < rhs.size()))
+      unbounded_int(rhs).swap(*this);
+    else
+    {
+      std::memcpy(base_type::digits_,
+                  rhs.digits(), rhs.size() * sizeof(digit_type));
+      base_type::set_size(rhs.size());
+      base_type::set_sign_bit(rhs.sign_bit());
+    }
+  }
+  return *this;
+}
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+template<class A, class T>
+unbounded_int<A,T>& unbounded_int<A,T>::operator = (unbounded_int<A,T>&& rhs)
+{
+  if (this != &rhs)
+  {
+    if (base_type::digits())
+      this->deallocate(base_type::digits(), base_type::capacity());
+    base_type::digits_   = 0;
+    base_type::size_     = 0;
+    base_type::capacity_ = 0;
+    swap(rhs);
+  }
+  return *this;
+}
+#endif
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T>&>::type
+unbounded_int<A,T>::operator = (IntegralT rhs)
+{
+  integral_ops<IntegralT>::assign(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename charT>
+unbounded_int<A,T>& unbounded_int<A,T>::operator = (const charT* s)
+{
+  base_type::set_size(0);
+  init_from_string(s, s + std::char_traits<charT>::length(s));
+  if (!*this)    // This may happen on the input "0"
+    base_type::set_sign(1);
+  return *this;
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+unbounded_int<A,T>&
+unbounded_int<A,T>::operator = (const std::basic_string<charT,traits,Alloc>& s)
+{
+  base_type::set_size(0);
+  init_from_string(s.begin(), s.end());
+  if (!*this)
+    base_type::set_sign(1);
+  return *this;
+}
+
+template<class A, class T>
+template<typename charT>
+inline void
+unbounded_int<A,T>::assign(const charT* s, std::ios_base::fmtflags f)
+{
+  assign(s, s + std::char_traits<charT>::length(s), f);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline void
+unbounded_int<A,T>::assign(const std::basic_string<charT,traits,Alloc>& s,
+                    std::ios_base::fmtflags f)
+{
+  assign(s.begin(), s.end(), f);
+}
+
+template<class A, class T>
+template<typename RandomAccessIterator>
+inline void
+unbounded_int<A,T>::assign(RandomAccessIterator first,
+                           RandomAccessIterator last,
+                           std::ios_base::fmtflags f)
+{
+  base_type::set_size(0);
+  init_from_string(first, last, f);
+  if (!*this)
+    base_type::set_sign(1);
+}
+
+template<class A, class T>
+void unbounded_int<A,T>::reserve(size_type n)
+{
+  if (base_type::capacity() < n)
+  {
+    const size_type new_cap = base_type::capacity() + base_type::capacity();
+    if (new_cap > n)
+      n = new_cap;
+    digit_type* d = this->allocate(n, base_type::digits_);
+    std::memcpy(d, base_type::digits(), sizeof(digit_type) * base_type::size());
+    this->deallocate(base_type::digits_, base_type::capacity());
+    base_type::digits_ = d;
+    base_type::set_capacity(n);
+  }
+}
+
+// prefix ops
+template<class A, class T>
+inline unbounded_int<A,T>& unbounded_int<A,T>::operator ++()
+{
+  reserve(base_type::size() + 1);
+  base_type::operator++();
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>& unbounded_int<A,T>::operator --()
+{
+  base_type::operator--();
+  return *this;
+}
+
+// postfix ops
+template<class A, class T>
+inline unbounded_int<A,T> unbounded_int<A,T>::operator ++(int)
+{
+  unbounded_int<A,T> tmp(*this);
+  ++(*this);
+  return tmp;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T> unbounded_int<A,T>::operator --(int)
+{
+  unbounded_int<A,T> tmp(*this);
+  --(*this);
+  return tmp;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>& unbounded_int<A,T>::operator <<= (size_type n)
+{
+  if (*this != digit_type(0))
+    detail::shifter<unbounded_int>::shift_bits_left(*this, n);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>& unbounded_int<A,T>::operator >>= (size_type n)
+{
+  detail::shifter<unbounded_int>::shift_bits_right(*this, n);
+  if (!*this)
+    base_type::set_sign_bit(0);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>
+operator << (const unbounded_int<A,T>& x,
+             typename unbounded_int<A,T>::size_type n)
+{
+  unbounded_int<A,T> nrv(x);
+  nrv <<= n;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>
+operator >> (const unbounded_int<A,T>& x,
+             typename unbounded_int<A,T>::size_type n)
+{
+  unbounded_int<A,T> nrv(x);
+  nrv >>= n;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>&
+unbounded_int<A,T>::operator += (const unbounded_int<A,T>& rhs)
+{
+  detail::adder<unbounded_int, true>::add(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>&
+unbounded_int<A,T>::operator -= (const unbounded_int<A,T>& rhs)
+{
+  detail::adder<unbounded_int, true>::subtract(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>&
+unbounded_int<A,T>::operator *= (const unbounded_int<A,T>& rhs)
+{
+  detail::multiplier<unbounded_int>::multiply_or_square(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+unbounded_int<A,T>&
+unbounded_int<A,T>::operator /= (const unbounded_int<A,T>& rhs)
+{
+  const unbounded_int tmp(*this);
+  detail::divider<unbounded_int>::classic_divide(tmp, rhs, *this);
+  base_type::set_sign_bit(tmp.sign_bit() ^ rhs.sign_bit());
+  return *this;
+}
+
+template<class A, class T>
+unbounded_int<A,T>&
+unbounded_int<A,T>::operator %= (const unbounded_int<A,T>& rhs)
+{
+  const bool sign = base_type::sign_bit();
+  unbounded_int quotient;
+  detail::divider<unbounded_int>::classic_divide(*this, rhs, quotient, this);
+  if (*this)
+    base_type::set_sign_bit(sign);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>&
+unbounded_int<A,T>::operator |= (const unbounded_int<A,T>& rhs)
+{
+  detail::bitwise_ops<unbounded_int>::or_bits(*this, *this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>&
+unbounded_int<A,T>::operator &= (const unbounded_int<A,T>& rhs)
+{
+  detail::bitwise_ops<unbounded_int>::and_bits(*this, *this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T>&
+unbounded_int<A,T>::operator ^= (const unbounded_int<A,T>& rhs)
+{
+  detail::bitwise_ops<unbounded_int>::xor_bits(*this, *this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T> operator + (const unbounded_int<A,T>& lhs,
+                                      const unbounded_int<A,T>& rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv += rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T> operator - (const unbounded_int<A,T>& lhs,
+                                      const unbounded_int<A,T>& rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv -= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T> operator * (const unbounded_int<A,T>& lhs,
+                                      const unbounded_int<A,T>& rhs)
+{
+  unbounded_int<A,T> nrv;
+  detail::multiplier<unbounded_int<A,T> >::multiply_or_square(nrv, lhs, rhs);
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T> operator / (const unbounded_int<A,T>& lhs,
+                                      const unbounded_int<A,T>& rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv /= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T> operator % (const unbounded_int<A,T>& lhs,
+                                      const unbounded_int<A,T>& rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv %= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T> operator | (const unbounded_int<A,T>& lhs,
+                                      const unbounded_int<A,T>& rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv |= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T> operator & (const unbounded_int<A,T>& lhs,
+                                      const unbounded_int<A,T>& rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv &= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_int<A,T> operator ^ (const unbounded_int<A,T>& lhs,
+                                      const unbounded_int<A,T>& rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv ^= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+unbounded_int<A,T> operator ~ (const unbounded_int<A,T>& x)
+{
+  unbounded_int<A,T> nrv;
+  nrv.reserve(x.size());
+  detail::base::bitwise_ops<unbounded_int<A,T> >::compl_bits(nrv, x);
+  return nrv;
+}
+
+// Arithmetic and bitwise operators involving integral types
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T>&>::type
+unbounded_int<A,T>::operator += (IntegralT rhs)
+{
+  integral_ops<IntegralT>::add(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T>&>::type
+unbounded_int<A,T>::operator -= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::subtract(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T>&>::type
+unbounded_int<A,T>::operator *= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::multiply(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T>&>::type
+unbounded_int<A,T>::operator /= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::divide(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T>&>::type
+unbounded_int<A,T>::operator %= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::modulo(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T>&>::type
+unbounded_int<A,T>::operator |= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_or(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T>&>::type
+unbounded_int<A,T>::operator &= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_and(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T>&>::type
+unbounded_int<A,T>::operator ^= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_xor(*this, rhs);
+  return *this;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T> >::type
+operator + (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv += rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T> >::type
+operator - (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv -= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T> >::type
+operator * (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv *= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T> >::type
+operator / (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv /= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T> >::type
+operator % (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv %= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T> >::type
+operator | (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv |= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T> >::type
+operator & (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv &= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_int<A,T> >::type
+operator ^ (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_int<A,T> nrv(lhs);
+  nrv ^= rhs;
+  return nrv;
+}
+
+// compare unbounded_int to unbounded_int
+template<class A, class T>
+inline bool
+operator == (const unbounded_int<A,T>& lhs, const unbounded_int<A,T>& rhs)
+{
+  return (lhs.sign_bit() == rhs.sign_bit()) &&
+         (lhs.size()     == rhs.size()    ) &&
+         std::equal(lhs.begin(), lhs.end(), rhs.begin());
+}
+
+template<class A, class T>
+inline bool
+operator != (const unbounded_int<A,T>& lhs, const unbounded_int<A,T>& rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class A, class T>
+bool
+operator < (const unbounded_int<A,T>& lhs, const unbounded_int<A,T>& rhs)
+{
+  if (lhs.sign_bit() != rhs.sign_bit())
+  {
+    if (lhs.is_negative())
+      return true;
+    else
+      return false;
+  }
+
+  if (lhs.size() < rhs.size())
+    return true;
+  if (lhs.size() > rhs.size())
+    return false;
+
+  if (lhs.is_negative())
+    return std::lexicographical_compare(
+      rhs.rbegin(), rhs.rend(), lhs.rbegin(), lhs.rend());
+  else
+    return std::lexicographical_compare(
+      lhs.rbegin(), lhs.rend(), rhs.rbegin(), rhs.rend());
+}
+
+template<class A, class T>
+inline bool
+operator > (const unbounded_int<A,T>& lhs, const unbounded_int<A,T>& rhs)
+{
+  return rhs < lhs;
+}
+
+template<class A, class T>
+inline bool
+operator <= (const unbounded_int<A,T>& lhs, const unbounded_int<A,T>& rhs)
+{
+  return !(rhs < lhs);
+}
+
+template<class A, class T>
+inline bool
+operator >= (const unbounded_int<A,T>& lhs, const unbounded_int<A,T>& rhs)
+{
+  return !(lhs < rhs);
+}
+
+// compare unbounded_int to integral
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  return detail::unbounded_int_integral_ops<
+    unbounded_int<A,T>, IntegralT>::equal(lhs, rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  return detail::unbounded_int_integral_ops<
+    unbounded_int<A,T>, IntegralT>::less(lhs, rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  return rhs < lhs;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  return (lhs < rhs) || (lhs == rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (const unbounded_int<A,T>& lhs, IntegralT rhs)
+{
+  return !(lhs < rhs);
+}
+
+// compare integral to unbounded_int
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (IntegralT lhs, const unbounded_int<A,T>& rhs)
+{
+  return rhs == lhs;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (IntegralT lhs, const unbounded_int<A,T>& rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (IntegralT lhs, const unbounded_int<A,T>& rhs)
+{
+  return !(rhs <= lhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (IntegralT lhs, const unbounded_int<A,T>& rhs)
+{
+  return rhs < lhs;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (IntegralT lhs, const unbounded_int<A,T>& rhs)
+{
+  return !(rhs < lhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (IntegralT lhs, const unbounded_int<A,T>& rhs)
+{
+  return rhs <= lhs;
+}
+
+// compare unbounded_int to const charT*
+template<class A, class T, typename charT>
+inline bool
+operator == (const unbounded_int<A,T>& lhs, const charT* rhs)
+{
+  return lhs == unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator != (const unbounded_int<A,T>& lhs, const charT* rhs)
+{
+  return lhs != unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator < (const unbounded_int<A,T>& lhs, const charT* rhs)
+{
+  return lhs < unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator > (const unbounded_int<A,T>& lhs, const charT* rhs)
+{
+  return lhs > unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator <= (const unbounded_int<A,T>& lhs, const charT* rhs)
+{
+  return lhs <= unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator >= (const unbounded_int<A,T>& lhs, const charT* rhs)
+{
+  return lhs >= unbounded_int<A,T>(rhs);
+}
+
+// comparison const charT* to unbounded_int
+template<class A, class T, typename charT>
+inline bool
+operator == (const charT* lhs, const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) == rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator != (const charT* lhs, const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) != rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator < (const charT* lhs, const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) < rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator > (const charT* lhs, const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) > rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator <= (const charT* lhs, const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) <= rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator >= (const charT* lhs, const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) >= rhs;
+}
+
+// compare unbounded_int to basic_string
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator == (const unbounded_int<A,T>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs == unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator != (const unbounded_int<A,T>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs != unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator < (const unbounded_int<A,T>& lhs,
+            const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs < unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator > (const unbounded_int<A,T>& lhs,
+            const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs > unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const unbounded_int<A,T>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs <= unbounded_int<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const unbounded_int<A,T>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs >= unbounded_int<A,T>(rhs);
+}
+
+// compare basic_string to unbounded_int
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator == (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) == rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator != (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) != rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator < (const std::basic_string<charT,Traits,Alloc>& lhs,
+            const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) < rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator > (const std::basic_string<charT,Traits,Alloc>& lhs,
+            const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) > rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) <= rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const unbounded_int<A,T>& rhs)
+{
+  return unbounded_int<A,T>(lhs) >= rhs;
+}
+
+// Input/Output
+template<class A, class T, typename charT, class traits>
+std::basic_istream<charT, traits>&
+operator >> (std::basic_istream<charT, traits>& is, unbounded_int<A,T>& x)
+{
+  typename std::basic_istream<charT, traits>::sentry sentry(is);
+  if (!sentry)
+    return is;
+
+  // TODO we read into a string first which costs memory and std::string
+  // allocator is not under user control. We should convert incoming digits
+  // directly. Actually we should check what is the fastest way.
+  std::string s;
+
+  const std::istreambuf_iterator<charT, traits> end;
+  std::istreambuf_iterator<charT, traits> c(is);
+
+  if (*c == '+' || *c == '-')
+  {
+    s.push_back(*c);
+    ++c;
+  }
+
+  int base;
+  if (*c == '0')
+  {
+    base = 8;
+    s.push_back(*c);
+    ++c;
+    if (*c == 'x' || *c == 'X')
+    {
+      base = 16;
+      s.push_back(*c);
+      ++c;
+    }
+  }
+  else if (*c >= '0' && *c <= '9')
+    base = 10;
+  else
+  {
+    is.setstate(std::ios_base::failbit);
+    return is;
+  }
+
+  switch (base)
+  {
+    case 8:
+      while (c != end)
+      {
+        if (*c >= '0' && *c <= '7')
+          s.push_back(*c);
+        else
+          break;
+        ++c;
+      }
+      break;
+    case 10:
+      while (c != end)
+      {
+        if (*c >= '0' && *c <= '9')
+          s.push_back(*c);
+        else
+          break;
+        ++c;
+      }
+      break;
+    case 16:
+      while (c != end)
+      {
+        if ((*c >= '0' && *c <= '9') ||
+            (*c >= 'A' && *c <= 'F') ||
+            (*c >= 'a' && *c <= 'f'))
+          s.push_back(*c);
+        else
+          break;
+        ++c;
+      }
+      break;
+  }
+
+  const unbounded_int<A,T> tmp(s.begin(), s.end());
+  x = tmp;
+
+  return is;
+}
+
+template<class A, class T, typename charT, class traits>
+std::basic_ostream<charT, traits>&
+operator << (std::basic_ostream<charT, traits>& os, const unbounded_int<A,T>& x)
+{
+  // TODO same as above, we should output digits directly to the stream
+  return os << x.template to_string<std::string>(os.flags());
+}
+
+
+template<class A, class T>
+unbounded_int<A,T> abs(const unbounded_int<A,T>& x)
+{
+  unbounded_int<A,T> tmp(x);
+  tmp.set_sign_bit(0);
+  return tmp;
+}
+
+template<class A, class T>
+inline
+unbounded_int<A,T> gcd(const unbounded_int<A,T>& a,
+                       const unbounded_int<A,T>& b)
+{
+  unbounded_int<A,T> z;
+  detail::gcd_finder<unbounded_int<A,T> >::gcd(z, a, b);
+  return z;
+}
+
+#ifndef BOOST_NO_VARIADIC_TEMPLATES
+template<class A, class T, class... Integer>
+unbounded_int<A,T> gcd(const unbounded_int<A,T>& a,
+                       const unbounded_int<A,T>& b,
+                       const Integer&... args)
+{
+  return gcd(gcd(a, b), args...);
+}
+#endif
+
+template<class A, class T>
+inline
+unbounded_int<A,T> lcm(const unbounded_int<A,T>& a,
+                       const unbounded_int<A,T>& b)
+{
+  unbounded_int<A,T> z;
+  detail::lcm_finder<unbounded_int<A,T> >::lcm(z, a, b);
+  return z;
+}
+
+#ifndef BOOST_NO_VARIADIC_TEMPLATES
+template<class A, class T, class... Integer>
+unbounded_int<A,T> lcm(const unbounded_int<A,T>& a,
+                       const unbounded_int<A,T>& b,
+                       const Integer&... args)
+{
+  return lcm(lcm(a, b), args...);
+}
+#endif
+
+template<class A, class T>
+inline
+unbounded_int<A,T>
+pow(const unbounded_int<A,T>& x, typename unbounded_int<A,T>::size_type y)
+{
+  unbounded_int<A,T> z;
+  detail::power<unbounded_int<A,T> >::pow(z, x, y);
+  return z;
+}
+
+template<class A, class T>
+inline
+unbounded_int<A,T>
+pow(const unbounded_int<A,T>& x, const unbounded_int<A,T>& y)
+{
+  unbounded_int<A,T> z;
+  detail::power<unbounded_int<A,T> >::pow(z, x, y);
+  return z;
+}
+
+template<class A, class T>
+inline
+unbounded_int<A,T> sqrt(const unbounded_int<A,T>& x)
+{
+  unbounded_int<A,T> z;
+  detail::root<unbounded_int<A,T> >::sqrt(z, x);
+  return z;
+}
+
+template<class A, class T>
+inline
+unbounded_int<A,T> nth_root(typename unbounded_int<A,T>::size_type n,
+                            const unbounded_int<A,T>& x)
+{
+  unbounded_int<A,T> z;
+  detail::root<unbounded_int<A,T> >::nth_root(z, n, x);
+  return z;
+}
+
+template<class A, class T>
+inline
+unbounded_int<A,T> nth_root(const unbounded_int<A,T>& n,
+                            const unbounded_int<A,T>& x)
+{
+  unbounded_int<A,T> z;
+  detail::root<unbounded_int<A,T> >::nth_root(z, n, x);
+  return z;
+}
+
+template<class A, class T>
+inline
+unbounded_int<A,T> modinv(const unbounded_int<A,T>& x,
+                          const unbounded_int<A,T>& m)
+{
+  unbounded_int<A,T> nrv;
+  detail::modular_inverter<unbounded_int<A,T> >::modinv(nrv, x, m);
+  return nrv;
+}
+
+template<class A, class T>
+struct modpow_ctx<unbounded_int<A,T> >
+:
+  detail::modpow_ctx<unbounded_int<A,T> >
+{};
+
+// returns base^exp % mod
+template<class A, class T>
+inline
+unbounded_int<A,T> modpow(const unbounded_int<A,T>& base,
+                          const unbounded_int<A,T>& exp,
+                          const unbounded_int<A,T>& mod,
+                          modpow_ctx<unbounded_int<A,T> >* ctx = 0)
+{
+  unbounded_int<A,T> z;
+  detail::modular_power<unbounded_int<A,T> >::modpow(z, base, exp, mod, ctx);
+  return z;
+}
+
+template<class A, class T>
+inline
+int jacobi(const unbounded_int<A,T>& x, const unbounded_int<A,T>& y)
+{
+  return detail::jacobi(x, y);
+}
+
+
+
+} // namespace mp_math
+} // namespace boost
+
+#endif
Copied: sandbox/mp_math/boost/mp_math/integer/unbounded_traits.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int/traits.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int/traits.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/unbounded_traits.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,10 +1,10 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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_MP_MATH_MP_INT_TRAITS_HPP
-#define BOOST_MP_MATH_MP_INT_TRAITS_HPP
+#ifndef BOOST_MP_MATH_INTEGER_UNBOUNDED_TRAITS_HPP
+#define BOOST_MP_MATH_INTEGER_UNBOUNDED_TRAITS_HPP
 
 #include <cstddef> // size_t
 #include <limits>
@@ -15,6 +15,7 @@
 #include <boost/mpl/deref.hpp>
 #include <boost/mpl/lower_bound.hpp>
 #include <boost/mpl/vector.hpp>
+#include <boost/mp_math/integer/detail/base/primitive_ops.hpp>
 
 
 namespace boost {
@@ -61,34 +62,56 @@
 
 
 template<
-  typename Digit = detail::choose::digit_type,
-  typename Word = detail::choose::word_type/*,
-  bool debug = false*/
+  typename DigitT = detail::choose::digit_type,
+  typename WordT = detail::choose::word_type,
+  typename SizeT = std::size_t,
+  bool debug = false
 >
-struct mp_int_traits
+struct unbounded_traits
 {
   BOOST_STATIC_ASSERT(
-    std::numeric_limits<Digit>::digits <= std::numeric_limits<Word>::digits/2
+    std::numeric_limits<DigitT>::digits <= std::numeric_limits<WordT>::digits/2
   );
 
-  typedef Digit digit_type;
-  typedef Word  word_type;
+  typedef DigitT digit_type;
+  typedef WordT  word_type;
+  typedef SizeT  size_type;
+
+#ifdef BOOST_MP_MATH_PRIMITIVE_OPS_OLD
+  typedef detail::base::primitive_ops<
+    digit_type, word_type, size_type> ops_type;
+#else
+  typedef detail::base::primitive_ops<digit_type, size_type> ops_type;
+#endif
 
-  static std::size_t toom_mul_cutoff;
-  static std::size_t toom_sqr_cutoff;
-  static std::size_t karatsuba_mul_cutoff;
-  static std::size_t karatsuba_sqr_cutoff;
-};
+  static const bool enable_debug_mode = debug;
 
+  static const size_type radix_bits = std::numeric_limits<digit_type>::digits;
+  static const size_type digit_bits = std::numeric_limits<digit_type>::digits;
+  static const digit_type max_digit_value = static_cast<digit_type>(-1);
+
+  static size_type toom_mul_threshold;
+  static size_type toom_sqr_threshold;
+  static size_type karatsuba_mul_threshold;
+  static size_type karatsuba_sqr_threshold;
+};
 
-#define BMPINT_init(S) template<typename D, typename W>\
-  S mp_int_traits<D,W>::
-BMPINT_init(std::size_t)toom_mul_cutoff = 350;
-BMPINT_init(std::size_t)toom_sqr_cutoff = 400;
-BMPINT_init(std::size_t)karatsuba_mul_cutoff = 80;
-BMPINT_init(std::size_t)karatsuba_sqr_cutoff = 120;
 
-#undef BMPINT_init
+template<typename D, typename W, typename S, bool b>
+typename unbounded_traits<D,W,S,b>::size_type
+unbounded_traits<D,W,S,b>::toom_mul_threshold = 350;
+
+template<typename D, typename W, typename S, bool b>
+typename unbounded_traits<D,W,S,b>::size_type
+unbounded_traits<D,W,S,b>::toom_sqr_threshold = 400;
+
+template<typename D, typename W, typename S, bool b>
+typename unbounded_traits<D,W,S,b>::size_type
+unbounded_traits<D,W,S,b>::karatsuba_mul_threshold = 80;
+
+template<typename D, typename W, typename S, bool b>
+typename unbounded_traits<D,W,S,b>::size_type
+unbounded_traits<D,W,S,b>::karatsuba_sqr_threshold = 120;
 
 
 
Added: sandbox/mp_math/boost/mp_math/integer/unbounded_uint.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/unbounded_uint.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,1702 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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_MP_MATH_INTEGER_UNBOUNDED_UINT_HPP
+#define BOOST_MP_MATH_INTEGER_UNBOUNDED_UINT_HPP
+
+#include <boost/config.hpp>
+#include <boost/mp_math/integer/contexts.hpp>
+#include <boost/mp_math/integer/unbounded_traits.hpp>
+#include <boost/mp_math/integer/detail/adder.hpp>
+#include <boost/mp_math/integer/detail/bitwise_ops.hpp>
+#include <boost/mp_math/integer/detail/divider.hpp>
+#include <boost/mp_math/integer/detail/gcd.hpp>
+#include <boost/mp_math/integer/detail/jacobi.hpp>
+#include <boost/mp_math/integer/detail/lcm.hpp>
+#include <boost/mp_math/integer/detail/multiplier.hpp>
+#include <boost/mp_math/integer/detail/power.hpp>
+#include <boost/mp_math/integer/detail/root.hpp>
+#include <boost/mp_math/integer/detail/string_conversion.hpp>
+#include <boost/mp_math/integer/detail/unbounded_uint_integral.hpp>
+#include <boost/mp_math/integer/detail/base/unbounded_uint.hpp>
+
+namespace boost {
+namespace mp_math {
+
+template<
+  class Alloc = std::allocator<void>,
+  class Traits = unbounded_traits<>
+>
+struct unbounded_uint
+:
+  /*typename*/ Alloc::template rebind<typename Traits::digit_type>::other,
+  detail::base::unbounded_uint<Traits>
+{
+protected:
+
+  typedef detail::base::unbounded_uint<Traits> base_type;
+
+  typedef typename Alloc::template
+    rebind<typename Traits::digit_type>::other base_allocator_type;
+
+public:
+
+  template<typename IntegralT>
+  struct integral_ops
+  :
+    detail::unbounded_uint_integral_ops<unbounded_uint, IntegralT>
+  {};
+
+  typedef Alloc                              allocator_type;
+  typedef Traits                             traits_type;
+  typedef typename traits_type::digit_type   digit_type;
+  typedef typename allocator_type::size_type size_type;
+
+  typedef typename base_type::iterator               iterator;
+  typedef typename base_type::const_iterator         const_iterator;
+  typedef typename base_type::reverse_iterator       reverse_iterator;
+  typedef typename base_type::const_reverse_iterator const_reverse_iterator;
+
+  unbounded_uint();
+
+  explicit unbounded_uint(const allocator_type& a);
+
+  template<typename IntegralT>
+  unbounded_uint(IntegralT,
+         const allocator_type& a = allocator_type(),
+         typename enable_if<is_integral<IntegralT> >::type* dummy = 0);
+
+  template<typename charT>
+  unbounded_uint(const charT*, const allocator_type& a = allocator_type());
+
+  template<typename charT>
+  unbounded_uint(const charT*,
+                 std::ios_base::fmtflags,
+                 const allocator_type& a = allocator_type());
+
+  template<typename charT, class traits, class alloc>
+  unbounded_uint(const std::basic_string<charT,traits,alloc>&,
+                 const allocator_type& a = allocator_type());
+
+  template<typename charT, class traits, class alloc>
+  unbounded_uint(const std::basic_string<charT,traits,alloc>&,
+                 std::ios_base::fmtflags,
+                 const allocator_type& a = allocator_type());
+
+  template<typename RandomAccessIterator>
+  unbounded_uint(RandomAccessIterator first,
+                 RandomAccessIterator last,
+                 const allocator_type& a = allocator_type());
+
+  template<typename RandomAccessIterator>
+  unbounded_uint(RandomAccessIterator first,
+                 RandomAccessIterator last,
+                 std::ios_base::fmtflags f,
+                 const allocator_type& a = allocator_type());
+
+  unbounded_uint(const unbounded_uint& copy);
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  unbounded_uint(unbounded_uint&& copy);
+  #endif
+
+  ~unbounded_uint();
+
+  unbounded_uint& operator = (const unbounded_uint& rhs);
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  unbounded_uint& operator = (unbounded_uint&& rhs);
+  #endif
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint&>::type
+  operator = (IntegralT rhs);
+
+  template<typename charT>
+  unbounded_uint& operator = (const charT*);
+
+  template<typename charT, class traits, class alloc>
+  unbounded_uint& operator = (const std::basic_string<charT,traits,alloc>&);
+
+  template<typename charT>
+  void assign(const charT*, std::ios_base::fmtflags);
+
+  template<typename charT, class traits, class alloc>
+  void assign(const std::basic_string<charT,traits,alloc>&,
+              std::ios_base::fmtflags);
+
+  template<typename RandomAccessIterator>
+  void assign(RandomAccessIterator first, RandomAccessIterator last,
+              std::ios_base::fmtflags);
+
+  #ifndef BOOST_NO_RVALUE_REFERENCES
+  void swap(unbounded_uint&& other)
+  #else
+  void swap(unbounded_uint& other)
+  #endif
+  {
+    base_type::swap(other);
+  }
+
+  allocator_type get_allocator() const { return allocator_type(); }
+
+  void reserve(size_type n);
+
+  unbounded_uint& operator ++();
+  unbounded_uint& operator --();
+  unbounded_uint  operator ++(int);
+  unbounded_uint  operator --(int);
+  unbounded_uint& operator <<= (size_type);
+  unbounded_uint& operator >>= (size_type);
+
+  unbounded_uint& operator += (const unbounded_uint&);
+  unbounded_uint& operator -= (const unbounded_uint&);
+  unbounded_uint& operator *= (const unbounded_uint&);
+  unbounded_uint& operator /= (const unbounded_uint&);
+  unbounded_uint& operator %= (const unbounded_uint&);
+  unbounded_uint& operator |= (const unbounded_uint&);
+  unbounded_uint& operator &= (const unbounded_uint&);
+  unbounded_uint& operator ^= (const unbounded_uint&);
+
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint&>::type
+  operator += (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint&>::type
+  operator -= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint&>::type
+  operator *= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint&>::type
+  operator /= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint&>::type
+  operator %= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint&>::type
+  operator |= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint&>::type
+  operator &= (IntegralT);
+  template<typename IntegralT>
+  typename enable_if<is_integral<IntegralT>, unbounded_uint&>::type
+  operator ^= (IntegralT);
+
+  template<typename charT> unbounded_uint& operator += (const charT*);
+  template<typename charT> unbounded_uint& operator -= (const charT*);
+  template<typename charT> unbounded_uint& operator *= (const charT*);
+  template<typename charT> unbounded_uint& operator /= (const charT*);
+  template<typename charT> unbounded_uint& operator %= (const charT*);
+  template<typename charT> unbounded_uint& operator |= (const charT*);
+  template<typename charT> unbounded_uint& operator &= (const charT*);
+  template<typename charT> unbounded_uint& operator ^= (const charT*);
+
+  template<typename charT, class traits, class alloc>
+  unbounded_uint& operator += (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint& operator -= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint& operator *= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint& operator /= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint& operator %= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint& operator |= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint& operator &= (const std::basic_string<charT,traits,alloc>&);
+  template<typename charT, class traits, class alloc>
+  unbounded_uint& operator ^= (const std::basic_string<charT,traits,alloc>&);
+
+  template<class StringT>
+  StringT to_string(std::ios_base::fmtflags f = std::ios_base::dec) const
+  {
+    StringT tmp;
+    detail::to_string_converter<unbounded_uint> conv;
+    conv.convert(tmp, *this, f);
+    return tmp;
+  }
+
+protected:
+
+  template<typename Iter>
+  void init_from_string(Iter first, Iter last)
+  {
+    if (first < last)
+    {
+      detail::from_string_converter<unbounded_uint> conv;
+      conv.detect_properties(first, last);
+      if (!conv.is_positive)
+        throw std::invalid_argument("unbounded_uint::init_from_string: "
+            "cannot convert negative number to unsigned integer");
+      conv.convert(*this, first, last);
+    }
+  }
+
+  template<typename Iter>
+  void init_from_string(Iter first, Iter last, std::ios_base::fmtflags f)
+  {
+    if (first < last)
+    {
+      detail::from_string_converter<unbounded_uint> conv;
+      conv.detect_properties(first, last, f);
+      if (!conv.is_positive)
+        throw std::invalid_argument("unbounded_uint::init_from_string: "
+            "cannot convert negative number to unsigned integer");
+      conv.convert(*this, first, last);
+    }
+  }
+};
+
+
+template<class A, class T>
+unbounded_uint<A,T>::unbounded_uint()
+:
+  base_type(0, 0, 0)
+{
+}
+
+template<class A, class T>
+unbounded_uint<A,T>::unbounded_uint(const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+}
+
+template<class A, class T>
+template<typename IntegralT>
+unbounded_uint<A,T>::unbounded_uint(
+    IntegralT b,
+    const allocator_type& a,
+    typename enable_if<is_integral<IntegralT> >::type*)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  integral_ops<IntegralT>::assign(*this, b);
+}
+
+
+template<class A, class T>
+template<typename RandomAccessIterator>
+unbounded_uint<A,T>::unbounded_uint(RandomAccessIterator first,
+                                    RandomAccessIterator last,
+                                    const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(first, last);
+}
+
+template<class A, class T>
+template<typename charT>
+unbounded_uint<A,T>::unbounded_uint(const charT* s, const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(s, s + std::char_traits<charT>::length(s));
+}
+
+template<class A, class T>
+template<typename charT>
+unbounded_uint<A,T>::unbounded_uint(const charT* s,
+                                    std::ios_base::fmtflags f,
+                                    const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(s, s + std::char_traits<charT>::length(s), f);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+unbounded_uint<A,T>::unbounded_uint(
+    const std::basic_string<charT,traits,Alloc>& s,
+    const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(s.begin(), s.end());
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+unbounded_uint<A,T>::unbounded_uint(
+    const std::basic_string<charT,traits,Alloc>& s,
+    std::ios_base::fmtflags f,
+    const allocator_type& a)
+:
+  base_allocator_type(a),
+  base_type(0, 0, 0)
+{
+  init_from_string(s.begin(), s.end(), f);
+}
+
+
+template<class A, class T>
+unbounded_uint<A,T>::unbounded_uint(const unbounded_uint& copy)
+:
+  base_allocator_type(copy.get_allocator())
+{
+  base_type::digits_ = this->allocate(copy.size());
+  std::memcpy(base_type::digits_,
+              copy.digits(), copy.size() * sizeof(digit_type));
+  base_type::set_size(copy.size());
+  base_type::set_capacity(copy.size());
+}
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+template<class A, class T>
+unbounded_uint<A,T>::unbounded_uint(unbounded_uint&& copy)
+:
+  base_type(copy.digits(), copy.size(), copy.capacity())
+{
+  copy.digits_   = 0;
+  copy.size_     = 0;
+  copy.capacity_ = 0;
+}
+#endif
+
+
+template<class A, class T>
+unbounded_uint<A,T>::~unbounded_uint()
+{
+  base_type::assert_invariants();
+  if (base_type::digits())
+    this->deallocate(base_type::digits(), base_type::capacity());
+}
+
+template<class A, class T>
+unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator = (const unbounded_uint<A,T>& rhs)
+{
+  if (this != &rhs)
+  {
+    if ((base_type::capacity() == 0) || (base_type::capacity() < rhs.size()))
+      unbounded_uint(rhs).swap(*this);
+    else
+    {
+      std::memcpy(base_type::digits_,
+                  rhs.digits(), rhs.size() * sizeof(digit_type));
+      base_type::set_size(rhs.size());
+    }
+  }
+  return *this;
+}
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+template<class A, class T>
+unbounded_uint<A,T>& unbounded_uint<A,T>::operator = (unbounded_uint<A,T>&& rhs)
+{
+  if (this != &rhs)
+  {
+    if (base_type::digits())
+      this->deallocate(base_type::digits(), base_type::capacity());
+    base_type::digits_   = 0;
+    base_type::size_     = 0;
+    base_type::capacity_ = 0;
+    swap(rhs);
+  }
+  return *this;
+}
+#endif
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T>&>::type
+unbounded_uint<A,T>::operator = (IntegralT rhs)
+{
+  integral_ops<IntegralT>::assign(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename charT>
+unbounded_uint<A,T>& unbounded_uint<A,T>::operator = (const charT* s)
+{
+  base_type::set_size(0);
+  init_from_string(s, s + std::char_traits<charT>::length(s));
+  return *this;
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator = (const std::basic_string<charT,traits,Alloc>& s)
+{
+  base_type::set_size(0);
+  init_from_string(s.begin(), s.end());
+  return *this;
+}
+
+template<class A, class T>
+template<typename charT>
+inline void
+unbounded_uint<A,T>::assign(const charT* s, std::ios_base::fmtflags f)
+{
+  assign(s, s + std::char_traits<charT>::length(s), f);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline void
+unbounded_uint<A,T>::assign(const std::basic_string<charT,traits,Alloc>& s,
+                            std::ios_base::fmtflags f)
+{
+  assign(s.begin(), s.end(), f);
+}
+
+template<class A, class T>
+template<typename RandomAccessIterator>
+inline void
+unbounded_uint<A,T>::assign(RandomAccessIterator first,
+                            RandomAccessIterator last,
+                            std::ios_base::fmtflags f)
+{
+  base_type::set_size(0);
+  init_from_string(first, last, f);
+;
+}
+
+template<class A, class T>
+void unbounded_uint<A,T>::reserve(size_type n)
+{
+  if (base_type::capacity() < n)
+  {
+    const size_type new_cap = base_type::capacity() + base_type::capacity();
+    if (new_cap > n)
+      n = new_cap;
+    digit_type* d = this->allocate(n, base_type::digits_);
+    std::memcpy(d, base_type::digits(), sizeof(digit_type) * base_type::size());
+    this->deallocate(base_type::digits_, base_type::capacity());
+    base_type::digits_ = d;
+    base_type::set_capacity(n);
+  }
+}
+
+// prefix ops
+template<class A, class T>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator ++()
+{
+  reserve(base_type::size() + 1);
+  base_type::operator++();
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator --()
+{
+  base_type::operator--();
+  return *this;
+}
+
+// postfix ops
+template<class A, class T>
+inline unbounded_uint<A,T> unbounded_uint<A,T>::operator ++(int)
+{
+  unbounded_uint<A,T> tmp(*this);
+  ++(*this);
+  return tmp;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T> unbounded_uint<A,T>::operator --(int)
+{
+  unbounded_uint<A,T> tmp(*this);
+  --(*this);
+  return tmp;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator <<= (size_type n)
+{
+  if (*this != digit_type(0))
+    detail::shifter<unbounded_uint>::shift_bits_left(*this, n);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator >>= (size_type n)
+{
+  detail::shifter<unbounded_uint>::shift_bits_right(*this, n);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>
+operator << (const unbounded_uint<A,T>& x,
+             typename unbounded_uint<A,T>::size_type n)
+{
+  unbounded_uint<A,T> nrv(x);
+  nrv <<= n;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>
+operator >> (const unbounded_uint<A,T>& x,
+             typename unbounded_uint<A,T>::size_type n)
+{
+  unbounded_uint<A,T> nrv(x);
+  nrv >>= n;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator += (const unbounded_uint<A,T>& rhs)
+{
+  detail::adder<unbounded_uint, false>::add(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator -= (const unbounded_uint<A,T>& rhs)
+{
+  detail::adder<unbounded_uint, false>::subtract(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator *= (const unbounded_uint<A,T>& rhs)
+{
+  detail::multiplier<unbounded_uint>::multiply_or_square(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator /= (const unbounded_uint<A,T>& rhs)
+{
+  const unbounded_uint tmp(*this);
+  detail::divider<unbounded_uint>::classic_divide(tmp, rhs, *this);
+  return *this;
+}
+
+template<class A, class T>
+unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator %= (const unbounded_uint<A,T>& rhs)
+{
+  unbounded_uint quotient;
+  detail::divider<unbounded_uint>::classic_divide(*this, rhs, quotient, this);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator |= (const unbounded_uint<A,T>& rhs)
+{
+  detail::bitwise_ops<unbounded_uint>::or_bits(*this, *this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator &= (const unbounded_uint<A,T>& rhs)
+{
+  detail::bitwise_ops<unbounded_uint>::and_bits(*this, *this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator ^= (const unbounded_uint<A,T>& rhs)
+{
+  detail::bitwise_ops<unbounded_uint>::xor_bits(*this, *this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T> operator + (const unbounded_uint<A,T>& lhs,
+                                       const unbounded_uint<A,T>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv += rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T> operator - (const unbounded_uint<A,T>& lhs,
+                                       const unbounded_uint<A,T>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv -= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T> operator * (const unbounded_uint<A,T>& lhs,
+                                       const unbounded_uint<A,T>& rhs)
+{
+  unbounded_uint<A,T> nrv;
+  detail::multiplier<unbounded_uint<A,T> >::multiply_or_square(nrv, lhs, rhs);
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T> operator / (const unbounded_uint<A,T>& lhs,
+                                       const unbounded_uint<A,T>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv /= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T> operator % (const unbounded_uint<A,T>& lhs,
+                                       const unbounded_uint<A,T>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv %= rhs;
+  return nrv;
+}
+
+// TODO can do optimization here depending on which arg is larger, then
+// construct nrv from the larger to avoid a reallocation in op <<=. Same for
+// other args. The specific optimization that is possible depends on the
+// kind of operator we are looking at. That also means that we would need to
+// forward to these ops directly in integer.hpp. The same can be done for shift
+// operators << and >>.
+template<class A, class T>
+inline unbounded_uint<A,T> operator | (const unbounded_uint<A,T>& lhs,
+                                       const unbounded_uint<A,T>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv |= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T> operator & (const unbounded_uint<A,T>& lhs,
+                                       const unbounded_uint<A,T>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv &= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+inline unbounded_uint<A,T> operator ^ (const unbounded_uint<A,T>& lhs,
+                                       const unbounded_uint<A,T>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv ^= rhs;
+  return nrv;
+}
+
+template<class A, class T>
+unbounded_uint<A,T> operator ~ (const unbounded_uint<A,T>& x)
+{
+  unbounded_uint<A,T> nrv;
+  nrv.reserve(x.size());
+  detail::base::bitwise_ops<unbounded_uint<A,T> >::compl_bits(nrv, x);
+  return nrv;
+}
+
+// Arithmetic and bitwise operators involving integral types
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T>&>::type
+unbounded_uint<A,T>::operator += (IntegralT rhs)
+{
+  integral_ops<IntegralT>::add(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T>&>::type
+unbounded_uint<A,T>::operator -= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::subtract(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T>&>::type
+unbounded_uint<A,T>::operator *= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::multiply(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T>&>::type
+unbounded_uint<A,T>::operator /= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::divide(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T>&>::type
+unbounded_uint<A,T>::operator %= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::modulo(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T>&>::type
+unbounded_uint<A,T>::operator |= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_or(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T>&>::type
+unbounded_uint<A,T>::operator &= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_and(*this, rhs);
+  return *this;
+}
+
+template<class A, class T>
+template<typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T>&>::type
+unbounded_uint<A,T>::operator ^= (IntegralT rhs)
+{
+  integral_ops<IntegralT>::bitwise_xor(*this, rhs);
+  return *this;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T> >::type
+operator + (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv += rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T> >::type
+operator - (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv -= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T> >::type
+operator * (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv *= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T> >::type
+operator / (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv /= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T> >::type
+operator % (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv %= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T> >::type
+operator | (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv |= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T> >::type
+operator & (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv &= rhs;
+  return nrv;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, unbounded_uint<A,T> >::type
+operator ^ (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv ^= rhs;
+  return nrv;
+}
+
+// Arithmetic and bitwise operators involving character strings
+template<class A, class T>
+template<typename charT>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator += (const charT* s)
+{
+  return *this += unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator -= (const charT* s)
+{
+  return *this -= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator *= (const charT* s)
+{
+  return *this *= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator /= (const charT* s)
+{
+  return *this /= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator %= (const charT* s)
+{
+  return *this %= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator |= (const charT* s)
+{
+  return *this |= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator &= (const charT* s)
+{
+  return *this &= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT>
+inline unbounded_uint<A,T>& unbounded_uint<A,T>::operator ^= (const charT* s)
+{
+  return *this ^= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T, typename charT>
+inline
+unbounded_uint<A,T> operator + (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv += unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT>
+inline
+unbounded_uint<A,T> operator - (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv -= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT>
+inline
+unbounded_uint<A,T> operator * (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv *= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT>
+inline
+unbounded_uint<A,T> operator / (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv /= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT>
+inline
+unbounded_uint<A,T> operator % (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv %= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT>
+inline
+unbounded_uint<A,T> operator | (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv |= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT>
+inline
+unbounded_uint<A,T> operator & (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv &= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT>
+inline
+unbounded_uint<A,T> operator ^ (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv ^= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+
+// Arithmetic and bitwise operators involving basic_string
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator += (const std::basic_string<charT,traits,Alloc>& s)
+{
+  return *this += unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator -= (const std::basic_string<charT,traits,Alloc>& s)
+{
+  return *this -= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator *= (const std::basic_string<charT,traits,Alloc>& s)
+{
+  return *this *= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator /= (const std::basic_string<charT,traits,Alloc>& s)
+{
+  return *this /= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator %= (const std::basic_string<charT,traits,Alloc>& s)
+{
+  return *this %= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator |= (const std::basic_string<charT,traits,Alloc>& s)
+{
+  return *this |= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator &= (const std::basic_string<charT,traits,Alloc>& s)
+{
+  return *this &= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T>
+template<typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>&
+unbounded_uint<A,T>::operator ^= (const std::basic_string<charT,traits,Alloc>& s)
+{
+  return *this ^= unbounded_uint<A,T>(s);
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>
+operator + (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,traits,Alloc>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv += unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>
+operator - (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,traits,Alloc>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv -= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>
+operator * (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,traits,Alloc>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv *= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>
+operator / (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,traits,Alloc>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv /= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>
+operator % (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,traits,Alloc>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv %= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>
+operator | (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,traits,Alloc>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv |= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>
+operator & (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,traits,Alloc>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv &= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+template<class A, class T, typename charT, class traits, class Alloc>
+inline unbounded_uint<A,T>
+operator ^ (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,traits,Alloc>& rhs)
+{
+  unbounded_uint<A,T> nrv(lhs);
+  nrv ^= unbounded_uint<A,T>(rhs);
+  return nrv;
+}
+
+
+// compare unbounded_uint to unbounded_uint
+template<class A, class T>
+inline bool
+operator == (const unbounded_uint<A,T>& lhs, const unbounded_uint<A,T>& rhs)
+{
+  return (lhs.size() == rhs.size()) &&
+         std::equal(lhs.begin(), lhs.end(), rhs.begin());
+}
+
+template<class A, class T>
+inline bool
+operator != (const unbounded_uint<A,T>& lhs, const unbounded_uint<A,T>& rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class A, class T>
+bool
+operator < (const unbounded_uint<A,T>& lhs, const unbounded_uint<A,T>& rhs)
+{
+  if (lhs.size() < rhs.size())
+    return true;
+  if (lhs.size() > rhs.size())
+    return false;
+
+  // TODO ops_type::compare_magnitude vs lexicographical_compare
+  return std::lexicographical_compare(lhs.rbegin(), lhs.rend(),
+                                      rhs.rbegin(), rhs.rend());
+}
+
+template<class A, class T>
+inline bool
+operator > (const unbounded_uint<A,T>& lhs, const unbounded_uint<A,T>& rhs)
+{
+  return rhs < lhs;
+}
+
+template<class A, class T>
+inline bool
+operator <= (const unbounded_uint<A,T>& lhs, const unbounded_uint<A,T>& rhs)
+{
+  return !(rhs < lhs);
+}
+
+template<class A, class T>
+inline bool
+operator >= (const unbounded_uint<A,T>& lhs, const unbounded_uint<A,T>& rhs)
+{
+  return !(lhs < rhs);
+}
+
+// compare unbounded_uint to integral
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  return detail::unbounded_uint_integral_ops<
+    unbounded_uint<A,T>, IntegralT>::equal(lhs, rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  return detail::unbounded_uint_integral_ops<
+    unbounded_uint<A,T>, IntegralT>::less(lhs, rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  return rhs < lhs;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  return (lhs < rhs) || (lhs == rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (const unbounded_uint<A,T>& lhs, IntegralT rhs)
+{
+  return !(lhs < rhs);
+}
+
+// compare integral to unbounded_uint
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator == (IntegralT lhs, const unbounded_uint<A,T>& rhs)
+{
+  return rhs == lhs;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator != (IntegralT lhs, const unbounded_uint<A,T>& rhs)
+{
+  return !(lhs == rhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator < (IntegralT lhs, const unbounded_uint<A,T>& rhs)
+{
+  return !(rhs <= lhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator > (IntegralT lhs, const unbounded_uint<A,T>& rhs)
+{
+  return rhs < lhs;
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator <= (IntegralT lhs, const unbounded_uint<A,T>& rhs)
+{
+  return !(rhs < lhs);
+}
+
+template<class A, class T, typename IntegralT>
+inline
+typename enable_if<is_integral<IntegralT>, bool>::type
+operator >= (IntegralT lhs, const unbounded_uint<A,T>& rhs)
+{
+  return rhs <= lhs;
+}
+
+// compare unbounded_uint to const charT*
+template<class A, class T, typename charT>
+bool
+operator == (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  detail::from_string_converter<unbounded_uint<A,T> > conv;
+  conv.detect_properties(rhs, rhs + std::char_traits<charT>::length(rhs));
+
+  if (conv.total_length == 0)
+  {
+    if (lhs.is_uninitialized())
+      return true;
+    else
+      return false;
+  }
+
+  // if we see a minus sign and it is not "-0" then return false
+  if (!conv.is_positive && !(conv.length == 0 && conv.radix == 8))
+    return false;
+  // TODO that also means we skip scanning the string for invalid characters
+
+  unbounded_uint<A,T> tmp;
+  conv.convert(tmp, rhs, rhs + std::char_traits<charT>::length(rhs));
+
+  return lhs == tmp;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator != (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  return lhs != unbounded_uint<A,T>(rhs);
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator < (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  return lhs < unbounded_uint<A,T>(rhs);
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator > (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  return lhs > unbounded_uint<A,T>(rhs);
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator <= (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  return lhs <= unbounded_uint<A,T>(rhs);
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator >= (const unbounded_uint<A,T>& lhs, const charT* rhs)
+{
+  return lhs >= unbounded_uint<A,T>(rhs);
+}
+
+// comparison const charT* to unbounded_uint
+template<class A, class T, typename charT>
+inline bool
+operator == (const charT* lhs, const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) == rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator != (const charT* lhs, const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) != rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator < (const charT* lhs, const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) < rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator > (const charT* lhs, const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) > rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator <= (const charT* lhs, const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) <= rhs;
+}
+
+template<class A, class T, typename charT>
+inline bool
+operator >= (const charT* lhs, const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) >= rhs;
+}
+
+// compare unbounded_uint to basic_string
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator == (const unbounded_uint<A,T>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs == unbounded_uint<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator != (const unbounded_uint<A,T>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs != unbounded_uint<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator < (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs < unbounded_uint<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator > (const unbounded_uint<A,T>& lhs,
+            const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs > unbounded_uint<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const unbounded_uint<A,T>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs <= unbounded_uint<A,T>(rhs);
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const unbounded_uint<A,T>& lhs,
+             const std::basic_string<charT,Traits,Alloc>& rhs)
+{
+  return lhs >= unbounded_uint<A,T>(rhs);
+}
+
+// compare basic_string to unbounded_uint
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator == (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) == rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator != (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) != rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator < (const std::basic_string<charT,Traits,Alloc>& lhs,
+            const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) < rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator > (const std::basic_string<charT,Traits,Alloc>& lhs,
+            const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) > rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator <= (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) <= rhs;
+}
+
+template<class A, class T, class charT, class Traits, class Alloc>
+inline bool
+operator >= (const std::basic_string<charT,Traits,Alloc>& lhs,
+             const unbounded_uint<A,T>& rhs)
+{
+  return unbounded_uint<A,T>(lhs) >= rhs;
+}
+
+// Input/Output
+template<class A, class T, typename charT, class traits>
+std::basic_istream<charT, traits>&
+operator >> (std::basic_istream<charT, traits>& is, unbounded_uint<A,T>& x)
+{
+  typename std::basic_istream<charT, traits>::sentry sentry(is);
+  if (!sentry)
+    return is;
+
+  // TODO we read into a string first which costs memory and std::string
+  // allocator is not under user control. We should convert incoming digits
+  // directly. Actually we should check what is the fastest way.
+  std::string s;
+
+  const std::istreambuf_iterator<charT, traits> end;
+  std::istreambuf_iterator<charT, traits> c(is);
+
+  // TODO we should stop if we see a minus sign
+  if (*c == '+' || *c == '-')
+  {
+    s.push_back(*c);
+    ++c;
+  }
+
+  int base;
+  if (*c == '0')
+  {
+    base = 8;
+    s.push_back(*c);
+    ++c;
+    if (*c == 'x' || *c == 'X')
+    {
+      base = 16;
+      s.push_back(*c);
+      ++c;
+    }
+  }
+  else if (*c >= '0' && *c <= '9')
+    base = 10;
+  else
+  {
+    is.setstate(std::ios_base::failbit);
+    return is;
+  }
+
+  switch (base)
+  {
+    case 8:
+      while (c != end)
+      {
+        if (*c >= '0' && *c <= '7')
+          s.push_back(*c);
+        else
+          break;
+        ++c;
+      }
+      break;
+    case 10:
+      while (c != end)
+      {
+        if (*c >= '0' && *c <= '9')
+          s.push_back(*c);
+        else
+          break;
+        ++c;
+      }
+      break;
+    case 16:
+      while (c != end)
+      {
+        if ((*c >= '0' && *c <= '9') ||
+            (*c >= 'A' && *c <= 'F') ||
+            (*c >= 'a' && *c <= 'f'))
+          s.push_back(*c);
+        else
+          break;
+        ++c;
+      }
+      break;
+  }
+
+  const unbounded_uint<A,T> tmp(s.begin(), s.end());
+  x = tmp;
+
+  return is;
+}
+
+template<class A, class T, typename charT, class traits>
+std::basic_ostream<charT, traits>&
+operator << (std::basic_ostream<charT, traits>& os, const unbounded_uint<A,T>& x)
+{
+  // TODO same as above, we should output digits directly to the stream
+  return os << x.template to_string<std::string>(os.flags());
+}
+
+
+template<class A, class T>
+inline
+unbounded_uint<A,T> abs(const unbounded_uint<A,T>& x)
+{
+  return x;
+}
+
+template<class A, class T>
+inline
+unbounded_uint<A,T> gcd(const unbounded_uint<A,T>& a,
+                        const unbounded_uint<A,T>& b)
+{
+  unbounded_uint<A,T> z;
+  detail::gcd_finder<unbounded_uint<A,T> >::gcd(z, a, b);
+  return z;
+}
+
+#ifndef BOOST_NO_VARIADIC_TEMPLATES
+template<class A, class T, class... Integer>
+unbounded_uint<A,T> gcd(const unbounded_uint<A,T>& a,
+                        const unbounded_uint<A,T>& b,
+                        const Integer&... args)
+{
+  return gcd(gcd(a, b), args...);
+}
+#endif
+
+template<class A, class T>
+inline
+unbounded_uint<A,T> lcm(const unbounded_uint<A,T>& a,
+                        const unbounded_uint<A,T>& b)
+{
+  unbounded_uint<A,T> z;
+  detail::lcm_finder<unbounded_uint<A,T> >::lcm(z, a, b);
+  return z;
+}
+
+#ifndef BOOST_NO_VARIADIC_TEMPLATES
+template<class A, class T, class... Integer>
+unbounded_uint<A,T> lcm(const unbounded_uint<A,T>& a,
+                        const unbounded_uint<A,T>& b,
+                        const Integer&... args)
+{
+  return lcm(lcm(a, b), args...);
+}
+#endif
+
+template<class A, class T>
+inline
+unbounded_uint<A,T>
+pow(const unbounded_uint<A,T>& x, typename unbounded_uint<A,T>::size_type y)
+{
+  unbounded_uint<A,T> z;
+  detail::power<unbounded_uint<A,T> >::pow(z, x, y);
+  return z;
+}
+
+template<class A, class T>
+inline
+unbounded_uint<A,T>
+pow(const unbounded_uint<A,T>& x, const unbounded_uint<A,T>& y)
+{
+  unbounded_uint<A,T> z;
+  detail::power<unbounded_uint<A,T> >::pow(z, x, y);
+  return z;
+}
+
+template<class A, class T>
+inline
+unbounded_uint<A,T> sqrt(const unbounded_uint<A,T>& x)
+{
+  unbounded_uint<A,T> z;
+  detail::root<unbounded_uint<A,T> >::sqrt(z, x);
+  return z;
+}
+
+template<class A, class T>
+inline
+unbounded_uint<A,T> nth_root(typename unbounded_uint<A,T>::size_type n,
+                             const unbounded_uint<A,T>& x)
+{
+  unbounded_uint<A,T> z;
+  detail::root<unbounded_uint<A,T> >::nth_root(z, n, x);
+  return z;
+}
+
+template<class A, class T>
+inline
+unbounded_uint<A,T> nth_root(const unbounded_uint<A,T>& n,
+                             const unbounded_uint<A,T>& x)
+{
+  unbounded_uint<A,T> z;
+  detail::root<unbounded_uint<A,T> >::nth_root(z, n, x);
+  return z;
+}
+
+template<class A, class T>
+inline
+int jacobi(const unbounded_uint<A,T>& x, const unbounded_uint<A,T>& y)
+{
+  return detail::jacobi(x, y);
+}
+
+
+} // namespace mp_math
+} // namespace boost
+
+#endif
+
Copied: sandbox/mp_math/boost/mp_math/integer_serialization.hpp (from r54148, /sandbox/mp_math/boost/mp_math/mp_int_serialization.hpp)
==============================================================================
--- /sandbox/mp_math/boost/mp_math/mp_int_serialization.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer_serialization.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,18 +1,51 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
 
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
+#ifndef BOOST_MP_MATH_INTEGER_SERIALIZATION_HPP
+#define BOOST_MP_MATH_INTEGER_SERIALIZATION_HPP
+
+#include <boost/mp_math/integer/integer_fwd.hpp>
+#include <boost/serialization/base_object.hpp>
 #include <boost/serialization/split_free.hpp>
 #include <boost/serialization/string.hpp>
 
+
 namespace boost {
 namespace serialization {
 
+
+template<class Archive, class A, class T>
+void save(Archive& ar,
+          const boost::mp_math::unbounded_int<A,T>& x,
+          const unsigned int /*version*/)
+{
+  const std::string s = x.template to_string<std::string>(std::ios_base::hex);
+  ar & s;
+}
+
+template<class Archive, class A, class T>
+void load(Archive& ar,
+          boost::mp_math::unbounded_int<A,T>& x,
+          const unsigned int /*version*/)
+{
+  std::string s;
+  ar & s;
+  x.template assign(s, std::ios_base::hex);
+}
+
+template<class Archive, class A, class T>
+inline void serialize(Archive& ar,
+                      boost::mp_math::unbounded_int<A,T>& x,
+                      const unsigned int version)
+{
+  split_free(ar, x, version);
+}
+
 template<class Archive, class A, class T>
 void save(Archive& ar,
-          const boost::mp_math::mp_int<A,T>& x,
+          const boost::mp_math::unbounded_uint<A,T>& x,
           const unsigned int /*version*/)
 {
   const std::string s = x.template to_string<std::string>(std::ios_base::hex);
@@ -21,7 +54,7 @@
 
 template<class Archive, class A, class T>
 void load(Archive& ar,
-          boost::mp_math::mp_int<A,T>& x,
+          boost::mp_math::unbounded_uint<A,T>& x,
           const unsigned int /*version*/)
 {
   std::string s;
@@ -31,12 +64,31 @@
 
 template<class Archive, class A, class T>
 inline void serialize(Archive& ar,
-                      boost::mp_math::mp_int<A,T>& x,
+                      boost::mp_math::unbounded_uint<A,T>& x,
                       const unsigned int version)
 {
-  boost::serialization::split_free(ar, x, version);
+  split_free(ar, x, version);
 }
 
+template<class Archive, bool S, class A, class T>
+inline void serialize(Archive & ar,
+                      boost::mp_math::unbounded<S,A,T>& x,
+                      const unsigned int /*version*/)
+{
+  ar & base_object<typename boost::mp_math::unbounded<S,A,T>::base_type>(x);
+}
+
+template<class Archive, class Type>
+inline void serialize(Archive & ar,
+                      boost::mp_math::integer<Type>& x,
+                      const unsigned int /*version*/)
+{
+  ar & base_object<Type>(x);
+}
+
+
 } // namespace serialization
 } // namespace boost
 
+#endif
+
Added: sandbox/mp_math/boost/mp_math/libtom.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/libtom.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,12 @@
+// Copyright Kevin Sopp 2009.
+// 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_MP_MATH_LIBTOM_HPP
+#define BOOST_MP_MATH_LIBTOM_HPP
+
+#include <boost/mp_math/integer/libtom_integer.hpp>
+
+#endif
+
Deleted: sandbox/mp_math/boost/mp_math/mp_int.hpp
==============================================================================
--- sandbox/mp_math/boost/mp_math/mp_int.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,21 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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_MP_MATH_MP_INT_HPP
-#define BOOST_MP_MATH_MP_INT_HPP
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-#include <boost/mp_math/mp_int/mp_int.hpp>
-
-#include <boost/mp_math/mp_int/gcd.hpp>
-#include <boost/mp_math/mp_int/jacobi.hpp>
-#include <boost/mp_math/mp_int/lcm.hpp>
-#include <boost/mp_math/mp_int/modinv.hpp>
-#include <boost/mp_math/mp_int/modpow.hpp>
-#include <boost/mp_math/mp_int/numeric_limits.hpp>
-#include <boost/mp_math/mp_int/prime.hpp>
-#include <boost/mp_math/mp_int/root.hpp>
-
-#endif
Deleted: sandbox/mp_math/boost/mp_math/mp_int_serialization.hpp
==============================================================================
--- sandbox/mp_math/boost/mp_math/mp_int_serialization.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,42 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-#include <boost/serialization/split_free.hpp>
-#include <boost/serialization/string.hpp>
-
-namespace boost {
-namespace serialization {
-
-template<class Archive, class A, class T>
-void save(Archive& ar,
-          const boost::mp_math::mp_int<A,T>& x,
-          const unsigned int /*version*/)
-{
-  const std::string s = x.template to_string<std::string>(std::ios_base::hex);
-  ar & s;
-}
-
-template<class Archive, class A, class T>
-void load(Archive& ar,
-          boost::mp_math::mp_int<A,T>& x,
-          const unsigned int /*version*/)
-{
-  std::string s;
-  ar & s;
-  x.template assign(s, std::ios_base::hex);
-}
-
-template<class Archive, class A, class T>
-inline void serialize(Archive& ar,
-                      boost::mp_math::mp_int<A,T>& x,
-                      const unsigned int version)
-{
-  boost::serialization::split_free(ar, x, version);
-}
-
-} // namespace serialization
-} // namespace boost
-
Added: sandbox/mp_math/libs/mp_math/examples/answer.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/examples/answer.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,46 @@
+// Copyright Kevin Sopp 2009.
+// 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)
+
+#include <boost/mp_math/integer.hpp>
+
+typedef boost::mp_math::integer<> int_type;
+
+
+int main(int, char**)
+{
+  int_type x(2), y(0x257);
+
+  x = pow(x, 101);
+
+  x = modpow(x, y, int_type(257));
+
+  while (y > 2)
+  {
+    x *= y;
+    --y;
+  }
+
+  x = y + y + y * x % (int_type(12));
+
+  for (int i = 0; i < 15; ++i)
+  {
+    x -= x * y;
+    y += 15;
+    x += i;
+  };
+
+  x *= -1;
+
+  x = sqrt(x);
+
+  // now x should be 0x66d74da264f9
+  std::cout << std::hex << std::showbase << "The answer is " << x << "." << std::endl;
+
+
+  return 0;
+}
+
+
+
Added: sandbox/mp_math/libs/mp_math/examples/drops_in_the_ocean.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/examples/drops_in_the_ocean.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,63 @@
+// Copyright Kevin Sopp 2009.
+// 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)
+
+// calculate the number of water drops in earth's oceans
+
+#include <boost/timer.hpp>
+#include <boost/mp_math/integer.hpp>
+#include <boost/mp_math/integer/gmp_integer.hpp>
+
+typedef boost::mp_math::integer<> int_type;
+
+
+int main(int, char**)
+{
+  // assume that the oceans have a volume of 1.3 billion km^3
+  // assume that one drop has a volume of 0.05 ml
+  const unsigned long ocean_vol = 1300000000UL;
+  const unsigned long drops_per_ml = 20;
+
+  // there are 1000 ml in 1 liter and 1 liter = 1 dm^3
+
+  int_type num_drops = 1; // start with one drop
+
+  num_drops *= drops_per_ml; // now we have the number of drops per ml
+  num_drops *= 1000;         // now we have the number of drops per liter
+  num_drops *= 1000;         // 1  m^3 = 1000 dm^ 3
+  num_drops *= 1000000000UL; // 1 km^3 = 1000000000 m^3
+  num_drops *= ocean_vol;
+
+  std::cout << "Earth's oceans consist of " << num_drops << " water drops!"
+            << std::endl;
+
+
+  int_type counter = num_drops;
+
+  boost::timer t;
+  while (t.elapsed() < 2.0)
+    --counter;
+
+  //counter /= 2; // FIXME!! this makes a larger number out of counter
+  //c1 = 25999999999999999995604718
+  //c2 = 26000000005912711854358254
+
+  const int_type difference = (num_drops - counter) / 2;
+  int_type years = num_drops / difference;
+
+  years /= 60;
+  years /= 60;
+  years /= 24;
+  years /= 365;
+
+  std::cout << "This computer can count about " << difference << " water drops "
+            << "per second.\n"
+            << "Counting all water drops would take about " << years
+            << " years on this computer." << std::endl;
+
+  return 0;
+}
+
+
+
Added: sandbox/mp_math/libs/mp_math/examples/gmp.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/examples/gmp.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,24 @@
+// Copyright Kevin Sopp 2009.
+// 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)
+
+#include <boost/mp_math/integer.hpp>
+#include <boost/mp_math/gmp.hpp>
+
+typedef boost::mp_math::integer<boost::mp_math::gmp_integer<> > int_type;
+
+int main(int, char**)
+{
+  int_type x, y;
+
+  x = 0x1223;
+  y = "0x2984389248923984ababab";
+
+  const int_type z = pow(y, x);
+
+  std::cout << z << std::endl;
+
+  return 0;
+}
+
Added: sandbox/mp_math/libs/mp_math/examples/jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/examples/jamfile.v2	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,40 @@
+# Copyright Kevin Sopp 2009.
+# 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)
+
+project
+  :
+    requirements
+    <include>../../../..
+    <include>.
+    <link>static
+  ;
+
+
+exe drops_in_the_ocean
+  :
+    drops_in_the_ocean.cpp
+  :
+    <variant>release
+  ;
+
+exe answer
+  :
+    answer.cpp
+  :
+    <variant>release
+  ;
+
+
+lib gmp_library   : : <name>gmp ;
+
+exe gmp
+  :
+    gmp.cpp
+    gmp_library
+  :
+    <variant>release
+  ;
+
+
Modified: sandbox/mp_math/libs/mp_math/index.html
==============================================================================
--- sandbox/mp_math/libs/mp_math/index.html	(original)
+++ sandbox/mp_math/libs/mp_math/index.html	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -5,7 +5,7 @@
 <head>
   <title>Boost.Mp_math Documentation</title>
   <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
-  <meta http-equiv="refresh" content="0; URL=doc/index.html" />
+  <meta http-equiv="refresh" content="0; URL=doc/html/index.html" />
 </head>
 
 <body>
Deleted: sandbox/mp_math/libs/mp_math/test/add.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/add.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,217 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("123456");
-  mp_int_type y("987777");
-  mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "1111233");
-  x = 999U;
-  y = 123456U;
-  z = x + y;
-  BOOST_CHECK_EQUAL(z, "124455");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("21474836470");
-  const mp_int_type y("1234567845600");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "1256042682070");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0xffffffffffffffff");
-  const mp_int_type y("0xffffffffffffffff");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "0x1fffffffffffffffe");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0xffffffffffffffff");
-  const mp_int_type y("0xffffffff");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "0x100000000fffffffe");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_negative_numbers, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-123456");
-  const mp_int_type y("-987777");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "-1111233");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-123456");
-  const mp_int_type y("987777");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "864321");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("123456");
-  const mp_int_type y("-987777");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "-864321");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-123456");
-  const mp_int_type y("123456");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("123456");
-  const mp_int_type y("-123456");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1000");
-  const mp_int_type y("-12345678901000");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "-12345678900000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers6, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-12345678901000");
-  const mp_int_type y("1000");
-  const mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "-12345678900000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_small, mp_int_type, mp_int_types)
-{
-  mp_int_type x("123456789");
-  mp_int_type y("123");
-  mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "123456912");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_small_and_large, mp_int_type, mp_int_types)
-{
-  mp_int_type x("123");
-  mp_int_type y("123456789");
-  mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z, "123456912");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_large, mp_int_type, mp_int_types)
-{
-  mp_int_type x(
-    "76563204409879018101322737668344063995824904757312285775560614771886933079"
-    "77822556905976720912850551355328340715074887289899094852653102687850101285"
-    "85715275531977696497398396067715769512450915961775500023723324150851793075"
-    "51871751151095323159497918186624088118225730504044262785072662119470825604"
-    "40835072257208973943520251201155002832786969323087571220195329601804141972"
-    "71293425859967733061169954398382700046379970842289727254846347411792122453"
-    "98890529530611217475343335863666953662801553948341581412563112340543629531"
-    "01094529771464590172847457807673685591148055046712881378811934516545088775"
-    "38198087116656466935095055228728162461388333618793883566996616940381738437"
-    "03453867953392241443573580380271627517797446062394044787118140775664622031"
-    "49144609407766890328547643707523663509662747376486271392344480900673178645"
-    "33198519112197059826509662943577383543858946941049753393431035706592040680"
-    "43848484065292542884106550381079282660840705126574766636237650938379223350"
-    "073087806800887586256085275775217219429527000017403144");
-  
-  mp_int_type y(
-    "29156720459736055974643337783563754269574952607968485689453462316428566668"
-    "95504701770860331979649536167161534866285341319360225416010322271645564229"
-    "97610536562445338176729838019564690253931232562709745122032537539983616770"
-    "01864876491464203683664927984801289460556480278145114367860332493722569194"
-    "34026051618152579992400234314328079213866348120156368725488604236521299603"
-    "05243915357553896356662519397274629471920043679673543282319268893065423613"
-    "03777840501083119668898860689222271939900089123195611475211708096094521743"
-    "23436842195705603262202927396682954198215622617086455718070601797199587530"
-    "86110222151397352239086193648500251298495752840008363650931395221675337916"
-    "21665907282124706187656074325458499695895652068822763794228458103499408841"
-    "68233732651102406546734395563663969020820490032431359396293047454261598159"
-    "68165818673838448637209074584819780088546111644065538550490486693301185614"
-    "61602638472505490238203390055056474763248195271964604045005807592301719483"
-    "66411676459481184297663915491569500245585996483678005964410842919747216111"
-    "69086269285356198998091850661544255466466926579668887000118948737207396398"
-    "39189399212362197497646493143022100680619252808094160907526003969639965485"
-    "31238493375062268758735445211914107215235958346264702774326161208396163240"
-    "36339482493382189215697343908873498104516190541170342091008828518924813674"
-    "46253090923280613514725437269574928515018666111820866090440006060807129643"
-    "38626199608899966829344884873038261232122027815715568990196536130996880104"
-    "97887027262726591236620461428328000537452828616386217063092509908555188454"
-    "27278763741671312528892659532960085933913140197210561287118971031419725940"
-    "702202830556069344716729071140147820999566475298895832");
-  mp_int_type z = x + y;
-  BOOST_CHECK_EQUAL(z,
-    "29156720459736055974643337783563754269574952607968485689453462316428566668"
-    "95504701770860331979649536167161534866285341319360225416010322271645564229"
-    "97610536562445338176729838019564690253931232562709745122032537539983616770"
-    "01864876491464203683664927984801289460556480278145114367860332493722569194"
-    "34026051618152579992400234314328079213866348120156368725488604236521299603"
-    "05243915357553896356662519397274629471920043679673543282319268893065423613"
-    "03777840501083119668898860689222271939900089123195611475211708096094521743"
-    "23436842195705603262202927396682954198215622617086455718070601797199587530"
-    "86110222151397352239086193648500251298495752840008363650931395221675337916"
-    "98229111692003724288978811993802563691720556826135049569789072875386341921"
-    "46056289557079127459584946918992309735895377322330454248946150142111699445"
-    "53881094205816145134607470652535549600997027605841038574213810844152978690"
-    "13474389623600813397701308241680562881473925776008866830078469711772545088"
-    "07246748716690158241184166692724503078372965806765577184606172521551358084"
-    "40379695145323932059261805059926955512846897421958614254965296148999518852"
-    "38079928742973414972989829006689054343420806756435742320089116310183595016"
-    "32333023146526858931582903019587792806384013392977584153138095724941252015"
-    "74537569610038656150792399137601660565904524159964225658005445459306552111"
-    "49706958876672854958299017649846556032816112174214910877558146836471751674"
-    "87770809016666857157892528580561924741784775192201840382541017031670058750"
-    "31085546374923651063130124371905384081311775557435970456523545615147229134"
-    "71127247806963855412999209914039368594753845323785327923356621969798949290"
-    "775290637356956930972814346915365040429093475316298976");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(increment1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0");
-  for (int i = 0; i < 10; ++i)
-    ++x;
-  BOOST_CHECK_EQUAL(x, "10");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(increment2, mp_int_type, mp_int_types)
-{
-  mp_int_type x("-4");
-  for (int i = 0; i < 10; ++i)
-    ++x;
-  BOOST_CHECK_EQUAL(x, "6");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(increment3, mp_int_type, mp_int_types)
-{
-  mp_int_type x("-130");
-  for (int i = 0; i < 10; ++i)
-    ++x;
-  BOOST_CHECK_EQUAL(x, "-120");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(increment4, mp_int_type, mp_int_types)
-{
-  mp_int_type x("120");
-  for (int i = 0; i < 10; ++i)
-    ++x;
-  BOOST_CHECK_EQUAL(x, "130");
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/bitmanipulation.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/bitmanipulation.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,118 +0,0 @@
-// Copyright Kevin Sopp 2009.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0xff00000000ff");
-  x.set_bits(8, 40);
-  BOOST_CHECK_EQUAL(x, "0xffffffffffff");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits2, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0x8000");
-  x.set_bits(2, 7);
-  BOOST_CHECK_EQUAL(x, "0x807c");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits3, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0x80000000000000");
-  x.set_bits(12, 13);
-  BOOST_CHECK_EQUAL(x, "0x80000000001000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits4, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0x8000000000000000");
-  x.set_bits(0, 18);
-  BOOST_CHECK_EQUAL(x, "0x800000000003FFFF");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits5, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0x80000000");
-  x.set_bits(8, 16);
-  BOOST_CHECK_EQUAL(x, "0x8000FF00");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0xffffffffffff");
-  x.clear_bits(8, 40);
-  BOOST_CHECK_EQUAL(x, "0xff00000000ff");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits2, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0x807c");
-  x.clear_bits(2, 7);
-  BOOST_CHECK_EQUAL(x, "0x8000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits3, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0x80000000001000");
-  x.clear_bits(12, 13);
-  BOOST_CHECK_EQUAL(x, "0x80000000000000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits4, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0x800000000003FFFF");
-  x.clear_bits(0, 18);
-  BOOST_CHECK_EQUAL(x, "0x8000000000000000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits5, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0x8000FF00");
-  x.clear_bits(8, 16);
-  BOOST_CHECK_EQUAL(x, "0x80000000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
-  x.truncate(32);
-  x.clamp();
-  BOOST_CHECK_EQUAL(x, "0xFFFFFFFF");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate2, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
-  x.truncate(0);
-  x.clamp();
-  BOOST_CHECK_EQUAL(x, "");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate3, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
-  x.truncate(1);
-  x.clamp();
-  BOOST_CHECK_EQUAL(x, "1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate4, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
-  x.truncate(31);
-  x.clamp();
-  BOOST_CHECK_EQUAL(x, "0x7FFFFFFF");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate5, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFF");
-  x.truncate(80);
-  x.clamp();
-  BOOST_CHECK_EQUAL(x, "0xFFFFFFFFFFFFFFFFFFFF");
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/bitwise_ops.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/bitwise_ops.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,56 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(and_op1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x00ff0000000f");
-  const mp_int_type y("0xffffffffffff");
-  const mp_int_type z = x & y;
-  BOOST_CHECK_EQUAL(z, x);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(and_op2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x00ff0000000ffffffffff");
-  const mp_int_type y(         "0xffffffffffff");
-  const mp_int_type z = x & y;
-  BOOST_CHECK_EQUAL(z, "0xffffffffff");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(or_op1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x00ff0000000f");
-  const mp_int_type y("0xffffffffffff");
-  const mp_int_type z = x | y;
-  BOOST_CHECK_EQUAL(z, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(or_op2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x00ff0000000ffffffffff");
-  const mp_int_type y(         "0xaaffffffffff");
-  const mp_int_type z = x | y;
-  BOOST_CHECK_EQUAL(z, "0x00ff00000aaffffffffff");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x00ff0000000f");
-  const mp_int_type y("0xffffffffffff");
-  const mp_int_type z = x ^ y;
-  BOOST_CHECK_EQUAL(z, "0xff00fffffff0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x00ff0000000ffffffffff");
-  const mp_int_type y(         "0x33aaffffffff");
-  const mp_int_type z = x ^ y;
-  BOOST_CHECK_EQUAL(z,"0x00ff00000335500000000");
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/bool_conversion.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/bool_conversion.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,40 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(bool1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1");
-  const mp_int_type y("0");
-  BOOST_CHECK_EQUAL(x, true);
-  BOOST_CHECK_EQUAL(y, false);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(bool_or, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1");
-  const mp_int_type y("0");
-  const bool z = x || y;
-  BOOST_CHECK_EQUAL(z, true);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1");
-  const mp_int_type y("0");
-  const bool z = x && y;
-  BOOST_CHECK_EQUAL(z, false);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1");
-  const mp_int_type y("1");
-  const bool z = x && y;
-  BOOST_CHECK_EQUAL(z, true);
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/cmp.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/cmp.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,171 +0,0 @@
-// Copyright Kevin Sopp 2008 - 2009.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-1");
-  const mp_int_type y("-1");
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("12");
-  const mp_int_type y("13");
-  BOOST_CHECK_LT(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1");
-  const mp_int_type y("123456789");
-  BOOST_CHECK_LT(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-1");
-  const mp_int_type y("0");
-  BOOST_CHECK_LT(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-123");
-  const mp_int_type y("-10");
-  BOOST_CHECK_LT(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-123456789");
-  const mp_int_type y("123456798");
-  BOOST_CHECK_LT(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const mp_int_type y("0");
-  BOOST_CHECK_LE(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-1");
-  const mp_int_type y("0");
-  BOOST_CHECK_LE(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-123456789");
-  const mp_int_type y("-123456789");
-  BOOST_CHECK_LE(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("11");
-  const mp_int_type y("49941");
-  BOOST_CHECK_LE(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  BOOST_CHECK_EQUAL(x, 0);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("20");
-  BOOST_CHECK_EQUAL(x, 20U);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("300");
-  BOOST_CHECK_EQUAL(x, 300);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-1");
-  BOOST_CHECK_EQUAL(x, -1);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-32101");
-  BOOST_CHECK_EQUAL(x, -32101);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_integral_type1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("123456789");
-  BOOST_CHECK_LT(x, 123456790);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_integral_type2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x100000000");
-  BOOST_CHECK_LE(1, x);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_integral_type3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-0x100000000");
-  BOOST_CHECK_LT(x, -1);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_integral_type4, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<int>::min());
-  x -= 1;
-  BOOST_CHECK_LT(x, std::numeric_limits<int>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_unsigned_integral_type, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("123456789");
-  BOOST_CHECK_LT(x, 123456790U);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_le_integral_type1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  BOOST_CHECK_LE(x, 123456789);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_le_integral_type2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("32101");
-  BOOST_CHECK_LE(x, 32102);
-}
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_le_unsigned_integral_type, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  BOOST_CHECK_LE(x, 32101U);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_integral_type_lt_mp_int, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("32101");
-  BOOST_CHECK_LT(32100, x);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_integral_type_le_mp_int, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("32101");
-  BOOST_CHECK_LE(x, 32102);
-}
-
-
Deleted: sandbox/mp_math/libs/mp_math/test/compile_all.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/compile_all.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,96 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-// Compile all functions in the presence of the cmath header
-
-#include <cmath>
-#include <boost/mp_math/mp_int.hpp>
-
-
-// first explicitly instantiate the class template
-template class boost::mp_math::mp_int<>;
-
-
-
-// a different allocator type used in conjunction with the basic_string class
-// template
-template<typename T>
-struct my_alloc : std::allocator<T>
-{
-  template<typename U> struct rebind { typedef my_alloc<U> other; };
-};
-
-typedef std::basic_string<
-  char, std::char_traits<char>, my_alloc<char> > my_string;
-
-
-
-template<class MpInt>
-MpInt compile_constructors()
-{
-  const std::string  a("0x123456789abcdefABCDEF");
-  const std::wstring b(L"012345676543210");
-  const my_string    c("0xabcdefabcdef0001");
-
-  // constructors from string
-  MpInt u("0x123456789abcdef");
-  MpInt v(L"0x123456789abcdef");
-  MpInt w(a);
-  MpInt x(a.begin(), a.end());
-  MpInt y(b);
-  MpInt z(c);
-
-  const signed char sc = -100;
-  const unsigned char uc = 200;
-  const int i = -12000;
-  const unsigned int ui = 22000;
-
-  // constructors from integral type
-  MpInt m(sc);
-  MpInt n(uc);
-  MpInt o(i);
-  MpInt p(ui);
-
-  // copy constructor
-  MpInt copy(z);
-
-  return u + v + w + x + y + z + copy + m + n + o + p;
-}
-
-template<class MpInt>
-MpInt compile_assignment_ops()
-{
-  MpInt a = "0xfffffffffffffffffff";
-  MpInt b = "0xabcd";
-  MpInt c = 1000;
-  MpInt d = "07777777777777777777000001";
-
-  a = b;
-  b = d;
-
-  const my_string s("0xa123b566c78e9aafdf");
-  c = s;
-
-  d.assign("-12345678901234", std::ios_base::dec);
-
-  return a + b + c + d;
-}
-
-
-int main(int, char**)
-{
-  
-  typedef boost::mp_math::mp_int<> mp_int_type;
-  
-  mp_int_type a("0");
-
-  a += compile_constructors<mp_int_type>();
-  a += compile_assignment_ops<mp_int_type>();
-  a = boost::mp_math::pow(a, 3);
-  a = boost::mp_math::abs(a);
-
-  return 0;
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/ctors.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/ctors.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,188 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor, mp_int_type, mp_int_types)
-{
-  const mp_int_type a;
-  BOOST_CHECK_EQUAL(a.size(), 0U);
-  BOOST_CHECK_EQUAL(a.is_positive(), true);
-  BOOST_CHECK_EQUAL(a.is_negative(), false);
-  BOOST_CHECK_EQUAL(a, "");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string1, mp_int_type, mp_int_types)
-{
-  const mp_int_type y("12");
-  BOOST_CHECK_EQUAL(y, "12");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("123456789");
-  BOOST_CHECK_EQUAL(x, "123456789");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1000000000");
-  BOOST_CHECK_EQUAL(x, "1000000000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string4, mp_int_type, mp_int_types)
-{
-  const mp_int_type y("0");
-  BOOST_CHECK_EQUAL(!y, true);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_positive_decimal_string1, mp_int_type, mp_int_types)
-{
-  const mp_int_type z("+1");
-  BOOST_CHECK_EQUAL(z, "1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_negative_decimal_string1, mp_int_type, mp_int_types)
-{
-  const mp_int_type z("-1");
-  BOOST_CHECK_EQUAL(z, "-1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_negative_decimal_string2, mp_int_type, mp_int_types)
-{
-  const mp_int_type z("-888888");
-  BOOST_CHECK_EQUAL(z, "-888888");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string1, mp_int_type, mp_int_types)
-{
-  const mp_int_type y("012");
-  BOOST_CHECK_EQUAL(y, "10");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string2, mp_int_type, mp_int_types)
-{
-  const mp_int_type y("000000000000000000000000000000000");
-  BOOST_CHECK_EQUAL(!y, true);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0123456777");
-  BOOST_CHECK_EQUAL(x, "21913087");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string4, mp_int_type, mp_int_types)
-{
-  const mp_int_type z("-0777777");
-  BOOST_CHECK_EQUAL(z, "-262143");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string1, mp_int_type, mp_int_types)
-{
-  const mp_int_type y("0xF");
-  BOOST_CHECK_EQUAL(y, "15");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string2, mp_int_type, mp_int_types)
-{
-  const mp_int_type y("0xa0");
-  BOOST_CHECK_EQUAL(y, "160");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x123456789abcdef");
-  BOOST_CHECK_EQUAL(x, "0x123456789abcdef");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-0x8F888b");
-  BOOST_CHECK_EQUAL(x, "-0x8F888b");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0xA0000000");
-  BOOST_CHECK_EQUAL(x, "2684354560");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_long_string, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("87500402519005030061267904448809305029512439942506161234260852587645856336946409871074842737283625535525153833045575858681216");
-  BOOST_CHECK_EQUAL(x, "87500402519005030061267904448809305029512439942506161234260852587645856336946409871074842737283625535525153833045575858681216");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_iterators1, mp_int_type, mp_int_types)
-{
-  const std::string s("123456789");
-  const mp_int_type z(s.begin(), s.end());
-  BOOST_CHECK_EQUAL(z, "123456789");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x(9999999U);
-  BOOST_CHECK_EQUAL(x, "9999999");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x(123456U);
-  BOOST_CHECK_EQUAL(x, "123456");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_signed_char, mp_int_type, mp_int_types)
-{
-  signed char c = -14;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "-14");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_unsigned_char, mp_int_type, mp_int_types)
-{
-  unsigned char c = 42;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "42");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_short_int, mp_int_type, mp_int_types)
-{
-  short int c = -14789;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "-14789");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_int, mp_int_type, mp_int_types)
-{
-  int c = -9999;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "-9999");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_long_int, mp_int_type, mp_int_types)
-{
-  const long int c = -100000000;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "-100000000");
-}
-
-#ifndef BOOST_NO_CWCHAR
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wchar_t, mp_int_type, mp_int_types)
-{
-  const mp_int_type x(L"0xA0000000");
-  BOOST_CHECK_EQUAL(x, "2684354560");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wstring, mp_int_type, mp_int_types)
-{
-  const std::wstring s(L"0xA0000000");
-  const mp_int_type x(s);
-  BOOST_CHECK_EQUAL(x, "2684354560");
-}
-#endif
Deleted: sandbox/mp_math/libs/mp_math/test/div.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/div.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,112 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type y("123456");
-  const mp_int_type z = x / y;
-  BOOST_CHECK_EQUAL(z, "8");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type y("-123456");
-  const mp_int_type z = x / y;
-  BOOST_CHECK_EQUAL(z, "-8");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("263825472");
-  const mp_int_type y("123456");
-  const mp_int_type z = x / y;
-  BOOST_CHECK_EQUAL(z, "2137");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x89ab89745cc653de58eecc8f8a874120065ea545f6f5f");
-  const mp_int_type y("0x1889ba8a789456adfc8005b1");
-  const mp_int_type z = x / y;
-  BOOST_CHECK_EQUAL(z, "0x59c48aa7a1446110b31f70");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x1889ba8a789456adfc8005b1");
-  const mp_int_type y("0x1889ba8a789456adfc8005b2");
-  const mp_int_type z = x / y;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_2, mp_int_type, mp_int_types)
-{
-  mp_int_type x("263825472");
-  x.divide_by_2();
-  BOOST_CHECK_EQUAL(x, "131912736");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(shift_right1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("263825472");
-  x >>= 3;
-  BOOST_CHECK_EQUAL(x, "32978184");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type y("123456");
-  const mp_int_type z = x % y;
-  BOOST_CHECK_EQUAL(z, "129");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-987777");
-  const mp_int_type y("123456");
-  const mp_int_type z = x % y;
-  BOOST_CHECK_EQUAL(z, "-129");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type y("-123456");
-  const mp_int_type z = x % y;
-  BOOST_CHECK_EQUAL(z, "129");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-987777");
-  const mp_int_type y("-123456");
-  const mp_int_type z = x % y;
-  BOOST_CHECK_EQUAL(z, "-129");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-123456");
-  const mp_int_type y("123456");
-  const mp_int_type z = x % y;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod6, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const mp_int_type y("5");
-  const mp_int_type z = x % y;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-
-
Deleted: sandbox/mp_math/libs/mp_math/test/gcd.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/gcd.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,62 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(gcd1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("10");
-  const mp_int_type y("2");
-  const mp_int_type z = boost::mp_math::gcd(x,y);
-  BOOST_CHECK_EQUAL(z, "2");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(gcd2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("456489798");
-  const mp_int_type y("987");
-  const mp_int_type z = boost::mp_math::gcd(x,y);
-  BOOST_CHECK_EQUAL(z, "3");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(gcd3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-16384");
-  const mp_int_type y("16384");
-  const mp_int_type z = boost::mp_math::gcd(x,y);
-  BOOST_CHECK_EQUAL(z, "16384");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(gcd4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const mp_int_type y("0");
-  const mp_int_type z = boost::mp_math::gcd(x,y);
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-#ifdef BOOST_HAS_VARIADIC_TMPL
-BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_gcd1, mp_int_type, mp_int_types)
-{
-  const mp_int_type a("42");
-  const mp_int_type b("56");
-  const mp_int_type c("140");
-  const mp_int_type z = boost::mp_math::gcd(a,b,c);
-  BOOST_CHECK_EQUAL(z, "14");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_gcd2, mp_int_type, mp_int_types)
-{
-  const mp_int_type a("1200000000");
-  const mp_int_type b("2400000000");
-  const mp_int_type c("3600000000");
-  const mp_int_type d("600000000000000");
-  const mp_int_type z = boost::mp_math::gcd(a,b,c,d);
-  BOOST_CHECK_EQUAL(z, "1200000000");
-}
-#endif
-
Deleted: sandbox/mp_math/libs/mp_math/test/integral_ops.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/integral_ops.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,292 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(construct_from_zero, mp_int_type, mp_int_types)
-{
-  const mp_int_type x(0);
-  BOOST_CHECK_EQUAL(!x, true);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_signed_char_min, mp_int_type, mp_int_types)
-{
-  const signed char x = std::numeric_limits<signed char>::min();
-  const mp_int_type y(x);
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_signed_char_max, mp_int_type, mp_int_types)
-{
-  const signed char x = std::numeric_limits<signed char>::max();
-  const mp_int_type y(x);
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_char_min, mp_int_type, mp_int_types)
-{
-  const unsigned char x = std::numeric_limits<unsigned char>::min();
-  const mp_int_type y(x);
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_char_max, mp_int_type, mp_int_types)
-{
-  const unsigned char x = std::numeric_limits<unsigned char>::max();
-  const mp_int_type y(x);
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_int_min, mp_int_type, mp_int_types)
-{
-  const int x = std::numeric_limits<int>::min();
-  const mp_int_type y(x);
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_int_max, mp_int_type, mp_int_types)
-{
-  const int x = std::numeric_limits<int>::max();
-  const mp_int_type y(x);
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_int_min, mp_int_type, mp_int_types)
-{
-  const unsigned int x = std::numeric_limits<unsigned int>::min();
-  const mp_int_type y(x);
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_int_max, mp_int_type, mp_int_types)
-{
-  const unsigned int x = std::numeric_limits<unsigned int>::max();
-  const mp_int_type y(x);
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type z = x + 1;
-  BOOST_CHECK_EQUAL(z, "987778");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type z = x + (-1);
-  BOOST_CHECK_EQUAL(z, "987776");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-1");
-  const mp_int_type z = x + 5;
-  BOOST_CHECK_EQUAL(z, "4");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_unsigned_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("9999999");
-  const mp_int_type z = x + 1U;
-  BOOST_CHECK_EQUAL(z, "10000000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_char_min, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const mp_int_type z = x + std::numeric_limits<signed char>::min();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<signed char>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_char_max, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const mp_int_type z = x + std::numeric_limits<signed char>::max();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<signed char>::max());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_int_min, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const mp_int_type z = x + std::numeric_limits<int>::min();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_int_max, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const mp_int_type z = x + std::numeric_limits<int>::max();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::max());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type z = x - 12345;
-  BOOST_CHECK_EQUAL(z, "975432");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("98000");
-  const mp_int_type z = x - (-1);
-  BOOST_CHECK_EQUAL(z, "98001");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("125642682070");
-  const long y = 2147483647;
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "123495198423");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1");
-  const mp_int_type z = x - 2;
-  BOOST_CHECK_EQUAL(z, "-1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_unsigned_char1, mp_int_type, mp_int_types)
-{
-  const unsigned char y = 14;
-  const mp_int_type x("987777");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "987763");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type z = x * 12345;
-  BOOST_CHECK_EQUAL(z, "12194107065");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type z = x * -12345;
-  BOOST_CHECK_EQUAL(z, "-12194107065");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-987777");
-  const mp_int_type z = x * -12345;
-  BOOST_CHECK_EQUAL(z, "12194107065");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_unsigned_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1256");
-  const mp_int_type z = x * 100U;
-  mp_int_type w("125600");
-  BOOST_CHECK_EQUAL(z, "125600");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_zero1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-9877234234252377");
-  const mp_int_type z = x * 0;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_negative_zero1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-9877234234252377");
-  const mp_int_type z = x * -0;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_unsigned_char1, mp_int_type, mp_int_types)
-{
-  const unsigned char y = 16;
-  const mp_int_type x("10000001");
-  const mp_int_type z = x / y;
-  BOOST_CHECK_EQUAL(z, "625000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_unsigned_char2, mp_int_type, mp_int_types)
-{
-  const unsigned char y = 128;
-  const mp_int_type x("14222200");
-  const mp_int_type z = x / y;
-  BOOST_CHECK_EQUAL(z, "111110");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_signed_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("786432");
-  const mp_int_type z = x / 12;
-  BOOST_CHECK_EQUAL(z, "65536");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("786432");
-  const mp_int_type z = x % 12;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-987777");
-  const mp_int_type z = x % 123456;
-  BOOST_CHECK_EQUAL(z, "-129");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987777");
-  const mp_int_type z = x % -123456;
-  BOOST_CHECK_EQUAL(z, "129");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-987777");
-  const mp_int_type z = x % -123456;
-  BOOST_CHECK_EQUAL(z, "-129");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_unsigned_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987771");
-  const mp_int_type z = x % 16U;
-  BOOST_CHECK_EQUAL(z, "11");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_unsigned_integral2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-987771");
-  const mp_int_type z = x % 16U;
-  BOOST_CHECK_EQUAL(z, "-11");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_signed_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("786432");
-  const mp_int_type z = x | 1;
-  BOOST_CHECK_EQUAL(z, "786433");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_signed_integral2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("786432");
-  const mp_int_type z = x | -1;
-  BOOST_CHECK_EQUAL(z, "786433");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_unsigned_integral1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("786432");
-  const mp_int_type z = x | 1U;
-  BOOST_CHECK_EQUAL(z, "786433");
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/jacobi.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/jacobi.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,32 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1236");
-  const mp_int_type y("20003");
-  const int z = boost::mp_math::jacobi(x,y);
-  BOOST_CHECK_EQUAL(z, 1);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("987897");
-  const mp_int_type y("987");
-  const int z = boost::mp_math::jacobi(x,y);
-  BOOST_CHECK_EQUAL(z, 0);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("610");
-  const mp_int_type y("987");
-  const int z = boost::mp_math::jacobi(x,y);
-  BOOST_CHECK_EQUAL(z, -1);
-}
Added: sandbox/mp_math/libs/mp_math/test/jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/jamfile.v2	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,14 @@
+# Copyright Kevin Sopp 2008 - 2009.
+# 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)
+
+project
+  : requirements
+    <include>../../..
+    <link>static
+    <define>BOOST_TEST_DYN_LINK
+    <define>BOOST_TEST_MAIN
+    <define>BOOST_MP_MATH_MP_INT_USE_ASM
+  ;
+
Deleted: sandbox/mp_math/libs/mp_math/test/lcm.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/lcm.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,54 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(lcm1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const mp_int_type y("0");
-  const mp_int_type z = boost::mp_math::lcm(x,y);
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(lcm2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("51111");
-  const mp_int_type y("0");
-  const mp_int_type z = boost::mp_math::lcm(x,y);
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(lcm3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("4");
-  const mp_int_type y("6");
-  const mp_int_type z = boost::mp_math::lcm(x,y);
-  BOOST_CHECK_EQUAL(z, "12");
-}
-
-#ifdef BOOST_HAS_VARIADIC_TMPL
-BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_lcm1, mp_int_type, mp_int_types)
-{
-  const mp_int_type a("120");
-  const mp_int_type b("204");
-  const mp_int_type c("136");
-  const mp_int_type z = boost::mp_math::lcm(a,b,c);
-  BOOST_CHECK_EQUAL(z, "2040");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_lcm2, mp_int_type, mp_int_types)
-{
-  const mp_int_type a("12010");
-  const mp_int_type b("3299");
-  const mp_int_type c("84780");
-  const mp_int_type d("15");
-  const mp_int_type z = boost::mp_math::lcm(a,b,c,d);
-  BOOST_CHECK_EQUAL(z, "335906753220");
-}
-#endif
-
Deleted: sandbox/mp_math/libs/mp_math/test/modinv.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/modinv.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,25 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modinv1, mp_int_type, mp_int_types)
-{
-  mp_int_type a("35");
-  mp_int_type m("33");
-  mp_int_type i = boost::mp_math::modinv(a, m);
-  BOOST_CHECK_EQUAL(i, "17");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modinv2, mp_int_type, mp_int_types)
-{
-  mp_int_type a("17");
-  mp_int_type m("26");
-  mp_int_type i = boost::mp_math::modinv(a, m);
-  BOOST_CHECK_EQUAL(i, "23");
-}
-
-
Deleted: sandbox/mp_math/libs/mp_math/test/modpow.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/modpow.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,103 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("2");
-  const mp_int_type exp("14");
-  const mp_int_type m("8");
-  const mp_int_type z = modpow(x, exp, m);
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("4");
-  const mp_int_type exp("13");
-  const mp_int_type m("497");
-  const mp_int_type z = modpow(x, exp, m);
-  BOOST_CHECK_EQUAL(z, "445");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("2395422");
-  const mp_int_type exp("2424832");
-  const mp_int_type m("2424833");
-  const mp_int_type z = modpow(x, exp, m);
-  BOOST_CHECK_EQUAL(z, "1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("184");
-  const mp_int_type exp("560");
-  const mp_int_type m("561");
-  const mp_int_type z = modpow(x, exp, m);
-  BOOST_CHECK_EQUAL(z, "1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("997028168093060821869770104094480850560519901475");
-  const mp_int_type exp("7455602825647884208337395736200454918783366342656");
-  const mp_int_type m("7455602825647884208337395736200454918783366342657");
-  const mp_int_type z = modpow(x, exp, m);
-  BOOST_CHECK_EQUAL(z, "1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow6, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("184");
-  const mp_int_type exp("5600");
-  const mp_int_type m("2668");
-  const mp_int_type z = modpow(x, exp, m);
-  BOOST_CHECK_EQUAL(z, "552");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow7, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x201abcff00aaffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffd6d7");
-  const mp_int_type exp("0x123456789abcdef01");
-  // a modulus of type unrestricted diminished radix (2^253 - 41);
-  const mp_int_type m("0x1fffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffd7");
-  const mp_int_type z = modpow(x, exp, m);
-  BOOST_CHECK_EQUAL(z, "0x8f112a89871984cde410bb05621d5a6073557d2da0444b6681699"
-                       "80b5ef825a");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow8, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x201abcff00aaffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffd6d7123456789abcdef01123456789abcdef01ffffffff");
-  const mp_int_type exp("0x123456789abcdef018978979899");
-  // a modulus of type unrestricted diminished radix slow (2^503 - exp)
-  const mp_int_type m("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                      "fffffffffffffffffffffffffffffffffffffffffffffedcba987654"
-                      "3210fe7687686767");
-  const mp_int_type z = modpow(x, exp, m);
-  BOOST_CHECK_EQUAL(z, "0x1ada35751ae1f5fec7ab0e60f6c924d5f4a4a5d8f6786cdd78838"
-                       "5ab16ebd994ee9aaea5faef3f490822ef443fd3e169caa3b608162e"
-                       "01d40a593e775c9fa5");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow9, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x201abcff00aaffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffd6d7123456789abcdef01123456789abcdef01ffffffff");
-  const mp_int_type exp("0x123456789abcdef018978979899");
-  // a modulus of type restricted diminished radix (2^256 - 53)
-  const mp_int_type m("0xffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffcb");
-  const mp_int_type z = modpow(x, exp, m);
-  BOOST_CHECK_EQUAL(z, "0x777b5d9b290fbb5f99e4668cf1b0f723d3228fc252da492c54b75"
-                       "8379f3024e4");
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/mul.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/mul.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,366 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("12");
-  const mp_int_type y("22459455");
-  const mp_int_type z = x * y;
-  BOOST_CHECK_EQUAL(z, "269513460");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("280708");
-  const mp_int_type y("2245945");
-  const mp_int_type z = x * y;
-  BOOST_CHECK_EQUAL(z, "630454729060");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("65536");
-  const mp_int_type y("65536");
-  const mp_int_type z = x * y;
-  BOOST_CHECK_EQUAL(z, "4294967296");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1234567890123456789");
-  const mp_int_type y("9877771234567890123");
-  const mp_int_type z = x * y;
-  BOOST_CHECK_EQUAL(z, "12194779192182653090000267987090395047");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("789456120556882111687894651457623561325656871513");
-  const mp_int_type y("54564563128978513215");
-  const mp_int_type z = x * y;
-  BOOST_CHECK_EQUAL(z, "43076328327684465744675616648356768900793087398990591539995027544295");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul6, mp_int_type, mp_int_types)
-{
-  // this tests karatsuba multiplication for 8, 16 and 32 bit digit_type
-  const mp_int_type x(
-    "87500402519005030061267904448809305029512439942506161234260852587645856336"
-    "94640987107484273728362553552515383304557585868121651546490330517814007487"
-    "34682745159208158750835203309620570274592666481348052963762094268695162425"
-    "18850320172906096781969070339129822281355221058882087466637338881223511228"
-    "63144016884857141834687376804878770495858121023810198067988560350169566260"
-    "59441070673981642057711662497893572913873133654626566743289483229067287310"
-    "16863866837882738076436342057320810154710294295605465397209378421688020320"
-    "35702406032061642794728883255642074744145228324022219347019013411158803532"
-    "45994041206565648683544493690427219798945006072652042753387791345064784511"
-    "50227920502852884378111055250850357557404795594025600468996407045934090727"
-    "08041078777870387730504");
-  const mp_int_type y(
-    "87500402519005030061267904448809305029512439942506161234260852587645856336"
-    "94640987107484273728362553552515383304557585868121651546490330517814007487"
-    "34682745159208158750835203309620570274592666481348052963762094268695162425"
-    "18850320172906096781969070339129822281355221058882087466637338881223511228"
-    "63144016884857141834687376804878770495858121023810198067988560350169566260"
-    "59441070673981642057711662497893572913873133654626566743289483229067287310"
-    "16863866837882738076436342057320810154710294295605465397209378421688020320"
-    "35702406032061642794728883255642074744145228324022219347019013411158803532"
-    "45994041206565648683544493690427219798945006072652042753387791345064784511"
-    "50227920502852884378111055250850357557404795594025600468996407045934090727"
-    "08041078777870387730504938308922524767076619493071600607096868205642593777"
-    "83064672064693123083586511497969514956199763260628691421422356349215807298"
-    "53893432372651287096347803705731068491268031212879821570628466049198139563"
-    "07225373203247341492567070512742515269237115281940442618925655326204507165"
-    "43018685973456180521304052296263372550548657267007681462726186588489921154"
-    "03738735312309811855295260282588410141887442245474311543699839300870263148"
-    "89969642893224272388306131900850182843780525186002406202200057400419364041"
-    "12480917884571681605871307558328122948240801747503773233227317344565943160"
-    "78184811118761000119446172201197213166958413376441353073591860771242469526"
-    "34162171790217465073689788174652534961638870987430329380376975097234424950"
-    "28626203467171261194438985008578074151902043501430333019202385199270557942"
-    "82069487032265791643884311563532673152911052140807076806223793474752085674"
-    "51690168224265201474031350018449280412602665727006489664736651532321662145"
-    "22395731894311806382965185156526606660906262290677223798531105431808835740"
-    "80068277468617762211054331907328141344243411630209274782352265433366236954"
-    "62340796945506470082986574244652633468578747126384423018749343237426427830"
-    "62597495610006322516869046617226177792891514414040880511098169575819779926"
-    "53267511946096311413217967853431922008343789549408902117132966444741997352"
-    "58418657379544687590177580275674377304583931111620683151992749560156615440"
-    "09956001573216294273550652829235006290995819615078227235050765818475452342"
-    "95118077784320900839083926375344280915278665450149678774001364483022411118"
-    "86989210613864536835695555040115554865868694788922281253334356037168116291"
-    "99227045413249316876243936449829162763370534672670641521910718921661373160"
-    "93948899172794003245737017747952580428164207428777214495975431645589773283"
-    "12391742034637254884903040666536846003583703264118132242307521988982264762"
-    "13953490712153270721924306359669195669881431604926261623147833800912453474"
-    "06542388952383807976431616628717886593805647129190060659586374949333503420"
-    "5241703455510726935");
-  
-  const mp_int_type z = x * y;
-  
-  const mp_int_type w(
-    "76563204409879018101322737668344063995824904757312285775560614771886933079"
-    "77822556905976720912850551355328340715074887289899094852653102687850101285"
-    "85715275531977696497398396067715769512450915961775500023723324150851793075"
-    "51871751151095323159497918186624088118225730504044262785072662119470825604"
-    "40835072257208973943520251201155002832786969323087571220195329601804141972"
-    "71293425859967733061169954398382700046379970842289727254846347411792122453"
-    "98890529530611217475343335863666953662801553948341581412563112340543629531"
-    "01094529771464590172847457807673685591148055046712881378811934516545088775"
-    "38198087116656466935095055228728162461388333618793883566996616940381738437"
-    "03453867953392241443573580380271627517797446062394044787118140775664622031"
-    "49144609407766890328547643707523663509662747376486271392344480900673178645"
-    "33198519112197059826509662943577383543858946941049753393431035706592040680"
-    "43848484065292542884106550381079282660840705126574766636237650938379223350"
-    "07308780680088758625608527577521721942952700001740314426688555136034651920"
-    "92948869415921251533176579828351648585255631612516166131530519177426817087"
-    "53127165191235539369253485175856164884318259457319518574027800748530624722"
-    "30999853784133144744590149844870058500033133557974954747400058296439058233"
-    "59080109028703731380219724583279605028258137468666258706566102379192203551"
-    "90274426910716106736469216457355540125186992654301008720830993368763363204"
-    "11036960264301276622450044075944548104639523605502445335712149154791061273"
-    "09156720459736055974643337783563754269574952607968485689453462316428566668"
-    "95504701770860331979649536167161534866285341319360225416010322271645564229"
-    "97610536562445338176729838019564690253931232562709745122032537539983616770"
-    "01864876491464203683664927984801289460556480278145114367860332493722569194"
-    "34026051618152579992400234314328079213866348120156368725488604236521299603"
-    "05243915357553896356662519397274629471920043679673543282319268893065423613"
-    "03777840501083119668898860689222271939900089123195611475211708096094521743"
-    "23436842195705603262202927396682954198215622617086455718070601797199587530"
-    "86110222151397352239086193648500251298495752840008363650931395221675337916"
-    "21665907282124706187656074325458499695895652068822763794228458103499408841"
-    "68233732651102406546734395563663969020820490032431359396293047454261598159"
-    "68165818673838448637209074584819780088546111644065538550490486693301185614"
-    "61602638472505490238203390055056474763248195271964604045005807592301719483"
-    "66411676459481184297663915491569500245585996483678005964410842919747216111"
-    "69086269285356198998091850661544255466466926579668887000118948737207396398"
-    "39189399212362197497646493143022100680619252808094160907526003969639965485"
-    "31238493375062268758735445211914107215235958346264702774326161208396163240"
-    "36339482493382189215697343908873498104516190541170342091008828518924813674"
-    "46253090923280613514725437269574928515018666111820866090440006060807129643"
-    "38626199608899966829344884873038261232122027815715568990196536130996880104"
-    "97887027262726591236620461428328000537452828616386217063092509908555188454"
-    "27278763741671312528892659532960085933913140197210561287118971031419725940"
-    "70220283055606934471672907114014782099956647529889583250740029484462218658"
-    "62960901244568848989478467720707250809806379509214397878558772543587967635"
-    "96161034019645060913914198361071023036142203589230741296078930717247341831"
-    "26204308310630181474853421564903407641109879794777661716811159608177803322"
-    "61170286373919980640839261570604290919653466216587527613203517128403418424"
-    "791614399508711582164287714644181913925240");
-
-  BOOST_CHECK_EQUAL(z, w);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul7, mp_int_type, mp_int_types)
-{
-  // this tests toom cook multiplication for 8, 16 and 32 bit digit_type
-  const mp_int_type x(
-    "0x5004a2519b00503006126bb044af8930502951243994250616123426085258764a856336"
-    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
-    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
-    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
-    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
-    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
-    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
-    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
-    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "9464098710748f27372836255355251ae330455ffaa58681216515eeff0330517814dd7487"
-    "34682745159208158750835203309620570274592666481348052963762094268695162425"
-    "18850320172906096781969070339129822281355221058882087466637338881223511228"
-    "63144016884857141834687376804878770495858121023810198067988560350169566260"
-    "5944107067ac5771a1662497b8b93cfe57291387313365462656674328aaaaaf9067287310"
-    "ea6863ec68378827380764363420573208101547102942bf05465397209378421688020320"
-    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
-    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
-    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
-    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
-    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
-    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
-    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
-    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "18850320172906096781969070339129822281355221058882087466637338881223511228"
-    "63144016884857141834687376804878770495858121023810198067988560350169566260"
-    "59441070673981642057711662497893572913873133654626566743289483229067287310"
-    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
-    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
-    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
-    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
-    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
-    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
-    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
-    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "16863866837882738076436342057320810154710294295605465397209378421688020320"
-    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
-    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
-    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
-    "f84c878148cc7020890befffaa4506cebbef9a3f7c67178f2");
-  const mp_int_type y(
-    "0x875aa402519005030061267904ccc8809d0502243994250616123426085258764585633a"
-    "94640987107484273728362553552515383304557585868121651546490330517814007487"
-    "34682745159208158750835203309620570274592666481348052963762094268695162425"
-    "18850320172906096781969070339129822281355221058882087466637338881223511228"
-    "63144016884857141834687376804878770495858121023810198067988560350169566260"
-    "59441070673981642057711662497893572913873133654626566743289483229067287310"
-    "16863866837882738076436342057320810154710294295605465397209378421688020320"
-    "357024060320616427947288832ff6420747dd145228324022219347019013411158803532"
-    "45994041206565648683544493690427219798945006072652042753387791345064784511"
-    "50227920502852884378111055250850357557404795594025600468996407045934090727"
-    "08041078777870387730504938308922524767076619493071600607096868205642593777"
-    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
-    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
-    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
-    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
-    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
-    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
-    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
-    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "83064672064693123083586511497969514956199763260628691421422356349215807298"
-    "53893432372651287096347803705731068491268031212879821570628466049198139563"
-    "07225373203247341492562497b8b93568861230addd281940442618925655326204507165"
-    "43018685973456180521304052296263372550548657267007681462726186588489921154"
-    "03738735312309811855295260282588410141887442245474311543699839300870263148"
-    "cdd69642893224272388306131f0a850182843780525186002406202200057400419364041"
-    "12480917884571681605871307558328122948240801747503773233227317344565943160"
-    "78184811118761000119446172201197213166958413376441353073591860771242469526"
-    "34162171790217465073689788174652534961638870987430329380376975097234424950"
-    "286262034671712611944389850085780a4151902043501430333019202385199270557942"
-    "82069487032265791643884311563532673152911052140807076806223793474752085674"
-    "51690168224265201474031350018449280412602665727006489664736651532321662145"
-    "22395731894311806382965185156526606660906262290677223798531105431808835740"
-    "80068277468617762211054331907328141344243411630209274782352265433366236954"
-    "62340796945506470082986574244652633468578747126384423018749343237426427830"
-    "62597495610006322516869046617226177792891514414040880511098169575819779926"
-    "53267511946096311413217967853431922008343789549408902117132966444741997352"
-    "5841865737954468759a177580275674377304583931111620683151992749560156615440"
-    "09956001573216294273550652829235006290995819615078227235050765818475452342"
-    "95118077784320900839083926375344280915278665450149678774001364483022411118"
-    "86989210613864536835695555040115554865868694788922281253334356037168116291"
-    "99227045413249316876243936449829162763370534672670641521910718921661373160"
-    "93948899172794003245737017747952580428164207428777214495975431645589773283"
-    "12391742034637254884903040666536846003583703264118132242307521988982264762"
-    "13953490712153270721924306359669195669881431604926261623147833800912453474"
-    "06542388952383807976431616628717886593805647129190060659586374949333503420"
-    "ffab023789d7d78f78a45a45fee789001a1a");
-  
-  const mp_int_type z = x * y;
-
-  const mp_int_type w(
-    "0x2a4ec67dcaf1afdd14bf63d7cd883f269ca00be2cae5c539545352050e33af7bb008713c"
-    "63587bc02911b0cb1fb807d94cd4a937f6e19801a28500f45ba1dc90a548e8e15e0c31536b"
-    "39f3940191a76b6fd96fda83c7aa9aa675f536633917587fbdb4990f73dc4650e19af67392"
-    "712b0a94aeec78f21523bd2ae92cee0b5d42ce2ead649060ff8134dbca0790f051b132b8fd"
-    "2f0bbe66f3226f7fe7a80c0be18fcd0238ff0100e4353f4973c1cb72c40e83804192fbd008"
-    "1e3d4dfe03e1d4c8d1ed4ba8ffe7cf5d00237598de949ab89cd6f95cbc3545a4d797e425f9"
-    "041fbe52955af28221505ce3e53cb5bc12d8d9a13f39704463db4db21aaea4fc29643a2746"
-    "2e6d3b40f9eb621106bda6223bf2aaa4f027e037acb45406cd39b242c90df3b4fae1bf788a"
-    "1529dac1ce1b77f4d1557e2aa8a4adf9c6b3b0c364ce68300b5f65efc8166dae1b2e0f8443"
-    "76975b12b72c36f2dfc4a533adca3db43955265d91d15232bcfd712e46dd4cd4f63981317b"
-    "31be8e9fc0a56275da498e8a4c13419eb8560fa05d73373ff238787b77c0b45c0b44b6b042"
-    "365bfb3b3a4d96cdb3ad7cb9b9248498a02b43a16206db5cc3f52c4cdf2c58807a68a6d1b0"
-    "f24bf8daa4eaf6ffdd3e781fd52b5fe609678d045944d7ea6a6689954b82a737b136a86d32"
-    "e8de0c6b88e66300487b83deb53038fc298c2b1d1ffe64ab7ebf0e7682b285bb567c3ad4bc"
-    "69c0e0216f5c8df2681a3e84435b39dbd4a3cd5dcdf0b776bc0b5281f8806155318e70d237"
-    "4267ca699ebdc5df58e282f7a6d2a7401a3544193741e9597df7fb92c7a0c87128b53ae873"
-    "14aacf233fc20cba4ac4835579bd82b6efcadd591dbf826d470795d64bb698202e3fc5bbd3"
-    "9ca2249167520764d448a95c7a7ed00f43d2f36f4158fccacf2f5738878099da8a323e7d2c"
-    "57579da5e348b45aabe59366085532c73c2388b3a2672b08758bdaae3746364b49d0217b27"
-    "5d22b2b4916628afd5009e103803f4ba5241413200d85e119ceb4dc876c1521047a8be7650"
-    "767b0d83fcbf991c6b04a51213692867fe4c9e452b2800fe5fc57df9d8f75cab72609a49af"
-    "92b1e2407b64ea424344a626b2e86eacdf18af6a000af8c5607019df1d670307a65df3e4bf"
-    "51e9809212a3288001e1df69a6070558e24f686ff34b50e7b2daf5f3f7abc7be88fff8fb5d"
-    "f0aab1f952f91eec5c5ff7e25d2babb61db263e7381fbe40ad81b3494c323a35d3333fcadd"
-    "d6b057c88fe2f43ec1bf754de9fdbc768457d7fc44c90c2e44f79c32849f56d7d2152b96d1"
-    "4b7735e8eae29d8e9ccdd61be1f73f7d1d2e16732505448a33145a5b1d5c342f0990a0a731"
-    "a5e034cb3c0f5658e20b8ac7f4e93c249ec9badb93c4e064b59c34b11e4327d0dacb0951ac"
-    "1c13831520a06deee884613bce16fe5b92e1e0776caf6aa1a7aadccad11a741e7c08512816"
-    "e1c4a0f8910c35450a7448c180528decdc54a9af2cf5b5244c03d088be6d8b6978f2e90baa"
-    "3ce9f85456b51768f7b2d2261785f7680e62cdc420d0e62e41aba012a391c250d3579665ec"
-    "06a0e137c8d3da6ec07be1c2f0599dcbd1f6a801a06a062734ec34889edcd57ca99bc35d5b"
-    "9686b7fc073aa06d9d052ae7d762a7dbc5740e73ef730b478acdb54455d4db80e80b03bc61"
-    "aa013ab9c0b9ece6a00e4e46c16068a2771d0c9c42432f4ef1279481886c6cf890d656a8fa"
-    "e248c9c17bedb151ea802c3b8d7918296dc38a71f173c0b6fceb72611bc817429271ff1d1f"
-    "9fc29780727dbab824eb6ff07e552c8a6679c667bbb20925b7920c7307e3f553c64e1f8962"
-    "e556168cef58af8f406f9f6847719addd6083d19e351b2281bb6f8f64789cdab8f29915f71"
-    "128cd2152ba95124b935770dda3231973037cb7c1e8d22ee4bd10331c91d4db53c291cb16c"
-    "f498366646a27bc18df39aeb5790ba6e02c9904b0fe7e6127dd412daaafdc9b1548727eb05"
-    "57e191893e391f038797139cdf054dab4a208b00dbea79313c3952bcaf8384882456dace78"
-    "117550a133acd3cc883c036e2ecb133eaca4f6df4c002589436f529f3975fde6c779ab3038"
-    "85b1decf3f9b625dd31d634e98410486ba3e3dfff5e90da22c1734fbf9b52b92db6b44af70"
-    "da57859ca38220d8a24dca3251f9f65a1abfcbd2386732f3919c88af189efeb31ee6da9deb"
-    "f70e85bbaa928abb1d2ba86d3b038c1eea98c1a36d0e783a79e578cbc3b98d9a9f4a9c0392"
-    "bf51fcb31325c1b9131f762cd31583c231d786190dc92752781192a72ff75c3c8c297706a0"
-    "4d14571575e076dc13c8bf2c3202bb468ef6f20f6ae27ba91a0182af2c73a40477a9e1d23d"
-    "60fc5f57e9f3a86315b11ea7dc922ba70d38a24c18e1552e15239b2a29d6fc7517f5aabdd5"
-    "e0c800178beeac9b582c44af59f7c2cee341813eb13220d4bee3ef07e9ab8d35ccc0f684e9"
-    "902affb65f87cee827e6bd42fbc433df0070dc210d078fdc92fb7f559b577150e28f21f64a"
-    "c0edc61da523858e62cca0c85b8c16b8bd784f7ed8efb96314e75b3b9bd26ea93bdfc45565"
-    "85ea59cda0c92be16321ed27d93b9a05980574fc99dcb079e6145a0b0ab0c4cbebdc0e51af"
-    "2825278224922511ab721f412589b8a160fa95c3bc9038a3af4a330f5e796d30bf60017921"
-    "bc01a0200e87c26a0afedc292ff05a3e9d564323d0e0c738bcbf24f226d9aa59944abc109a"
-    "9916f57dad39fd1c928da18c32184a230be2eef814c47cea0baea02241c34fae2c8d025a02"
-    "0ab4faf8409cbc467333b807af12473f5dc3be988bb9ef61a60ff1672e07de7f5f6bf99583"
-    "f876305337ca3bbc6b2cc1f562d9f4b90cd9e54d85e04b8aa47dcb4dd5efb271f2a1d61922"
-    "cefdabcad5c3565f3f65a3e421e688b53c15a568c368eeed28d546e47dd53afc3944bfce69"
-    "94841555ac1a1968412a5504d68ae69b2067aaf3c8516a993ffb0657f82cfcb4950e6da431"
-    "de09b4a1d104e3190af9518bd2d10921ee2a3cbba8c25e1ef98606121d60cb48dbe91994f6"
-    "afceb6ea5187fdbd6d943b24c6a2584516d014ca5549828b1c5dcb80016f5dbe91667d03c0"
-    "ed9db277261ff9a7fe77886bb1c9c7d3e95e8a4204b984115323b3a8895ae102921e807294"
-    "131b5554246e6004541e11d1e449f017f1590b18c695ab79b098683f4693e0c6d87836feae"
-    "3db0bceca8b11f9b2190b8f61d77fdad0687ce678c31059af3771bc54170fad3171efa5eaa"
-    "39a4dc3d3fa837e868d1cd704de7c1877e4b77cd9fa44d500b74d0a52cf1b9c5ca6f031005"
-    "c6362066e930694a5d8063a2f27c899a78dd4f79f89e47c46e24c454efcb034105824c009f"
-    "9ce5f9b0eb6998ee1a61a2b83ed878ac81e50ffa48f6c5eaf225a56c9cbca51312808c0c51"
-    "7f49f131c12ecb7094f389228b77db2a305a01f69975138aa67dce71b80285fa1f21993189"
-    "b38898d0e2c5e6fddb644101107f610ac20ab744140addc41021fbf68b041b80fa3c1a3851"
-    "65038651ac3a07ef76368658c5a984d28e149981a7ab931e6fa1d87aa8756331927c54443a"
-    "54177cb8617bd8f54aba47a06af8f41f28cc47d71bd153d821c0c45adbad135170cfe68429"
-    "683a0bc06e4e7a06bd060a87fb8309e4f14c31a3732eada80079072e55fc26cb02ac710791"
-    "0a95d32111198ac6c07625c117acf23fefbbff59fb4c84bc6ac1a3fde905cf1d75693caaf7"
-    "7d2728e7c66d6005a236176e85cb3b282fb7a577e5e4c617c23b2af879810b560882c93552"
-    "27ee9670073d5288c4af9e57a0c81c7af0142670dbb0a18a2f79fe3ae3791739e732784600"
-    "fe9a9a4475ad985499e81ce7a06a04368fbdd007ddb2a222a0268c086252e73f18ef9b165a"
-    "c044c5f42af698b80eba1c1b4423c3b8d010d31ea85831fae7bbb74efe9a22283c1e238d09"
-    "6ae5d00ded7ae17744925d316b3d1c92861c58e1e6668dd52f4932c1e891ed5441f29786fd"
-    "d41a78b75730b8cc193ed85ac5a667a86ba4bbc1ad45aeddc56d32e16f410ad06f5cd2e6b8"
-    "2a31feb6585cfe987b8db1dc8dfdd3a4a8b09518f341fac8f8c7aeb8052cec62bf23eab8a1"
-    "b35cab3e3ed3acc3b64e29c1cc4d7cdeaefcd61f06c61b8a48b90a838ee0aac2cc76a2e56f"
-    "d8dda42e2ff863f75132ff39dd4241ac3ac1aa21845a66bdd02b77b4c38dd5ada02e3863e0"
-    "12b5bf5ad2eae7f6b1b85b4fdf960b915c257dc2be810ce92bb82c58bc478994a71332502c"
-    "ea5e5cf5bfc2ba0480d53dd2dec046f718001eba5088463e6598488dbca8cf07024102458c"
-    "abac35a14188323195f0bcc8a4d7b006467ad4ee46e6cc61f91243e311e0a775582ca3be74"
-    "9193f6044b573435eb7185c437ce3abb6b232f7d85d5beb68ebe859b9af9d6216a5c1a236c"
-    "499c661d705e9df96466429370c573b7c02d6b66c9725f39550e9bd8f63b69dd1d91ae3b7d"
-    "daf6e53f36111e43f185b2a19e6969c95441159ab96ba7928d9a8c66a81d8cb2967d90f5b8"
-    "65bf2b0986e7e10275476faf729ff6ff275347c3afb647cfaf80b76a7d51c1530e5e305241"
-    "e46f992416baa5e204ed1ccc29ab615e71ee06a21d29fabf1c114bcb0262a5031bbb8bf5d5"
-    "a4fcf004f0276eb27cb4007eb0cfc99fc515e858170e135707b07b5f0839f602d1f1ce9eb7"
-    "a41e02aea4c95a499f9ade35d8f1de41791d62ee88fac1e74828aa5025efa0444425f58edc"
-    "1158f0c1afa86f9cf062ef973eb852fe203a48a8cc6f9ef89bbd76e5602aa93c3af0cab8e0"
-    "0433b8beaf63024c36d652dfc1065c483ce480e6b36250d8bf4c3e8500ca1ab6457fa02206"
-    "6592d25f38e376a4e9d7b1dec77b378b6daf4a3e33e5aac75ff2a93808b163e738b62d6f32"
-    "c8526d92795fa623217fcb8c4450bd0ed300742327457928fb0ac0d9a1a47c490db6d3eb56"
-    "900e091c8e047e6f618acac52dea702c4ca72acd001f2c056291d71e8e7e49ea13afae0d3f"
-    "66a7d7dd8d6a264ca4be9eb02549bf40e61f1e2e4f01fe4ceafd7855686747eb1b1acd2c96"
-    "92fcedc94");
-  
-  BOOST_CHECK_EQUAL(z, w);
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/pow.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/pow.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,430 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_1, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x.pow2(0);
-  BOOST_CHECK_EQUAL(x, "1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_2, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x.pow2(1);
-  BOOST_CHECK_EQUAL(x, "2");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_3, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x.pow2(64);
-  BOOST_CHECK_EQUAL(x, "18446744073709551616");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("2");
-  const mp_int_type z = pow(x, 0);
-  BOOST_CHECK_EQUAL(z, "1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("2");
-  const mp_int_type z = pow(x, 1);
-  BOOST_CHECK_EQUAL(z, "2");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("2");
-  const mp_int_type z = pow(x, 64);
-  BOOST_CHECK_EQUAL(z, "18446744073709551616");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x = pow(mp_int_type("301"), mp_int_type("259"));
-  const mp_int_type z(
-    "0x16becbb1b891cbbbab4825ed1335f0f4ef5250f620023061045e87ca80d80ea7daf0cda8"
-    "023aed1a969864de781297ae556f2bba6d951ae294805dc888f6de01dac2b7dd3ab47db207"
-    "b0f980f26a54f1c7dbb3ebc6cd5b952cccc67569487fd2aea057d4326cc56aad90ecd89b3c"
-    "74c1f30f6ac637a64b706087f2fe16c3bf2be3692106717387813a8a2c9da65b657a8a2a61"
-    "abdfdc6698a6f6543d8f5ae88b192293e2a76ed402d3c914ca0c40e21fb1508cb2c5a7dfe5"
-    "1a357fa58bf9e2f1d1fdd2c3e72b600a8e7390ac0ec65cda8b0636595a83dfeed163a0e161"
-    "b17acc476db2cc246bb3b14a1b33cdfd659d43437b2c4a203e07a8f297ad3a716b53d8ce28"
-    "e84f1b3ad36ba0d2f5");
-  BOOST_CHECK_EQUAL(x, z);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x = pow(mp_int_type("3"), mp_int_type("66666"));
-  const mp_int_type z(
-    "0x8a25f1339bf63db8e5881f75e7f89ad860d393776362040a47448cfbcb4a9402558acf60"
-    "7a590c1fa521b672329cc18a63eca1cadf87465bf8b44ef05fce12fb020ebf2c2b246d9a36"
-    "af527f947f3d238d3e2504dd5a0f3a071dc98784d1084cbfc4554fc21d72f72ae65766600a"
-    "007b364d2c182ba9b9b16011c2853a28fa2455bce4ac2af57f6c8337b85a8e01fd4086f128"
-    "bedf51902d90fb9e9a7e859e65219b46ee14d5a1660f37884801c65d2f580577f7644014a7"
-    "f26f648308b7e7852fcd1702740aeddf1c63d2e41e3a70f13347c1236f8dda54db58b1df1c"
-    "0849b96ec08286e3160db6c7c71b7488d8516af84eb08e8188a4bfbf045f3ed85ad3d63a16"
-    "79a4dab46fd15caf25543e21751c164b9e7bf0c3ca98ce518e95dc7dc9c949b114aac50935"
-    "f3744f4cea72d9f857c2aed3a1b9e682dd00d6c470365b2af4f95733c16cebdd56ca2d0f23"
-    "846be5f1b6bbf0f5fa7ce974bd310e07fe23502def57e53d495364f5b6db3b11ca05582a36"
-    "d17ffb5a409044e2352bfcb4fb721e39a530c8d9d8373c50ec0063aabacff9781e9cc6df7d"
-    "aaa44256e70ec2e3e0db73b4bdcdbc62d86406dd63dcb24551bb1719232ae07381129299c1"
-    "81c17e69b45391e668c5711112e00f90d492a428c15d93e331fc50faa7f0bf3e3de80050ae"
-    "b198df940c84501f2b419b19b03b339b86b5eaed0647808fe1094601bb6d948f2865194f8f"
-    "b661e26e60ce3a0850258ae914b6c35acf512b4ff6b8adad70eb32e649757368216a02fcfb"
-    "dbc887e9003a2edc863c23c878cb9cb84e7bf478258d0c5c297bddf56dc30b87f693efdf7c"
-    "b1c6c42d867ff7c1d953749905e90c74eb8db7c83ba48a69d4c7b5a4d49bda733fb7e18ad3"
-    "df329e4bedb322678ba5b1884509ce90db795dae188978bd1308796f6d34fb4b9b8e95ca7a"
-    "af4599dcff213ace57690345ee9cca65f870fed4d59072a9de2a9d8d523b34881c78e79f6a"
-    "1666e7f01a987d6052fc995f38c92b3412ecff1a009d4c55636afa1e11dd375f909026ad7a"
-    "caf6a593e6df0a607c5f2b231de83bf86d7817dc7f927d05dea16e3752ab18ff6fcac9031b"
-    "390036a0b3c6e89f5d880a3c31755bc9bbe3b74b7cb0ff521f0c61f4b772c1dfc7fdc834e4"
-    "aedb0b257490b0b6f926648617463aceb4b6b6f16e8145cedac27bb671f4a38986c15302e5"
-    "51e1f0e5d38b767990c944b3f2a652d71eb3d3065d2872c0816a9a59bf57b760eae8748254"
-    "54e8c3623b0515c83387318a2c9c0a8c99e497f4684fd8ec03505b4b1eb7f5f3ecb8505c2e"
-    "96c0e9d8b44af13a9197d415766f38e9dcf11c4cde6232f1d43f63765d45212535a628aa1e"
-    "354bc23e810f71058e38dbeab9e2ff3f335abcb58293f4e594d643f10be1a7669b667ab735"
-    "1899f7664015a4d5b4051ac01129710f03df6dc71146123e7d443f307341cab65f197bfe87"
-    "5313d66c8dc0338e87c52773ae8f3bdba84dbf8a1a3f4f73b3e0ef9452981521d5a30c01d6"
-    "a6827882790ed81f599371c5ae2a266167cf96d9d01431a6358a669d63f21034e998b47c32"
-    "4ddd505f27253dcef488b1c203ae3f46206769669dd1122ab00dfbf36f89c557d75a6bf7be"
-    "a889f32493efb3bd63a1432c7d7130b7502d2dcc55c85a80ec915370c90f0719328d1a87e0"
-    "2652c515b710488f3509faf0792e6d853ad1fbd5322fcc5c78bf2da284fb8ebe79304db8a2"
-    "ebb0a14e5eae45a5627b8f81714821ce0e83f742fc79804e27d8bbc38eca3994243a8f5f48"
-    "ae202e7575835c760eb05742dbd11b31111450148dbfafb29ffd28718dada8f6ae40d498fc"
-    "e7d6a24ed98e1aff5e453f70def935430a795b4daddbe4945710f5553d903f95e60b731f41"
-    "8a6e570492b52e0c8b7fb00bec64703e8f62262f32d70686a9cc9244491b8e5ef606a40787"
-    "e6b41bd08c24499abf57227b142baae204fc0b4d55a81011d9252c3f4fc5543fa0fd912d13"
-    "44da807f30d314669ef47d9cef9f7e316bd3e5b706b87237b0aa86365452116f0229d3e35c"
-    "5684db8b6ae7076d6decc75822d7ef0ff94f7ed3db1f7296cdc2465faf0ea31e4e11bfe5e9"
-    "a7a65493ea438ddedf92036914a54a20f03f3d65a91fb138714b74d6e6fdea549719e3613b"
-    "2840e277dac23aa4d466b7f895801e6ad95532e1f2c3183c8f3c2adfe96fd0c0c47e23c172"
-    "bd993fe30ac299e12941a8a60ebd499b31fed0ef7c2981a862aa5ad6486eabaf38bdd838d3"
-    "8ed62fb21fc76fdc50935c3003c02fe61000218e8507511602b29969ce1648371f8fed081e"
-    "395726af42734f3cb8910f52180d01178242dcd9093dfb7abfd3bfcbcc543f495820dcb1ee"
-    "60a1b69ff7f080fc21e39f22e4aa9643558bbe37d2e92563938e3f4a8958ff7d5becc6246c"
-    "bf2e0f24481e1593122000897d171e2cf9b18bcac4951305f0ce9e74837a4cad004b5b91c3"
-    "ecc8507758143e4df2c8d5901b8e9185241a6bada332682e764e3b9d55e06132205b257c3c"
-    "8ada391d6b6a82fa493eddfdfb141371480e04a0ba6f7ffac004aef32247e99463319aeb6b"
-    "93577df50cdd3c4189478f04cdb9861c416e6a0a05ee0d60073d7f1473b06d4cc1d064b8fc"
-    "6b14d12e414f7f532d70bb953405a04c34c0edc0a6f2dc67fcbe7643bbe0cdb8275b41074b"
-    "a5a7c332fac3947f8dda001177147e8e8f1e509aa1b602c781614977c3cc06fd48115f9382"
-    "8e60f4d57f76b1a5b2fd9bfc03616eb0fba9339e4d59f2e0556c792f6ee3afd5b1369aecf6"
-    "2fab5eb9ecd6641b710a39753edc0d8c535f95c4fbbb0d44f51e8fc63dbd3bdfc48688446e"
-    "f255f4452f68b8bb0b0cba01bb0ba41ef33ddaa2c929841b9013b201424aafca3d1a98f19d"
-    "8dfe28eff5ba2f1645252ae27d3a8378d2c50b498f449291e85ebb65a82cdca952a47c77c7"
-    "680cafb603a202998d5c422d475ebc42eeba9d26a962feb579ea01509d5e47b1cf3da3a862"
-    "7527369ed4828eb893fb07fa6fcdb5c4c4fddef59dd2b04f63c09038351d7a6b12d2eefff2"
-    "b6b98af2650d7ce99c075b4bd45fd95bb07c79398341a754701b3e3d843b757c4389226fda"
-    "645adf339cb0d7a5a9966be122e103d5ea66ba6b7e17f8537139ba7a96bcf52d04f7349861"
-    "ca52e78fa5b3dbed6fac6cfcc2b254b9f5f9997d4b874e86c54b4ba4b3291b81afa23b6028"
-    "5c63cb8a59a4d52d774371e519df25cdc6099a571c668353721f34c55c2fd9e5aed9dd3526"
-    "1fba8e180f2e179101f894849c3deb5a19636442e405f48fe2bd7d984fb036a5cb933f2ac2"
-    "e350df4235d0d1219b47c0866911864fa88f83a67970cc4b051bf6214c55afcfd8501966c0"
-    "afe34612e2edbcd6e309d8486436e7ff0515fcd9a3541ee7d7a4462e21784d8e6876240afd"
-    "b74f14cf6a1ce0cdf99c7c511e3c92bc546586615e26dd8b02cc53c24d8070122b1fe63cc2"
-    "068a8b53f9f12023057bbd30a809b880bc33cbbff07b598e1190702ad8ff32044f0d3a714e"
-    "d7d86eb0e13bcf68af313453151bdb9a0ed8c550dcb9cbe28dc78a1d267f3ef25180ab3cdd"
-    "11390ce243bb2bde0ed3b1191b0f492a258d2dc73482fbedd891af36cf1f224ad7ac1b8de4"
-    "f36606294f1a228ad7eb390043b71916e9d0409a4ef0ee0f3a50f250e633008062ff6df9db"
-    "4ed7f69b396493ba0dc5a39d6804c4b93c962b3d70d25188e3a5d5e1f5487708e8dc3d7d80"
-    "989e76b69d7405b31bf12a2d043e523804b2d7ff95ad87e84bbd27cf2ac09a8c5d9762ccf3"
-    "dea56a320ec763ff4c25f2c4d4edf89c8b7512baa662548a6848411ac486af95c2987ef5f8"
-    "16ec5ffb476e560d8fd69c8ff9870b549d6da5f262abc1e07293178d5bec9a0520fbdb5a75"
-    "1663efcfb39ac505725e4e64d63841e7431fef657e0b293d8e6b6d4f8b9c81c7022ab701eb"
-    "f671896bcf9d05aa68b3c67bea8f464a000fcea3e231298c198e511654a0af214fea046f5a"
-    "cd6f204ffef81d67d17b7e0c81fd9e9e7eb88990bb39069ba164139bb2be2c816201f59c79"
-    "957cec370f81f7350614b2b6c94bcbf5f275e301db6a5b335df9b21a6898618be21e34d7c6"
-    "8a5474610d680726661ba18b39f432b257eaa2e2fb157dd4d5f1936ea1e6edc2b92088760f"
-    "74121b8335de082c7684a151ae853e3f5156b7577444b6c8e90d772fbf18259e3ea59ad4e8"
-    "177ac10728a506be1621d0064342bbb3c5ec7553dd03efa6466b9dc9740757b5e890444540"
-    "f60e9e6f32b5d770e76e321a950aeb32aafae3857aa3265dc16c1487989a5d84b598bf45d9"
-    "faf181a6130343e87f664ddc1b844302c2311515258c6e1b9a2d09b1eccccee59c2d69d2b5"
-    "1dadfa6e28db845fb8371184e72cc1ed9ad3d8b6db5eafa84895c8ae26fa99bf69787792b6"
-    "052eb6f1178de7d0a691a249aaa2545437fe89533c8c6aaaeff32d49cad1b6d41cf45a3b04"
-    "96fe7d1b177ba3ee3cd0415a3d1b81ce355fe18f9113a8628d9c057daaa0d1ec9f2c838589"
-    "a5b90774e5d55b7bb166806ae3ff2ee4027d8c8cb4d9c00b1b03d63add86212b87c3302cc4"
-    "9c9577c77a4f55b8f2c82189c6d3b63df882b473c2a17253add07ea88be17293429827d0dc"
-    "65071cf01c3ec3bb87df788f95ef3f5472c6e595c7629b1b7d7a27efc79b91ea8b348179af"
-    "e210ddfa00d7673beb345f13f39e455cba990056355f8634576f3f49e5937a90a8dabed519"
-    "dd045e95f471185c8bde7a27fe344b25ac6d97eed9a3ffc033900e025a38b72da43747dd06"
-    "c7f4ea8639b931f2852d8a3f60be3cdd74dea49e9fc303146e26e0af20cc7897e2a0bdacee"
-    "61187eb389d77060260502d276f541b71b98ffc04abf8e199aa53d831ba348e9820c2fbcf4"
-    "b07cc37008fae656db21ce91281ea5b389c75ed7c167c133e0bed82b40ba19e1f98be20b74"
-    "9266d185b8373b451768f8f1179950056086561c47fe3cb2e8b647f0fa5d511e3291cab566"
-    "b1ec0ffbccb7940e40c5b44a28c2fa9b7d100a05d4f59158b5dacc3cad1d6f054cb648ab7d"
-    "26db6126b26d011d1d982a63bc69804381b6ce05192b4996679962027e41c453fecfc41217"
-    "fd9e83c76cf1ff4151d9d32f209dc826c511a35dab3cf7252eb80ad9ce02290edc8de51c25"
-    "0ec5d874866b6389926dcdfd953ffafe8126a6b0582df5d5cf836002e41c04a9d6ee986ca5"
-    "a68fed99a57256d1401cd4b8ab19cc6fff65b328986dd30015e4c9f609510d6b93669aa2cc"
-    "13b9d457aa6c994007bbf00907935621f576c77ae91e8fe5b3f3f3040010e1921cb2087568"
-    "fe8fc74ba65295649bc97456be30b41b8f6576d5e9aa9bfa997ac307912bf074d70efa36df"
-    "5dc309d05625778f1ec83490f8524eb6f82de3f16363321d9e335a705cc4cd6e7f83d1428f"
-    "8b52e4d7998ac1de3a6956de0cde32b7231a5a96051a4de052263f5c14332f7f2cf585adeb"
-    "1ef6d4db6f963621da8e5baa50bc911b09264ba9c05e56976eaf1f749eed3380773797b8d2"
-    "d29d6bf9ea5ed0183e883d9815f0799b984207b893ebf438ef5226db72e1e74a56a83b5be7"
-    "ec28a8efbc18ccefe0f790dd9cbe6fd4e4576ddde67442e4da0a16245e973ee8c3c6b0cbb0"
-    "ccfb445be3eaf40c2e6c748af0496857ba0aebfd7c4abdcb7faf2d511c23ef6e33e63be6bd"
-    "db711b5fbadd579be403d06776fc5f9028bfe6c0adac730b0d728380434e80a2f85b01ff68"
-    "092f5780b701217866abcde23955d4513d76eb738e4e746a32862d5bf4a7e576dc5e0733a4"
-    "ea9ddf0080a5098d7f86af82ff52a14f9b8eeb85d03bf5a4856844b6a49db23403eb36647f"
-    "2123f86fe89f240be30e47207a74e509804d3201eb06c0a33746f4efd275a358a709777b8a"
-    "d85cde65a481cf7d52d3a48137d0e3f464e5b7083bb4d56639d0e5ca5ef91265e32e1d76c2"
-    "c318505f735762d33f8da0a5a0b2ff9a0538654fd7dae9d4795f0ce2cef620933972a90637"
-    "219764fa6dc342e69059dfc73dc29a7da6cc5f0466272cb4f42d46013be2dfe8bdac4d795a"
-    "89368f473eb7335a2101f64a5a07a5cf8fd7f66245b68a7e49c57d1a1e146aaa7f33859dfd"
-    "d1762846044e5f38e246716d51321c1040540259b41d9daad868cae75580c50e3810d20228"
-    "e7cedd1097b8f91104c20d057b821ee97fc9aacd7cc225fb62e86490d3a0ce7ea1554769f2"
-    "508673b27f7195a1b5cb4d2396cb008043c54edbf03c7033fe46f2e04ab4c9d9a33cd4941a"
-    "826169216b96af7ffe43b1b00433ce8e5d0892d518eef9b1315486661abddb7224bbc7e020"
-    "0d73aa1c677a66ed5e4e9e9c24083e9d6f1729c2544679cbcca14f99709d2cd4f92d79ec53"
-    "043f2194b21378971d4109df46c34cd662edd8f783ce05bfe634b3e6ebb2b6ea4fd93b3ed4"
-    "9011b00fda3661f7447185e3cbfe18a74eb6fc0d27cf52dd5b40106d458542b3fdb16debf4"
-    "b746549226b22b1d657c7d0ace25cd4ceee9cd91f868e7abcedfe12942c069e287f64679ab"
-    "9ae9018a2c1d39a1a67f6c9fa74fb52aba56f25b49528490a97f320cdc4f723d92d5d641f2"
-    "0d9d9809661707ef09e6fae3d855dd6d944fb9f596008426cde5b74176f94504adb0b99811"
-    "cfd49f7317d712656db9034bc03ceeb18bb5d84fb03c6c9843b2e0de64db7f0d170818a7d4"
-    "009226270e52f2148b827b3874054d014072b2d6fea3bf8d3391a212b87f729b14fb5cb2b2"
-    "af51c5a1198c68836d802c77df67eee5c03a1ef3ae76d1f362377a9497603439408ffd2ff8"
-    "bb14ba82fe9127ee636856bef4f15dd93a508cba2fa17b3edd83550f4f4b726dc5bd1d3c6a"
-    "c3116b13a32464b833463468a1290c2e80b2ddc8fc0259d71e16444a7949aa35ad482fc068"
-    "d5014dfee33075c27e9a8061dc76b142aae617ac05bed9ee847e26f41014336ed24e480e08"
-    "3544df22e5dca68e081d1ff2b3732208858d9f782fedabff8d3bc83242733169d3222403a3"
-    "72d9335146a6af07d7f75aff8b1d73f4a8423a517b5d0b4c390a780e10722965b9f74d5721"
-    "17d2986b54ddc54a6b58b7e7189c4d1293446d5325912a19672d68b7237db891cf59d0b6b8"
-    "9092161991eca1563df8b2e0f1881f4900d7a41d34ba55d55bc170e9069dcb73f61a6cacad"
-    "e21b4f20a7c25eb7d0fac2033f9a372805c755f99f6b838e556a45018d7a2bcd3d60dd583d"
-    "46f35d2553beac5928f5bf4f695c0b4d328854791c0b99bfbb9f9dba732eef4275e1f6a553"
-    "182ac6471650967ff83367ecdcb61f6bf67a77e617526c67dad885413738b00f3242948c5e"
-    "3a70ec4ef77db5867a0ca673eff3602b2f242f97e98ee946ef8f8b7684991b5c14a9d31011"
-    "b9aa4d3915d84ddd798c304776f4cb50f375f46459e4d637bf3b30258ea21a7e0fb6689ad2"
-    "5f814ddae78fdd88cc59824723b063175b9ead2f2612da72e7c458049e4b68ee04a409d5b2"
-    "6e7696a4f700a1c64fdb3164cec26fa673fbbf60f72c2bc717690bdfc575d595648468c5ad"
-    "848c627130d6ebb468159536ce59f9b6d62c772e9fa23ae4413c26e8d2f0a50c95f736c246"
-    "80cc0d8fe94b8674702a92929f464504aa2404f66e76331c0b08d2e31ee04ac9e99b695a0d"
-    "8799e52fac2e21c1928cfef8c08acc7c5959a9d42c7e038177f5d7f0f64ccd5b890498ff51"
-    "549be791874928b7f43d2982db3ad1bab48ecb757b51e12a9c6626871ff177abe783a94296"
-    "e5e37baecf5a376a5212556475262172c6afcddb3d8ca8041f7fe80868c846230ec31ab5db"
-    "78f2a92b39fca377fd0000631c95c512b090e87b2291ed912593259aae0198f2895f8ae769"
-    "04c103a79aaf777d96e7c999a6a2ee92dd17f3c06021545b5801c6c0a2e5788e285cca6380"
-    "5bdbf51a4c81a290cf1796c36c9e2f5944b227c6521f681d376670488931b89f24f79357a4"
-    "7bf4af9e2303659a5c623edbe472b7a4d1ad85ee60c3adfdd1a30f7f14c455d43510a15f21"
-    "20c0fe148707cf3e777ad2102c3381013d482e2dd2b68ced555ef58955f6293ac891ea6cc1"
-    "6607b6b51c16e54671960a3c1c00b1285696bd85c458a663dd9d638814ee65e71b77fa783f"
-    "78e175e2a880ee3093aba5bfc3ff0e5b6e1b6ab7ea4f184ecf11c6621e2187f0ba112d6036"
-    "4d95e2acebc75b9255d1e681476b55d5cb9d682519212dd03521c5d00b84b97a934877b574"
-    "ff4a180d777bc446e7584cbf5f0e8ba20f04a899f0c684dedbd7c87cb33642d1828e3bbaeb"
-    "8b4c077fca8fd08e460740daa26b2a924181db0e2103f08c3862e1fd23795eb530ca6589dc"
-    "90a1f2fb893743a495a4140bff2e7b49330e5ef5584ca5b395679f479ee3802632add5b660"
-    "3e14729ed8d13666ba6ecff0f10dcf30cb820143c8e3e07c96031bc42c81c9b63842e9fdb4"
-    "c248e246c758abb4e07ecd5c89b4376e371ee862a1a8f66ee5a2a464d9366bf1b381558079"
-    "59b8705e1890a9fa46c1cc54f7310a240c88b2c36f5b9db8e710b38510d1645ee8a4a4e0e8"
-    "b14c05892371a200dad579e14af518de70f0120fdafa14f5cd62f74467c4544660b094da9e"
-    "9e00a0cb1d7a7c382d30e75cc8c5517f5e02a68e67398e505a88998593152af5a96e09e718"
-    "b6e719b4631a4cb2f8d1f64a3c673ef01e640628383004da91f1045cf47c7e0d34b437d571"
-    "a68f40e2f6b4af1a00a2c83592b11c9a736ec23ff83479d9503a562571f3dfd9f2398bbedf"
-    "825af5bcf88bda170d915b11dbb2a3749ce6908cffc0ce7819b4f6ef60f6fb5b0210a29863"
-    "998aab74607a6fd818e4cf3a0143b61570186a98864ab65c288268817201431ab2637ccfe2"
-    "a977a725cb5fffebe5b481f531f0a6857c763c226f7fba39ec939580dd28965801d68eb8c3"
-    "1605341e85d22e68bd661652b0c8a3e64a0f469a7a16debb45dbd0edf47ff7d761f99255e7"
-    "ed9e3fdea5328e26bf5fcfa789b1c7f2cd3c9234c99c030b1db4071779bd2ebd7ad8d20023"
-    "00d94cde83293dc1fa698821f7c8792397835a599fe7d359e88906df7440a3edb4b9d6b285"
-    "7b0e6fdd0f1485862e2ff3244d7821719e72899eb5f5a0bcc413f634ebf4e5ea7798e09536"
-    "be917c6d6b97646873cd30bed56972fc3abdc042463a6a606be95b9d96b4484a53ef5d5b9a"
-    "11a52fa31e268df46551789f5b7f09dc2fa09e4a958fbb76c4503a48a8e0faa4ec422aa3e3"
-    "6776327726786e18bcc17a2ff0b58979b41e7f8da369a21927bba63dab179ce341073034e3"
-    "c50ae3bf27b25dc791479904d3dbb5c3a42f00da0b0f16a89578fad646c9f8c8f93776ecdf"
-    "eb71acb61a9a7cd3be74c0a3492c529ad76c9003fa781e57f8513d92cc5b2ed1cf69880e3e"
-    "45bd298e94aa174191f294cadcddd954c431d0dd7f045032005873d943ab7172a4bf64f382"
-    "c789f6a8ac0e5a3caebbf8fbf26cbbcd9d58970ca1b22157e7929c8517bf633d28946cec27"
-    "6aebdb0a638720a1e1cb382826e4cfaa5cce5a68572904567d0a1ac7cc6be9211126de62ff"
-    "49a2164b5e7a74d49ac1c385fd8d6f7880c4fcd5e173c5d215be1a3785d8025edb7a31c0f0"
-    "9b528918a48a083133e181df412777ecc9fef1693c7c19cb79d6943b4d58617cdc6e9cf83b"
-    "7562bf4b93a8b8fd865bacc383d552450fd1571e2eca6557a27270fe21975cedcccdab20a4"
-    "ff6a754b9a0502194aafbbbd738afd2fc3ed3ff5c6190ac6ffdffd494fe5f25e7cb4ff44a0"
-    "445bcaad32d9cfc2b58de9d1d53bcc6007617f0fc713eb5b5acbd6858c999b96dfb1b46da1"
-    "6a0fe11accde3b4e011614980cca78325599de8f93a6f8e4af4126993b1f940fac19f649fe"
-    "721474cac4d32227e92a2adab1b9ff9d1e5935f806d8721d09be737ac1b024eb67750c154e"
-    "61e6bdf8cabc98755fa16d3640e80b94e4e23deb3a36a2172da28dc9eeea3675be759de36b"
-    "ee0e951fd77d7aa68ae4caee0fc80175045595957fd00ea3ec4536e666a691efba0380d05c"
-    "0c88154b4ab67f34ea6c201b600da60ff8b46ceb971a663bcdf2ba0eef26095f3783b42c60"
-    "10dd3959df46c4d631e7a89e62f5391d6857b79f9e4502cb3862586a80a7f33576820f9985"
-    "eccea22b4534a5e121db3ed2e21a2d7a9dd80a624479bbb061b91c38ae5714ecc996e4b1ee"
-    "ea6498f1b5b7aa11d0475b591b8769dc10bcb405ca2a6c5de880c7c533272dd6e3bc9b13b9"
-    "e8705b549bb50e72da1e943a0c98d313e43eb847f4e8b79a549b5cc8992a59677a473f694a"
-    "3e94f4048e0fd7164772aae1056149dc9f747be8f59f365702f24222fe0f6f320de6345a3a"
-    "00677bcdcf1a99592c45076b049616db7b447c4fe3a7937febeb392c4baed841c4e96c7cb2"
-    "a63ea3322adbc2e88078b6d0f10c7b373cca2fe3ab24cf2bfb4c0bf253222ab49011cad073"
-    "23bfb8b554b513025e4f04a61fa2218b7f2e341fdf86633cf90fcef924f8175e30f3290cc7"
-    "bab09b7cf8bc574f7dcdac67d5c59436f6762ef35d4b1327fefaac7d575314acec5af01cd7"
-    "477e13de5ba16c9798a8868767fbb2633eb152cfd1c946b500090a43abbc4c322f5639f0a1"
-    "5e8d99573860a14960e36ea8cebd1eae0a15da0494a29f80cd4912b18dd6305a093409c7ac"
-    "796a3e6a8b5e15ac469cbd8e6f60d0549e4a31713bc639dc3754d857d2a97790b7487efbf2"
-    "99ad8259a31c45e64e0cbb464b1fe0b74c4a24fd1317363103252144820b45bc0702a756fa"
-    "6e89ab4166385106051713cb6ba5cc5b4dc92819cef9c33d27b9550eda8300e3583af8b10e"
-    "7f18501c59ec2f4563792e8cce5a68b261a9b961de92edee5e5a78c4e7bad2a2484e5bb46c"
-    "ef8b1ff7c0d111e012e5d295065398f99d85a9511f3dcff5fb2a7549b0934a3af06294e43c"
-    "d8d4d6c65fcce4dd86a673bdb9f3be3fe177215187d3514f10a387b7aa22d1368d0735b200"
-    "8ac19612fe39cd0ebaee1adba3c94cbebdb21855f0fc5d9484ef26bf7c85b7c92fd1b67531"
-    "3ec37086b7bd647c0cff49f39ec2f64838e0605fc5d423b0934a6a3ba1a5de2b32d8234269"
-    "f282f2abbdb546d1186d9986cccca90a4cc781a634d797d8c89efa7af57d8584ba8d6f9a32"
-    "f7d158a940b9c7bf74e232173a573cf42a38cc3ef85b5b838846aa8de09484df405c21fb1f"
-    "492a5e30376925e49cbac45feabe81d7c5451ed3d97a458866aaeb241cc3f1257903aa854d"
-    "ec01bbefaf65338bddb7af026b3afc91b38e09775676075d343935e6f04a3a7e11f4e1fc3a"
-    "1dcd064aad3adb7ed5ce42c0905d0be146601683b2a8ac6670fb05f4ae73c18460d3f17506"
-    "4de1ed3d61cc1378edb7b0d20b7ff8d14c228c9c597b8df4cb96c37e38561bfcebcade33a8"
-    "5c1ed148b69e5362427f86b020468fc72432d2f50e5bcd73c5bea6b4f44c2a09aa7bd2c2f9"
-    "adc85be963e0770cf2f5aa38e7f5de6bfc4fcc8498b09c815abb3d90aba39b849d1dc5e2b0"
-    "906481b888ec4b50d7169caf274f22848e35a405273aa58bd4de8b92db57914bd4d88644fa"
-    "e5a2673ba8b7ce95d0d798d88ab08a5dc53b78c0be8d8f4f8804195cb2b816258ec66bde39"
-    "e22a66ad5e14931ce4de9deb8aab0237cbec2abcca45a2feed085541982eaf663316c9710f"
-    "66ced3b0f8ba1bf69106967d013323b2656de0b93ca15f4895c8ff15a339315e25ba5fb252"
-    "14a503bb688fda76a5551ef529235c5ffa09611aa59598a47b4c8ce22aa49df7217950a74b"
-    "03a0e8a0ebd9424eb170d5277b573b223289cc520b467c834b4c53f1d4e5b574380ded24bb"
-    "59cd70ed0f905f15c798952d29f9ce3c8b4a04678a58842b6b3bfb7669e5a0f2a153e02001"
-    "a7b012548050699dda11fc95f026466062bde597fd61be5c32ebaa19075636f212ceb0ff46"
-    "122e4ab88be9439d4ec653f7599dcb0caa86f26469da9f9d537793f1b890d682a84464b4f2"
-    "6a5481bc12802684c1d73dba5f7acfc4451a213645c39e0b3c7c6681623ecf255bc6c75d59"
-    "4726ce1a7318bb3ddb80cddb77806cdde22b90fb1a998d931d596bc833dcd0764993ce42bf"
-    "b40befaa469aae29b2758d584fa4804551046fe36452cce20e26e9454c9bb20e7dd9b5f63e"
-    "e35bbf7c43f772f38cb3baa2bea11e9881a8c94cd5385b75611abe8dcd17b33a5dd1c9b928"
-    "41cc08cd032c91408b475a0ae8866d4b7eb005d5f2bb227f2298444db54e8af8ff5b6e08af"
-    "5e609429ecba4c4ab5faa9669378be9308c900d0f04e2c65f0327c3e41c574dae5f96dfd66"
-    "41b96cb8923ff9ed42060e2d089ebf0dceec2d386da7f98c2726a142e0527f47be4559e0c9"
-    "f555bc6d87737f93cc82b6dbf2ab73921c57c28c0340273e8daf79a9a1db2ca7c88fa4531b"
-    "4e4b89c27f5cc4f59255d5a92656c984e2041a2eaac1cbff11e1720fa3425f9c97ce2789c0"
-    "0c6eee26e07639f47a3f0798708b4f5e3feda3b35e45504f42ddb10ab545175d82060c5eba"
-    "b9ff97fe51e33860f3edfea8c38ec927ec15398f811a0995ba948a790278c0bd2c6a398fb8"
-    "43a2646a11e0600560f729e412859cd21e1325ed505f2d06b1f77f69306e689d1b0b91b7df"
-    "1b7d97d96609bbfec187bb7a93288b37cc96fb22ec72b0493f0a60f1e00858d056970e535c"
-    "e4803c135e97c999df22c34d2524913c7a70313bf3601b07e3fcf5a257b46a87f48d58e73f"
-    "ce9447a8d10353a55e8ddbd99178e8c93e3681b16543cbf12dae84c93083111b0dc89a4f19"
-    "dba14e0b5ecb7b9793336a1768da49f72befd65bf67e13255c703bb4b7f6c9c8304d0de149"
-    "01fac221603a39941f57d9201c506e8440dad927d1e9a1f0e28d986949bdc4dc700c1998f7"
-    "1641f7d7a335f4295abedafdbb71e1ac829402443b4953386c9302d141bb6cd9d218c66d26"
-    "6c460aca44a0c49f3fcd3347fb7bd0ff8858f2bd37efa64c73ca85b4830f0181079619aaeb"
-    "675bea0e15aa2afaa62d25a5a1b3d45573705986c1a8a67ca5be85b062e77685f69313d87b"
-    "a16bfa2cc2810fc3882313f640a1f1eb0ee759b8f52f89a2a9d5853bd24e7d09c150e4b294"
-    "d65ec1d246aceb217d5a0cba04673d3c70bb2630d914e513f4f6cf30ef82e6b8f43aa4e168"
-    "6c259c76f593a3dab623ca0440d90fd99e84ea49ff376f2e300f8628ea27a9dd57b4e44219"
-    "67d7d55945be9e75c06f2be4c96fbf1b2f379cfed2c7e28cc66b205fb87f3ecc6f81081253"
-    "65ba7443907fa9129be3abf3147b9be54f7c8dea7df51330078877a0974843eb6f0667969f"
-    "73b5a64b406459f6ba6b266ec8a0032be573ff5ae53637d9d343d41af68346d974681f4cb8"
-    "922b3cd1ebbf695ed46dab551a245675f82a8f53e178684ea4da62fd817d0a9fbadfc12df5"
-    "9d18f6373fb111f0d3f9712b98ff16611f8eabc59997d0f975b67c47daaedf03521eea6beb"
-    "3dd569be0e9d14af9a6eda4650fe712789a6d59b8388997e9e0a8f1b215b5bb327ac5b4984"
-    "e1513baf6053ad05bd4eec0162ba25b5a3f37a2219230b9f940f7337a047dc2b6f71267fcc"
-    "64e2fec49cba93405125b185987f3f96276067a51b71b0668aab901ed1957c9c752c628825"
-    "04c2c2a8f81551161a1b015e36db1fdcf9520c2c5fe02c8bde49e1e422dcc7d04ba746e3f3"
-    "442a2b9a2443579058eb91bf39575f7f03fdf8d8cfdbfa22095834356ca28eddd87e174ceb"
-    "958d21d3f6af03175334f2ac43c7385701e08da369bd8d73899874a06759fdd4d747250d65"
-    "9f1a4fdf9f82ae6615cb5bc093266b5f3629d066a9094923249199fb816dc6d4f9bcf84384"
-    "569fb6ce070ae60811af0e8d88ec983b9b00d492b3a28ac0c64aff11bb9054406b7eb464ab"
-    "9f29e0947329de4811aba7546aca0f35f24d93f701ce9b58fe6c0379ed182149913a599adb"
-    "ef2f7c57a40a7654503a520e07b29a8a9e398b34ac99b4d29a5c4aa2a61abe583489c304c2"
-    "a3b708d3beea806720a179a7fd20de94c24e87fe3dd3856ce5381cb4d1ccd33d1b5323bd48"
-    "f364f8c995a3f8ab098118f66f5f111c4efa9739b69be6f8a09ea4a88c6d24d5d9ab3bb595"
-    "0ecb7fc5f3f9c3c1aac7c89c95ca75931c64651f081181f182d3235dd726329f9ec43c8c2a"
-    "fa9d8ec5058b22ef627105d6dcad48158ec6e8ad202a6c2f034d37c022342fcaec10fc9800"
-    "51c3c3d5d014e58a2be79061a78811860bf2137ee1a1510d4e72f7029252ec8e1f691ddcb0"
-    "8cfa7ab971d1f7b6e20d7c012177eb0f3f6e4a1cab589ee85e09f4c27579f3ff52c09a416b"
-    "5c585b7e6a1b7424779734820eb93e66be93044d09ee8ca34126b47358244b5bc25299b69c"
-    "5d39ed2826de5cfb285981e2ea043cbfbc603ebf6c6a885f68edcff2f0cf4addf628ad5992"
-    "84a798f3ad659f36fae28cb16fcd439ffa5a69c516dff3dad3760f663fb7ba084bc3dc66d4"
-    "6b31f3120c57bf46f7a20c6b225e867977245b3acf75e2136c39fe744999b76dbf44152043"
-    "b7af96a3a0ed4463f6b1b61d5f07a1e0c395c0051656959767e654eb163f53b80026dd5b49"
-    "b90cdbf2ab50306a23287665afc61d7e4bf0d6d5ff4c6416c07d1ca8d6390c1a69084d408e"
-    "1cb35a3afa0bca0c9fe58344d7e992c23b05c22c6cf57349b90f523e7227becdb320f39255"
-    "c3ffbf8e43b20fbd1e898cd181c6abcef5456807bf2914766bc70fb406228ae3c7c23a64ae"
-    "42b3293e17bb4dd622052f433a65fa781c221187aedcfefa816cb040ba11647c785f64ba3a"
-    "1e2eadd17bc6f8eb7e2ba480da06b6606e6f4ede7f9fdaf26fe89cc7cdb0ec08f1c53ea273"
-    "6a83a53824d1f9d05022aba64e65a59f19e6713d60e7c64f5270befed0570ac245490c77ea"
-    "af2baa4165a8cd1b268458b634df1f38c20e79b20d1fa6453e9ceb74c447c53705fab82e7f"
-    "a23251e425215c1fd55818ddcf4449f58ec238ffb1a3cb24b53caaa8430f8b01a1cfd515d9"
-    "91c6547c165b34d3608bc117207480396338645097f84499296425333bb68bf39349c59d04"
-    "dca85341a816fabed09c2d42c601c1966ad4e2baf3eea257f75524e96798b9af773169cf95"
-    "0186968f5aec8fd5906e55c9486a70f44f5435b112a47a33b782f01b5a0dd26ebb6ebb95fa"
-    "0a83d02b444416e2a340f5bade3c76a9217f993d508d48d013737da2c6ed9af245a0877ea1"
-    "b50719b77d26eb1085cd2a418f7c04b9fc413629923aea6b7ecc795958b0ecfec3b820d5b5"
-    "ea6bd1f7cb1b555c2820165f01aa85c49343f7b7005b28a28bcad9bc77999207559b60295a"
-    "e2ed8b11702e14b98c0026712400ec219ff867dd78aa2637927c9921238165292ab08409be"
-    "a2bc683b00e771510fa0db6c956603313a985e2dd1f13d0aaa1f7331aac6b8a5d5b195e8a9"
-    "3f5d5a07e4ce064258e2049f6c4eb1efcd3a7d890d881dfb080e990927d93bea148b5e7645"
-    "7c1bdf2a73d364cc30b81345edf3dcb375c5cc5bcf34536ad0481f3669ed32cb1e9c0895a5"
-    "0d2542bdb135878a8fa4fec38d46f0e3c8f9b14738ff36865d29c94b31faf6119b479b8e2f"
-    "dc9e1c838b82605809c66b08576b97b7b5d90d4865c77201c678cdcf770a7db91f2070c17c"
-    "67d4327e4d7ced8e2a73285993b1a19fe3eab29154035e4cac04d0cfada92aa5963e785f8c"
-    "a20d77e9f7e65169db4d9196abfc76c70f520b41017313d7ff8c43d129134a0f265ff6f10f"
-    "ad88054ddf128680ac133315bdd91b00d92d026a0d692f80069bb45aede03f09622237bae8"
-    "ef09462a0bfc4bbdda430833702a8481d6eb028f111b7305d33f30c8558a7d270a3aa5610c"
-    "aa8bcb39867efce7a44b0595c556c0befe0899908b82af48c07106e30c667ecd75df0df03f"
-    "9a606f680afff7c1b12625177d3f829adc2e304a5b1bb6c8788b712ebb6759629857d243d9"
-    "57b8aa44369fe3eda0474827c60ba9a042879c9e5896b71b35aa19f8d6e5ef5e0f713ed302"
-    "b8f50bc1d9083b7fd28765c8206e774ff62a522949c56dbe738b99d9e9b2eee7fce9029a92"
-    "b7c21f31cb36fdb974d237c7641060105e77a6a6a0e61d3a60aa4f792622e897e89bf6809c"
-    "d9f72674ee4aab58e636200e0de7d08efabbcbba05e408b16d9b472f8b993e0d3b5b74c105"
-    "e171ed02150e3a9c4a95a8b5cee3d35788a45bf328e2018501b86e973300221be59787fb68"
-    "1064a6f2bbaa44aa4be578bb8fa3c24e0dfcd16f8da1bcf72b9ee98c86ab8fea3913f5f3fa"
-    "c6840cf705fc1e1b945047e7301efa976135fc0bdbdc2188d9911cbb2ca2cc99f0d62b1888"
-    "cfbdff94ebd6b1583ebc07ad468ff5ca600e28438cc89e5a7ba3fa97742e51c45eddee2c21"
-    "46c29f0fd3f8ef8e2e3be6ca727e1d35ccfc5539f372103ea30803779089fb811aaf517213"
-    "ea35fb33c0d4a2464f37f286be1804030d59bf53be9bbc11fbdfa9b2fee8deb60f6ac7d6b4"
-    "070f4d666235ee4dc314b85869f339333a1b3cff2eaec781ea6a07a2440bb035b75a00ee0a"
-    "7d42672f160604a2e372c3ced65d4a556412837c8038f6a93e4eecfbcb4408a42159e76625"
-    "3b2e0f443edfb3e6f098021eb7b030f6d0d4b20243222604ea84d81e03a0f7e63a447f9bd1"
-    "a3f26485bf69912e16dcfb0222c8c5d74e7166e1f899101c74abcf4fc0558b4ae26a2c0e08"
-    "e2dc20c91d2c9fbe835d44ff15a26c6b976fcece277e4ff9fe80c0a28d5bf40bc40af5f782"
-    "13476c0b6873fe734a066fda3eb350302d7206168dd61ee4de813c8ac65a3a48cb40ccc821"
-    "c8efa14ce9320e6f0de35b5e68735bab8d03ef1185799151bb5f8a3f4d956752aec525cc73"
-    "d187665a0027189cd895f01422e59abed3bba5b655828d4aff00d77c846ea690c18a5a3f2b"
-    "86fd9da63f095da01f3778107b640a2813197a3f7023d652b2865ea8e2f93398fafa2f9af9"
-    "0ee81a8d6eba0d6671951ae831f85bb510605caf3ef2550ed0ded1fb90061857dd26eded72"
-    "5fe4399711fb2d0178a386046db054259a44896fcb795961e283fcda0d13be9b390fdc71a3"
-    "e3aadbac44dc71b9086e4b204cae1b0fa06268bd73b746807fd4c0ece38fdf877c490cdc7f"
-    "b622c8ec94b374a3b739c013476ba680edf46739c981ab095c175acc045c445ae15b208637"
-    "b13b841eae64b9b571630dc82119547ceefbab3288fa224d73b572ab1ac600258dbb7711c3"
-    "2801723744a2f80902b46286d52665d368892de15e283f30a5e3fe1d36284ad42afeb58a7f"
-    "a9850d6afd277ce4709c716160521dfabc755803932fdac96c096606be2690af795f418ba1"
-    "a3fd1e5758f570d702be4855c76c8ffeb3cf31056b47ca5d7aa498fd83302e490c61b32c8d"
-    "3586f43ea5772ad98b724cc51e2337d4674f086f915556b69ecfb837e4586c84b147cfbea8"
-    "a6427fd5cef19750866fb59dbc669de92972052b651c8d4c2f7cad2db4e2690b23db7830c1"
-    "c20658fce756d74db87eb7b93020dfbc49b86fb1ca81291f337d4642a0b330665aa8f4087f"
-    "ee34d22b190639bd02cf126ad96a34f21957e92549e0d96f54d0b1aeb904c33ea8e6733f0f"
-    "42abc821451471293415c18d4e01c044a3b96f85850c73a26aa01a382e424350f85eb5007c"
-    "d23878fd90f21c0413eeca6337a0a1b7bebf8042fbb10c6b6f6469dcd61ac494bd3efb2d5f"
-    "fbfd5e5398920d5a13e84da91a1636ae862c95b2a4d99e8e62eb43a7ce89a543db8c942926"
-    "e48b08d33b89afb9582bf56e50c5cd9d64e9e733e9a47404217b51d8854872800edcfd5426"
-    "39385e1f66242e01f97fd3a97e201eb95d16305956e57a8f9adede23791b8ee2fa3b81db49"
-    "f56cd02fa900439c2bb8b9fa7c65ee662d415164f5930a7c65769156080b3cce889e103330"
-    "a9a7934962d5ef10e8577438524c484aeccf8f556975a2006cc4e7d7143165f2f771d77a64"
-    "06d2251b8dd659c8a42aebac5d8e5513bd0527f9b6f709714bd82cceda33a18a572d7b1f28"
-    "e998a96d4fb596f021f68215356439f40ad42282bf784b954bc4900860bc07f4452ccae599"
-    "5a27afc8535b5854c5305ff02af7b876879512071f6d7aa7eb5ed7d37c0e657c00962f3441"
-    "2b23a694e75a52a60fc7a861deec2f27ce4f323dce313b98dcd9c4d419985ad696c5f58361"
-    "392563e2b0a0f72ca286e9a5a044a32685a01e4ade75983f3e53f74f4e1022b82479269ef5"
-    "279ec1765955642c27aa83847e0b9c029b63da839835575820699af9a038b587a468e556d4"
-    "26601282fbe9be24e1b33d0e1bcab5c5398f3ac6b67889f4c99b40cfa906fc2cf002868c2f"
-    "3d6f3bc73b683bf210ee4a5f5281c416898ae4cd14ced66f51e1c48a08420d275c90c3d3c7"
-    "7ca4eb22fdc5df97ff81eb1adf987118b7fc6b501b8a2c7a9be1933ab3b6f651ae93141ff9"
-    "7de2fe9ad3fc3852df6c89b2959a0fbfca0b63a7cec988e7eddc256962d58c2916f17b4981"
-    "0fe5543a37b5d74b52fa3bbb5385b7a08ad38b99b80b4744d48aaab4075c7672a45736e3d3"
-    "8c58f827472ba8550dff056e919f439796ba9c905a5a1df24e93d40958e215c59edba0886f"
-    "5c9f8c8b05dba2f2c9d4e568555ea29018cef66b10ebbbf76cfbf6d72c1795402a70bed95a"
-    "c819b0f05431b2203355e77827c72fb5b0270b1817df07cd9c99a4df89f8cbec7a87ab59e6"
-    "3cfc554d19d1f38a29206d3e5e590de1e6e329c2585d215945e9397d6762d60e23992a450b"
-    "e389e03eccdc0901808be8ebc45051b32956a1189649f25c37a09287762f5f4a5c69c54867"
-    "d63159662c6d83cfdaa0a9ffd19b356ef4aaeae58d6c481b84ede83decbbc44717f6e0be29"
-  );
-  BOOST_CHECK_EQUAL(x, z);
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/prerequisite.hpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/prerequisite.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,42 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/cstdint.hpp>
-#include <boost/mp_math/mp_int.hpp>
-#include <boost/mpl/unique.hpp>
-#include <boost/mpl/vector.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-//typedef boost::mp_math::mp_int_traits<boost::uint8_t, boost::uint16_t> traits_type;
-//typedef boost::mp_math::mp_int_traits<boost::uint16_t, boost::uint32_t> traits_type;
-//typedef boost::mp_math::mp_int_traits<boost::uint32_t, boost::uint64_t> traits_type;
-//typedef boost::mp_math::mp_int_traits<> traits_type;
-
-//typedef boost::mp_math::mp_int<std::allocator<void>, traits_type> mp_int_type;
-
-
-typedef boost::mpl::vector<
-  boost::mp_math::mp_int<
-    std::allocator<void>,
-    boost::mp_math::mp_int_traits<boost::uint8_t, boost::uint16_t>
-  >,
-  boost::mp_math::mp_int<
-    std::allocator<void>,
-    boost::mp_math::mp_int_traits<boost::uint16_t, boost::uint32_t>
-  >,
-#ifndef BOOST_NO_INT64_T
-  boost::mp_math::mp_int<
-    std::allocator<void>,
-    boost::mp_math::mp_int_traits<boost::uint32_t, boost::uint64_t>
-  >,
-#endif
-  boost::mp_math::mp_int<>
-> some_mp_int_types;
-
-typedef boost::mpl::unique<
-  some_mp_int_types, boost::is_same<boost::mpl::_1, boost::mpl::_2>
->::type mp_int_types;
-
-
Deleted: sandbox/mp_math/libs/mp_math/test/prime.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/prime.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,243 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/bind.hpp>
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-
-template<class MpInt>
-struct fixture
-{
-  std::vector<MpInt> primes;
-  std::vector<MpInt> composites;
-  std::vector<MpInt> carmichaels;
-
-  fixture();
-};
-
-template<class MpInt>
-fixture<MpInt>::fixture()
-{
-  // from http://primes.utm.edu/
-  primes.push_back("2424833");
-  primes.push_back("5915587277");
-  primes.push_back("48112959837082048697");
-  primes.push_back("671998030559713968361666935769");
-  primes.push_back("2425967623052370772757633156976982469681");
-  primes.push_back("22953686867719691230002707821868552601124472329079");
-  primes.push_back("31353958997402666638501031970734176101289470405573395248411"
-                   "3");
-  primes.push_back("46695238499321305088763925547134075213191172396379432249800"
-                   "15676156491");
-  primes.push_back("18532395500947174450709383384936679868383424444311405679463"
-                   "280782405796233163977");
-  primes.push_back("28275548353370728705475218432112134576686148069744870344385"
-                   "7012153264407439766013042402571");
-  primes.push_back("20747222467734852078216952221076085874809964747211172927529"
-                   "92589912196684750549658310084416732550077");
-  primes.push_back("35201546659608842026088328007565866231962578784643756647773"
-                   "109869245232364730066609837018108561065242031153677");
-  primes.push_back("49949091806585030192119760356408111278062369027342098434296"
-                   "86905940646121085912172293044610060051708652944665271663688"
-                   "51");
-  primes.push_back("54522121518442644531155217703627128153004567880738702606371"
-                   "72006414987479914150831821202259862091373741738511579629040"
-                   "732909194883");
-  primes.push_back("11116154175595527770308362725647119128773382144932530406518"
-                   "51655768643786825585565208246254887946100346011818823101363"
-                   "6706338524913578946637");
-  primes.push_back("65669205018189751363824155419918192392295592176092883676630"
-                   "41617905539892282237934618347035068727470717051679959727072"
-                   "53940099469869516422893633357693");
-  primes.push_back("51665668390920744584663348665715976941144605703879863575380"
-                   "48450432901440804868689337999823161841839689242893622491638"
-                   "917313351308387294478994745350551549126803");
-  primes.push_back("27218343798190233889779431662111815254174074647423987223301"
-                   "82099632472829888864333146379225493741435309651830476334589"
-                   "6749125106775048493507719412795029690510090142402163");
-  primes.push_back("27834442010031021673804244175247010833232390861821952548705"
-                   "37102073847719982865971352904187195267023851783658963402109"
-                   "57041552257518693488098683242070746473230980005141419410511"
-                   "409");
-  primes.push_back("50774619156173716518115936073898485346139106651602235699024"
-                   "04065418076795944656510340577164207672426574638345121648036"
-                   "69334456133986869450012704680852639785739151463455742734197"
-                   "2391976756821");
-  primes.push_back("58021664585639791181184025950440248398226136069516938232493"
-                   "68750582247183653682429882273371034225069773999682593823264"
-                   "19406708576245141031259861340509976971601273015479957884681"
-                   "37887651823707102007839");
-  primes.push_back("7455602825647884208337395736200454918783366342657");
-
-  // composites with small factors
-  composites.push_back("2530121");
-  
-  // composites with large factors
-  // from http://web.mit.edu/kenta/www/three/prime/composites.html.gz
-  /*composites.push_back("241999944999997");
-  composites.push_back("9247999997483999999981");
-  composites.push_back("9247999999996395999999999973");
-  composites.push_back("2738000000000000184999999999998407");
-  composites.push_back("172979999999999999711699999999999999867");
-  composites.push_back("3920000000000000000000000000000071399999999999999999999"
-                       "999999994969");
-  composites.push_back("6479999999999999999999999999999999999995877999999999999"
-                       "9999999999999999999999947559");
-  composites.push_back("1458000000000000000000000000000000000000000000000000000"
-                       "0000000006749999999999999999999999999999999999999999999"
-                       "99999999999999998367");
-  composites.push_back("1095200000000000000000000000000000000000000000000000000"
-                       "0000000000000000000000000000000003329999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "99999999999433");
-  composites.push_back("1999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999772999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999960081");
-  composites.push_back("7937999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999960"
-                       "7509999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999222"
-                       "63");
-  composites.push_back("6727999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999996154599999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "999999999999999999999999999999999999999999447193");
-  composites.push_back("4231999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999977321999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "999999999999999999999999999999999921103");
-  composites.push_back("1729799999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999383409999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "9999999999999999999999999999999999999999999999999999999"
-                       "999999610793");*/
-
-  // from http://de.wikibooks.org/wiki/Pseudoprimzahlen:_Tabelle_Carmichael-Zahlen
-  carmichaels.push_back("294409");
-  carmichaels.push_back("825265"); // 5*7*17*19*73
-  carmichaels.push_back("1152271");
-  carmichaels.push_back("23382529");
-  carmichaels.push_back("62756641");
-  carmichaels.push_back("114910489");
-  carmichaels.push_back("1407548341");
-  carmichaels.push_back("11346205609");
-  carmichaels.push_back("173032371289");
-  carmichaels.push_back("2199733160881");
-  carmichaels.push_back("84154807001953");
-  carmichaels.push_back("973694665856161");
-  carmichaels.push_back("9746347772161"); // 7*11*13*17*19*31*37*41*641
-}
-
-
-// primality tests
-BOOST_AUTO_TEST_CASE_TEMPLATE(prime_is_divisible1, mp_int_type, mp_int_types)
-{
-  using namespace boost::mp_math;
-
-  fixture<mp_int_type> f;
-  typedef typename std::vector<mp_int_type>::const_iterator iter;
-
-  for (iter i = f.primes.begin(); i != f.primes.end(); ++i)
-    BOOST_CHECK_EQUAL(is_prime(*i, primality_division_test()), true);
-  
-  for (iter i = f.composites.begin(); i != f.composites.end(); ++i)
-    BOOST_CHECK_EQUAL(is_prime(*i, primality_division_test()), false);
-}
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(prime_fermat_test1, mp_int_type, mp_int_types)
-{
-  using namespace boost;
-
-  mp_math::primality_fermat_test<
-    mp_math::uniform_mp_int<mp_int_type>
-  > fermat_test(1);
-
-  mt19937 rng;
-
-  fixture<mp_int_type> f;
-  typedef typename std::vector<mp_int_type>::const_iterator iter;
-
-  for (iter i = f.primes.begin(); i != f.primes.end(); ++i)
-    BOOST_CHECK_EQUAL(boost::mp_math::is_prime(*i, bind(fermat_test, rng, _1)), true);
-  
-  for (iter i = f.composites.begin(); i != f.composites.end(); ++i)
-    BOOST_CHECK_EQUAL(boost::mp_math::is_prime(*i, bind(fermat_test, rng, _1)), false);
-}
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(prime_miller_rabin_test1, mp_int_type, mp_int_types)
-{
-  using namespace boost;
-
-  mp_math::primality_miller_rabin_test<
-    mp_math::uniform_mp_int<mp_int_type>
-  > mr_test;
-
-  mt19937 rng;
-
-  fixture<mp_int_type> f;
-  typedef typename std::vector<mp_int_type>::const_iterator iter;
-  for (iter i = f.primes.begin(); i != f.primes.end(); ++i)
-    BOOST_CHECK_EQUAL(mp_math::is_prime(*i, bind(mr_test, rng, _1)), true);
-  
-  for (iter i = f.composites.begin(); i != f.composites.end(); ++i)
-    BOOST_CHECK_EQUAL(mp_math::is_prime(*i, bind(mr_test, rng, _1)), false);
-  
-  for (iter i = f.carmichaels.begin(); i != f.carmichaels.end(); ++i)
-    BOOST_CHECK_EQUAL(mp_math::is_prime(*i, bind(mr_test, rng, _1)), false);
-}
-
-
-// prime generation
-template<class Engine, class Distribution>
-struct tester
-{
-  boost::mp_math::primality_division_test                   test1;
-  boost::mp_math::primality_miller_rabin_test<Distribution> test2;
-  Engine rng;
-
-  explicit tester(const Engine& e) : rng(e) {}
-
-  template<class A, class T>
-  bool operator()(const boost::mp_math::mp_int<A,T>& p)
-  {
-    return test1(p) && test2(rng, p);
-  }
-};
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(generate_safe_prime_128bits, mp_int_type, mp_int_types)
-{
-  typedef tester<boost::mt19937, boost::mp_math::uniform_mp_int<mp_int_type> > tester_type;
-  typedef boost::mp_math::uniform_mp_int_bits<mp_int_type> distribution_type;
-  
-  boost::mt19937 rng;
-
-  boost::mp_math::safe_prime_generator<tester_type, distribution_type>
-    generator(128U, tester_type(rng));
-
-  const mp_int_type safe_prime = generator(rng);
-
-  BOOST_CHECK_EQUAL(safe_prime.precision(), 128U);
-}
Deleted: sandbox/mp_math/libs/mp_math/test/random.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/random.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,79 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int1, mp_int_type, mp_int_types)
-{
-  const mp_int_type min(0), max(128);
-  boost::mp_math::uniform_mp_int<mp_int_type> g(min, max);
-  boost::mt19937 e;
-  for (int i = 0; i < 128; ++i)
-  {
-    const mp_int_type x = g(e);
-    BOOST_REQUIRE_GE(x, min);
-    BOOST_REQUIRE_LE(x, max);
-  }
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int2, mp_int_type, mp_int_types)
-{
-  const mp_int_type min(11), max("26546549");
-  boost::mp_math::uniform_mp_int<mp_int_type> g(min, max);
-  boost::mt19937 e;
-  for (int i = 0; i < 1000; ++i)
-  {
-    const mp_int_type x = g(e);
-    BOOST_REQUIRE_GE(x, min);
-    BOOST_REQUIRE_LE(x, max);
-  }
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits1, mp_int_type, mp_int_types)
-{
-  BOOST_CHECK_EQUAL(
-      boost::mp_math::uniform_mp_int_bits<mp_int_type>::has_fixed_range, false);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits2, mp_int_type, mp_int_types)
-{
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(512);
-  boost::mt19937 e;
-  const mp_int_type x = g(e);
-  BOOST_CHECK_EQUAL(x.precision(), 512U);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits3, mp_int_type, mp_int_types)
-{
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(71);
-  boost::mt19937 e;
-  const mp_int_type x = g(e);
-  BOOST_CHECK_EQUAL(x.precision(), 71U);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits4, mp_int_type, mp_int_types)
-{
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(1001);
-  boost::mt19937 e;
-  const mp_int_type x = g(e);
-  BOOST_CHECK_EQUAL(x.precision(), 1001U);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits5, mp_int_type, mp_int_types)
-{
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(8);
-  BOOST_CHECK_EQUAL(g.min(), 128U);
-  BOOST_CHECK_EQUAL(g.max(), 255U);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits6, mp_int_type, mp_int_types)
-{
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(11);
-  BOOST_CHECK_EQUAL(g.min(), 1024U);
-  BOOST_CHECK_EQUAL(g.max(), 2047U);
-}
-
-
Deleted: sandbox/mp_math/libs/mp_math/test/root.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/root.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,43 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("279841");
-  const mp_int_type y = sqrt(x);
-  BOOST_CHECK_EQUAL(y, "529");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("78310985281");
-  const mp_int_type y = sqrt(x);
-  BOOST_CHECK_EQUAL(y, "279841");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("85766121");
-  const mp_int_type y = nth_root(x, 3);
-  BOOST_CHECK_EQUAL(y, "441");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x(
-    "0x2b93d251afa09c5481f4522279f7c19ca08124199621dfd18342a16c7303b31ccea8176b"
-    "d4a7a9bf991e30d8bde1e08356a728b9f5729c35d29884050101341228c5df3f98354d42b7"
-    "a0d7fdfbe8d5270b09ee89ba1eeab61be67eb4471d92fdffa88d1ca494ed3eec58a34ff958"
-    "b518a588584a2505c9c2b19ce1eb21cba36c7a5297cb6e532884e89451f4406b993582f3cd"
-    "b75cab98f8c4c6f3837977db2a594dfa16943062187ca95babc9da78bdd73ca7233eefc047"
-    "8d882e0d4f09a5083a31b801964343d47b6ce9e937df8c44a9a02bac5101da1823373e663c"
-    "1329ece1eb89fc178355660fe1c92c7d8ff11524702fad6e2255447946442356b00810101");
-  const mp_int_type y = nth_root(x, mp_int_type("257"));
-  BOOST_CHECK_EQUAL(y, "257");
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/serialization.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/serialization.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,28 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <sstream>
-#include <boost/archive/text_oarchive.hpp>
-#include <boost/archive/text_iarchive.hpp>
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-#include <boost/mp_math/mp_int_serialization.hpp>
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(test_serialization1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0x123456789abcdef257");
-  mp_int_type y;
-
-  std::stringstream s;
-  
-  boost::archive::text_oarchive oa(s);
-  oa << x;
-  
-  boost::archive::text_iarchive ia(s);
-  ia >> y;
-
-  BOOST_CHECK_EQUAL(x, y);
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/shift.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/shift.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,49 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("246556567891512374789511237456594795648912323213860000007849");
-  x <<= 2;
-  const mp_int_type y(
-      "986226271566049499158044949826379182595649292855440000031396");
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift2, mp_int_type, mp_int_types)
-{
-  mp_int_type x("246556567891512374789511237456594795648912323213860000007849");
-  x <<= 99;
-  const mp_int_type y(
-      "156273790638943927367154966864556037925514287264587565911690950563681284"
-      "261029491729498112");
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("246556567891512374789511237456594795648912323213860000007849");
-  x >>= 17;
-  mp_int_type y(
-      "1881077330715273855510797404911764493171022973738555908");
-  BOOST_CHECK_EQUAL(x, y);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift2, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0");
-  x >>= 17;
-  BOOST_CHECK_EQUAL(x, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift3, mp_int_type, mp_int_types)
-{
-  mp_int_type x("14222200");
-  x >>= 8;
-  BOOST_CHECK_EQUAL(x, "55555");
-}
Deleted: sandbox/mp_math/libs/mp_math/test/sqr.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/sqr.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,202 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("123456789");
-  const mp_int_type y = x * x;
-  BOOST_CHECK_EQUAL(y, "15241578750190521");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("25");
-  const mp_int_type y = x * x;
-  BOOST_CHECK_EQUAL(y, "625");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("300");
-  const mp_int_type y = x * x;
-  const mp_int_type z("90000");
-  BOOST_CHECK_EQUAL(y, z);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("2228218");
-  const mp_int_type y = x * x;
-  BOOST_CHECK_EQUAL(y, "4964955455524");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("999998000001");
-  const mp_int_type y = x * x;
-  const mp_int_type z("999996000005999996000001");
-  BOOST_CHECK_EQUAL(y, z);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr6, mp_int_type, mp_int_types)
-{
-  // this tests toom squaring and karatsuba squaring for 8, 16 and 32 bit
-  // digit_type
-  const mp_int_type x(
-    "0x5004a2519b00503006126bb044af8930502951243994250616123426085258764a856336"
-    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
-    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
-    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
-    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
-    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
-    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
-    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
-    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "9464098710748f27372836255355251ae330455ffaa58681216515eeff0330517814dd7487"
-    "34682745159208158750835203309620570274592666481348052963762094268695162425"
-    "18850320172906096781969070339129822281355221058882087466637338881223511228"
-    "63144016884857141834687376804878770495858121023810198067988560350169566260"
-    "5944107067ac5771a1662497b8b93cfe57291387313365462656674328aaaaaf9067287310"
-    "ea6863ec68378827380764363420573208101547102942bf05465397209378421688020320"
-    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
-    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
-    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
-    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
-    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
-    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
-    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
-    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "18850320172906096781969070339129822281355221058882087466637338881223511228"
-    "63144016884857141834687376804878770495858121023810198067988560350169566260"
-    "59441070673981642057711662497893572913873133654626566743289483229067287310"
-    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
-    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
-    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
-    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
-    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
-    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
-    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
-    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
-    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
-    "16863866837882738076436342057320810154710294295605465397209378421688020320"
-    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
-    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
-    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
-    "f84c878148cc7020890befffaa4506cebbef9a3f7c67178f2");
-
-  const mp_int_type y = x * x;
-  
-  const mp_int_type z(
-    "0x1902e5887a586c505ed49b0ef0db72e959da458fbfe7f7f1738b9da657ebc6b4f3eeda8f3"
-    "45f86a9439fb0a314af8a6d54e9002f6b9778bc217f31e1c2af869b890e50b105f2a6c8f6d4"
-    "d9f7ce008697c1ef9f6b1b3d58089517db9a209f0951f3843c9f5dd81da8082a4e79771c9fe"
-    "c7a967defed9c1d7229a9e6a78226389976caba3a3419a68d1376d7b67eb20136d1c47b480f"
-    "446428ec425ddeb779492e6e40c2318633e6783066d046486a419676066b0fcacf9c9da24ef"
-    "bb6ae2a639af668b9c732ed3ba74f4e73f28cffbc415d3a086decd149e1dd1f4265ede8666c"
-    "2963f2ef61b190fb094730110586e73afc7656f6e8e3188767ee075b98cceff2de2959b3c51"
-    "eb0cd03b5d277846536a3d5fa2baaff03d2ff90785581d170ad264d845d6e3522921afae94f"
-    "13eda75f99694a961beff0495830b53f1b282d4fc5fa665a402cc253d71aa411a16c7cf3825"
-    "6ff351d8e7f6c476d01ca3d39947a71703488cc0c85f7ce9ae7521e22ce4cb99e14dcaaaa69"
-    "d8f1390f8c8275c899e8ec14b2fb9100bd8c4e44bc2d531f049a31583e11d73070a815efad7"
-    "0e28caa18cd89a7e4bb1a17a961ae011511fe3ef495ae1c8e44653a73c6434ee77b242f7d9a"
-    "462613b92a5809da93c6d687222abf79b09a718fdf7787c7aff48b1e529da53898273abab56"
-    "00d67781a15c06e3741c79948cecbd3cd24414d40b0087844c9271bae8d470571a4e87309f9"
-    "ba510ef32c2def3e29f0f342f9a6f50fb00ee16159d0de74dfc85baf97c861a1ae63aca48b7"
-    "b2c3830ae11aa818f6da2a3cc74b5c2d0c635c9dd6d9fc5b9d35e46f8a53b93724e112a140e"
-    "cdee10eeaefa830d4678d06e1f3426abba1c9f76415ed479bee5160a8a5fcf9d5803552ca5a"
-    "810ea290fab7df557d9687af8782413fd04bf41454eae63c470ab231186c7aaf88b7e8de2ef"
-    "5e04cc8f9738f42ab5c8f993d13f8051765d4369709e54d24ec5e14138d1fe7ac81b311eb42"
-    "b0c35deebd10a3f5a60535870eeebd8662d11844ae4b39507232787d04e3c214e5b73b7b280"
-    "3395fd5a5c0c373cf2dbe76a2972e3bbaf6ff166c8134ad831ed000a4c4d5e615b74d697f8c"
-    "2be9fd8326e1aa352bcdb5ba460a0d34f750de03701e98ea43969c5b3b9de3e7bb562a320de"
-    "b10d1c8671b523611ffe7c2da353a1d3b86cf1c4d34d3347d02337e0656b9b39c8fe1f961f3"
-    "b5919df4469e895d3869590c042d6f881d9781c413613f6c5a22fd9cd24c906582e143b04b7"
-    "a09aefeed701bbf92687e995cc56578784b96c5a7a648d5c166c3b7c9a0c2df9c0166bf00b8"
-    "55c1f6e236ac96484638733eb9e84ccc4ccb33a49399e5057bd2d96ca51133496d5283a2085"
-    "56aa7f2b3264678f99f7cf5380bd61180230870ae35c00d272ec73d960ead550b29730a42a1"
-    "051e825890ec2283cf0de984af072a2125fd4ff692e47ef620b24a952c37ea379444061869c"
-    "aec75d2836afff972e54255daa9069f4c51f5bdb8ada41d3907fb5581dc7289d50577663616"
-    "464fc8b3f99676dd67bb93358a897feadd7a92336a0f4af44c9325fc53ba1d87f7b914e4847"
-    "462109cba84ad8498cd717c503d4c363b8ff405df44fa84bc9c8bed141c7f91954098b2ecb8"
-    "b59fc457ec86022bf6c395bb382f6a193e3387d52f3e1978af4576153fa7fb60d5b896cef43"
-    "e628045ec0577971b78e7ab1b3a9fa9ea6cc8e4a04f141e744f70fe0c800ce5dd3c748729c6"
-    "efa085877a7d9296ad489883ee966117e5db61bafbcd55284dc8d470646473761ec606357bb"
-    "fed899cd7c69e027656ef30b12e8a9e63868048bae95c7b67d26a843c94cec551ed5093542b"
-    "ff7437316a830e3c48f19491a81fb37aef5d89ee08b507b881e65fbf8dd3343e58b63ea3a2b"
-    "d465e02c5cb673e5c8cced17f5d3f9fad8307cd6c3abf9111e063fb197df4db52eac6092229"
-    "64e157a1b172004c1817162e688b55245c598cbdc5fd9f74db4911484feb5a390c27d0efeb3"
-    "a8bc21ff9dec02808fad5f882580facb5324a4f3a21b75c23cc311be7afe003895351fd07fa"
-    "c037d67718cc11aa5942837ee9048882e2564b625689ee3bd9487c4ec43f562508bbcd0671c"
-    "18434ca6ae92725d905210060d80e2524eb38ed600aeaf486d7b2b690a9f567d86444c35fd9"
-    "8bdf6b665dbf7e43557b281a792400274ca21fec996e5e6142780f8a7adcddbae4a2e9474a1"
-    "38931c19f96368bb2bc40aace10616bef5c975feca3c7f3e1122b41a39df9202a7a6405c647"
-    "d032f8c692e1e89838fc1dacb291d9e2d8ee90d88b6f598947d085289f9c4247548628a9e3f"
-    "6ea8ac5980e290749e39a9417b20f39dbbbed20209584a741747771020b2287007b37d17779"
-    "21303e3b7a9ee49db7b14dda965d9241548387e610758507c946eee0c49b67efaeedbe64e6b"
-    "114e3b4ddff5edd2050322d8298ae66388b1fb64435fa064364f41f129ce83a0cc563f8796e"
-    "1dd09be1a03bc5567caed9326df5714f6cf88ca247826ce93add7d17332d6870b1d0613a4fd"
-    "fd4c7d8185db385687d735d0bf22e87a045ad2a397db9c4ee0908a047f087a0fb49a27f65d0"
-    "e6e6ef0ef506d1411788ac027c29be3e93253e61ee76f951d3ce721c825bf5b883471f91f68"
-    "a37ca36d198adf93063e220a16b94e9aaca5c4691590ff2a696c1663b5ca69e3f3a11409cf9"
-    "727cf409a1f87a0a5e4805008c7488b7c9e23c42e33bfb0fab7e4f59e482ec50aa1b4d64996"
-    "4e7232c26acb75217ef1b200ebde38169d6ce7aeb2746aa29249d61af1e168a256e1848cb33"
-    "873c5457afd48194f77c786bcd8ce842605117c66b003abc05fb9b74869cc832c88df506e0e"
-    "79ebb0436443fb467269e42840a0486b3f35acca04b000876b9bf2c6a7f09ec6ff7ce198f8f"
-    "584e3e22b4a2e8279c1a043899fe0d2e5180ec1738b1cb23032374069b33a471fdd8e5f5be2"
-    "a4ff945697d9dc540878bc6a6704cb8b866914fbce94021bc2e6743dc7e160a8780912a90ff"
-    "732a81b060d97f777713881e9214474e1196ff13f07361385e19e5c5ffa24aa6b00f473cfd3"
-    "e71c42ed1c31eb9b5ec91635bf8c77e7aff696009da2163c7e1621bea9b30479a8e10906d3e"
-    "1ba06f3e64e776a62164238d18cebaf9684427fe8e5930fbd8892851c8cfa4e2c729558b909"
-    "a665f57919565d834fbebb0d64ba1721b083ca6fe55dab07546df6c1e60ab41f4836f64c27c"
-    "4f715764a472f01d947cbf8d3cd8e011129edecca4334b095edf3d37e27b7c30900eac3702c"
-    "3e09179a53462cda8dece1ecdda223d6cc32c9363f5123982b071367609b01bcfccfd4a0120"
-    "23b4dfacb5993d04434aac5a95e0192770206b4a3bdcb3a75013daedf68ed40cfca0e4bd802"
-    "4906ff8cc816d7bf556898545965b846f2b1dda3216d17d236e4ba5d2427ee799696c60297a"
-    "c720adacd63da47e2e3aeeb99c136e1b5de50cfe523823a87f94b1b4b8f6be2162ea40441dc"
-    "2f9af466c7642d0ef34429a986ae96e962e4a2cd9c12a41d71398ac03c990a15364c38a3bd9"
-    "af6605d1c9b807babd942bd66d2f6e4ccfaa2131354cf78aa09ffcec32258c9c3b53fbcc755"
-    "5bfeb11152332bef6420b08528d43f6865c5d53ade958d3b58dfe2f34391ea8d2d8fb35c32e"
-    "6a8f569d6cc9d456ff5b78fae829cc171f95f5389373a0dee3565a428237ec4e68b6e6efc3c"
-    "a5bd220699eb80bd498d2ea90d43b901881567e9c18898caea36334008b4a08e3e6cbda4e17"
-    "db7f5187d6f3284eca8c1a03faa28a2a23b27d560690642db0ea485e4be8c1c8b4441234f39"
-    "f31a6c9fe5cc7e50c777acd0746bbfb7399ee262a36a54a8ee25c334e503dcd6e00f7e9ac3a"
-    "80495156af9f9aaac62fe02c4c2373cc03d32c4be1b077d97f6167413661403a38b0df999d0"
-    "24701c5f17e5e5701cf9b9eccd9417af7637139473aab760b7ecafa863e7f049a6b98be603b"
-    "6bf0132b211b80123246c657cfdbb4b5dff7be43c364be943b5cdf03db86a6cd56a96187cb4"
-    "5b6acbf37383ca3fe7c9cc3b65a57c9ea6f4d686222801ce6d1463bb92ff5f2599619388660"
-    "99365474bbcba180f940ede8a02777bcf55d3549cfcd819aca8f055074d81af6472c3c9beaa"
-    "67b8f89066f1e02d1502aa13a4c872b9b1dc4e2a2b6d58eaa869c9e62a9f7e01efc2c87eb6a"
-    "9bc80d29c9c48a10edec1e5a799aeff2a580736525357ae40d677aa4fb6533c15b4afed1fde"
-    "f6e0e4c0a548c5be8751da42ffd8b409dcd77487437a16d769e232c95d0b780a46395ea0023"
-    "6cf19b1fafbda1c8c75aee09e06bcf0383816d0f9c364baa95a09fe2e2894693fc66166a16a"
-    "e152a24dfc5ca3646ce2cafe40a7ffbeb561ae4db74dc7ff045e85a9126a25152f0342d1f87"
-    "3ecb21bc411771eb7589f3df1be59fa97156ca5d3c93a7df10b90c525e25df36e7947614770"
-    "1f9ab2a368b179428ad005c7af2fb500fac032f0f1ff3f9694412d3c164fcc444075135fd9d"
-    "a58e2fab3ebf7b5fcaaf20256052e64b59c92db1cd3c2e0c2df41b06a540a754d349a284fa1"
-    "45a13795674240616f433d174fc67dda102db9e9e3bf23d4a8816ad130bca720ef707606206"
-    "7ab36f2061261981528dfdcaa3e21787f164e6ba318bb018f3974540ae8559790284852d31a"
-    "d8c77066f8620345f099606eced7f93e465b3a31a7b196b24e76a44d7ec6f597fb4a3a9a1a8"
-    "ba5611156e20c294b90cdde30166ee59c0c80936e992e5f3185c6396756194a7c8f1971a0b8"
-    "27477b2060dfe721fd0c2e725e25cc99d1227c6db9d5452dd70dbb0c2db67187a4e93c9bcfa"
-    "0049fad1289773ea6ffdcf6e6680a44cd577223b8f86eae3568ee5cd0b2f45a17f7b6d7531c"
-    "925e2c22b4004fd8e12ab70e2392e190dab556c0227b660cc226f5db558668bcb426a8153bc"
-    "32af18b8c7dbe3c2ad210300582f823fc5fd7aadc653c2c0b59b3e5362b158793485e56c7c4"
-    "c4");
-  
-  BOOST_CHECK_EQUAL(y, z);
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/stream_io.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/stream_io.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,124 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1024");
-  std::ostringstream os;
-  os << x;
-  BOOST_CHECK_EQUAL(os.str(), "1024");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output_w_showbase, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1024");
-  std::ostringstream os;
-  os.setf(std::ios_base::showbase);
-  os << x;
-  BOOST_CHECK_EQUAL(os.str(), "1024");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1024");
-  std::ostringstream os;
-  os.setf(std::ios_base::oct, std::ios_base::basefield);
-  os << x;
-  BOOST_CHECK_EQUAL(os.str(), "2000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output_w_showbase, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1024");
-  std::ostringstream os;
-  os.setf(std::ios_base::oct, std::ios_base::basefield);
-  os.setf(std::ios_base::showbase);
-  os << x;
-  BOOST_CHECK_EQUAL(os.str(), "02000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1024");
-  std::ostringstream os;
-  os.setf(std::ios_base::hex, std::ios_base::basefield);
-  os << x;
-  BOOST_CHECK_EQUAL(os.str(), "400");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1024");
-  std::ostringstream os;
-  os.setf(std::ios_base::hex, std::ios_base::basefield);
-  os.setf(std::ios_base::showbase);
-  os << x;
-  BOOST_CHECK_EQUAL(os.str(), "0x400");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_uppercase, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0xabcdef0");
-  std::ostringstream os;
-  os.setf(std::ios_base::hex, std::ios_base::basefield);
-  os.setf(std::ios_base::showbase | std::ios_base::uppercase);
-  os << x;
-  BOOST_CHECK_EQUAL(os.str(), "0XABCDEF0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_showpos, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1024");
-  std::ostringstream os;
-  os.setf(std::ios_base::hex, std::ios_base::basefield);
-  os.setf(std::ios_base::showbase | std::ios_base::showpos);
-  os << x;
-  BOOST_CHECK_EQUAL(os.str(), "+0x400");
-}
-
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input1, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  std::stringstream s;
-  s << "-123456";
-  s >> x;
-  BOOST_CHECK_EQUAL(x, "-123456");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input2, mp_int_type, mp_int_types)
-{
-  mp_int_type x, y;
-  std::stringstream s;
-  s << "-123456";
-  s << " " << "987654321";
-  s >> x;
-  BOOST_CHECK_EQUAL(x, "-123456");
-  BOOST_REQUIRE(s.good());
-  s >> y;
-  BOOST_CHECK_EQUAL(y, "987654321");
-  BOOST_CHECK(s.good());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(oct_input, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  std::stringstream s;
-  s << "0123456";
-  s >> x;
-  BOOST_CHECK_EQUAL(x, "0123456");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_input, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  std::stringstream s;
-  s << "0xFFFFAB01";
-  s >> x;
-  BOOST_CHECK_EQUAL(x, "0xFFFFAB01");
-}
Deleted: sandbox/mp_math/libs/mp_math/test/string_ops.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/string_ops.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,151 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0xabcdef123456789");
-  const std::string s =
-    x.template to_string<std::string>(std::ios::hex | std::ios::showbase);
-  BOOST_CHECK_EQUAL(s, "0xabcdef123456789");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("12345678901234567890");
-  const std::string s = x.template to_string<std::string>();
-  BOOST_CHECK_EQUAL(s, "12345678901234567890");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0xabcdef123456789");
-  const std::string s = x.template to_string<std::string>(
-      std::ios::hex | std::ios::showbase | std::ios::uppercase);
-  BOOST_CHECK_EQUAL(s, "0XABCDEF123456789");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("76484675");
-  const std::string s = x.template to_string<std::string>(std::ios::oct);
-  BOOST_CHECK_EQUAL(s, "443610103");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1024");
-  const std::string s = x.template to_string<std::string>(std::ios::oct);
-  BOOST_CHECK_EQUAL(s, "2000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string6, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const std::string s =
-    x.template to_string<std::string>(
-        std::ios_base::dec | std::ios_base::showbase | std::ios_base::showpos);
-  BOOST_CHECK_EQUAL(s, "+0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string7, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0");
-  const std::string s =
-    x.template to_string<std::string>(
-        std::ios_base::oct | std::ios_base::showbase | std::ios_base::showpos);
-  BOOST_CHECK_EQUAL(s, "+0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string8, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-0");
-  const std::string s =
-    x.template to_string<std::string>(
-        std::ios_base::oct | std::ios_base::showbase | std::ios_base::showpos);
-  BOOST_CHECK_EQUAL(s, "+0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string9, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-1");
-  const std::string s =
-    x.template to_string<std::string>(
-        std::ios_base::hex | std::ios_base::showbase | std::ios_base::showpos);
-  BOOST_CHECK_EQUAL(s, "-0x1");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string10, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x95a6801ce5292b9a8410e1a59dd29967");
-  const std::string s =
-    x.template to_string<std::string>(std::ios_base::hex);
-  BOOST_CHECK_EQUAL(s, "95a6801ce5292b9a8410e1a59dd29967");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string11, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0x12471fa56d6");
-  const std::string s = x.template to_string<std::string>();
-  BOOST_CHECK_EQUAL(s, "1256042682070");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign1, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x = "269513460";
-  BOOST_CHECK_EQUAL(x, "269513460");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign2, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x = "0xabcdef123456789";
-  BOOST_CHECK_EQUAL(x, "0xabcdef123456789");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign3, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x = "012345676543210000001";
-  BOOST_CHECK_EQUAL(x, "012345676543210000001");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign4, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x = "0";
-  BOOST_CHECK_EQUAL(!x, true);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign5, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0xabcedf03030303");
-  x = "-012345676543210000001";
-  BOOST_CHECK_EQUAL(x, "-012345676543210000001");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(assign1, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x.assign("123456789876543210000001", std::ios::dec);
-  BOOST_CHECK_EQUAL(x, "123456789876543210000001");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(assign2, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x.assign("abcdefabcdef1234567890", std::ios::hex);
-  BOOST_CHECK_EQUAL(x, "0xabcdefabcdef1234567890");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(assign3, mp_int_type, mp_int_types)
-{
-  mp_int_type x("-564897123123456456789789789897");
-  x.assign("1234567000000000000000000000000077", std::ios::oct);
-  BOOST_CHECK_EQUAL(x, "01234567000000000000000000000000077");
-}
Deleted: sandbox/mp_math/libs/mp_math/test/sub.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/sub.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,132 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub1, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("123456");
-  const mp_int_type y("987777");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "-864321");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub2, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("955588990000001");
-  const mp_int_type y("9801");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "955588989990200");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub3, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("99999991");
-  const mp_int_type y("987654321000123456789");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "-987654321000023456798");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub4, mp_int_type, mp_int_types)
-{
-  const mp_int_type x(
-    "49144609407766890328547643707523663509662747376486271392344480900673178645"
-    "33198519112197059826509662943577383543858946941049753393431035706592040680"
-    "43848484065292542884106550381079282660840705126574766636237650938379223350"
-    "073087806800887586256085275775217219429527000017403144");
-  const mp_int_type y(
-    "49144609407766890328547643707523663509662747376486271392344480900673178645"
-    "33198519112197059826509662943577383543858946941049753393431035706592040680"
-    "43848484065292542884106550381079282660840705126574766636237650938379223350"
-    "073087806800887586256085275775217219429527000017403144");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x(
-    "21665907282124706187656074325458499695895652068822763794228458103499408841");
-  const mp_int_type y(
-    "173087806800887586256085275775299999999889978789789");
-  const mp_int_type z = x - y;
-  const mp_int_type w(
-    "21665907282124706187655901237651698808309395983546988494228458213520619052");
-  BOOST_CHECK_EQUAL(z, w);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub6, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("0xff");
-  const mp_int_type y("0x1000ff0000000");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "-0x1000fefffff01");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub7, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("1000000");
-  const mp_int_type y("-1000000");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "2000000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub8, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-1000000");
-  const mp_int_type y("1000000");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "-2000000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub9, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-123456789");
-  const mp_int_type y("-123456789");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub10, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-1000000");
-  const mp_int_type y("-2500000");
-  const mp_int_type z = x - y;
-  BOOST_CHECK_EQUAL(z, "1500000");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(decrement1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0");
-  for (int i = 0; i < 10; ++i)
-    --x;
-  BOOST_CHECK_EQUAL(x, "-10");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(decrement2, mp_int_type, mp_int_types)
-{
-  mp_int_type x("4");
-  for (int i = 0; i < 10; ++i)
-    --x;
-  BOOST_CHECK_EQUAL(x, "-6");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(decrement3, mp_int_type, mp_int_types)
-{
-  mp_int_type x("-120");
-  for (int i = 0; i < 10; ++i)
-    --x;
-  BOOST_CHECK_EQUAL(x, "-130");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(decrement4, mp_int_type, mp_int_types)
-{
-  mp_int_type x("130");
-  for (int i = 0; i < 10; ++i)
-    --x;
-  BOOST_CHECK_EQUAL(x, "120");
-}
-
Deleted: sandbox/mp_math/libs/mp_math/test/to_integral.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/to_integral.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,136 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <boost/test/unit_test.hpp>
-#include "prerequisite.hpp"
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_char1, mp_int_type, mp_int_types)
-{
-  mp_int_type x("123");
-  char z = x.template to_integral<char>();
-  BOOST_CHECK_EQUAL(z, 123);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_char2, mp_int_type, mp_int_types)
-{
-  mp_int_type x("-123");
-  char z = x.template to_integral<char>();
-  BOOST_CHECK_EQUAL(z, -123);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_char_min, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<char>::min());
-  char z = x.template to_integral<char>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<char>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_char_max, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<char>::max());
-  int z = x.template to_integral<char>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<char>::max());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_min, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<unsigned char>::min());
-  unsigned char z = x.template to_integral<unsigned char>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned char>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_max, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<unsigned char>::max());
-  unsigned char z = x.template to_integral<unsigned char>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned char>::max());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_int_min, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<int>::min());
-  int z = x.template to_integral<int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_int_max, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<int>::max());
-  int z = x.template to_integral<int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::max());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_min, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<unsigned int>::min());
-  unsigned int z = x.template to_integral<unsigned int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned int>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_max, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<unsigned int>::max());
-  unsigned int z = x.template to_integral<unsigned int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned int>::max());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_int_min, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<long int>::min());
-  long int z = x.template to_integral<long int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<long int>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_int_max, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<long int>::max());
-  long int z = x.template to_integral<long int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<long int>::max());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_min, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<unsigned long int>::min());
-  unsigned long int z = x.template to_integral<unsigned long int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long int>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_max, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<unsigned long int>::max());
-  unsigned long int z = x.template to_integral<unsigned long int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long int>::max());
-}
-
-#ifdef BOOST_HAS_LONG_LONG
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_long_int_min, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<long long int>::min());
-  long long int z = x.template to_integral<long long int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<long long int>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_long_int_max, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<long long int>::max());
-  long long int z = x.template to_integral<long long int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<long long int>::max());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_min, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<unsigned long long int>::min());
-  unsigned long long int z = x.template to_integral<unsigned long long int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long long int>::min());
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_max, mp_int_type, mp_int_types)
-{
-  mp_int_type x(std::numeric_limits<unsigned long long int>::max());
-  unsigned long long int z = x.template to_integral<unsigned long long int>();
-  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long long int>::max());
-}
-#endif
-
Deleted: sandbox/mp_math/libs/mp_math/test/traits.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/traits.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
+++ (empty file)
@@ -1,39 +0,0 @@
-// Copyright Kevin Sopp 2008.
-// 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)
-
-#include <vector>
-#include <boost/test/unit_test.hpp>
-#include <boost/mp_math/mp_int.hpp>
-
-BOOST_AUTO_TEST_CASE(check_digit_type_and_word_type)
-{
-  typedef boost::mp_math::mp_int<> mp_int_type;
-
-  std::vector<int> x;
-  x.push_back(std::numeric_limits<unsigned char>::digits);
-  x.push_back(std::numeric_limits<unsigned short>::digits);
-  x.push_back(std::numeric_limits<unsigned int>::digits);
-  x.push_back(std::numeric_limits<unsigned long int>::digits);
-  #ifdef BOOST_HAS_LONG_LONG
-  x.push_back(std::numeric_limits<unsigned long long int>::digits);
-  #endif
-  
-  const int word_type_digits = x.back();
-
-  std::vector<int>::const_reverse_iterator it;
-  for (it = x.rbegin(); it != x.rend(); ++it)
-  {
-    if (*it <= word_type_digits / 2)
-      break;
-  }
-
-  const int digit_type_digits = *it;
-  
-  BOOST_CHECK_EQUAL(digit_type_digits,
-                    std::numeric_limits<mp_int_type::digit_type>::digits);
-  BOOST_CHECK_EQUAL(word_type_digits,
-                    std::numeric_limits<mp_int_type::word_type>::digits);
-}
-
Added: sandbox/mp_math/libs/mp_math/test/unbounded/signed/abs.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/abs.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,15 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(abs1, int_type, IntTypes)
+{
+  const int_type x("-0x123abdddfe4983");
+  const int_type y = boost::mp_math::abs(x);
+  BOOST_CHECK_EQUAL(y, "0x123abdddfe4983");
+}
+
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/add.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/add.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/add.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/add.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,117 +6,145 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_assign1, int_type, IntTypes)
 {
-  mp_int_type x("123456");
-  mp_int_type y("987777");
-  mp_int_type z = x + y;
+  int_type x("0xffffffff");
+  const int_type y("0xffffffffffffffff");
+  x += y;
+  BOOST_CHECK_EQUAL(x, "0x100000000fffffffe");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers1, int_type, IntTypes)
+{
+  const int_type x("123456");
+  const int_type y("987777");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "1111233");
-  x = 999U;
-  y = 123456U;
-  z = x + y;
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers2, int_type, IntTypes)
+{
+  const int_type x("999");
+  const int_type y("123456");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "124455");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers3, int_type, IntTypes)
 {
-  const mp_int_type x("21474836470");
-  const mp_int_type y("1234567845600");
-  const mp_int_type z = x + y;
+  const int_type x("21474836470");
+  const int_type y("1234567845600");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "1256042682070");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers4, int_type, IntTypes)
 {
-  const mp_int_type x("0xffffffffffffffff");
-  const mp_int_type y("0xffffffffffffffff");
-  const mp_int_type z = x + y;
+  const int_type x("0xffffffffffffffff");
+  const int_type y("0xffffffffffffffff");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "0x1fffffffffffffffe");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers5, int_type, IntTypes)
 {
-  const mp_int_type x("0xffffffffffffffff");
-  const mp_int_type y("0xffffffff");
-  const mp_int_type z = x + y;
+  const int_type x("0xffffffffffffffff");
+  const int_type y("0xffffffff");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "0x100000000fffffffe");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_negative_numbers, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_negative_numbers1, int_type, IntTypes)
 {
-  const mp_int_type x("-123456");
-  const mp_int_type y("-987777");
-  const mp_int_type z = x + y;
+  const int_type x("-123456");
+  const int_type y("-987777");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "-1111233");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_negative_numbers2, int_type, IntTypes)
 {
-  const mp_int_type x("-123456");
-  const mp_int_type y("987777");
-  const mp_int_type z = x + y;
+  const int_type x("-12345678900000000");
+  const int_type y("-987777");
+  const int_type z = x + y;
+  BOOST_CHECK_EQUAL(z, "-12345678900987777");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_negative_numbers3, int_type, IntTypes)
+{
+  const int_type x("-987777");
+  const int_type y("-12345678900000000");
+  const int_type z = x + y;
+  BOOST_CHECK_EQUAL(z, "-12345678900987777");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers1, int_type, IntTypes)
+{
+  const int_type x("-123456");
+  const int_type y("987777");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "864321");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers2, int_type, IntTypes)
 {
-  const mp_int_type x("123456");
-  const mp_int_type y("-987777");
-  const mp_int_type z = x + y;
+  const int_type x("123456");
+  const int_type y("-987777");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "-864321");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers3, int_type, IntTypes)
 {
-  const mp_int_type x("-123456");
-  const mp_int_type y("123456");
-  const mp_int_type z = x + y;
+  const int_type x("-123456");
+  const int_type y("123456");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers4, int_type, IntTypes)
 {
-  const mp_int_type x("123456");
-  const mp_int_type y("-123456");
-  const mp_int_type z = x + y;
+  const int_type x("123456");
+  const int_type y("-123456");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers5, int_type, IntTypes)
 {
-  const mp_int_type x("1000");
-  const mp_int_type y("-12345678901000");
-  const mp_int_type z = x + y;
+  const int_type x("1000");
+  const int_type y("-12345678901000");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "-12345678900000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers6, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_mixed_numbers6, int_type, IntTypes)
 {
-  const mp_int_type x("-12345678901000");
-  const mp_int_type y("1000");
-  const mp_int_type z = x + y;
+  const int_type x("-12345678901000");
+  const int_type y("1000");
+  const int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "-12345678900000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_small, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_small, int_type, IntTypes)
 {
-  mp_int_type x("123456789");
-  mp_int_type y("123");
-  mp_int_type z = x + y;
+  int_type x("123456789");
+  int_type y("123");
+  int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "123456912");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_small_and_large, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_small_and_large, int_type, IntTypes)
 {
-  mp_int_type x("123");
-  mp_int_type y("123456789");
-  mp_int_type z = x + y;
+  int_type x("123");
+  int_type y("123456789");
+  int_type z = x + y;
   BOOST_CHECK_EQUAL(z, "123456912");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_large, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_large, int_type, IntTypes)
 {
-  mp_int_type x(
+  int_type x(
     "76563204409879018101322737668344063995824904757312285775560614771886933079"
     "77822556905976720912850551355328340715074887289899094852653102687850101285"
     "85715275531977696497398396067715769512450915961775500023723324150851793075"
@@ -131,8 +159,8 @@
     "33198519112197059826509662943577383543858946941049753393431035706592040680"
     "43848484065292542884106550381079282660840705126574766636237650938379223350"
     "073087806800887586256085275775217219429527000017403144");
-  
-  mp_int_type y(
+
+  int_type y(
     "29156720459736055974643337783563754269574952607968485689453462316428566668"
     "95504701770860331979649536167161534866285341319360225416010322271645564229"
     "97610536562445338176729838019564690253931232562709745122032537539983616770"
@@ -156,7 +184,7 @@
     "97887027262726591236620461428328000537452828616386217063092509908555188454"
     "27278763741671312528892659532960085933913140197210561287118971031419725940"
     "702202830556069344716729071140147820999566475298895832");
-  mp_int_type z = x + y;
+  int_type z = x + y;
   BOOST_CHECK_EQUAL(z,
     "29156720459736055974643337783563754269574952607968485689453462316428566668"
     "95504701770860331979649536167161534866285341319360225416010322271645564229"
@@ -183,33 +211,33 @@
     "775290637356956930972814346915365040429093475316298976");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(increment1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment1, int_type, IntTypes)
 {
-  mp_int_type x("0");
+  int_type x("0");
   for (int i = 0; i < 10; ++i)
     ++x;
   BOOST_CHECK_EQUAL(x, "10");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(increment2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment2, int_type, IntTypes)
 {
-  mp_int_type x("-4");
+  int_type x("-4");
   for (int i = 0; i < 10; ++i)
     ++x;
   BOOST_CHECK_EQUAL(x, "6");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(increment3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment3, int_type, IntTypes)
 {
-  mp_int_type x("-130");
+  int_type x("-130");
   for (int i = 0; i < 10; ++i)
     ++x;
   BOOST_CHECK_EQUAL(x, "-120");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(increment4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment4, int_type, IntTypes)
 {
-  mp_int_type x("120");
+  int_type x("120");
   for (int i = 0; i < 10; ++i)
     ++x;
   BOOST_CHECK_EQUAL(x, "130");
Added: sandbox/mp_math/libs/mp_math/test/unbounded/signed/assign.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/assign.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,120 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign_zero, int_type, IntTypes)
+{
+  int_type x;
+  x = "0";
+  BOOST_CHECK_EQUAL(!x, true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign_dec1, int_type, IntTypes)
+{
+  int_type x;
+  x = "269513460000009900000000";
+  BOOST_CHECK_EQUAL(x, "269513460000009900000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign_dec2, int_type, IntTypes)
+{
+  int_type x;
+  x = "-269513460000009900000000";
+  BOOST_CHECK_EQUAL(x, "-269513460000009900000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign_oct1, int_type, IntTypes)
+{
+  int_type x;
+  x = "012345676543210000001";
+  BOOST_CHECK_EQUAL(x, "012345676543210000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign_oct2, int_type, IntTypes)
+{
+  int_type x;
+  x = "-012345676543210000001";
+  BOOST_CHECK_EQUAL(x, "-012345676543210000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign_hex1, int_type, IntTypes)
+{
+  int_type x;
+  x = "0xabcdef123456789000000000005000000000000007ffffff";
+  BOOST_CHECK_EQUAL(x, "0xabcdef123456789000000000005000000000000007ffffff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign_hex2, int_type, IntTypes)
+{
+  int_type x;
+  x = "-0xabcdef123456789000000000005000000000000007ffffff";
+  BOOST_CHECK_EQUAL(x, "-0xabcdef123456789000000000005000000000000007ffffff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign_hex3, int_type, IntTypes)
+{
+  int_type x;
+  x = "-0xABCDEF00000123456798EEEEEEEEEE";
+  BOOST_CHECK_EQUAL(x, "-0xABCDEF00000123456798EEEEEEEEEE");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign_hex4, int_type, IntTypes)
+{
+  int_type x;
+  x = "-0Xabcdef00000123456798eeeeeeeeee";
+  BOOST_CHECK_EQUAL(x, "-0Xabcdef00000123456798eeeeeeeeee");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign1, int_type, IntTypes)
+{
+  int_type x("-0x1");
+  x = "0123456765432100000000000000000000001";
+  BOOST_CHECK_EQUAL(x, "0123456765432100000000000000000000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign2, int_type, IntTypes)
+{
+  int_type x("-0xabcedf0303030300000000000000");
+  x = "01";
+  BOOST_CHECK_EQUAL(x, "01");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign3, int_type, IntTypes)
+{
+  int_type x("0xabcedf0303030300000000000000");
+  x = "-500";
+  BOOST_CHECK_EQUAL(x, "-500");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign4, int_type, IntTypes)
+{
+  int_type x("0x0");
+  x = "-0x500aaaaaaaaaaaa000000";
+  BOOST_CHECK_EQUAL(x, "-0x500aaaaaaaaaaaa000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(assign1, int_type, IntTypes)
+{
+  int_type x;
+  x.assign("123456789876543210000001", std::ios::dec);
+  BOOST_CHECK_EQUAL(x, "123456789876543210000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(assign2, int_type, IntTypes)
+{
+  int_type x;
+  x.assign("abcdefabcdef1234567890", std::ios::hex);
+  BOOST_CHECK_EQUAL(x, "0xabcdefabcdef1234567890");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(assign3, int_type, IntTypes)
+{
+  int_type x("-564897123123456456789789789897");
+  x.assign("1234567000000000000000000000000077", std::ios::oct);
+  BOOST_CHECK_EQUAL(x, "01234567000000000000000000000000077");
+}
+
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/bitmanipulation.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/bitmanipulation.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/bitmanipulation.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/bitmanipulation.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -6,113 +6,118 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits1, int_type, IntTypes)
 {
-  mp_int_type x("0xff00000000ff");
+  int_type x("-0xff00000000ff");
   x.set_bits(8, 40);
-  BOOST_CHECK_EQUAL(x, "0xffffffffffff");
+  BOOST_CHECK_EQUAL(x, "-0xffffffffffff");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits2, int_type, IntTypes)
 {
-  mp_int_type x("0x8000");
+  int_type x("0x8000");
   x.set_bits(2, 7);
   BOOST_CHECK_EQUAL(x, "0x807c");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits3, int_type, IntTypes)
 {
-  mp_int_type x("0x80000000000000");
+  int_type x("0x80000000000000");
   x.set_bits(12, 13);
   BOOST_CHECK_EQUAL(x, "0x80000000001000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits4, int_type, IntTypes)
 {
-  mp_int_type x("0x8000000000000000");
+  int_type x("-0x8000000000000000");
   x.set_bits(0, 18);
-  BOOST_CHECK_EQUAL(x, "0x800000000003FFFF");
+  BOOST_CHECK_EQUAL(x, "-0x800000000003FFFF");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits5, int_type, IntTypes)
 {
-  mp_int_type x("0x80000000");
+  int_type x("0x80000000");
   x.set_bits(8, 16);
   BOOST_CHECK_EQUAL(x, "0x8000FF00");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits1, int_type, IntTypes)
 {
-  mp_int_type x("0xffffffffffff");
+  int_type x("0xffffffffffff");
   x.clear_bits(8, 40);
   BOOST_CHECK_EQUAL(x, "0xff00000000ff");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits2, int_type, IntTypes)
 {
-  mp_int_type x("0x807c");
+  int_type x("0x807c");
   x.clear_bits(2, 7);
   BOOST_CHECK_EQUAL(x, "0x8000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits3, int_type, IntTypes)
 {
-  mp_int_type x("0x80000000001000");
+  int_type x("0x80000000001000");
   x.clear_bits(12, 13);
   BOOST_CHECK_EQUAL(x, "0x80000000000000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits4, int_type, IntTypes)
 {
-  mp_int_type x("0x800000000003FFFF");
+  int_type x("0x800000000003FFFF");
   x.clear_bits(0, 18);
   BOOST_CHECK_EQUAL(x, "0x8000000000000000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits5, int_type, IntTypes)
 {
-  mp_int_type x("0x8000FF00");
+  int_type x("0x8000FF00");
   x.clear_bits(8, 16);
   BOOST_CHECK_EQUAL(x, "0x80000000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits6, int_type, IntTypes)
 {
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
-  x.truncate(32);
+  int_type x("-0xffffffffffffffffffff");
+  x.clear_bits(0, 80);
   x.clamp();
+  if (!x)
+    x.set_sign_bit(0);
+  BOOST_CHECK_EQUAL(x, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate1, int_type, IntTypes)
+{
+  int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+  x.truncate(32);
   BOOST_CHECK_EQUAL(x, "0xFFFFFFFF");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate2, int_type, IntTypes)
 {
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+  int_type x("-0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
   x.truncate(0);
-  x.clamp();
   BOOST_CHECK_EQUAL(x, "");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate3, int_type, IntTypes)
 {
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+  int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
   x.truncate(1);
-  x.clamp();
   BOOST_CHECK_EQUAL(x, "1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate4, int_type, IntTypes)
 {
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+  int_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
   x.truncate(31);
-  x.clamp();
   BOOST_CHECK_EQUAL(x, "0x7FFFFFFF");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(truncate5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate5, int_type, IntTypes)
 {
-  mp_int_type x("0xFFFFFFFFFFFFFFFFFFFF");
+  int_type x("0xFFFFFFFFFFFFFFFFFFFF");
   x.truncate(80);
-  x.clamp();
   BOOST_CHECK_EQUAL(x, "0xFFFFFFFFFFFFFFFFFFFF");
 }
 
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/bitwise_ops.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/bitwise_ops.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/bitwise_ops.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/bitwise_ops.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,51 +6,95 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(and_op1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(and_op1, int_type, IntTypes)
 {
-  const mp_int_type x("0x00ff0000000f");
-  const mp_int_type y("0xffffffffffff");
-  const mp_int_type z = x & y;
+  const int_type x("0x00ff0000000f");
+  const int_type y("-0xffffffffffff");
+  const int_type z = x & y;
   BOOST_CHECK_EQUAL(z, x);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(and_op2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(and_op2, int_type, IntTypes)
 {
-  const mp_int_type x("0x00ff0000000ffffffffff");
-  const mp_int_type y(         "0xffffffffffff");
-  const mp_int_type z = x & y;
+  const int_type x("0x00ff0000000ffffffffff");
+  const int_type y(         "0xffffffffffff");
+  const int_type z = x & y;
   BOOST_CHECK_EQUAL(z, "0xffffffffff");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(or_op1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(or_op1, int_type, IntTypes)
 {
-  const mp_int_type x("0x00ff0000000f");
-  const mp_int_type y("0xffffffffffff");
-  const mp_int_type z = x | y;
+  const int_type x("0x00ff0000000f");
+  const int_type y("-0xffffffffffff");
+  const int_type z = x | y;
   BOOST_CHECK_EQUAL(z, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(or_op2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(or_op2, int_type, IntTypes)
 {
-  const mp_int_type x("0x00ff0000000ffffffffff");
-  const mp_int_type y(         "0xaaffffffffff");
-  const mp_int_type z = x | y;
+  const int_type x("0x00ff0000000ffffffffff");
+  const int_type y(         "0xaaffffffffff");
+  const int_type z = x | y;
   BOOST_CHECK_EQUAL(z, "0x00ff00000aaffffffffff");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op1, int_type, IntTypes)
 {
-  const mp_int_type x("0x00ff0000000f");
-  const mp_int_type y("0xffffffffffff");
-  const mp_int_type z = x ^ y;
+  const int_type x("0x00ff0000000f");
+  const int_type y("0xffffffffffff");
+  const int_type z = x ^ y;
   BOOST_CHECK_EQUAL(z, "0xff00fffffff0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op2, int_type, IntTypes)
 {
-  const mp_int_type x("0x00ff0000000ffffffffff");
-  const mp_int_type y(         "0x33aaffffffff");
-  const mp_int_type z = x ^ y;
+  const int_type x("0x00ff0000000ffffffffff");
+  const int_type y(         "0x33aaffffffff");
+  const int_type z = x ^ y;
   BOOST_CHECK_EQUAL(z,"0x00ff00000335500000000");
 }
 
+BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op3, int_type, IntTypes)
+{
+  const int_type x("-0x00ff0000000f");
+  const int_type y("-0xffffffffffff");
+  const int_type z = x ^ y;
+  BOOST_CHECK_EQUAL(z, "0xff00fffffff0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op4, int_type, IntTypes)
+{
+  const int_type x("0x00ff0000000f");
+  const int_type y("-0xffffffffffff");
+  const int_type z = x ^ y;
+  BOOST_CHECK_EQUAL(z, "-0xff00fffffff0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(compl1, int_type, IntTypes)
+{
+  int_type x("-0x6f0000000000000fabab");
+  x = ~x;
+  BOOST_CHECK_EQUAL(x, "0x10fffffffffffff05454");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(compl2, int_type, IntTypes)
+{
+  int_type x("0");
+  x = ~x;
+  BOOST_CHECK_EQUAL(x, "-1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(compl3, int_type, IntTypes)
+{
+  int_type x("1");
+  x = ~x;
+  BOOST_CHECK_EQUAL(x, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(compl4, int_type, IntTypes)
+{
+  int_type x("18446744073709551616"); // 2^65
+  x = ~x;
+  BOOST_CHECK_EQUAL(x, "-0xFFFFFFFFFFFFFFFF");
+}
+
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/bool_conversion.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/bool_conversion.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/bool_conversion.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/bool_conversion.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,35 +6,52 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(bool1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool1, int_type, IntTypes)
 {
-  const mp_int_type x("1");
-  const mp_int_type y("0");
+  // this just tests operator == (const int_type&, bool)
+  const int_type x("1");
+  const int_type y("0");
   BOOST_CHECK_EQUAL(x, true);
   BOOST_CHECK_EQUAL(y, false);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(bool_or, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_or, int_type, IntTypes)
 {
-  const mp_int_type x("1");
-  const mp_int_type y("0");
+  const int_type x("1");
+  const int_type y("0");
   const bool z = x || y;
   BOOST_CHECK_EQUAL(z, true);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and1, int_type, IntTypes)
 {
-  const mp_int_type x("1");
-  const mp_int_type y("0");
+  const int_type x("1");
+  const int_type y("0");
   const bool z = x && y;
   BOOST_CHECK_EQUAL(z, false);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and2, int_type, IntTypes)
 {
-  const mp_int_type x("1");
-  const mp_int_type y("1");
+  const int_type x("-1");
+  const int_type y("-1");
   const bool z = x && y;
   BOOST_CHECK_EQUAL(z, true);
 }
 
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_loop_condition1, int_type, IntTypes)
+{
+  int_type x("5");
+  while (x)
+    --x;
+  BOOST_CHECK_EQUAL(x, false);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_loop_condition2, int_type, IntTypes)
+{
+  int_type x("-5");
+  while (x)
+    ++x;
+  BOOST_CHECK_EQUAL(x, false);
+}
+
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/cmp.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/cmp.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/cmp.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/cmp.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -6,166 +6,584 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq1, int_type, IntTypes)
 {
-  const mp_int_type x("-1");
-  const mp_int_type y("-1");
+  const int_type x("0");
+  const int_type y("0");
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq2, int_type, IntTypes)
 {
-  const mp_int_type x("12");
-  const mp_int_type y("13");
+  const int_type x("1");
+  const int_type y("1");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq3, int_type, IntTypes)
+{
+  const int_type x("0xeeffeeeeee000000000000001");
+  const int_type y("0xeeffeeeeee000000000000001");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq4, int_type, IntTypes)
+{
+  const int_type x("-0xeeffeeeeee000000000000001");
+  const int_type y("-0xeeffeeeeee000000000000001");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ne1, int_type, IntTypes)
+{
+  const int_type x("0");
+  const int_type y("1");
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ne2, int_type, IntTypes)
+{
+  const int_type x("0xaaaaaaaaaaaaaaeeeeeeeeeeeeeee");
+  const int_type y("0xaaaaaaaaaaaaaabbbbbbbbbbbbbb8");
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ne3, int_type, IntTypes)
+{
+  const int_type x("1");
+  const int_type y("-1");
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt1, int_type, IntTypes)
+{
+  const int_type x("12");
+  const int_type y("13");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt2, int_type, IntTypes)
+{
+  const int_type x("1");
+  const int_type y("123456789");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt3, int_type, IntTypes)
+{
+  const int_type x("0x100000000000000000000");
+  const int_type y("0x100000000000000000001");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt4, int_type, IntTypes)
+{
+  const int_type x("15");
+  const int_type y("1023");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt5, int_type, IntTypes)
+{
+  const int_type x("-1");
+  const int_type y("0");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt6, int_type, IntTypes)
+{
+  const int_type x("-0x589789");
+  const int_type y("0x589789");
   BOOST_CHECK_LT(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_gt1, int_type, IntTypes)
+{
+  const int_type x("1");
+  const int_type y("0");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_gt2, int_type, IntTypes)
+{
+  const int_type x("0xfffffffffffffffffffffffff");
+  const int_type y("0");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_gt3, int_type, IntTypes)
+{
+  const int_type x("0xffffffffffffffeeeeeeeeeee1");
+  const int_type y("0xffffffffffffffeeeeeeeeeee0");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_gt4, int_type, IntTypes)
+{
+  const int_type x("1");
+  const int_type y("-1");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_gt5, int_type, IntTypes)
+{
+  const int_type x("0xffffffffffffffeeeeeeeeeee1");
+  const int_type y("-0xffffffffffffffeeeeeeeeeee0");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le1, int_type, IntTypes)
+{
+  const int_type x("0");
+  const int_type y("0");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le2, int_type, IntTypes)
+{
+  const int_type x("0");
+  const int_type y("1");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le3, int_type, IntTypes)
+{
+  const int_type x("0x123456789fffffffffff");
+  const int_type y("0x123456789fffffffffff");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le4, int_type, IntTypes)
+{
+  const int_type x("0x11");
+  const int_type y("0x49941faaaaaaaa332134");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le5, int_type, IntTypes)
+{
+  const int_type x("-0x123456789fffffffffff");
+  const int_type y("0x123456789fffffffffff");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le6, int_type, IntTypes)
+{
+  const int_type x("-0x123456789fffffffffff");
+  const int_type y("-0x123456789fffffffffff");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ge1, int_type, IntTypes)
+{
+  const int_type x("1");
+  const int_type y("1");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ge2, int_type, IntTypes)
+{
+  const int_type x("0xa0a0");
+  const int_type y("0");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ge3, int_type, IntTypes)
+{
+  const int_type x("0xff00ff00000000000000001ff");
+  const int_type y("0xff00ff00000000000000000ff");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ge4, int_type, IntTypes)
+{
+  const int_type x("0xff00ff00000000000000000ff");
+  const int_type y("-0xff00ff00000000000000000ff");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ge5, int_type, IntTypes)
+{
+  const int_type x("-0xff00ff00000000000000000ff");
+  const int_type y("-0xff00ff00000000000000000ff");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_integral1, int_type, IntTypes)
+{
+  const int_type x("0");
+  const int y = 0;
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_integral2, int_type, IntTypes)
+{
+  const int_type x("20");
+  const unsigned int y = 20;
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_integral3, int_type, IntTypes)
 {
-  const mp_int_type x("1");
-  const mp_int_type y("123456789");
+  const int_type x("30000");
+  const int y = 30000;
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_integral4, int_type, IntTypes)
+{
+  const int_type x("0xffff0000");
+  const unsigned long y = 0xffff0000;
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_integral5, int_type, IntTypes)
+{
+  const int_type x("-30000");
+  const int y = -30000;
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_integral1, int_type, IntTypes)
+{
+  const int_type x("1");
+  const int y = 0;
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_integral2, int_type, IntTypes)
+{
+  const int_type x("0");
+  const int y = -10000;
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_integral3, int_type, IntTypes)
+{
+  const int_type x("-10000");
+  const unsigned int y = 10000;
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_integral4, int_type, IntTypes)
+{
+  const int_type x("-10000");
+  const int y = -10001;
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_lt_integral1, int_type, IntTypes)
+{
+  const int_type x("0");
+  const int y = 1;
   BOOST_CHECK_LT(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_lt_integral2, int_type, IntTypes)
 {
-  const mp_int_type x("-1");
-  const mp_int_type y("0");
+  const int_type x("123456789");
+  const unsigned long y = 123456790;
   BOOST_CHECK_LT(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_lt_integral3, int_type, IntTypes)
 {
-  const mp_int_type x("-123");
-  const mp_int_type y("-10");
+  const int_type x("-0x500");
+  const int y = -0x400;
   BOOST_CHECK_LT(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_lt_integral4, int_type, IntTypes)
 {
-  const mp_int_type x("-123456789");
-  const mp_int_type y("123456798");
+  const int_type x("-0x500");
+  const unsigned int y = 0x400;
   BOOST_CHECK_LT(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_gt_integral1, int_type, IntTypes)
+{
+  const int_type x("1");
+  const int y = -1;
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_gt_integral2, int_type, IntTypes)
+{
+  const int_type x("0x5000000addddddd");
+  const unsigned int y = 1156;
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_gt_integral3, int_type, IntTypes)
+{
+  const int_type x("-1321");
+  const int y = -1500;
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_le_integral1, int_type, IntTypes)
+{
+  const int_type x("0");
+  const int y = 0;
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_le_integral2, int_type, IntTypes)
+{
+  const int_type x("0xffff");
+  const unsigned int y = 0xffff;
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_le_integral3, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  const mp_int_type y("0");
+  const int_type x("0xaa0");
+  const unsigned int y = 0xf000;
   BOOST_CHECK_LE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_le_integral4, int_type, IntTypes)
 {
-  const mp_int_type x("-1");
-  const mp_int_type y("0");
+  const int_type x("-0x100");
+  const int y = -0x100;
   BOOST_CHECK_LE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_le_integral5, int_type, IntTypes)
 {
-  const mp_int_type x("-123456789");
-  const mp_int_type y("-123456789");
+  const int_type x("-0x100");
+  const int y = 0x100;
   BOOST_CHECK_LE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_le_integral6, int_type, IntTypes)
 {
-  const mp_int_type x("11");
-  const mp_int_type y("49941");
+  const int_type x("-0x100");
+  const unsigned int y = 0x100;
   BOOST_CHECK_LE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ge_integral1, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  BOOST_CHECK_EQUAL(x, 0);
+  const int_type x("0");
+  const int y = 0;
+  BOOST_CHECK_GE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ge_integral2, int_type, IntTypes)
 {
-  const mp_int_type x("20");
-  BOOST_CHECK_EQUAL(x, 20U);
+  const int_type x("100");
+  const int y = -100;
+  BOOST_CHECK_GE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ge_integral3, int_type, IntTypes)
 {
-  const mp_int_type x("300");
-  BOOST_CHECK_EQUAL(x, 300);
+  const int_type x("0x56a4f564aaa445456");
+  const unsigned int y = 0xaab;
+  BOOST_CHECK_GE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ge_integral4, int_type, IntTypes)
 {
-  const mp_int_type x("-1");
-  BOOST_CHECK_EQUAL(x, -1);
+  const int_type x("-100");
+  const int y = -100;
+  BOOST_CHECK_GE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_eq_to_integral_type5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_eq_mp_int1, int_type, IntTypes)
 {
-  const mp_int_type x("-32101");
-  BOOST_CHECK_EQUAL(x, -32101);
+  const int x = 0;
+  const int_type y("0");
+  BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_integral_type1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_eq_mp_int2, int_type, IntTypes)
 {
-  const mp_int_type x("123456789");
-  BOOST_CHECK_LT(x, 123456790);
+  const unsigned int x = 1000;
+  const int_type y("1000");
+  BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_integral_type2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_eq_mp_int3, int_type, IntTypes)
 {
-  const mp_int_type x("0x100000000");
-  BOOST_CHECK_LE(1, x);
+  const int x = -1000;
+  const int_type y("-1000");
+  BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_integral_type3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ne_mp_int1, int_type, IntTypes)
 {
-  const mp_int_type x("-0x100000000");
-  BOOST_CHECK_LT(x, -1);
+  const int x = 0;
+  const int_type y("0x1000");
+  BOOST_CHECK_NE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_integral_type4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ne_mp_int2, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<int>::min());
-  x -= 1;
-  BOOST_CHECK_LT(x, std::numeric_limits<int>::min());
+  const int x = -500;
+  const int_type y("500");
+  BOOST_CHECK_NE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_lt_unsigned_integral_type, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ne_mp_int3, int_type, IntTypes)
 {
-  const mp_int_type x("123456789");
-  BOOST_CHECK_LT(x, 123456790U);
+  const unsigned int x = 500;
+  const int_type y("0xcaaff500");
+  BOOST_CHECK_NE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_le_integral_type1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ne_mp_int4, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  BOOST_CHECK_LE(x, 123456789);
+  const int x = 500;
+  const int_type y("-500");
+  BOOST_CHECK_NE(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_le_integral_type2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_lt_mp_int1, int_type, IntTypes)
 {
-  const mp_int_type x("32101");
-  BOOST_CHECK_LE(x, 32102);
+  const unsigned int x = 500;
+  const int_type y("0xcaaff500");
+  BOOST_CHECK_LT(x, y);
 }
 
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_lt_mp_int2, int_type, IntTypes)
+{
+  const int x = -500;
+  const int_type y("0");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_lt_mp_int3, int_type, IntTypes)
+{
+  const int x = -0x800;
+  const int_type y("-0x500");
+  BOOST_CHECK_LT(x, y);
+}
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_mp_int_le_unsigned_integral_type, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_gt_mp_int1, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  BOOST_CHECK_LE(x, 32101U);
+  const int x = 1;
+  const int_type y("0");
+  BOOST_CHECK_GT(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_integral_type_lt_mp_int, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_gt_mp_int2, int_type, IntTypes)
 {
-  const mp_int_type x("32101");
-  BOOST_CHECK_LT(32100, x);
+  const unsigned int x = 1000;
+  const int_type y("999");
+  BOOST_CHECK_GT(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_integral_type_le_mp_int, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_gt_mp_int3, int_type, IntTypes)
 {
-  const mp_int_type x("32101");
-  BOOST_CHECK_LE(x, 32102);
+  const int x = -0x999;
+  const int_type y("-0x1000");
+  BOOST_CHECK_GT(x, y);
 }
 
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_le_mp_int1, int_type, IntTypes)
+{
+  const unsigned int x = 999;
+  const int_type y("999");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_le_mp_int2, int_type, IntTypes)
+{
+  const int x = -1;
+  const int_type y("0x99999999999999");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_le_mp_int3, int_type, IntTypes)
+{
+  const int x = -0x999;
+  const int_type y("-0x999");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_le_mp_int4, int_type, IntTypes)
+{
+  const int x = -0x1000;
+  const int_type y("-0x999");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ge_mp_int1, int_type, IntTypes)
+{
+  const unsigned int x = 999;
+  const int_type y("999");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ge_mp_int2, int_type, IntTypes)
+{
+  const int x = 1023;
+  const int_type y("1010");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ge_mp_int3, int_type, IntTypes)
+{
+  const int x = -0x1023;
+  const int_type y("-0x1023");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ge_mp_int4, int_type, IntTypes)
+{
+  const int x = 0x1023;
+  const int_type y("-0x1023");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ge_mp_int5, int_type, IntTypes)
+{
+  const unsigned int x = 0x1023;
+  const int_type y("-0x102305615645ff");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_char_ptr1, int_type, IntTypes)
+{
+  const int_type x("0");
+  const char* y = "0";
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_char_ptr2, int_type, IntTypes)
+{
+  const int_type x("0x456561fcaa547650456456");
+  const char* y = "0x456561fcaa547650456456";
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_char_ptr3, int_type, IntTypes)
+{
+  const int_type x("-0x500000");
+  const char* y = "-0x500000";
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_char_ptr1, int_type, IntTypes)
+{
+  const int_type x("15");
+  const char* y = "22";
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_char_ptr2, int_type, IntTypes)
+{
+  const int_type x("0x456561fcaa547650456456");
+  const char* y = "-0x456561fcaa547650456456";
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_char_ptr3, int_type, IntTypes)
+{
+  const int_type x("-0x456561fcaa547650456456");
+  const char* y = "0x456561fcaa547650456456";
+  BOOST_CHECK_NE(x, y);
+}
 
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/ctors.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/ctors.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/ctors.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/ctors.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,183 +6,276 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
+// We mostly test from/to string conversions here since most other test cases
+// depend on these. If they are broken and senseless data gets into an integer
+// or we have wrong output then we need to fix this quickly.
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor, int_type, IntTypes)
 {
-  const mp_int_type a;
-  BOOST_CHECK_EQUAL(a.size(), 0U);
-  BOOST_CHECK_EQUAL(a.is_positive(), true);
-  BOOST_CHECK_EQUAL(a.is_negative(), false);
-  BOOST_CHECK_EQUAL(a, "");
+  const int_type x;
+  BOOST_CHECK_EQUAL(x.size(), 0U);
+  BOOST_CHECK_EQUAL(x.is_initialized(), false);
+  BOOST_CHECK_EQUAL(x.is_uninitialized(), true);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_empty_string1, int_type, IntTypes)
 {
-  const mp_int_type y("12");
-  BOOST_CHECK_EQUAL(y, "12");
+  const int_type x("");
+  BOOST_CHECK_EQUAL(x.size(), 0U);
+  BOOST_CHECK_EQUAL(x.is_initialized(), false);
+  BOOST_CHECK_EQUAL(x.is_uninitialized(), true);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string1, int_type, IntTypes)
 {
-  const mp_int_type x("123456789");
-  BOOST_CHECK_EQUAL(x, "123456789");
+  const int_type x("0");
+  BOOST_CHECK(x.is_positive());
+  BOOST_CHECK_EQUAL(x.is_initialized(), true);
+  BOOST_CHECK_EQUAL(x.is_uninitialized(), false);
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string2, int_type, IntTypes)
 {
-  const mp_int_type x("1000000000");
-  BOOST_CHECK_EQUAL(x, "1000000000");
+  const int_type x("12");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "12");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string3, int_type, IntTypes)
 {
-  const mp_int_type y("0");
-  BOOST_CHECK_EQUAL(!y, true);
+  const int_type x("123456789");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "123456789");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_positive_decimal_string1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string4, int_type, IntTypes)
 {
-  const mp_int_type z("+1");
-  BOOST_CHECK_EQUAL(z, "1");
+  const int_type x("1000000000");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "1000000000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_negative_decimal_string1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string5, int_type, IntTypes)
 {
-  const mp_int_type z("-1");
-  BOOST_CHECK_EQUAL(z, "-1");
+  const int_type x("+1");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_negative_decimal_string2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string6, int_type, IntTypes)
 {
-  const mp_int_type z("-888888");
-  BOOST_CHECK_EQUAL(z, "-888888");
+  const int_type x("-1");
+  BOOST_CHECK(x.is_negative());
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "-1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string7, int_type, IntTypes)
 {
-  const mp_int_type y("012");
-  BOOST_CHECK_EQUAL(y, "10");
+  const int_type x("8888000000009", std::ios_base::dec |
+                                     std::ios_base::showbase);
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "8888000000009");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string8, int_type, IntTypes)
 {
-  const mp_int_type y("000000000000000000000000000000000");
-  BOOST_CHECK_EQUAL(!y, true);
+  BOOST_CHECK_THROW(int_type("1234567890a456456"), std::invalid_argument);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string9, int_type, IntTypes)
 {
-  const mp_int_type x("0123456777");
-  BOOST_CHECK_EQUAL(x, "21913087");
+  BOOST_CHECK_THROW(
+      int_type("1230", std::ios_base::showpos),
+      std::invalid_argument);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string1, int_type, IntTypes)
 {
-  const mp_int_type z("-0777777");
-  BOOST_CHECK_EQUAL(z, "-262143");
+  const int_type x("0", std::ios_base::oct);
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string2, int_type, IntTypes)
 {
-  const mp_int_type y("0xF");
-  BOOST_CHECK_EQUAL(y, "15");
+  const int_type x("0", std::ios_base::oct | std::ios_base::showbase);
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string3, int_type, IntTypes)
 {
-  const mp_int_type y("0xa0");
-  BOOST_CHECK_EQUAL(y, "160");
+  const int_type x("012");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "10");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string4, int_type, IntTypes)
 {
-  const mp_int_type x("0x123456789abcdef");
-  BOOST_CHECK_EQUAL(x, "0x123456789abcdef");
+  const int_type x("000000000000000000000000000000000");
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string5, int_type, IntTypes)
 {
-  const mp_int_type x("-0x8F888b");
-  BOOST_CHECK_EQUAL(x, "-0x8F888b");
+  const int_type x("0123456777");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "21913087");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string6, int_type, IntTypes)
 {
-  const mp_int_type x("0xA0000000");
-  BOOST_CHECK_EQUAL(x, "2684354560");
+  BOOST_CHECK_THROW(int_type("012345678"), std::invalid_argument);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_long_string, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string7, int_type, IntTypes)
 {
-  const mp_int_type x("87500402519005030061267904448809305029512439942506161234260852587645856336946409871074842737283625535525153833045575858681216");
-  BOOST_CHECK_EQUAL(x, "87500402519005030061267904448809305029512439942506161234260852587645856336946409871074842737283625535525153833045575858681216");
+  BOOST_CHECK_THROW(
+      int_type("1234567", std::ios_base::oct | std::ios_base::showbase),
+      std::invalid_argument);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_iterators1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string1, int_type, IntTypes)
 {
-  const std::string s("123456789");
-  const mp_int_type z(s.begin(), s.end());
-  BOOST_CHECK_EQUAL(z, "123456789");
+  const int_type x("0x0");
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string2, int_type, IntTypes)
 {
-  const mp_int_type x(9999999U);
-  BOOST_CHECK_EQUAL(x, "9999999");
+  const int_type x("0X0");
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string3, int_type, IntTypes)
 {
-  const mp_int_type x(123456U);
-  BOOST_CHECK_EQUAL(x, "123456");
+  const int_type x("0", std::ios_base::hex);
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_signed_char, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string4, int_type, IntTypes)
 {
-  signed char c = -14;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "-14");
+  const int_type x("0xF");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "15");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_unsigned_char, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string5, int_type, IntTypes)
 {
-  unsigned char c = 42;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "42");
+  const int_type x("0xa0");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "160");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string6, int_type, IntTypes)
+{
+  const int_type x("0x123456789abcdef");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(std::ios_base::hex |
+                                                      std::ios_base::showbase),
+                    "0x123456789abcdef");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string7, int_type, IntTypes)
+{
+  const int_type x("0x123456789ABCDEF");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(std::ios_base::hex |
+                                                      std::ios_base::showbase |
+                                                      std::ios_base::uppercase),
+                    "0X123456789ABCDEF");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_short_int, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string8, int_type, IntTypes)
 {
-  short int c = -14789;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "-14789");
+  const int_type x("0xA0000000");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "2684354560");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_int, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string9, int_type, IntTypes)
 {
-  int c = -9999;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "-9999");
+  const int_type x("0x");
+  BOOST_CHECK_EQUAL(x.is_uninitialized(), true);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_long_int, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string10, int_type, IntTypes)
 {
-  const long int c = -100000000;
-  const mp_int_type x(c);
-  BOOST_CHECK_EQUAL(x, "-100000000");
+  const int_type x("-0x");
+  BOOST_CHECK_EQUAL(x.is_uninitialized(), true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string11, int_type, IntTypes)
+{
+  BOOST_CHECK_THROW(int_type("0x15656abg56"), std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string12, int_type, IntTypes)
+{
+  BOOST_CHECK_THROW(
+      int_type("156afc56", std::ios_base::hex | std::ios_base::showbase),
+      std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string13, int_type, IntTypes)
+{
+  BOOST_CHECK_THROW(
+      int_type("015656ABDEE0", std::ios_base::hex | std::ios_base::showbase |
+                               std::ios_base::uppercase),
+      std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_long_string, int_type, IntTypes)
+{
+  const int_type x(
+      "875004025190050300612679044488093050295124399425061612342608525876458563"
+      "36946409871074842737283625535525153833045575858681216");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(),
+      "875004025190050300612679044488093050295124399425061612342608525876458563"
+      "36946409871074842737283625535525153833045575858681216");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_iterators1, int_type, IntTypes)
+{
+  const std::string s("123456789");
+  const int_type x(s.begin(), s.end());
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "123456789");
 }
 
 #ifndef BOOST_NO_CWCHAR
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wchar_t, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wchar_t1, int_type, IntTypes)
 {
-  const mp_int_type x(L"0xA0000000");
+  const int_type x(L"0xA0000000");
   BOOST_CHECK_EQUAL(x, "2684354560");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wstring, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wstring1, int_type, IntTypes)
 {
   const std::wstring s(L"0xA0000000");
-  const mp_int_type x(s);
+  const int_type x(s);
   BOOST_CHECK_EQUAL(x, "2684354560");
 }
 #endif
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cctor1, int_type, IntTypes)
+{
+  const int_type x("0xabddd00012134f");
+  const int_type y(x);
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+
+/*
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type1, int_type, IntTypes)
+{
+  const int_type x(9999999U);
+  BOOST_CHECK_EQUAL(x, "9999999");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type2, int_type, IntTypes)
+{
+  const int_type x(123456U);
+  BOOST_CHECK_EQUAL(x, "123456");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_unsigned_char, int_type, IntTypes)
+{
+  unsigned char c = 42;
+  const int_type x(c);
+  BOOST_CHECK_EQUAL(x, "42");
+}
+*/
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/div.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/div.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/div.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/div.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,107 +6,163 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(division_by_zero, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type y("123456");
-  const mp_int_type z = x / y;
-  BOOST_CHECK_EQUAL(z, "8");
+  const int_type x("0x201abcff00aaffffff");
+  const int_type y("0");
+  BOOST_CHECK_THROW(x / y, std::domain_error);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide1, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type y("-123456");
-  const mp_int_type z = x / y;
-  BOOST_CHECK_EQUAL(z, "-8");
+  const int_type x("987777");
+  const int_type y("123456");
+  const int_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "8");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide2, int_type, IntTypes)
 {
-  const mp_int_type x("263825472");
-  const mp_int_type y("123456");
-  const mp_int_type z = x / y;
+  const int_type x("263825472");
+  const int_type y("123456");
+  const int_type z = x / y;
   BOOST_CHECK_EQUAL(z, "2137");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide3, int_type, IntTypes)
+{
+  const int_type x("-0xaf000001100008");
+  const int_type y("0x100000");
+  const int_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "-0xaf0000011");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide4, int_type, IntTypes)
+{
+  const int_type x("0x8005000000ffffff");
+  const int_type y("-0x155ff");
+  const int_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "-0x5fd41dd02f04");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide5, int_type, IntTypes)
 {
-  const mp_int_type x("0x89ab89745cc653de58eecc8f8a874120065ea545f6f5f");
-  const mp_int_type y("0x1889ba8a789456adfc8005b1");
-  const mp_int_type z = x / y;
+  const int_type x("-0x8005000000ffffff");
+  const int_type y("-0x155ff");
+  const int_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "0x5fd41dd02f04");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide6, int_type, IntTypes)
+{
+  const int_type x("0x89ab89745cc653de58eecc8f8a874120065ea545f6f5f");
+  const int_type y("0x1889ba8a789456adfc8005b1");
+  const int_type z = x / y;
   BOOST_CHECK_EQUAL(z, "0x59c48aa7a1446110b31f70");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide7, int_type, IntTypes)
 {
-  const mp_int_type x("0x1889ba8a789456adfc8005b1");
-  const mp_int_type y("0x1889ba8a789456adfc8005b2");
-  const mp_int_type z = x / y;
+  const int_type x("0x1889ba8a789456adfc8005b1");
+  const int_type y("0x1889ba8a789456adfc8005b2");
+  const int_type z = x / y;
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide8, int_type, IntTypes)
+{
+  const int_type x("0x201abcff00aaffffff");
+  const int_type y("0x1fffffffffffffff");
+  const int_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "256");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide9, int_type, IntTypes)
+{
+  const int_type x(
+      "0xffffffffffffffff00000000000000000000000ffffffffffff00000000000000000000"
+      "000000000000000eeeeeeeeeeeeee0");
+  const int_type y("0xffffffff00000000000");
+  const int_type z = x / y;
+  BOOST_CHECK_EQUAL(z,
+      "0x100000001000000000000000000000000000000100000000ffff0000ffff0000ffff00"
+      "00ffff0000fff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide10, int_type, IntTypes)
+{
+  const int_type x("0x7fffffff800000010000000000000000");
+  const int_type y("0x800000008000000200000005");
+  const int_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "0xfffffffd");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide11, int_type, IntTypes)
 {
-  mp_int_type x("263825472");
-  x.divide_by_2();
-  BOOST_CHECK_EQUAL(x, "131912736");
+  const int_type x("0x1581b6d300d0225a000000");
+  const int_type y("0x449f21");
+  const int_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "0x503ba38a5226b3aa");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(shift_right1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(shift_right1, int_type, IntTypes)
 {
-  mp_int_type x("263825472");
+  int_type x("263825472");
   x >>= 3;
   BOOST_CHECK_EQUAL(x, "32978184");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod_zero, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type y("123456");
-  const mp_int_type z = x % y;
+  const int_type x("987777");
+  const int_type y("0");
+  BOOST_CHECK_THROW(x % y, std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod1, int_type, IntTypes)
+{
+  const int_type x("987777");
+  const int_type y("123456");
+  const int_type z = x % y;
   BOOST_CHECK_EQUAL(z, "129");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod2, int_type, IntTypes)
+{
+  const int_type x("0");
+  const int_type y("0x55464565");
+  const int_type z = x % y;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod3, int_type, IntTypes)
 {
-  const mp_int_type x("-987777");
-  const mp_int_type y("123456");
-  const mp_int_type z = x % y;
+  const int_type x("-987777");
+  const int_type y("123456");
+  const int_type z = x % y;
   BOOST_CHECK_EQUAL(z, "-129");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod4, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type y("-123456");
-  const mp_int_type z = x % y;
+  const int_type x("987777");
+  const int_type y("-123456");
+  const int_type z = x % y;
   BOOST_CHECK_EQUAL(z, "129");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod5, int_type, IntTypes)
 {
-  const mp_int_type x("-987777");
-  const mp_int_type y("-123456");
-  const mp_int_type z = x % y;
+  const int_type x("-987777");
+  const int_type y("-123456");
+  const int_type z = x % y;
   BOOST_CHECK_EQUAL(z, "-129");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod5, mp_int_type, mp_int_types)
-{
-  const mp_int_type x("-123456");
-  const mp_int_type y("123456");
-  const mp_int_type z = x % y;
-  BOOST_CHECK_EQUAL(z, "0");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(mod6, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod6, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  const mp_int_type y("5");
-  const mp_int_type z = x % y;
+  const int_type x("-123456");
+  const int_type y("123456");
+  const int_type z = x % y;
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-
-
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/gcd.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/gcd.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/gcd.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/gcd.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -7,55 +7,55 @@
 #include "prerequisite.hpp"
 
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(gcd1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd1, int_type, IntTypes)
 {
-  const mp_int_type x("10");
-  const mp_int_type y("2");
-  const mp_int_type z = boost::mp_math::gcd(x,y);
+  const int_type x("10");
+  const int_type y("2");
+  const int_type z = boost::mp_math::gcd(x,y);
   BOOST_CHECK_EQUAL(z, "2");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(gcd2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd2, int_type, IntTypes)
 {
-  const mp_int_type x("456489798");
-  const mp_int_type y("987");
-  const mp_int_type z = boost::mp_math::gcd(x,y);
+  const int_type x("456489798");
+  const int_type y("987");
+  const int_type z = boost::mp_math::gcd(x,y);
   BOOST_CHECK_EQUAL(z, "3");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(gcd3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd3, int_type, IntTypes)
 {
-  const mp_int_type x("-16384");
-  const mp_int_type y("16384");
-  const mp_int_type z = boost::mp_math::gcd(x,y);
+  const int_type x("-16384");
+  const int_type y("16384");
+  const int_type z = boost::mp_math::gcd(x,y);
   BOOST_CHECK_EQUAL(z, "16384");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(gcd4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd4, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  const mp_int_type y("0");
-  const mp_int_type z = boost::mp_math::gcd(x,y);
+  const int_type x("0");
+  const int_type y("0");
+  const int_type z = boost::mp_math::gcd(x,y);
   BOOST_CHECK_EQUAL(z, "0");
 }
 
 #ifdef BOOST_HAS_VARIADIC_TMPL
-BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_gcd1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_gcd1, int_type, IntTypes)
 {
-  const mp_int_type a("42");
-  const mp_int_type b("56");
-  const mp_int_type c("140");
-  const mp_int_type z = boost::mp_math::gcd(a,b,c);
+  const int_type a("42");
+  const int_type b("56");
+  const int_type c("140");
+  const int_type z = boost::mp_math::gcd(a,b,c);
   BOOST_CHECK_EQUAL(z, "14");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_gcd2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_gcd2, int_type, IntTypes)
 {
-  const mp_int_type a("1200000000");
-  const mp_int_type b("2400000000");
-  const mp_int_type c("3600000000");
-  const mp_int_type d("600000000000000");
-  const mp_int_type z = boost::mp_math::gcd(a,b,c,d);
+  const int_type a("1200000000");
+  const int_type b("2400000000");
+  const int_type c("3600000000");
+  const int_type d("600000000000000");
+  const int_type z = boost::mp_math::gcd(a,b,c,d);
   BOOST_CHECK_EQUAL(z, "1200000000");
 }
 #endif
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/integral_ops.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/integral_ops.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/integral_ops.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/integral_ops.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,287 +6,377 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(construct_from_zero, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(construct_from_zero, int_type, IntTypes)
 {
-  const mp_int_type x(0);
+  const int_type x(0);
   BOOST_CHECK_EQUAL(!x, true);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_signed_char_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_signed_char_min, int_type, IntTypes)
 {
   const signed char x = std::numeric_limits<signed char>::min();
-  const mp_int_type y(x);
+  const int_type y(x);
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_signed_char_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_signed_char_max, int_type, IntTypes)
 {
   const signed char x = std::numeric_limits<signed char>::max();
-  const mp_int_type y(x);
+  const int_type y(x);
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_char_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_char_min, int_type, IntTypes)
 {
   const unsigned char x = std::numeric_limits<unsigned char>::min();
-  const mp_int_type y(x);
+  const int_type y(x);
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_char_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_char_max, int_type, IntTypes)
 {
   const unsigned char x = std::numeric_limits<unsigned char>::max();
-  const mp_int_type y(x);
+  const int_type y(x);
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_int_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_int_min, int_type, IntTypes)
 {
   const int x = std::numeric_limits<int>::min();
-  const mp_int_type y(x);
+  const int_type y(x);
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_int_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_int_max, int_type, IntTypes)
 {
   const int x = std::numeric_limits<int>::max();
-  const mp_int_type y(x);
+  const int_type y(x);
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_int_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_int_min, int_type, IntTypes)
 {
   const unsigned int x = std::numeric_limits<unsigned int>::min();
-  const mp_int_type y(x);
+  const int_type y(x);
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_int_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_int_max, int_type, IntTypes)
 {
   const unsigned int x = std::numeric_limits<unsigned int>::max();
-  const mp_int_type y(x);
+  const int_type y(x);
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral1, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type z = x + 1;
+  const int_type x("987777");
+  const int_type z = x + 1;
   BOOST_CHECK_EQUAL(z, "987778");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral2, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type z = x + (-1);
+  const int_type x("987777");
+  const int_type z = x + (-1);
   BOOST_CHECK_EQUAL(z, "987776");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral3, int_type, IntTypes)
 {
-  const mp_int_type x("-1");
-  const mp_int_type z = x + 5;
+  const int_type x("-1");
+  const int_type z = x + 5;
   BOOST_CHECK_EQUAL(z, "4");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_unsigned_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_unsigned_integral1, int_type, IntTypes)
 {
-  const mp_int_type x("9999999");
-  const mp_int_type z = x + 1U;
+  const int_type x("9999999");
+  const int_type z = x + 1U;
   BOOST_CHECK_EQUAL(z, "10000000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_char_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_char_min, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  const mp_int_type z = x + std::numeric_limits<signed char>::min();
+  const int_type x("0");
+  const int_type z = x + std::numeric_limits<signed char>::min();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<signed char>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_char_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_char_max, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  const mp_int_type z = x + std::numeric_limits<signed char>::max();
+  const int_type x("0");
+  const int_type z = x + std::numeric_limits<signed char>::max();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<signed char>::max());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_int_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_int_min, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  const mp_int_type z = x + std::numeric_limits<int>::min();
+  const int_type x("0");
+  const int_type z = x + std::numeric_limits<int>::min();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(add_int_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_int_max, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  const mp_int_type z = x + std::numeric_limits<int>::max();
+  const int_type x("0");
+  const int_type z = x + std::numeric_limits<int>::max();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::max());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral1, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type z = x - 12345;
+  const int_type x("987777");
+  const int_type z = x - 12345;
   BOOST_CHECK_EQUAL(z, "975432");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral2, int_type, IntTypes)
 {
-  const mp_int_type x("98000");
-  const mp_int_type z = x - (-1);
+  const int_type x("98000");
+  const int_type z = x - (-1);
   BOOST_CHECK_EQUAL(z, "98001");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral3, int_type, IntTypes)
 {
-  const mp_int_type x("125642682070");
+  const int_type x("125642682070");
   const long y = 2147483647;
-  const mp_int_type z = x - y;
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "123495198423");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral4, int_type, IntTypes)
 {
-  const mp_int_type x("1");
-  const mp_int_type z = x - 2;
+  const int_type x("1");
+  const int_type z = x - 2;
   BOOST_CHECK_EQUAL(z, "-1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_unsigned_char1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_unsigned_char1, int_type, IntTypes)
 {
   const unsigned char y = 14;
-  const mp_int_type x("987777");
-  const mp_int_type z = x - y;
+  const int_type x("987777");
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "987763");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply1, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type z = x * 12345;
-  BOOST_CHECK_EQUAL(z, "12194107065");
+  const int_type x("-14");
+  const signed char y = 100;
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "-1400");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply2, int_type, IntTypes)
+{
+  const int_type x("-14");
+  const int y = 10000;
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "-140000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply3, int_type, IntTypes)
+{
+  const int_type x("-14");
+  const signed char y = -100;
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "1400");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply4, int_type, IntTypes)
+{
+  const int_type x("-14");
+  const int y = -10000;
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "140000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply5, int_type, IntTypes)
+{
+  const int_type x("-14");
+  const unsigned char y = 100;
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "-1400");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply6, int_type, IntTypes)
+{
+  const int_type x("-14");
+  const unsigned int y = 10000;
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "-140000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply7, int_type, IntTypes)
+{
+  const int_type x("-987777");
+  const signed char y = 123;
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "-121496571");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply8, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type z = x * -12345;
+  const int_type x("-987777");
+  const int y = 12345;
+  const int_type z = x * y;
   BOOST_CHECK_EQUAL(z, "-12194107065");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply9, int_type, IntTypes)
 {
-  const mp_int_type x("-987777");
-  const mp_int_type z = x * -12345;
+  const int_type x("987777");
+  const int_type z = x * -12345;
+  BOOST_CHECK_EQUAL(z, "-12194107065");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply10, int_type, IntTypes)
+{
+  const int_type x("-987777");
+  const int_type z = x * -12345;
   BOOST_CHECK_EQUAL(z, "12194107065");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_unsigned_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply11, int_type, IntTypes)
 {
-  const mp_int_type x("1256");
-  const mp_int_type z = x * 100U;
-  mp_int_type w("125600");
+  const int_type x("1256");
+  const int_type z = x * 100U;
+  int_type w("125600");
   BOOST_CHECK_EQUAL(z, "125600");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_zero1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply12, int_type, IntTypes)
+{
+  const int_type x("-0x500001f0000000");
+  const unsigned long y = 0x413000;
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "-0x145f007e4d0000000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_zero1, int_type, IntTypes)
 {
-  const mp_int_type x("-9877234234252377");
-  const mp_int_type z = x * 0;
+  const int_type x("-1");
+  const int y = 0;
+  const int_type z = x * y;
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_negative_zero1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_zero2, int_type, IntTypes)
 {
-  const mp_int_type x("-9877234234252377");
-  const mp_int_type z = x * -0;
+  const int_type x("-9877234234252377");
+  const int y = 0;
+  const int_type z = x * y;
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_unsigned_char1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_zero3, int_type, IntTypes)
+{
+  const int_type x("-9877234234252377");
+  const unsigned int y = 0;
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_negative_zero1, int_type, IntTypes)
+{
+  const int_type x("-9877234234252377");
+  const int_type z = x * -0;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_unsigned_char1, int_type, IntTypes)
 {
   const unsigned char y = 16;
-  const mp_int_type x("10000001");
-  const mp_int_type z = x / y;
+  const int_type x("10000001");
+  const int_type z = x / y;
   BOOST_CHECK_EQUAL(z, "625000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_unsigned_char2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_unsigned_char2, int_type, IntTypes)
 {
   const unsigned char y = 128;
-  const mp_int_type x("14222200");
-  const mp_int_type z = x / y;
+  const int_type x("14222200");
+  const int_type z = x / y;
   BOOST_CHECK_EQUAL(z, "111110");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_signed_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_unsigned_int1, int_type, IntTypes)
 {
-  const mp_int_type x("786432");
-  const mp_int_type z = x / 12;
+  const unsigned int y = 140;
+  const int_type x("51065");
+  const int_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "364");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_signed_integral1, int_type, IntTypes)
+{
+  const int_type x("786432");
+  const int_type z = x / 12;
   BOOST_CHECK_EQUAL(z, "65536");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral1, int_type, IntTypes)
 {
-  const mp_int_type x("786432");
-  const mp_int_type z = x % 12;
+  const int_type x("786432");
+  const int_type z = x % 12;
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral2, int_type, IntTypes)
 {
-  const mp_int_type x("-987777");
-  const mp_int_type z = x % 123456;
+  const int_type x("-987777");
+  const int_type z = x % 123456;
   BOOST_CHECK_EQUAL(z, "-129");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral3, int_type, IntTypes)
 {
-  const mp_int_type x("987777");
-  const mp_int_type z = x % -123456;
+  const int_type x("987777");
+  const int_type z = x % -123456;
   BOOST_CHECK_EQUAL(z, "129");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral4, int_type, IntTypes)
 {
-  const mp_int_type x("-987777");
-  const mp_int_type z = x % -123456;
+  const int_type x("-987777");
+  const int_type z = x % -123456;
   BOOST_CHECK_EQUAL(z, "-129");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_unsigned_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_unsigned_integral1, int_type, IntTypes)
 {
-  const mp_int_type x("987771");
-  const mp_int_type z = x % 16U;
+  const int_type x("987771");
+  const int_type z = x % 16U;
   BOOST_CHECK_EQUAL(z, "11");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_unsigned_integral2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_unsigned_integral2, int_type, IntTypes)
 {
-  const mp_int_type x("-987771");
-  const mp_int_type z = x % 16U;
+  const int_type x("-987771");
+  const int_type z = x % 16U;
   BOOST_CHECK_EQUAL(z, "-11");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_signed_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_signed_integral1, int_type, IntTypes)
 {
-  const mp_int_type x("786432");
-  const mp_int_type z = x | 1;
+  const int_type x("786432");
+  const int_type z = x | 1;
   BOOST_CHECK_EQUAL(z, "786433");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_signed_integral2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_signed_integral2, int_type, IntTypes)
 {
-  const mp_int_type x("786432");
-  const mp_int_type z = x | -1;
-  BOOST_CHECK_EQUAL(z, "786433");
+  const int_type x("786432");
+  const int_type z = x | -1;
+  BOOST_CHECK_EQUAL(z, "-786433");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_unsigned_integral1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_unsigned_integral1, int_type, IntTypes)
 {
-  const mp_int_type x("786432");
-  const mp_int_type z = x | 1U;
+  const int_type x("786432");
+  const int_type z = x | 1U;
   BOOST_CHECK_EQUAL(z, "786433");
 }
 
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/jacobi.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/jacobi.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/jacobi.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/jacobi.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -7,26 +7,26 @@
 #include "prerequisite.hpp"
 
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi1, mp_int_type, mp_int_types)
+/*BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi1, int_type, IntTypes)
 {
-  const mp_int_type x("1236");
-  const mp_int_type y("20003");
+  const int_type x("1236");
+  const int_type y("20003");
   const int z = boost::mp_math::jacobi(x,y);
   BOOST_CHECK_EQUAL(z, 1);
-}
+}*/
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi2, int_type, IntTypes)
 {
-  const mp_int_type x("987897");
-  const mp_int_type y("987");
+  const int_type x("987897");
+  const int_type y("987");
   const int z = boost::mp_math::jacobi(x,y);
   BOOST_CHECK_EQUAL(z, 0);
 }
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi3, mp_int_type, mp_int_types)
+/*
+BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi3, int_type, IntTypes)
 {
-  const mp_int_type x("610");
-  const mp_int_type y("987");
+  const int_type x("610");
+  const int_type y("987");
   const int z = boost::mp_math::jacobi(x,y);
   BOOST_CHECK_EQUAL(z, -1);
-}
+}*/
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/jamfile.v2 (from r54148, /sandbox/mp_math/libs/mp_math/test/jamfile.v2)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/jamfile.v2	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/jamfile.v2	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -9,16 +9,9 @@
 alias boost_serialization
 : $(BOOST_ROOT)/libs/serialization/build//boost_serialization/<link>shared ;
 
-project
-  : requirements
-    <include>../../..
-    <link>static
-    <define>BOOST_TEST_DYN_LINK
-    <define>BOOST_TEST_MAIN
-    <define>BOOST_MP_MATH_MP_INT_USE_ASM
-  ;
-
+unit-test abs             : abs.cpp             boost_test ;
 unit-test add             : add.cpp             boost_test ;
+unit-test assign          : assign.cpp          boost_test ;
 unit-test bitmanipulation : bitmanipulation.cpp boost_test ;
 unit-test bitwise_ops     : bitwise_ops.cpp     boost_test ;
 unit-test bool_conversion : bool_conversion.cpp boost_test ;
@@ -32,6 +25,7 @@
 unit-test modinv          : modinv.cpp          boost_test ;
 unit-test modpow          : modpow.cpp          boost_test ;
 unit-test mul             : mul.cpp             boost_test ;
+unit-test numeric_limits  : numeric_limits.cpp  boost_test ;
 unit-test pow             : pow.cpp             boost_test ;
 unit-test prime           : prime.cpp           boost_test ;
 unit-test random          : random.cpp          boost_test ;
@@ -42,7 +36,6 @@
 unit-test sub             : sub.cpp             boost_test ;
 unit-test stream_io       : stream_io.cpp       boost_test ;
 unit-test string_ops      : string_ops.cpp      boost_test ;
+unit-test swap            : swap.cpp            boost_test ;
 unit-test to_integral     : to_integral.cpp     boost_test ;
-unit-test traits          : traits.cpp          boost_test ;
-#unit-test compile_all     : compile_all.cpp     boost_test ;
 
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/lcm.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/lcm.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/lcm.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/lcm.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -7,47 +7,71 @@
 #include "prerequisite.hpp"
 
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(lcm1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(lcm1, int_type, IntTypes)
 {
-  const mp_int_type x("0");
-  const mp_int_type y("0");
-  const mp_int_type z = boost::mp_math::lcm(x,y);
+  const int_type x("0");
+  const int_type y("0");
+  const int_type z = boost::mp_math::lcm(x,y);
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(lcm2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(lcm2, int_type, IntTypes)
 {
-  const mp_int_type x("51111");
-  const mp_int_type y("0");
-  const mp_int_type z = boost::mp_math::lcm(x,y);
+  const int_type x("51111");
+  const int_type y("0");
+  const int_type z = boost::mp_math::lcm(x,y);
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(lcm3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(lcm3, int_type, IntTypes)
 {
-  const mp_int_type x("4");
-  const mp_int_type y("6");
-  const mp_int_type z = boost::mp_math::lcm(x,y);
+  const int_type x("4");
+  const int_type y("6");
+  const int_type z = boost::mp_math::lcm(x,y);
+  BOOST_CHECK_EQUAL(z, "12");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(lcm4, int_type, IntTypes)
+{
+  const int_type x("-4");
+  const int_type y("6");
+  const int_type z = boost::mp_math::lcm(x,y);
+  BOOST_CHECK_EQUAL(z, "12");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(lcm5, int_type, IntTypes)
+{
+  const int_type x("4");
+  const int_type y("-6");
+  const int_type z = boost::mp_math::lcm(x,y);
+  BOOST_CHECK_EQUAL(z, "12");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(lcm6, int_type, IntTypes)
+{
+  const int_type x("-4");
+  const int_type y("-6");
+  const int_type z = boost::mp_math::lcm(x,y);
   BOOST_CHECK_EQUAL(z, "12");
 }
 
 #ifdef BOOST_HAS_VARIADIC_TMPL
-BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_lcm1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_lcm1, int_type, IntTypes)
 {
-  const mp_int_type a("120");
-  const mp_int_type b("204");
-  const mp_int_type c("136");
-  const mp_int_type z = boost::mp_math::lcm(a,b,c);
+  const int_type a("120");
+  const int_type b("204");
+  const int_type c("136");
+  const int_type z = boost::mp_math::lcm(a,b,c);
   BOOST_CHECK_EQUAL(z, "2040");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_lcm2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_lcm2, int_type, IntTypes)
 {
-  const mp_int_type a("12010");
-  const mp_int_type b("3299");
-  const mp_int_type c("84780");
-  const mp_int_type d("15");
-  const mp_int_type z = boost::mp_math::lcm(a,b,c,d);
+  const int_type a("12010");
+  const int_type b("3299");
+  const int_type c("84780");
+  const int_type d("15");
+  const int_type z = boost::mp_math::lcm(a,b,c,d);
   BOOST_CHECK_EQUAL(z, "335906753220");
 }
 #endif
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/modinv.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/modinv.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/modinv.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/modinv.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,20 +6,28 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modinv1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modinv1, int_type, IntTypes)
 {
-  mp_int_type a("35");
-  mp_int_type m("33");
-  mp_int_type i = boost::mp_math::modinv(a, m);
+  const int_type a("35");
+  const int_type m("33");
+  const int_type i = boost::mp_math::modinv(a, m);
   BOOST_CHECK_EQUAL(i, "17");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modinv2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modinv2, int_type, IntTypes)
 {
-  mp_int_type a("17");
-  mp_int_type m("26");
-  mp_int_type i = boost::mp_math::modinv(a, m);
+  const int_type a("17");
+  const int_type m("26");
+  const int_type i = boost::mp_math::modinv(a, m);
   BOOST_CHECK_EQUAL(i, "23");
 }
 
+BOOST_AUTO_TEST_CASE_TEMPLATE(modinv3, int_type, IntTypes)
+{
+  const int_type a("982451111"); // is a prime
+  const int_type m("982451653"); // is a prime
+  const int_type i = boost::mp_math::modinv(a, m);
+  BOOST_CHECK_EQUAL(i, "871880526");
+}
+
 
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/modpow.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/modpow.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/modpow.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/modpow.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,97 +6,97 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow1, int_type, IntTypes)
 {
-  const mp_int_type x("2");
-  const mp_int_type exp("14");
-  const mp_int_type m("8");
-  const mp_int_type z = modpow(x, exp, m);
+  const int_type x("2");
+  const int_type exp("14");
+  const int_type m("8");
+  const int_type z = boost::mp_math::modpow(x, exp, m);
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow2, int_type, IntTypes)
 {
-  const mp_int_type x("4");
-  const mp_int_type exp("13");
-  const mp_int_type m("497");
-  const mp_int_type z = modpow(x, exp, m);
+  const int_type x("4");
+  const int_type exp("13");
+  const int_type m("497");
+  const int_type z = boost::mp_math::modpow(x, exp, m);
   BOOST_CHECK_EQUAL(z, "445");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow3, int_type, IntTypes)
 {
-  const mp_int_type x("2395422");
-  const mp_int_type exp("2424832");
-  const mp_int_type m("2424833");
-  const mp_int_type z = modpow(x, exp, m);
+  const int_type x("2395422");
+  const int_type exp("2424832");
+  const int_type m("2424833");
+  const int_type z = boost::mp_math::modpow(x, exp, m);
   BOOST_CHECK_EQUAL(z, "1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow4, int_type, IntTypes)
 {
-  const mp_int_type x("184");
-  const mp_int_type exp("560");
-  const mp_int_type m("561");
-  const mp_int_type z = modpow(x, exp, m);
+  const int_type x("184");
+  const int_type exp("560");
+  const int_type m("561");
+  const int_type z = boost::mp_math::modpow(x, exp, m);
   BOOST_CHECK_EQUAL(z, "1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow5, int_type, IntTypes)
 {
-  const mp_int_type x("997028168093060821869770104094480850560519901475");
-  const mp_int_type exp("7455602825647884208337395736200454918783366342656");
-  const mp_int_type m("7455602825647884208337395736200454918783366342657");
-  const mp_int_type z = modpow(x, exp, m);
+  const int_type x("997028168093060821869770104094480850560519901475");
+  const int_type exp("7455602825647884208337395736200454918783366342656");
+  const int_type m("7455602825647884208337395736200454918783366342657");
+  const int_type z = boost::mp_math::modpow(x, exp, m);
   BOOST_CHECK_EQUAL(z, "1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow6, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow6, int_type, IntTypes)
 {
-  const mp_int_type x("184");
-  const mp_int_type exp("5600");
-  const mp_int_type m("2668");
-  const mp_int_type z = modpow(x, exp, m);
+  const int_type x("184");
+  const int_type exp("5600");
+  const int_type m("2668");
+  const int_type z = boost::mp_math::modpow(x, exp, m);
   BOOST_CHECK_EQUAL(z, "552");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow7, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow7, int_type, IntTypes)
 {
-  const mp_int_type x("0x201abcff00aaffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffd6d7");
-  const mp_int_type exp("0x123456789abcdef01");
+  const int_type x("0x201abcff00aaffffffffffffffffffffffffffffffffffffffffff"
+                   "ffffffffd6d7");
+  const int_type exp("0x123456789abcdef01");
   // a modulus of type unrestricted diminished radix (2^253 - 41);
-  const mp_int_type m("0x1fffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffd7");
-  const mp_int_type z = modpow(x, exp, m);
+  const int_type m("0x1fffffffffffffffffffffffffffffffffffffffffffffffffffff"
+                   "ffffffffd7");
+  const int_type z = boost::mp_math::modpow(x, exp, m);
   BOOST_CHECK_EQUAL(z, "0x8f112a89871984cde410bb05621d5a6073557d2da0444b6681699"
                        "80b5ef825a");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow8, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow8, int_type, IntTypes)
 {
-  const mp_int_type x("0x201abcff00aaffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffd6d7123456789abcdef01123456789abcdef01ffffffff");
-  const mp_int_type exp("0x123456789abcdef018978979899");
+  const int_type x("0x201abcff00aaffffffffffffffffffffffffffffffffffffffffff"
+                   "ffffffffd6d7123456789abcdef01123456789abcdef01ffffffff");
+  const int_type exp("0x123456789abcdef018978979899");
   // a modulus of type unrestricted diminished radix slow (2^503 - exp)
-  const mp_int_type m("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                      "fffffffffffffffffffffffffffffffffffffffffffffedcba987654"
-                      "3210fe7687686767");
-  const mp_int_type z = modpow(x, exp, m);
+  const int_type m("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffff"
+                   "fffffffffffffffffffffffffffffffffffffffffffffedcba987654"
+                   "3210fe7687686767");
+  const int_type z = boost::mp_math::modpow(x, exp, m);
   BOOST_CHECK_EQUAL(z, "0x1ada35751ae1f5fec7ab0e60f6c924d5f4a4a5d8f6786cdd78838"
                        "5ab16ebd994ee9aaea5faef3f490822ef443fd3e169caa3b608162e"
                        "01d40a593e775c9fa5");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(modpow9, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(modpow9, int_type, IntTypes)
 {
-  const mp_int_type x("0x201abcff00aaffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffd6d7123456789abcdef01123456789abcdef01ffffffff");
-  const mp_int_type exp("0x123456789abcdef018978979899");
+  const int_type x("0x201abcff00aaffffffffffffffffffffffffffffffffffffffffff"
+                   "ffffffffd6d7123456789abcdef01123456789abcdef01ffffffff");
+  const int_type exp("0x123456789abcdef018978979899");
   // a modulus of type restricted diminished radix (2^256 - 53)
-  const mp_int_type m("0xffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-                      "ffffffffcb");
-  const mp_int_type z = modpow(x, exp, m);
+  const int_type m("0xffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+                   "ffffffffcb");
+  const int_type z = boost::mp_math::modpow(x, exp, m);
   BOOST_CHECK_EQUAL(z, "0x777b5d9b290fbb5f99e4668cf1b0f723d3228fc252da492c54b75"
                        "8379f3024e4");
 }
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/mul.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/mul.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/mul.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/mul.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,51 +6,60 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul_assign1, int_type, IntTypes)
+{
+  int_type x("12");
+  const int_type y("22459455");
+  x *= y;
+  BOOST_CHECK_EQUAL(x, "269513460");
+}
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul1, int_type, IntTypes)
 {
-  const mp_int_type x("12");
-  const mp_int_type y("22459455");
-  const mp_int_type z = x * y;
+  const int_type x("12");
+  const int_type y("22459455");
+  const int_type z = x * y;
   BOOST_CHECK_EQUAL(z, "269513460");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul2, int_type, IntTypes)
 {
-  const mp_int_type x("280708");
-  const mp_int_type y("2245945");
-  const mp_int_type z = x * y;
+  const int_type x("280708");
+  const int_type y("2245945");
+  const int_type z = x * y;
   BOOST_CHECK_EQUAL(z, "630454729060");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul3, int_type, IntTypes)
 {
-  const mp_int_type x("65536");
-  const mp_int_type y("65536");
-  const mp_int_type z = x * y;
-  BOOST_CHECK_EQUAL(z, "4294967296");
+  const int_type x("-65536");
+  const int_type y("65536");
+  const int_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "-4294967296");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul4, int_type, IntTypes)
 {
-  const mp_int_type x("1234567890123456789");
-  const mp_int_type y("9877771234567890123");
-  const mp_int_type z = x * y;
+  const int_type x("-1234567890123456789");
+  const int_type y("-9877771234567890123");
+  const int_type z = x * y;
   BOOST_CHECK_EQUAL(z, "12194779192182653090000267987090395047");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul5, int_type, IntTypes)
 {
-  const mp_int_type x("789456120556882111687894651457623561325656871513");
-  const mp_int_type y("54564563128978513215");
-  const mp_int_type z = x * y;
-  BOOST_CHECK_EQUAL(z, "43076328327684465744675616648356768900793087398990591539995027544295");
+  const int_type x("789456120556882111687894651457623561325656871513");
+  const int_type y("54564563128978513215");
+  const int_type z = x * y;
+  const int_type w(
+    "43076328327684465744675616648356768900793087398990591539995027544295");
+  BOOST_CHECK_EQUAL(z, w);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul6, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul6, int_type, IntTypes)
 {
   // this tests karatsuba multiplication for 8, 16 and 32 bit digit_type
-  const mp_int_type x(
+  const int_type x(
     "87500402519005030061267904448809305029512439942506161234260852587645856336"
     "94640987107484273728362553552515383304557585868121651546490330517814007487"
     "34682745159208158750835203309620570274592666481348052963762094268695162425"
@@ -62,7 +71,7 @@
     "45994041206565648683544493690427219798945006072652042753387791345064784511"
     "50227920502852884378111055250850357557404795594025600468996407045934090727"
     "08041078777870387730504");
-  const mp_int_type y(
+  const int_type y(
     "87500402519005030061267904448809305029512439942506161234260852587645856336"
     "94640987107484273728362553552515383304557585868121651546490330517814007487"
     "34682745159208158750835203309620570274592666481348052963762094268695162425"
@@ -101,10 +110,10 @@
     "13953490712153270721924306359669195669881431604926261623147833800912453474"
     "06542388952383807976431616628717886593805647129190060659586374949333503420"
     "5241703455510726935");
-  
-  const mp_int_type z = x * y;
-  
-  const mp_int_type w(
+
+  const int_type z = x * y;
+
+  const int_type w(
     "76563204409879018101322737668344063995824904757312285775560614771886933079"
     "77822556905976720912850551355328340715074887289899094852653102687850101285"
     "85715275531977696497398396067715769512450915961775500023723324150851793075"
@@ -157,10 +166,10 @@
   BOOST_CHECK_EQUAL(z, w);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(mul7, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul7, int_type, IntTypes)
 {
   // this tests toom cook multiplication for 8, 16 and 32 bit digit_type
-  const mp_int_type x(
+  const int_type x(
     "0x5004a2519b00503006126bb044af8930502951243994250616123426085258764a856336"
     "35702406cff061642794728883255642074744145228324022219347019013411158803532"
     "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
@@ -209,7 +218,7 @@
     "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
     "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
     "f84c878148cc7020890befffaa4506cebbef9a3f7c67178f2");
-  const mp_int_type y(
+  const int_type y(
     "0x875aa402519005030061267904ccc8809d0502243994250616123426085258764585633a"
     "94640987107484273728362553552515383304557585868121651546490330517814007487"
     "34682745159208158750835203309620570274592666481348052963762094268695162425"
@@ -259,10 +268,10 @@
     "13953490712153270721924306359669195669881431604926261623147833800912453474"
     "06542388952383807976431616628717886593805647129190060659586374949333503420"
     "ffab023789d7d78f78a45a45fee789001a1a");
-  
-  const mp_int_type z = x * y;
 
-  const mp_int_type w(
+  const int_type z = x * y;
+
+  const int_type w(
     "0x2a4ec67dcaf1afdd14bf63d7cd883f269ca00be2cae5c539545352050e33af7bb008713c"
     "63587bc02911b0cb1fb807d94cd4a937f6e19801a28500f45ba1dc90a548e8e15e0c31536b"
     "39f3940191a76b6fd96fda83c7aa9aa675f536633917587fbdb4990f73dc4650e19af67392"
@@ -360,7 +369,7 @@
     "900e091c8e047e6f618acac52dea702c4ca72acd001f2c056291d71e8e7e49ea13afae0d3f"
     "66a7d7dd8d6a264ca4be9eb02549bf40e61f1e2e4f01fe4ceafd7855686747eb1b1acd2c96"
     "92fcedc94");
-  
+
   BOOST_CHECK_EQUAL(z, w);
 }
 
Added: sandbox/mp_math/libs/mp_math/test/unbounded/signed/numeric_limits.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/numeric_limits.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,18 @@
+// Copyright Kevin Sopp 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(is_signed, int_type, IntTypes)
+{
+  BOOST_CHECK_EQUAL(std::numeric_limits<int_type>::is_signed, true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(is_bounded, int_type, IntTypes)
+{
+  BOOST_CHECK_EQUAL(std::numeric_limits<int_type>::is_bounded, false);
+}
+
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/pow.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/pow.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/pow.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/pow.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,52 +6,82 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_1, mp_int_type, mp_int_types)
+/*BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_1, int_type, IntTypes)
 {
-  mp_int_type x;
+  int_type x;
   x.pow2(0);
   BOOST_CHECK_EQUAL(x, "1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_2, int_type, IntTypes)
 {
-  mp_int_type x;
+  int_type x;
   x.pow2(1);
   BOOST_CHECK_EQUAL(x, "2");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_3, int_type, IntTypes)
 {
-  mp_int_type x;
+  int_type x;
   x.pow2(64);
   BOOST_CHECK_EQUAL(x, "18446744073709551616");
 }
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow1, mp_int_type, mp_int_types)
+*/
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow1, int_type, IntTypes)
 {
-  const mp_int_type x("2");
-  const mp_int_type z = pow(x, 0);
+  const int_type x("2");
+  const int_type z = pow(x, 0);
   BOOST_CHECK_EQUAL(z, "1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow2, int_type, IntTypes)
 {
-  const mp_int_type x("2");
-  const mp_int_type z = pow(x, 1);
+  const int_type x("2");
+  const int_type z = pow(x, 1);
   BOOST_CHECK_EQUAL(z, "2");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow3, int_type, IntTypes)
 {
-  const mp_int_type x("2");
-  const mp_int_type z = pow(x, 64);
+  const int_type x("2");
+  const int_type z = pow(x, 64);
   BOOST_CHECK_EQUAL(z, "18446744073709551616");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow4, int_type, IntTypes)
+{
+  const int_type x("-2");
+  const int_type z = pow(x, 64);
+  BOOST_CHECK_EQUAL(z, "18446744073709551616");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow5, int_type, IntTypes)
+{
+  const int_type x("-2");
+  const int_type z = pow(x, 63);
+  BOOST_CHECK_EQUAL(z, "-0x8000000000000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow6, int_type, IntTypes)
+{
+  const int_type x("-0x5abbdf3478aa00");
+  const int_type z = pow(x, 4);
+  BOOST_CHECK_EQUAL(z,
+    "0x40a2f27784f54fc480bce13f80a50a2ed92396abc2b4b1000000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow7, int_type, IntTypes)
+{
+  const int_type x("-0x5abbdf3478aa00");
+  const int_type z = pow(x, 5);
+  BOOST_CHECK_EQUAL(z,
+    "-0x16e8b8a052d3083215ce1982a007171c266ccb004649d9f8cf36f2f58a00000000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow8, int_type, IntTypes)
 {
-  const mp_int_type x = pow(mp_int_type("301"), mp_int_type("259"));
-  const mp_int_type z(
+  const int_type x = pow(int_type("301"), int_type("259"));
+  const int_type z(
     "0x16becbb1b891cbbbab4825ed1335f0f4ef5250f620023061045e87ca80d80ea7daf0cda8"
     "023aed1a969864de781297ae556f2bba6d951ae294805dc888f6de01dac2b7dd3ab47db207"
     "b0f980f26a54f1c7dbb3ebc6cd5b952cccc67569487fd2aea057d4326cc56aad90ecd89b3c"
@@ -63,10 +93,10 @@
   BOOST_CHECK_EQUAL(x, z);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(pow5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow9, int_type, IntTypes)
 {
-  const mp_int_type x = pow(mp_int_type("3"), mp_int_type("66666"));
-  const mp_int_type z(
+  const int_type x = pow(int_type("3"), int_type("66666"));
+  const int_type z(
     "0x8a25f1339bf63db8e5881f75e7f89ad860d393776362040a47448cfbcb4a9402558acf60"
     "7a590c1fa521b672329cc18a63eca1cadf87465bf8b44ef05fce12fb020ebf2c2b246d9a36"
     "af527f947f3d238d3e2504dd5a0f3a071dc98784d1084cbfc4554fc21d72f72ae65766600a"
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/prerequisite.hpp (from r54148, /sandbox/mp_math/libs/mp_math/test/prerequisite.hpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/prerequisite.hpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/prerequisite.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,42 +1,60 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
 
 #include <boost/cstdint.hpp>
-#include <boost/mp_math/mp_int.hpp>
+#include <boost/mp_math/integer.hpp>
 #include <boost/mpl/unique.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/type_traits/is_same.hpp>
 
-//typedef boost::mp_math::mp_int_traits<boost::uint8_t, boost::uint16_t> traits_type;
-//typedef boost::mp_math::mp_int_traits<boost::uint16_t, boost::uint32_t> traits_type;
-//typedef boost::mp_math::mp_int_traits<boost::uint32_t, boost::uint64_t> traits_type;
-//typedef boost::mp_math::mp_int_traits<> traits_type;
-
-//typedef boost::mp_math::mp_int<std::allocator<void>, traits_type> mp_int_type;
-
+static const bool use_debug_mode = true;
 
 typedef boost::mpl::vector<
-  boost::mp_math::mp_int<
-    std::allocator<void>,
-    boost::mp_math::mp_int_traits<boost::uint8_t, boost::uint16_t>
+  boost::mp_math::integer<
+    boost::mp_math::unbounded<
+      true,
+      std::allocator<void>,
+      boost::mp_math::unbounded_traits<
+        boost::uint8_t, boost::uint16_t, std::size_t, use_debug_mode
+      >
+    >
   >,
-  boost::mp_math::mp_int<
-    std::allocator<void>,
-    boost::mp_math::mp_int_traits<boost::uint16_t, boost::uint32_t>
+  boost::mp_math::integer<
+    boost::mp_math::unbounded<
+      true,
+      std::allocator<void>,
+      boost::mp_math::unbounded_traits<
+        boost::uint16_t, boost::uint32_t, std::size_t, use_debug_mode
+      >
+    >
   >,
 #ifndef BOOST_NO_INT64_T
-  boost::mp_math::mp_int<
-    std::allocator<void>,
-    boost::mp_math::mp_int_traits<boost::uint32_t, boost::uint64_t>
+  boost::mp_math::integer<
+    boost::mp_math::unbounded<
+      true,
+      std::allocator<void>,
+      boost::mp_math::unbounded_traits<
+        boost::uint32_t, boost::uint64_t, std::size_t, use_debug_mode
+      >
+    >
   >,
 #endif
-  boost::mp_math::mp_int<>
-> some_mp_int_types;
+  boost::mp_math::integer<boost::mp_math::unbounded<true> >
+> IntTypes2;
+
 
-typedef boost::mpl::unique<
-  some_mp_int_types, boost::is_same<boost::mpl::_1, boost::mpl::_2>
->::type mp_int_types;
+struct IntTypes
+:
+  boost::mpl::if_c<
+    use_debug_mode,
+      IntTypes2,
+      boost::mpl::unique<
+        IntTypes2,
+        boost::is_same<boost::mpl::_1, boost::mpl::_2>
+    >
+  >::type
+{};
 
 
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/prime.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/prime.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/prime.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/prime.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -74,7 +74,7 @@
 
   // composites with small factors
   composites.push_back("2530121");
-  
+
   // composites with large factors
   // from http://web.mit.edu/kenta/www/three/prime/composites.html.gz
   /*composites.push_back("241999944999997");
@@ -151,60 +151,62 @@
 
 
 // primality tests
-BOOST_AUTO_TEST_CASE_TEMPLATE(prime_is_divisible1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(prime_is_divisible1, int_type, IntTypes)
 {
   using namespace boost::mp_math;
 
-  fixture<mp_int_type> f;
-  typedef typename std::vector<mp_int_type>::const_iterator iter;
+  fixture<int_type> f;
+  typedef typename std::vector<int_type>::const_iterator iter;
 
   for (iter i = f.primes.begin(); i != f.primes.end(); ++i)
     BOOST_CHECK_EQUAL(is_prime(*i, primality_division_test()), true);
-  
+
   for (iter i = f.composites.begin(); i != f.composites.end(); ++i)
     BOOST_CHECK_EQUAL(is_prime(*i, primality_division_test()), false);
 }
 
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(prime_fermat_test1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(prime_fermat_test1, int_type, IntTypes)
 {
   using namespace boost;
 
   mp_math::primality_fermat_test<
-    mp_math::uniform_mp_int<mp_int_type>
+    mp_math::uniform_integer<int_type>
   > fermat_test(1);
 
   mt19937 rng;
 
-  fixture<mp_int_type> f;
-  typedef typename std::vector<mp_int_type>::const_iterator iter;
+  fixture<int_type> f;
+  typedef typename std::vector<int_type>::const_iterator iter;
 
   for (iter i = f.primes.begin(); i != f.primes.end(); ++i)
-    BOOST_CHECK_EQUAL(boost::mp_math::is_prime(*i, bind(fermat_test, rng, _1)), true);
-  
+    BOOST_CHECK_EQUAL(
+        boost::mp_math::is_prime(*i, bind(fermat_test, rng, _1)), true);
+
   for (iter i = f.composites.begin(); i != f.composites.end(); ++i)
-    BOOST_CHECK_EQUAL(boost::mp_math::is_prime(*i, bind(fermat_test, rng, _1)), false);
+    BOOST_CHECK_EQUAL(
+        boost::mp_math::is_prime(*i, bind(fermat_test, rng, _1)), false);
 }
 
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(prime_miller_rabin_test1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(prime_miller_rabin_test1, int_type, IntTypes)
 {
   using namespace boost;
 
   mp_math::primality_miller_rabin_test<
-    mp_math::uniform_mp_int<mp_int_type>
+    mp_math::uniform_integer<int_type>
   > mr_test;
 
   mt19937 rng;
 
-  fixture<mp_int_type> f;
-  typedef typename std::vector<mp_int_type>::const_iterator iter;
+  fixture<int_type> f;
+  typedef typename std::vector<int_type>::const_iterator iter;
   for (iter i = f.primes.begin(); i != f.primes.end(); ++i)
     BOOST_CHECK_EQUAL(mp_math::is_prime(*i, bind(mr_test, rng, _1)), true);
-  
+
   for (iter i = f.composites.begin(); i != f.composites.end(); ++i)
     BOOST_CHECK_EQUAL(mp_math::is_prime(*i, bind(mr_test, rng, _1)), false);
-  
+
   for (iter i = f.carmichaels.begin(); i != f.carmichaels.end(); ++i)
     BOOST_CHECK_EQUAL(mp_math::is_prime(*i, bind(mr_test, rng, _1)), false);
 }
@@ -220,24 +222,27 @@
 
   explicit tester(const Engine& e) : rng(e) {}
 
-  template<class A, class T>
-  bool operator()(const boost::mp_math::mp_int<A,T>& p)
+  template<class ApInt>
+  bool operator()(const ApInt& p)
   {
     return test1(p) && test2(rng, p);
   }
 };
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(generate_safe_prime_128bits, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(generate_safe_prime_128bits, int_type, IntTypes)
 {
-  typedef tester<boost::mt19937, boost::mp_math::uniform_mp_int<mp_int_type> > tester_type;
-  typedef boost::mp_math::uniform_mp_int_bits<mp_int_type> distribution_type;
-  
+  typedef tester<
+    boost::mt19937, boost::mp_math::uniform_integer<int_type>
+  > tester_type;
+
+  typedef boost::mp_math::uniform_integer_bits<int_type> distribution_type;
+
   boost::mt19937 rng;
 
   boost::mp_math::safe_prime_generator<tester_type, distribution_type>
     generator(128U, tester_type(rng));
 
-  const mp_int_type safe_prime = generator(rng);
+  const int_type safe_prime = generator(rng);
 
   BOOST_CHECK_EQUAL(safe_prime.precision(), 128U);
 }
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/random.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/random.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/random.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/random.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,72 +6,73 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int1, mp_int_type, mp_int_types)
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_integer1, int_type, IntTypes)
 {
-  const mp_int_type min(0), max(128);
-  boost::mp_math::uniform_mp_int<mp_int_type> g(min, max);
+  const int_type min(0), max(128);
+  boost::mp_math::uniform_integer<int_type> g(min, max);
   boost::mt19937 e;
   for (int i = 0; i < 128; ++i)
   {
-    const mp_int_type x = g(e);
+    const int_type x = g(e);
     BOOST_REQUIRE_GE(x, min);
     BOOST_REQUIRE_LE(x, max);
   }
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_integer2, int_type, IntTypes)
 {
-  const mp_int_type min(11), max("26546549");
-  boost::mp_math::uniform_mp_int<mp_int_type> g(min, max);
+  const int_type min(11), max("26546549");
+  boost::mp_math::uniform_integer<int_type> g(min, max);
   boost::mt19937 e;
   for (int i = 0; i < 1000; ++i)
   {
-    const mp_int_type x = g(e);
+    const int_type x = g(e);
     BOOST_REQUIRE_GE(x, min);
     BOOST_REQUIRE_LE(x, max);
   }
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_integer_bits1, int_type, IntTypes)
 {
   BOOST_CHECK_EQUAL(
-      boost::mp_math::uniform_mp_int_bits<mp_int_type>::has_fixed_range, false);
+      boost::mp_math::uniform_integer_bits<int_type>::has_fixed_range, false);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_integer_bits2, int_type, IntTypes)
 {
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(512);
+  boost::mp_math::uniform_integer_bits<int_type> g(512);
   boost::mt19937 e;
-  const mp_int_type x = g(e);
+  const int_type x = g(e);
   BOOST_CHECK_EQUAL(x.precision(), 512U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_integer_bits3, int_type, IntTypes)
 {
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(71);
+  boost::mp_math::uniform_integer_bits<int_type> g(71);
   boost::mt19937 e;
-  const mp_int_type x = g(e);
+  const int_type x = g(e);
   BOOST_CHECK_EQUAL(x.precision(), 71U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_integer_bits4, int_type, IntTypes)
 {
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(1001);
+  boost::mp_math::uniform_integer_bits<int_type> g(1001);
   boost::mt19937 e;
-  const mp_int_type x = g(e);
+  const int_type x = g(e);
   BOOST_CHECK_EQUAL(x.precision(), 1001U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_integer_bits5, int_type, IntTypes)
 {
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(8);
+  boost::mp_math::uniform_integer_bits<int_type> g(8);
   BOOST_CHECK_EQUAL(g.min(), 128U);
   BOOST_CHECK_EQUAL(g.max(), 255U);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_mp_int_bits6, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(uniform_integer_bits6, int_type, IntTypes)
 {
-  boost::mp_math::uniform_mp_int_bits<mp_int_type> g(11);
+  boost::mp_math::uniform_integer_bits<int_type> g(11);
   BOOST_CHECK_EQUAL(g.min(), 1024U);
   BOOST_CHECK_EQUAL(g.max(), 2047U);
 }
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/root.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/root.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/root.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/root.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,30 +6,44 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt1, int_type, IntTypes)
 {
-  const mp_int_type x("279841");
-  const mp_int_type y = sqrt(x);
+  const int_type x("279841");
+  const int_type y = sqrt(x);
   BOOST_CHECK_EQUAL(y, "529");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt2, int_type, IntTypes)
 {
-  const mp_int_type x("78310985281");
-  const mp_int_type y = sqrt(x);
+  const int_type x("78310985281");
+  const int_type y = sqrt(x);
   BOOST_CHECK_EQUAL(y, "279841");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root1, int_type, IntTypes)
 {
-  const mp_int_type x("85766121");
-  const mp_int_type y = nth_root(x, 3);
+  const int_type x("130321");
+  const int_type y = nth_root(4, x);
+  BOOST_CHECK_EQUAL(y, "19");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root2, int_type, IntTypes)
+{
+  const int_type x("85766121");
+  const int_type y = nth_root(3, x);
   BOOST_CHECK_EQUAL(y, "441");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root3, int_type, IntTypes)
+{
+  const int_type x("-85766121");
+  const int_type y = nth_root(3, x);
+  BOOST_CHECK_EQUAL(y, "-441");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root4, int_type, IntTypes)
 {
-  const mp_int_type x(
+  const int_type x(
     "0x2b93d251afa09c5481f4522279f7c19ca08124199621dfd18342a16c7303b31ccea8176b"
     "d4a7a9bf991e30d8bde1e08356a728b9f5729c35d29884050101341228c5df3f98354d42b7"
     "a0d7fdfbe8d5270b09ee89ba1eeab61be67eb4471d92fdffa88d1ca494ed3eec58a34ff958"
@@ -37,7 +51,21 @@
     "b75cab98f8c4c6f3837977db2a594dfa16943062187ca95babc9da78bdd73ca7233eefc047"
     "8d882e0d4f09a5083a31b801964343d47b6ce9e937df8c44a9a02bac5101da1823373e663c"
     "1329ece1eb89fc178355660fe1c92c7d8ff11524702fad6e2255447946442356b00810101");
-  const mp_int_type y = nth_root(x, mp_int_type("257"));
+  const int_type y = nth_root(int_type("257"), x);
   BOOST_CHECK_EQUAL(y, "257");
 }
 
+BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root5, int_type, IntTypes)
+{
+  const int_type x(
+    "-0x2b93d251afa09c5481f4522279f7c19ca08124199621dfd18342a16c7303b31ccea8176b"
+    "d4a7a9bf991e30d8bde1e08356a728b9f5729c35d29884050101341228c5df3f98354d42b7"
+    "a0d7fdfbe8d5270b09ee89ba1eeab61be67eb4471d92fdffa88d1ca494ed3eec58a34ff958"
+    "b518a588584a2505c9c2b19ce1eb21cba36c7a5297cb6e532884e89451f4406b993582f3cd"
+    "b75cab98f8c4c6f3837977db2a594dfa16943062187ca95babc9da78bdd73ca7233eefc047"
+    "8d882e0d4f09a5083a31b801964343d47b6ce9e937df8c44a9a02bac5101da1823373e663c"
+    "1329ece1eb89fc178355660fe1c92c7d8ff11524702fad6e2255447946442356b00810101");
+  const int_type y = nth_root(int_type("257"), x);
+  BOOST_CHECK_EQUAL(y, "-257");
+}
+
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/serialization.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/serialization.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/serialization.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/serialization.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -8,20 +8,28 @@
 #include <boost/archive/text_iarchive.hpp>
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
-#include <boost/mp_math/mp_int_serialization.hpp>
+#include <boost/mp_math/integer_serialization.hpp>
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(test_serialization1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_serialization1, int_type, IntTypes)
 {
-  mp_int_type x("0x123456789abcdef257");
-  mp_int_type y;
+  int_type x("-0x123456789abcdef25700000000003a");
+  int_type y;
 
   std::stringstream s;
-  
-  boost::archive::text_oarchive oa(s);
-  oa << x;
-  
-  boost::archive::text_iarchive ia(s);
-  ia >> y;
+
+  // Wrap this in a block so that the text_oarchive dtor writes a terminating
+  // null character to the stream before opening an input archive on it.
+  // See the note on the stream_error exception in the Boost.Serialization
+  // documentation.
+  {
+    boost::archive::text_oarchive oa(s);
+    oa << x;
+  }
+
+  {
+    boost::archive::text_iarchive ia(s);
+    ia >> y;
+  }
 
   BOOST_CHECK_EQUAL(x, y);
 }
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/shift.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/shift.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/shift.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/shift.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,44 +6,52 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift1, int_type, IntTypes)
 {
-  mp_int_type x("246556567891512374789511237456594795648912323213860000007849");
+  int_type x("12");
+  x <<= 3;
+  const int_type y("96");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift2, int_type, IntTypes)
+{
+  int_type x("246556567891512374789511237456594795648912323213860000007849");
   x <<= 2;
-  const mp_int_type y(
+  const int_type y(
       "986226271566049499158044949826379182595649292855440000031396");
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift3, int_type, IntTypes)
 {
-  mp_int_type x("246556567891512374789511237456594795648912323213860000007849");
+  int_type x("246556567891512374789511237456594795648912323213860000007849");
   x <<= 99;
-  const mp_int_type y(
+  const int_type y(
       "156273790638943927367154966864556037925514287264587565911690950563681284"
       "261029491729498112");
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift1, int_type, IntTypes)
 {
-  mp_int_type x("246556567891512374789511237456594795648912323213860000007849");
+  int_type x("246556567891512374789511237456594795648912323213860000007849");
   x >>= 17;
-  mp_int_type y(
+  int_type y(
       "1881077330715273855510797404911764493171022973738555908");
   BOOST_CHECK_EQUAL(x, y);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift2, int_type, IntTypes)
 {
-  mp_int_type x("0");
+  int_type x("0");
   x >>= 17;
   BOOST_CHECK_EQUAL(x, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift3, int_type, IntTypes)
 {
-  mp_int_type x("14222200");
+  int_type x("14222200");
   x >>= 8;
   BOOST_CHECK_EQUAL(x, "55555");
 }
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/sqr.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/sqr.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/sqr.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/sqr.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -7,48 +7,55 @@
 #include "prerequisite.hpp"
 
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr1, int_type, IntTypes)
 {
-  const mp_int_type x("123456789");
-  const mp_int_type y = x * x;
+  int_type x("-123456789");
+  x *= x;
+  BOOST_CHECK_EQUAL(x, "15241578750190521");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr2, int_type, IntTypes)
+{
+  const int_type x("-123456789");
+  const int_type y = x * x;
   BOOST_CHECK_EQUAL(y, "15241578750190521");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr3, int_type, IntTypes)
 {
-  const mp_int_type x("25");
-  const mp_int_type y = x * x;
+  const int_type x("-25");
+  const int_type y = x * x;
   BOOST_CHECK_EQUAL(y, "625");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr4, int_type, IntTypes)
 {
-  const mp_int_type x("300");
-  const mp_int_type y = x * x;
-  const mp_int_type z("90000");
+  const int_type x("300");
+  const int_type y = x * x;
+  const int_type z("90000");
   BOOST_CHECK_EQUAL(y, z);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr5, int_type, IntTypes)
 {
-  const mp_int_type x("2228218");
-  const mp_int_type y = x * x;
+  const int_type x("2228218");
+  const int_type y = x * x;
   BOOST_CHECK_EQUAL(y, "4964955455524");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr6, int_type, IntTypes)
 {
-  const mp_int_type x("999998000001");
-  const mp_int_type y = x * x;
-  const mp_int_type z("999996000005999996000001");
+  const int_type x("-999998000001");
+  const int_type y = x * x;
+  const int_type z("999996000005999996000001");
   BOOST_CHECK_EQUAL(y, z);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sqr6, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr7, int_type, IntTypes)
 {
   // this tests toom squaring and karatsuba squaring for 8, 16 and 32 bit
   // digit_type
-  const mp_int_type x(
+  const int_type x(
     "0x5004a2519b00503006126bb044af8930502951243994250616123426085258764a856336"
     "35702406cff061642794728883255642074744145228324022219347019013411158803532"
     "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
@@ -98,9 +105,9 @@
     "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
     "f84c878148cc7020890befffaa4506cebbef9a3f7c67178f2");
 
-  const mp_int_type y = x * x;
-  
-  const mp_int_type z(
+  const int_type y = x * x;
+
+  const int_type z(
     "0x1902e5887a586c505ed49b0ef0db72e959da458fbfe7f7f1738b9da657ebc6b4f3eeda8f3"
     "45f86a9439fb0a314af8a6d54e9002f6b9778bc217f31e1c2af869b890e50b105f2a6c8f6d4"
     "d9f7ce008697c1ef9f6b1b3d58089517db9a209f0951f3843c9f5dd81da8082a4e79771c9fe"
@@ -196,7 +203,32 @@
     "925e2c22b4004fd8e12ab70e2392e190dab556c0227b660cc226f5db558668bcb426a8153bc"
     "32af18b8c7dbe3c2ad210300582f823fc5fd7aadc653c2c0b59b3e5362b158793485e56c7c4"
     "c4");
-  
+
+  BOOST_CHECK_EQUAL(y, z);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr8, int_type, IntTypes)
+{
+  const int_type x(
+    "-0x10ef8a70456e96e5d20ac502fce83ab3218dff7522c2d02088a667bc00eb467c18c5c91"
+    "17bedaf7d79b09357862f8a8eac280a29cfee813f0721484ca7b8010000000000000000000"
+    "00000000000000000000000000000000000000000000000000000000000000000000000000"
+    "00000000000000000000000000000000000000000000000000000000000000000000000000"
+    "0000000000000000000000000");
+
+  const int_type y = x * x;
+
+  const int_type z(
+    "0x11ed171d12cb37289a825658ab14c26a6870e9895c9beff0e5a8c415c68d5bb7991c061e"
+    "99888c8c93d69f4a8aa8b2b4c81d63a1bba5e0191de7511edb701f7e0f4c337c5dbf8e57b6"
+    "54eaacb22f542e3ef3d3ca3d255a8bf76604ad5e4b32164949c50c4144377417897fdcad19"
+    "602dc396ac9c2ed00c9c5b22d8f70010000000000000000000000000000000000000000000"
+    "00000000000000000000000000000000000000000000000000000000000000000000000000"
+    "00000000000000000000000000000000000000000000000000000000000000000000000000"
+    "00000000000000000000000000000000000000000000000000000000000000000000000000"
+    "00000000000000000000000000000000000000000000000000000000000000000000000000"
+    "000000000000000000000000000000000000000000000");
+
   BOOST_CHECK_EQUAL(y, z);
 }
 
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/stream_io.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/stream_io.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/stream_io.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/stream_io.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,64 +6,64 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output, int_type, IntTypes)
 {
-  const mp_int_type x("1024");
+  const int_type x("-1024");
   std::ostringstream os;
   os << x;
-  BOOST_CHECK_EQUAL(os.str(), "1024");
+  BOOST_CHECK_EQUAL(os.str(), "-1024");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output_w_showbase, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output_w_showbase, int_type, IntTypes)
 {
-  const mp_int_type x("1024");
+  const int_type x("-1024");
   std::ostringstream os;
   os.setf(std::ios_base::showbase);
   os << x;
-  BOOST_CHECK_EQUAL(os.str(), "1024");
+  BOOST_CHECK_EQUAL(os.str(), "-1024");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output, int_type, IntTypes)
 {
-  const mp_int_type x("1024");
+  const int_type x("-1024");
   std::ostringstream os;
   os.setf(std::ios_base::oct, std::ios_base::basefield);
   os << x;
-  BOOST_CHECK_EQUAL(os.str(), "2000");
+  BOOST_CHECK_EQUAL(os.str(), "-2000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output_w_showbase, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output_w_showbase, int_type, IntTypes)
 {
-  const mp_int_type x("1024");
+  const int_type x("-1024");
   std::ostringstream os;
   os.setf(std::ios_base::oct, std::ios_base::basefield);
   os.setf(std::ios_base::showbase);
   os << x;
-  BOOST_CHECK_EQUAL(os.str(), "02000");
+  BOOST_CHECK_EQUAL(os.str(), "-02000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output, int_type, IntTypes)
 {
-  const mp_int_type x("1024");
+  const int_type x("-1024");
   std::ostringstream os;
   os.setf(std::ios_base::hex, std::ios_base::basefield);
   os << x;
-  BOOST_CHECK_EQUAL(os.str(), "400");
+  BOOST_CHECK_EQUAL(os.str(), "-400");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase, int_type, IntTypes)
 {
-  const mp_int_type x("1024");
+  const int_type x("-1024");
   std::ostringstream os;
   os.setf(std::ios_base::hex, std::ios_base::basefield);
   os.setf(std::ios_base::showbase);
   os << x;
-  BOOST_CHECK_EQUAL(os.str(), "0x400");
+  BOOST_CHECK_EQUAL(os.str(), "-0x400");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_uppercase, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_uppercase, int_type, IntTypes)
 {
-  const mp_int_type x("0xabcdef0");
+  const int_type x("0xabcdef0");
   std::ostringstream os;
   os.setf(std::ios_base::hex, std::ios_base::basefield);
   os.setf(std::ios_base::showbase | std::ios_base::uppercase);
@@ -71,54 +71,54 @@
   BOOST_CHECK_EQUAL(os.str(), "0XABCDEF0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_showpos, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_showpos, int_type, IntTypes)
 {
-  const mp_int_type x("1024");
+  const int_type x("-1024");
   std::ostringstream os;
   os.setf(std::ios_base::hex, std::ios_base::basefield);
   os.setf(std::ios_base::showbase | std::ios_base::showpos);
   os << x;
-  BOOST_CHECK_EQUAL(os.str(), "+0x400");
+  BOOST_CHECK_EQUAL(os.str(), "-0x400");
 }
 
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input1, int_type, IntTypes)
 {
-  mp_int_type x;
+  int_type x;
   std::stringstream s;
   s << "-123456";
   s >> x;
   BOOST_CHECK_EQUAL(x, "-123456");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input2, int_type, IntTypes)
 {
-  mp_int_type x, y;
+  int_type x, y;
   std::stringstream s;
-  s << "-123456";
+  s << "123456";
   s << " " << "987654321";
   s >> x;
-  BOOST_CHECK_EQUAL(x, "-123456");
+  BOOST_CHECK_EQUAL(x, "123456");
   BOOST_REQUIRE(s.good());
   s >> y;
   BOOST_CHECK_EQUAL(y, "987654321");
   BOOST_CHECK(s.good());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(oct_input, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(oct_input, int_type, IntTypes)
 {
-  mp_int_type x;
+  int_type x;
   std::stringstream s;
   s << "0123456";
   s >> x;
   BOOST_CHECK_EQUAL(x, "0123456");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(hex_input, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_input, int_type, IntTypes)
 {
-  mp_int_type x;
+  int_type x;
   std::stringstream s;
-  s << "0xFFFFAB01";
+  s << "-0xFFFFAB01";
   s >> x;
-  BOOST_CHECK_EQUAL(x, "0xFFFFAB01");
+  BOOST_CHECK_EQUAL(x, "-0xFFFFAB01");
 }
+
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/string_ops.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/string_ops.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/string_ops.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/string_ops.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,146 +6,91 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string1, int_type, IntTypes)
 {
-  const mp_int_type x("0xabcdef123456789");
+  const int_type x("0xabcdef123456789");
   const std::string s =
     x.template to_string<std::string>(std::ios::hex | std::ios::showbase);
   BOOST_CHECK_EQUAL(s, "0xabcdef123456789");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string2, int_type, IntTypes)
 {
-  const mp_int_type x("12345678901234567890");
+  const int_type x("12345678901234567890");
   const std::string s = x.template to_string<std::string>();
   BOOST_CHECK_EQUAL(s, "12345678901234567890");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string3, int_type, IntTypes)
 {
-  const mp_int_type x("0xabcdef123456789");
+  const int_type x("0xabcdef123456789");
   const std::string s = x.template to_string<std::string>(
       std::ios::hex | std::ios::showbase | std::ios::uppercase);
   BOOST_CHECK_EQUAL(s, "0XABCDEF123456789");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string4, int_type, IntTypes)
 {
-  const mp_int_type x("76484675");
+  const int_type x("76484675");
   const std::string s = x.template to_string<std::string>(std::ios::oct);
   BOOST_CHECK_EQUAL(s, "443610103");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string5, int_type, IntTypes)
 {
-  const mp_int_type x("1024");
+  const int_type x("1024");
   const std::string s = x.template to_string<std::string>(std::ios::oct);
   BOOST_CHECK_EQUAL(s, "2000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string6, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string6, int_type, IntTypes)
 {
-  const mp_int_type x("0");
+  const int_type x("0");
   const std::string s =
     x.template to_string<std::string>(
         std::ios_base::dec | std::ios_base::showbase | std::ios_base::showpos);
   BOOST_CHECK_EQUAL(s, "+0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string7, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string7, int_type, IntTypes)
 {
-  const mp_int_type x("0");
+  const int_type x("0");
   const std::string s =
     x.template to_string<std::string>(
         std::ios_base::oct | std::ios_base::showbase | std::ios_base::showpos);
   BOOST_CHECK_EQUAL(s, "+0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string8, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string8, int_type, IntTypes)
 {
-  const mp_int_type x("-0");
+  const int_type x("-0");
   const std::string s =
     x.template to_string<std::string>(
         std::ios_base::oct | std::ios_base::showbase | std::ios_base::showpos);
   BOOST_CHECK_EQUAL(s, "+0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string9, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string9, int_type, IntTypes)
 {
-  const mp_int_type x("-1");
+  const int_type x("-1");
   const std::string s =
     x.template to_string<std::string>(
         std::ios_base::hex | std::ios_base::showbase | std::ios_base::showpos);
   BOOST_CHECK_EQUAL(s, "-0x1");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string10, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string10, int_type, IntTypes)
 {
-  const mp_int_type x("0x95a6801ce5292b9a8410e1a59dd29967");
+  const int_type x("0x95a6801ce5292b9a8410e1a59dd29967");
   const std::string s =
     x.template to_string<std::string>(std::ios_base::hex);
   BOOST_CHECK_EQUAL(s, "95a6801ce5292b9a8410e1a59dd29967");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string11, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string11, int_type, IntTypes)
 {
-  const mp_int_type x("0x12471fa56d6");
+  const int_type x("0x12471fa56d6");
   const std::string s = x.template to_string<std::string>();
   BOOST_CHECK_EQUAL(s, "1256042682070");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign1, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x = "269513460";
-  BOOST_CHECK_EQUAL(x, "269513460");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign2, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x = "0xabcdef123456789";
-  BOOST_CHECK_EQUAL(x, "0xabcdef123456789");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign3, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x = "012345676543210000001";
-  BOOST_CHECK_EQUAL(x, "012345676543210000001");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign4, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x = "0";
-  BOOST_CHECK_EQUAL(!x, true);
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign5, mp_int_type, mp_int_types)
-{
-  mp_int_type x("0xabcedf03030303");
-  x = "-012345676543210000001";
-  BOOST_CHECK_EQUAL(x, "-012345676543210000001");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(assign1, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x.assign("123456789876543210000001", std::ios::dec);
-  BOOST_CHECK_EQUAL(x, "123456789876543210000001");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(assign2, mp_int_type, mp_int_types)
-{
-  mp_int_type x;
-  x.assign("abcdefabcdef1234567890", std::ios::hex);
-  BOOST_CHECK_EQUAL(x, "0xabcdefabcdef1234567890");
-}
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(assign3, mp_int_type, mp_int_types)
-{
-  mp_int_type x("-564897123123456456789789789897");
-  x.assign("1234567000000000000000000000000077", std::ios::oct);
-  BOOST_CHECK_EQUAL(x, "01234567000000000000000000000000077");
-}
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/sub.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/sub.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/sub.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/sub.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,125 +6,132 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub_assign1, int_type, IntTypes)
 {
-  const mp_int_type x("123456");
-  const mp_int_type y("987777");
-  const mp_int_type z = x - y;
+  int_type x("0xf2378eeec78234932222111000000f");
+  x -= x;
+  BOOST_CHECK_EQUAL(x, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub1, int_type, IntTypes)
+{
+  const int_type x("123456");
+  const int_type y("987777");
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "-864321");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub2, int_type, IntTypes)
 {
-  const mp_int_type x("955588990000001");
-  const mp_int_type y("9801");
-  const mp_int_type z = x - y;
+  const int_type x("955588990000001");
+  const int_type y("9801");
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "955588989990200");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub3, int_type, IntTypes)
 {
-  const mp_int_type x("99999991");
-  const mp_int_type y("987654321000123456789");
-  const mp_int_type z = x - y;
+  const int_type x("99999991");
+  const int_type y("987654321000123456789");
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "-987654321000023456798");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub4, int_type, IntTypes)
 {
-  const mp_int_type x(
+  const int_type x(
     "49144609407766890328547643707523663509662747376486271392344480900673178645"
     "33198519112197059826509662943577383543858946941049753393431035706592040680"
     "43848484065292542884106550381079282660840705126574766636237650938379223350"
     "073087806800887586256085275775217219429527000017403144");
-  const mp_int_type y(
+  const int_type y(
     "49144609407766890328547643707523663509662747376486271392344480900673178645"
     "33198519112197059826509662943577383543858946941049753393431035706592040680"
     "43848484065292542884106550381079282660840705126574766636237650938379223350"
     "073087806800887586256085275775217219429527000017403144");
-  const mp_int_type z = x - y;
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub5, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub5, int_type, IntTypes)
 {
-  const mp_int_type x(
+  const int_type x(
     "21665907282124706187656074325458499695895652068822763794228458103499408841");
-  const mp_int_type y(
+  const int_type y(
     "173087806800887586256085275775299999999889978789789");
-  const mp_int_type z = x - y;
-  const mp_int_type w(
+  const int_type z = x - y;
+  const int_type w(
     "21665907282124706187655901237651698808309395983546988494228458213520619052");
   BOOST_CHECK_EQUAL(z, w);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub6, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub6, int_type, IntTypes)
 {
-  const mp_int_type x("0xff");
-  const mp_int_type y("0x1000ff0000000");
-  const mp_int_type z = x - y;
+  const int_type x("0xff");
+  const int_type y("0x1000ff0000000");
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "-0x1000fefffff01");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub7, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub7, int_type, IntTypes)
 {
-  const mp_int_type x("1000000");
-  const mp_int_type y("-1000000");
-  const mp_int_type z = x - y;
+  const int_type x("1000000");
+  const int_type y("-1000000");
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "2000000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub8, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub8, int_type, IntTypes)
 {
-  const mp_int_type x("-1000000");
-  const mp_int_type y("1000000");
-  const mp_int_type z = x - y;
+  const int_type x("-1000000");
+  const int_type y("1000000");
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "-2000000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub9, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub9, int_type, IntTypes)
 {
-  const mp_int_type x("-123456789");
-  const mp_int_type y("-123456789");
-  const mp_int_type z = x - y;
+  const int_type x("-123456789");
+  const int_type y("-123456789");
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "0");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(sub10, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub10, int_type, IntTypes)
 {
-  const mp_int_type x("-1000000");
-  const mp_int_type y("-2500000");
-  const mp_int_type z = x - y;
+  const int_type x("-1000000");
+  const int_type y("-2500000");
+  const int_type z = x - y;
   BOOST_CHECK_EQUAL(z, "1500000");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(decrement1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement1, int_type, IntTypes)
 {
-  mp_int_type x("0");
+  int_type x("0");
   for (int i = 0; i < 10; ++i)
     --x;
   BOOST_CHECK_EQUAL(x, "-10");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(decrement2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement2, int_type, IntTypes)
 {
-  mp_int_type x("4");
+  int_type x("4");
   for (int i = 0; i < 10; ++i)
     --x;
   BOOST_CHECK_EQUAL(x, "-6");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(decrement3, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement3, int_type, IntTypes)
 {
-  mp_int_type x("-120");
+  int_type x("-120");
   for (int i = 0; i < 10; ++i)
     --x;
   BOOST_CHECK_EQUAL(x, "-130");
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(decrement4, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement4, int_type, IntTypes)
 {
-  mp_int_type x("130");
+  int_type x("130");
   for (int i = 0; i < 10; ++i)
     --x;
   BOOST_CHECK_EQUAL(x, "120");
Added: sandbox/mp_math/libs/mp_math/test/unbounded/signed/swap.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/swap.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,58 @@
+// Copyright Kevin Sopp 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(swap1, int_type, IntTypes)
+{
+  int_type x("-0xabff23742384bf892734029323819048039");
+  int_type y("0x1fee55d048039");
+
+  boost::mp_math::swap(x, y);
+
+  BOOST_CHECK_EQUAL(x, "0x1fee55d048039");
+  BOOST_CHECK_EQUAL(y, "-0xabff23742384bf892734029323819048039");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(swap2, int_type, IntTypes)
+{
+  int_type x("-0xabff23742384bf892734029323819048039");
+  int_type y("-0x1fee55d048039");
+
+  x.swap(y);
+
+  BOOST_CHECK_EQUAL(x, "-0x1fee55d048039");
+  BOOST_CHECK_EQUAL(y, "-0xabff23742384bf892734029323819048039");
+}
+
+#ifdef BOOST_HAS_RVALUE_REFS
+BOOST_AUTO_TEST_CASE_TEMPLATE(swap3, int_type, IntTypes)
+{
+  int_type x;
+  int_type y;
+
+  boost::mp_math::swap(int_type("-0x1fee55d048039"), x);
+  boost::mp_math::swap(y, int_type("-0x1fee55d048039"));
+
+  BOOST_CHECK_EQUAL(x, "-0x1fee55d048039");
+  BOOST_CHECK_EQUAL(y, "-0x1fee55d048039");
+}
+#endif
+
+#include <algorithm>
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(swap4, int_type, IntTypes)
+{
+  int_type x("-0xabff23742384bf892734029323819048039");
+  int_type y("0x1fee55d048039");
+
+  std::swap(x, y);
+
+  BOOST_CHECK_EQUAL(x, "0x1fee55d048039");
+  BOOST_CHECK_EQUAL(y, "-0xabff23742384bf892734029323819048039");
+}
+
Copied: sandbox/mp_math/libs/mp_math/test/unbounded/signed/to_integral.cpp (from r54148, /sandbox/mp_math/libs/mp_math/test/to_integral.cpp)
==============================================================================
--- /sandbox/mp_math/libs/mp_math/test/to_integral.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/signed/to_integral.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,130 +6,132 @@
 #include <boost/test/unit_test.hpp>
 #include "prerequisite.hpp"
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_char1, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char1, int_type, IntTypes)
 {
-  mp_int_type x("123");
-  char z = x.template to_integral<char>();
+  const int_type x("123");
+  const char z = x.template to_integral<char>();
   BOOST_CHECK_EQUAL(z, 123);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_char2, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char2, int_type, IntTypes)
 {
-  mp_int_type x("-123");
-  char z = x.template to_integral<char>();
+  const int_type x("-123");
+  const char z = x.template to_integral<char>();
   BOOST_CHECK_EQUAL(z, -123);
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_char_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char_min, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<char>::min());
-  char z = x.template to_integral<char>();
+  const int_type x(std::numeric_limits<char>::min());
+  const char z = x.template to_integral<char>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<char>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_char_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char_max, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<char>::max());
-  int z = x.template to_integral<char>();
+  const int_type x(std::numeric_limits<char>::max());
+  const int z = x.template to_integral<char>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<char>::max());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_min, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<unsigned char>::min());
-  unsigned char z = x.template to_integral<unsigned char>();
+  int_type x(std::numeric_limits<unsigned char>::min());
+  const unsigned char z = x.template to_integral<unsigned char>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned char>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_max, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<unsigned char>::max());
-  unsigned char z = x.template to_integral<unsigned char>();
+  int_type x(std::numeric_limits<unsigned char>::max());
+  const unsigned char z = x.template to_integral<unsigned char>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned char>::max());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_int_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_int_min, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<int>::min());
-  int z = x.template to_integral<int>();
+  int_type x(std::numeric_limits<int>::min());
+  const int z = x.template to_integral<int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_int_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_int_max, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<int>::max());
-  int z = x.template to_integral<int>();
+  int_type x(std::numeric_limits<int>::max());
+  const int z = x.template to_integral<int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::max());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_min, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<unsigned int>::min());
-  unsigned int z = x.template to_integral<unsigned int>();
+  int_type x(std::numeric_limits<unsigned int>::min());
+  const unsigned int z = x.template to_integral<unsigned int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned int>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_max, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<unsigned int>::max());
-  unsigned int z = x.template to_integral<unsigned int>();
+  int_type x(std::numeric_limits<unsigned int>::max());
+  const unsigned int z = x.template to_integral<unsigned int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned int>::max());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_int_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_int_min, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<long int>::min());
-  long int z = x.template to_integral<long int>();
+  int_type x(std::numeric_limits<long int>::min());
+  const long int z = x.template to_integral<long int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<long int>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_int_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_int_max, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<long int>::max());
-  long int z = x.template to_integral<long int>();
+  int_type x(std::numeric_limits<long int>::max());
+  const long int z = x.template to_integral<long int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<long int>::max());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_min, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<unsigned long int>::min());
-  unsigned long int z = x.template to_integral<unsigned long int>();
+  int_type x(std::numeric_limits<unsigned long int>::min());
+  const unsigned long int z = x.template to_integral<unsigned long int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long int>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_max, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<unsigned long int>::max());
-  unsigned long int z = x.template to_integral<unsigned long int>();
+  int_type x(std::numeric_limits<unsigned long int>::max());
+  const unsigned long int z = x.template to_integral<unsigned long int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long int>::max());
 }
 
 #ifdef BOOST_HAS_LONG_LONG
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_long_int_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_long_int_min, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<long long int>::min());
-  long long int z = x.template to_integral<long long int>();
+  int_type x(std::numeric_limits<long long int>::min());
+  const long long int z = x.template to_integral<long long int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<long long int>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_long_int_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_long_int_max, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<long long int>::max());
-  long long int z = x.template to_integral<long long int>();
+  int_type x(std::numeric_limits<long long int>::max());
+  const long long int z = x.template to_integral<long long int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<long long int>::max());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_min, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_min, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<unsigned long long int>::min());
-  unsigned long long int z = x.template to_integral<unsigned long long int>();
+  int_type x(std::numeric_limits<unsigned long long int>::min());
+  const unsigned long long int z =
+    x.template to_integral<unsigned long long int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long long int>::min());
 }
 
-BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_max, mp_int_type, mp_int_types)
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_max, int_type, IntTypes)
 {
-  mp_int_type x(std::numeric_limits<unsigned long long int>::max());
-  unsigned long long int z = x.template to_integral<unsigned long long int>();
+  int_type x(std::numeric_limits<unsigned long long int>::max());
+  const unsigned long long int z =
+    x.template to_integral<unsigned long long int>();
   BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long long int>::max());
 }
 #endif
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/abs.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/abs.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,15 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(abs1, uint_type, UIntTypes)
+{
+  const uint_type x("0x123abdddfe4983");
+  const uint_type y = boost::mp_math::abs(x);
+  BOOST_CHECK_EQUAL(y, x);
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/add.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/add.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,149 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers1, uint_type, UIntTypes)
+{
+  const uint_type x("123456");
+  const uint_type y("987777");
+  const uint_type z = x + y;
+  BOOST_CHECK_EQUAL(z, "1111233");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers2, uint_type, UIntTypes)
+{
+  const uint_type x("999");
+  const uint_type y("123456");
+  const uint_type z = x + y;
+  BOOST_CHECK_EQUAL(z, "124455");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers3, uint_type, UIntTypes)
+{
+  const uint_type x("21474836470");
+  const uint_type y("1234567845600");
+  const uint_type z = x + y;
+  BOOST_CHECK_EQUAL(z, "1256042682070");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers4, uint_type, UIntTypes)
+{
+  const uint_type x("0xffffffffffffffff");
+  const uint_type y("0xffffffffffffffff");
+  const uint_type z = x + y;
+  BOOST_CHECK_EQUAL(z, "0x1fffffffffffffffe");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_positive_numbers5, uint_type, UIntTypes)
+{
+  const uint_type x("0xffffffffffffffff");
+  const uint_type y("0xffffffff");
+  const uint_type z = x + y;
+  BOOST_CHECK_EQUAL(z, "0x100000000fffffffe");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_small, uint_type, UIntTypes)
+{
+  uint_type x("123456789");
+  uint_type y("123");
+  uint_type z = x + y;
+  BOOST_CHECK_EQUAL(z, "123456912");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_small_and_large, uint_type, UIntTypes)
+{
+  uint_type x("123");
+  uint_type y("123456789");
+  uint_type z = x + y;
+  BOOST_CHECK_EQUAL(z, "123456912");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_large_and_large, uint_type, UIntTypes)
+{
+  uint_type x(
+    "76563204409879018101322737668344063995824904757312285775560614771886933079"
+    "77822556905976720912850551355328340715074887289899094852653102687850101285"
+    "85715275531977696497398396067715769512450915961775500023723324150851793075"
+    "51871751151095323159497918186624088118225730504044262785072662119470825604"
+    "40835072257208973943520251201155002832786969323087571220195329601804141972"
+    "71293425859967733061169954398382700046379970842289727254846347411792122453"
+    "98890529530611217475343335863666953662801553948341581412563112340543629531"
+    "01094529771464590172847457807673685591148055046712881378811934516545088775"
+    "38198087116656466935095055228728162461388333618793883566996616940381738437"
+    "03453867953392241443573580380271627517797446062394044787118140775664622031"
+    "49144609407766890328547643707523663509662747376486271392344480900673178645"
+    "33198519112197059826509662943577383543858946941049753393431035706592040680"
+    "43848484065292542884106550381079282660840705126574766636237650938379223350"
+    "073087806800887586256085275775217219429527000017403144");
+
+  uint_type y(
+    "29156720459736055974643337783563754269574952607968485689453462316428566668"
+    "95504701770860331979649536167161534866285341319360225416010322271645564229"
+    "97610536562445338176729838019564690253931232562709745122032537539983616770"
+    "01864876491464203683664927984801289460556480278145114367860332493722569194"
+    "34026051618152579992400234314328079213866348120156368725488604236521299603"
+    "05243915357553896356662519397274629471920043679673543282319268893065423613"
+    "03777840501083119668898860689222271939900089123195611475211708096094521743"
+    "23436842195705603262202927396682954198215622617086455718070601797199587530"
+    "86110222151397352239086193648500251298495752840008363650931395221675337916"
+    "21665907282124706187656074325458499695895652068822763794228458103499408841"
+    "68233732651102406546734395563663969020820490032431359396293047454261598159"
+    "68165818673838448637209074584819780088546111644065538550490486693301185614"
+    "61602638472505490238203390055056474763248195271964604045005807592301719483"
+    "66411676459481184297663915491569500245585996483678005964410842919747216111"
+    "69086269285356198998091850661544255466466926579668887000118948737207396398"
+    "39189399212362197497646493143022100680619252808094160907526003969639965485"
+    "31238493375062268758735445211914107215235958346264702774326161208396163240"
+    "36339482493382189215697343908873498104516190541170342091008828518924813674"
+    "46253090923280613514725437269574928515018666111820866090440006060807129643"
+    "38626199608899966829344884873038261232122027815715568990196536130996880104"
+    "97887027262726591236620461428328000537452828616386217063092509908555188454"
+    "27278763741671312528892659532960085933913140197210561287118971031419725940"
+    "702202830556069344716729071140147820999566475298895832");
+  uint_type z = x + y;
+  BOOST_CHECK_EQUAL(z,
+    "29156720459736055974643337783563754269574952607968485689453462316428566668"
+    "95504701770860331979649536167161534866285341319360225416010322271645564229"
+    "97610536562445338176729838019564690253931232562709745122032537539983616770"
+    "01864876491464203683664927984801289460556480278145114367860332493722569194"
+    "34026051618152579992400234314328079213866348120156368725488604236521299603"
+    "05243915357553896356662519397274629471920043679673543282319268893065423613"
+    "03777840501083119668898860689222271939900089123195611475211708096094521743"
+    "23436842195705603262202927396682954198215622617086455718070601797199587530"
+    "86110222151397352239086193648500251298495752840008363650931395221675337916"
+    "98229111692003724288978811993802563691720556826135049569789072875386341921"
+    "46056289557079127459584946918992309735895377322330454248946150142111699445"
+    "53881094205816145134607470652535549600997027605841038574213810844152978690"
+    "13474389623600813397701308241680562881473925776008866830078469711772545088"
+    "07246748716690158241184166692724503078372965806765577184606172521551358084"
+    "40379695145323932059261805059926955512846897421958614254965296148999518852"
+    "38079928742973414972989829006689054343420806756435742320089116310183595016"
+    "32333023146526858931582903019587792806384013392977584153138095724941252015"
+    "74537569610038656150792399137601660565904524159964225658005445459306552111"
+    "49706958876672854958299017649846556032816112174214910877558146836471751674"
+    "87770809016666857157892528580561924741784775192201840382541017031670058750"
+    "31085546374923651063130124371905384081311775557435970456523545615147229134"
+    "71127247806963855412999209914039368594753845323785327923356621969798949290"
+    "775290637356956930972814346915365040429093475316298976");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment1, uint_type, UIntTypes)
+{
+  uint_type x("0");
+  for (int i = 0; i < 10; ++i)
+    ++x;
+  BOOST_CHECK_EQUAL(x, "10");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(increment2, uint_type, UIntTypes)
+{
+  uint_type x("120");
+  for (int i = 0; i < 10; ++i)
+    ++x;
+  BOOST_CHECK_EQUAL(x, "130");
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/bitmanipulation.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/bitmanipulation.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,113 @@
+// Copyright Kevin Sopp 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits1, uint_type, UIntTypes)
+{
+  uint_type x("0xff00000000ff");
+  x.set_bits(8, 40);
+  BOOST_CHECK_EQUAL(x, "0xffffffffffff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits2, uint_type, UIntTypes)
+{
+  uint_type x("0x8000");
+  x.set_bits(2, 7);
+  BOOST_CHECK_EQUAL(x, "0x807c");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits3, uint_type, UIntTypes)
+{
+  uint_type x("0x80000000000000");
+  x.set_bits(12, 13);
+  BOOST_CHECK_EQUAL(x, "0x80000000001000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits4, uint_type, UIntTypes)
+{
+  uint_type x("0x8000000000000000");
+  x.set_bits(0, 18);
+  BOOST_CHECK_EQUAL(x, "0x800000000003FFFF");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(set_bits5, uint_type, UIntTypes)
+{
+  uint_type x("0x80000000");
+  x.set_bits(8, 16);
+  BOOST_CHECK_EQUAL(x, "0x8000FF00");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits1, uint_type, UIntTypes)
+{
+  uint_type x("0xffffffffffff");
+  x.clear_bits(8, 40);
+  BOOST_CHECK_EQUAL(x, "0xff00000000ff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits2, uint_type, UIntTypes)
+{
+  uint_type x("0x807c");
+  x.clear_bits(2, 7);
+  BOOST_CHECK_EQUAL(x, "0x8000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits3, uint_type, UIntTypes)
+{
+  uint_type x("0x80000000001000");
+  x.clear_bits(12, 13);
+  BOOST_CHECK_EQUAL(x, "0x80000000000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits4, uint_type, UIntTypes)
+{
+  uint_type x("0x800000000003FFFF");
+  x.clear_bits(0, 18);
+  BOOST_CHECK_EQUAL(x, "0x8000000000000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(clear_bits5, uint_type, UIntTypes)
+{
+  uint_type x("0x8000FF00");
+  x.clear_bits(8, 16);
+  BOOST_CHECK_EQUAL(x, "0x80000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate1, uint_type, UIntTypes)
+{
+  uint_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+  x.truncate(32);
+  BOOST_CHECK_EQUAL(x, "0xFFFFFFFF");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate2, uint_type, UIntTypes)
+{
+  uint_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+  x.truncate(0);
+  BOOST_CHECK_EQUAL(x, "");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate3, uint_type, UIntTypes)
+{
+  uint_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+  x.truncate(1);
+  BOOST_CHECK_EQUAL(x, "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate4, uint_type, UIntTypes)
+{
+  uint_type x("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
+  x.truncate(31);
+  BOOST_CHECK_EQUAL(x, "0x7FFFFFFF");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(truncate5, uint_type, UIntTypes)
+{
+  uint_type x("0xFFFFFFFFFFFFFFFFFFFF");
+  x.truncate(80);
+  BOOST_CHECK_EQUAL(x, "0xFFFFFFFFFFFFFFFFFFFF");
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/bitwise_ops.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/bitwise_ops.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,56 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(and_op1, uint_type, UIntTypes)
+{
+  const uint_type x("0x00ff0000000f");
+  const uint_type y("0xffffffffffff");
+  const uint_type z = x & y;
+  BOOST_CHECK_EQUAL(z, x);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(and_op2, uint_type, UIntTypes)
+{
+  const uint_type x("0x00ff0000000ffffffffff");
+  const uint_type y(         "0xffffffffffff");
+  const uint_type z = x & y;
+  BOOST_CHECK_EQUAL(z, "0xffffffffff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(or_op1, uint_type, UIntTypes)
+{
+  const uint_type x("0x00ff0000000f");
+  const uint_type y("0xffffffffffff");
+  const uint_type z = x | y;
+  BOOST_CHECK_EQUAL(z, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(or_op2, uint_type, UIntTypes)
+{
+  const uint_type x("0x00ff0000000ffffffffff");
+  const uint_type y(         "0xaaffffffffff");
+  const uint_type z = x | y;
+  BOOST_CHECK_EQUAL(z, "0x00ff00000aaffffffffff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op1, uint_type, UIntTypes)
+{
+  const uint_type x("0x00ff0000000f");
+  const uint_type y("0xffffffffffff");
+  const uint_type z = x ^ y;
+  BOOST_CHECK_EQUAL(z, "0xff00fffffff0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(xor_op2, uint_type, UIntTypes)
+{
+  const uint_type x("0x00ff0000000ffffffffff");
+  const uint_type y(         "0x33aaffffffff");
+  const uint_type z = x ^ y;
+  BOOST_CHECK_EQUAL(z,"0x00ff00000335500000000");
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/bool_conversion.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/bool_conversion.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,49 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool1, uint_type, UIntTypes)
+{
+  // this just tests operator == (const uint_type&, bool)
+  const uint_type x("1");
+  const uint_type y("0");
+  BOOST_CHECK_EQUAL(x, true);
+  BOOST_CHECK_EQUAL(y, false);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_or, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const uint_type y("0");
+  const bool z = x || y;
+  BOOST_CHECK_EQUAL(z, true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and1, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const uint_type y("0");
+  const bool z = x && y;
+  BOOST_CHECK_EQUAL(z, false);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_and2, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const uint_type y("1");
+  const bool z = x && y;
+  BOOST_CHECK_EQUAL(z, true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bool_loop_condition, uint_type, UIntTypes)
+{
+  uint_type x("5");
+  while (x)
+    --x;
+  BOOST_CHECK_EQUAL(x, false);
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/cmp.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/cmp.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,372 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type y("0");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq2, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const uint_type y("1");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_eq3, uint_type, UIntTypes)
+{
+  const uint_type x("0xeeffeeeeee000000000000001");
+  const uint_type y("0xeeffeeeeee000000000000001");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ne1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type y("1");
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ne2, uint_type, UIntTypes)
+{
+  const uint_type x("0xaaaaaaaaaaaaaaeeeeeeeeeeeeeee");
+  const uint_type y("0xaaaaaaaaaaaaaabbbbbbbbbbbbbb8");
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt1, uint_type, UIntTypes)
+{
+  const uint_type x("12");
+  const uint_type y("13");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt2, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const uint_type y("123456789");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt3, uint_type, UIntTypes)
+{
+  const uint_type x("0x100000000000000000000");
+  const uint_type y("0x100000000000000000001");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_lt4, uint_type, UIntTypes)
+{
+  const uint_type x("15");
+  const uint_type y("1023");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_gt1, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const uint_type y("0");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_gt2, uint_type, UIntTypes)
+{
+  const uint_type x("0xfffffffffffffffffffffffff");
+  const uint_type y("0");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_gt3, uint_type, UIntTypes)
+{
+  const uint_type x("0xffffffffffffffeeeeeeeeeee1");
+  const uint_type y("0xffffffffffffffeeeeeeeeeee0");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type y("0");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le2, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type y("1");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le3, uint_type, UIntTypes)
+{
+  const uint_type x("0x123456789fffffffffff");
+  const uint_type y("0x123456789fffffffffff");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_le4, uint_type, UIntTypes)
+{
+  const uint_type x("0x11");
+  const uint_type y("0x49941faaaaaaaa332134");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ge1, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const uint_type y("1");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ge2, uint_type, UIntTypes)
+{
+  const uint_type x("0xa0a0");
+  const uint_type y("0");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cmp_ge3, uint_type, UIntTypes)
+{
+  const uint_type x("0xff00ff00000000000000001ff");
+  const uint_type y("0xff00ff00000000000000000ff");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const int y = 0;
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_integral2, uint_type, UIntTypes)
+{
+  const uint_type x("20");
+  const unsigned int y = 20;
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_integral3, uint_type, UIntTypes)
+{
+  const uint_type x("30000");
+  const int y = 30000;
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_integral4, uint_type, UIntTypes)
+{
+  const uint_type x("0xffff0000");
+  const unsigned long y = 0xffff0000;
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const int y = 0;
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_integral2, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const int y = -10000;
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_lt_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const int y = 1;
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_lt_integral2, uint_type, UIntTypes)
+{
+  const uint_type x("123456789");
+  const unsigned long y = 123456790;
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_gt_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const int y = -1;
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_gt_integral2, uint_type, UIntTypes)
+{
+  const uint_type x("0x5000000addddddd");
+  const unsigned int y = 1156;
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_le_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const int y = 0;
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_le_integral2, uint_type, UIntTypes)
+{
+  const uint_type x("0xffff");
+  const unsigned int y = 0xffff;
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_le_integral3, uint_type, UIntTypes)
+{
+  const uint_type x("0xaa0");
+  const unsigned int y = 0xf000;
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ge_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const int y = 0;
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ge_integral2, uint_type, UIntTypes)
+{
+  const uint_type x("100");
+  const int y = -100;
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ge_integral3, uint_type, UIntTypes)
+{
+  const uint_type x("0x56a4f564aaa445456");
+  const unsigned int y = 0xaab;
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_eq_mp_int1, uint_type, UIntTypes)
+{
+  const int x = 0;
+  const uint_type y("0");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_eq_mp_int2, uint_type, UIntTypes)
+{
+  const unsigned int x = 1000;
+  const uint_type y("1000");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ne_mp_int1, uint_type, UIntTypes)
+{
+  const int x = 0;
+  const uint_type y("0x1000");
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ne_mp_int2, uint_type, UIntTypes)
+{
+  const int x = -500;
+  const uint_type y("500");
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ne_mp_int3, uint_type, UIntTypes)
+{
+  const unsigned int x = 500;
+  const uint_type y("0xcaaff500");
+  BOOST_CHECK_NE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_lt_mp_int1, uint_type, UIntTypes)
+{
+  const unsigned int x = 500;
+  const uint_type y("0xcaaff500");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_lt_mp_int2, uint_type, UIntTypes)
+{
+  const int x = -500;
+  const uint_type y("0");
+  BOOST_CHECK_LT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_gt_mp_int1, uint_type, UIntTypes)
+{
+  const int x = 1;
+  const uint_type y("0");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_gt_mp_int2, uint_type, UIntTypes)
+{
+  const unsigned int x = 1000;
+  const uint_type y("999");
+  BOOST_CHECK_GT(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_le_mp_int1, uint_type, UIntTypes)
+{
+  const unsigned int x = 999;
+  const uint_type y("999");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_le_mp_int2, uint_type, UIntTypes)
+{
+  const int x = -1;
+  const uint_type y("0x99999999999999");
+  BOOST_CHECK_LE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ge_mp_int1, uint_type, UIntTypes)
+{
+  const unsigned int x = 999;
+  const uint_type y("999");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(integral_ge_mp_int2, uint_type, UIntTypes)
+{
+  const int x = 1023;
+  const uint_type y("1010");
+  BOOST_CHECK_GE(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_char_ptr1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const char* y = "0";
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_eq_char_ptr2, uint_type, UIntTypes)
+{
+  const uint_type x("0x456561fcaa547650456456");
+  const char* y = "0x456561fcaa547650456456";
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_char_ptr1, uint_type, UIntTypes)
+{
+  const uint_type x("15");
+  const char* y = "22";
+  BOOST_CHECK_NE(x, y);
+}
+
+/*BOOST_AUTO_TEST_CASE_TEMPLATE(mp_int_ne_char_ptr2, uint_type, UIntTypes)
+{
+  const uint_type x("0x456561fcaa547650456456");
+  const char* y = "-0x456561fcaa547650456456";
+  BOOST_CHECK_NE(x, y);
+}*/
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/ctors.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/ctors.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,232 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+// We mostly test from/to string conversions here since most other test cases
+// depend on these. If they are broken and senseless data gets into an integer
+// or we have wrong output then we need to fix this quickly.
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor, uint_type, UIntTypes)
+{
+  const uint_type x;
+  BOOST_CHECK_EQUAL(x.size(), 0U);
+  BOOST_CHECK_EQUAL(x.is_initialized(), false);
+  BOOST_CHECK_EQUAL(x.is_uninitialized(), true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_empty_string1, uint_type, UIntTypes)
+{
+  const uint_type x("");
+  BOOST_CHECK_EQUAL(x.size(), 0U);
+  BOOST_CHECK_EQUAL(x.is_initialized(), false);
+  BOOST_CHECK_EQUAL(x.is_uninitialized(), true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  BOOST_CHECK_EQUAL(x.is_initialized(), true);
+  BOOST_CHECK_EQUAL(x.is_uninitialized(), false);
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string2, uint_type, UIntTypes)
+{
+  const uint_type x("12");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "12");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string3, uint_type, UIntTypes)
+{
+  const uint_type x("123456789");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "123456789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string4, uint_type, UIntTypes)
+{
+  const uint_type x("1000000000");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "1000000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string5, uint_type, UIntTypes)
+{
+  const uint_type x("+1");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string6, uint_type, UIntTypes)
+{
+  const uint_type x("8888000000009", std::ios_base::dec |
+                                     std::ios_base::showbase);
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "8888000000009");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_decimal_string7, uint_type, UIntTypes)
+{
+  BOOST_CHECK_THROW(uint_type("1234567890a456456"), std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string1, uint_type, UIntTypes)
+{
+  const uint_type x("0", std::ios_base::oct);
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string2, uint_type, UIntTypes)
+{
+  const uint_type x("0", std::ios_base::oct | std::ios_base::showbase);
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string3, uint_type, UIntTypes)
+{
+  const uint_type x("012");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "10");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string4, uint_type, UIntTypes)
+{
+  const uint_type x("000000000000000000000000000000000");
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string5, uint_type, UIntTypes)
+{
+  const uint_type x("0123456777");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "21913087");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_octal_string6, uint_type, UIntTypes)
+{
+  BOOST_CHECK_THROW(uint_type("012345678"), std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string1, uint_type, UIntTypes)
+{
+  const uint_type x("0x0");
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string2, uint_type, UIntTypes)
+{
+  const uint_type x("0X0");
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string3, uint_type, UIntTypes)
+{
+  const uint_type x("0", std::ios_base::hex);
+  BOOST_REQUIRE_EQUAL(x.size(), 1U);
+  BOOST_CHECK_EQUAL(x[0], 0U);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string4, uint_type, UIntTypes)
+{
+  const uint_type x("0xF");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "15");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string5, uint_type, UIntTypes)
+{
+  const uint_type x("0xa0");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "160");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string6, uint_type, UIntTypes)
+{
+  const uint_type x("0x123456789abcdef");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(std::ios_base::hex |
+                                                      std::ios_base::showbase),
+                    "0x123456789abcdef");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string7, uint_type, UIntTypes)
+{
+  const uint_type x("0x123456789ABCDEF");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(std::ios_base::hex |
+                                                      std::ios_base::showbase |
+                                                      std::ios_base::uppercase),
+                    "0X123456789ABCDEF");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string8, uint_type, UIntTypes)
+{
+  const uint_type x("0xA0000000");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "2684354560");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_hexadecimal_string9, uint_type, UIntTypes)
+{
+  BOOST_CHECK_THROW(uint_type("0x15656abg56"), std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_long_string, uint_type, UIntTypes)
+{
+  const uint_type x(
+      "875004025190050300612679044488093050295124399425061612342608525876458563"
+      "36946409871074842737283625535525153833045575858681216");
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(),
+      "875004025190050300612679044488093050295124399425061612342608525876458563"
+      "36946409871074842737283625535525153833045575858681216");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_iterators1, uint_type, UIntTypes)
+{
+  const std::string s("123456789");
+  const uint_type x(s.begin(), s.end());
+  BOOST_CHECK_EQUAL(x.template to_string<std::string>(), "123456789");
+}
+
+#ifndef BOOST_NO_CWCHAR
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wchar_t1, uint_type, UIntTypes)
+{
+  const uint_type x(L"0xA0000000");
+  BOOST_CHECK_EQUAL(x, "2684354560");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_wstring1, uint_type, UIntTypes)
+{
+  const std::wstring s(L"0xA0000000");
+  const uint_type x(s);
+  BOOST_CHECK_EQUAL(x, "2684354560");
+}
+#endif
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(cctor1, uint_type, UIntTypes)
+{
+  const uint_type x("0xabddd00012134f");
+  const uint_type y(x);
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+
+/*
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type1, uint_type, UIntTypes)
+{
+  const uint_type x(9999999U);
+  BOOST_CHECK_EQUAL(x, "9999999");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_unsigned_integral_type2, uint_type, UIntTypes)
+{
+  const uint_type x(123456U);
+  BOOST_CHECK_EQUAL(x, "123456");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(ctor_from_integral_type_unsigned_char, uint_type, UIntTypes)
+{
+  unsigned char c = 42;
+  const uint_type x(c);
+  BOOST_CHECK_EQUAL(x, "42");
+}
+*/
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/div.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/div.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,97 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(division_by_zero, uint_type, UIntTypes)
+{
+  const uint_type x("0x201abcff00aaffffff");
+  const uint_type y("0");
+  BOOST_CHECK_THROW(x / y, std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide1, uint_type, UIntTypes)
+{
+  const uint_type x("987777");
+  const uint_type y("123456");
+  const uint_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "8");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide2, uint_type, UIntTypes)
+{
+  const uint_type x("263825472");
+  const uint_type y("123456");
+  const uint_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "2137");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide3, uint_type, UIntTypes)
+{
+  const uint_type x("0x89ab89745cc653de58eecc8f8a874120065ea545f6f5f");
+  const uint_type y("0x1889ba8a789456adfc8005b1");
+  const uint_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "0x59c48aa7a1446110b31f70");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide4, uint_type, UIntTypes)
+{
+  const uint_type x("0x1889ba8a789456adfc8005b1");
+  const uint_type y("0x1889ba8a789456adfc8005b2");
+  const uint_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide5, uint_type, UIntTypes)
+{
+  const uint_type x("0x201abcff00aaffffff");
+  const uint_type y("0x1fffffffffffffff");
+  const uint_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "256");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide6, uint_type, UIntTypes)
+{
+  const uint_type x(
+      "0xffffffffffffffff00000000000000000000000ffffffffffff00000000000000000000"
+      "000000000000000eeeeeeeeeeeeee0");
+  const uint_type y("0xffffffff00000000000");
+  const uint_type z = x / y;
+  BOOST_CHECK_EQUAL(z,
+      "0x100000001000000000000000000000000000000100000000ffff0000ffff0000ffff00"
+      "00ffff0000fff");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(shift_right1, uint_type, UIntTypes)
+{
+  uint_type x("263825472");
+  x >>= 3;
+  BOOST_CHECK_EQUAL(x, "32978184");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod_zero, uint_type, UIntTypes)
+{
+  const uint_type x("987777");
+  const uint_type y("0");
+  BOOST_CHECK_THROW(x % y, std::domain_error);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod1, uint_type, UIntTypes)
+{
+  const uint_type x("987777");
+  const uint_type y("123456");
+  const uint_type z = x % y;
+  BOOST_CHECK_EQUAL(z, "129");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mod2, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type y("5");
+  const uint_type z = x % y;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/gcd.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/gcd.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,62 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd1, uint_type, UIntTypes)
+{
+  const uint_type x("10");
+  const uint_type y("2");
+  const uint_type z = boost::mp_math::gcd(x,y);
+  BOOST_CHECK_EQUAL(z, "2");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd2, uint_type, UIntTypes)
+{
+  const uint_type x("456489798");
+  const uint_type y("987");
+  const uint_type z = boost::mp_math::gcd(x,y);
+  BOOST_CHECK_EQUAL(z, "3");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd3, uint_type, UIntTypes)
+{
+  const uint_type x("16384");
+  const uint_type y("16384");
+  const uint_type z = boost::mp_math::gcd(x,y);
+  BOOST_CHECK_EQUAL(z, "16384");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(gcd4, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type y("0");
+  const uint_type z = boost::mp_math::gcd(x,y);
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+#ifdef BOOST_HAS_VARIADIC_TMPL
+BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_gcd1, uint_type, UIntTypes)
+{
+  const uint_type a("42");
+  const uint_type b("56");
+  const uint_type c("140");
+  const uint_type z = boost::mp_math::gcd(a,b,c);
+  BOOST_CHECK_EQUAL(z, "14");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_gcd2, uint_type, UIntTypes)
+{
+  const uint_type a("1200000000");
+  const uint_type b("2400000000");
+  const uint_type c("3600000000");
+  const uint_type d("600000000000000");
+  const uint_type z = boost::mp_math::gcd(a,b,c,d);
+  BOOST_CHECK_EQUAL(z, "1200000000");
+}
+#endif
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/integral_ops.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/integral_ops.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,195 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(construct_from_zero, uint_type, UIntTypes)
+{
+  const uint_type x(0);
+  BOOST_CHECK_EQUAL(!x, true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_signed_char_max, uint_type, UIntTypes)
+{
+  const signed char x = std::numeric_limits<signed char>::max();
+  const uint_type y(x);
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_char_max, uint_type, UIntTypes)
+{
+  const unsigned char x = std::numeric_limits<unsigned char>::max();
+  const uint_type y(x);
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_int_max, uint_type, UIntTypes)
+{
+  const int x = std::numeric_limits<int>::max();
+  const uint_type y(x);
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(equal_unsigned_int_max, uint_type, UIntTypes)
+{
+  const unsigned int x = std::numeric_limits<unsigned int>::max();
+  const uint_type y(x);
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("987777");
+  const uint_type z = x + 1;
+  BOOST_CHECK_EQUAL(z, "987778");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_integral2, uint_type, UIntTypes)
+{
+  const uint_type x("987777");
+  const uint_type z = x + (-1);
+  BOOST_CHECK_EQUAL(z, "987776");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_unsigned_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("9999999");
+  const uint_type z = x + 1U;
+  BOOST_CHECK_EQUAL(z, "10000000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_signed_char_max, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type z = x + std::numeric_limits<signed char>::max();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<signed char>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(add_int_max, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type z = x + std::numeric_limits<int>::max();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("987777");
+  const uint_type z = x - 12345;
+  BOOST_CHECK_EQUAL(z, "975432");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral2, uint_type, UIntTypes)
+{
+  const uint_type x("98000");
+  const uint_type z = x - (-1);
+  BOOST_CHECK_EQUAL(z, "98001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_signed_integral3, uint_type, UIntTypes)
+{
+  const uint_type x("125642682070");
+  const long y = 2147483647;
+  const uint_type z = x - y;
+  BOOST_CHECK_EQUAL(z, "123495198423");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(subtract_unsigned_char1, uint_type, UIntTypes)
+{
+  const unsigned char y = 14;
+  const uint_type x("987777");
+  const uint_type z = x - y;
+  BOOST_CHECK_EQUAL(z, "987763");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_signed_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("987777");
+  const uint_type z = x * 12345;
+  BOOST_CHECK_EQUAL(z, "12194107065");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_unsigned_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("1256");
+  const uint_type z = x * 100U;
+  uint_type w("125600");
+  BOOST_CHECK_EQUAL(z, "125600");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_zero1, uint_type, UIntTypes)
+{
+  const uint_type x("9877234234252377");
+  const uint_type z = x * 0;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(multiply_by_negative_zero1, uint_type, UIntTypes)
+{
+  const uint_type x("9877234234252377");
+  const uint_type z = x * -0;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_unsigned_char1, uint_type, UIntTypes)
+{
+  const unsigned char y = 16;
+  const uint_type x("10000001");
+  const uint_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "625000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_unsigned_char2, uint_type, UIntTypes)
+{
+  const unsigned char y = 128;
+  const uint_type x("14222200");
+  const uint_type z = x / y;
+  BOOST_CHECK_EQUAL(z, "111110");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(divide_by_signed_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("786432");
+  const uint_type z = x / 12;
+  BOOST_CHECK_EQUAL(z, "65536");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("786432");
+  const uint_type z = x % 12;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+// TODO should this work?
+//BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_signed_integral3, uint_type, UIntTypes)
+//{
+//  const uint_type x("987777");
+//  const uint_type z = x % -123456;
+//  BOOST_CHECK_EQUAL(z, "129");
+//}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modulo_unsigned_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("987771");
+  const uint_type z = x % 16U;
+  BOOST_CHECK_EQUAL(z, "11");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_signed_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("786432");
+  const uint_type z = x | 1;
+  BOOST_CHECK_EQUAL(z, "786433");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(bitwise_or_unsigned_integral1, uint_type, UIntTypes)
+{
+  const uint_type x("786432");
+  const uint_type z = x | 1U;
+  BOOST_CHECK_EQUAL(z, "786433");
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/jacobi.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/jacobi.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,32 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi1, uint_type, UIntTypes)
+{
+  const uint_type x("1236");
+  const uint_type y("20003");
+  const int z = boost::mp_math::jacobi(x,y);
+  BOOST_CHECK_EQUAL(z, 1);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi2, uint_type, UIntTypes)
+{
+  const uint_type x("987897");
+  const uint_type y("987");
+  const int z = boost::mp_math::jacobi(x,y);
+  BOOST_CHECK_EQUAL(z, 0);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(jacobi3, uint_type, UIntTypes)
+{
+  const uint_type x("610");
+  const uint_type y("987");
+  const int z = boost::mp_math::jacobi(x,y);
+  BOOST_CHECK_EQUAL(z, -1);
+}
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/jamfile.v2	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,42 @@
+# Copyright Kevin Sopp 2008 - 2009.
+# 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)
+
+alias boost_test
+: $(BOOST_ROOT)/libs/test/build//boost_unit_test_framework/<link>shared ;
+
+alias boost_serialization
+: $(BOOST_ROOT)/libs/serialization/build//boost_serialization/<link>shared ;
+
+unit-test abs             : abs.cpp             boost_test ;
+unit-test add             : add.cpp             boost_test ;
+unit-test bitmanipulation : bitmanipulation.cpp boost_test ;
+unit-test bitwise_ops     : bitwise_ops.cpp     boost_test ;
+unit-test bool_conversion : bool_conversion.cpp boost_test ;
+unit-test cmp             : cmp.cpp             boost_test ;
+unit-test ctors           : ctors.cpp           boost_test ;
+unit-test div             : div.cpp             boost_test ;
+unit-test gcd             : gcd.cpp             boost_test ;
+unit-test integral_ops    : integral_ops.cpp    boost_test ;
+unit-test jacobi          : jacobi.cpp          boost_test ;
+unit-test lcm             : lcm.cpp             boost_test ;
+unit-test modinv          : modinv.cpp          boost_test ;
+#unit-test modpow          : modpow.cpp          boost_test ;
+unit-test mul             : mul.cpp             boost_test ;
+unit-test numeric_limits  : numeric_limits.cpp  boost_test ;
+unit-test pow             : pow.cpp             boost_test ;
+#unit-test prime           : prime.cpp           boost_test ;
+#unit-test random          : random.cpp          boost_test ;
+unit-test root            : root.cpp            boost_test ;
+unit-test serialization   : serialization.cpp   boost_test boost_serialization ;
+unit-test shift           : shift.cpp           boost_test ;
+unit-test sqr             : sqr.cpp             boost_test ;
+unit-test sub             : sub.cpp             boost_test ;
+unit-test stream_io       : stream_io.cpp       boost_test ;
+unit-test string_ops      : string_ops.cpp      boost_test ;
+unit-test to_integral     : to_integral.cpp     boost_test ;
+#unit-test traits          : traits.cpp          boost_test ;
+
+#unit-test compile_all     : compile_all.cpp     boost_test ;
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/lcm.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/lcm.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,54 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(lcm1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type y("0");
+  const uint_type z = boost::mp_math::lcm(x,y);
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(lcm2, uint_type, UIntTypes)
+{
+  const uint_type x("51111");
+  const uint_type y("0");
+  const uint_type z = boost::mp_math::lcm(x,y);
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(lcm3, uint_type, UIntTypes)
+{
+  const uint_type x("4");
+  const uint_type y("6");
+  const uint_type z = boost::mp_math::lcm(x,y);
+  BOOST_CHECK_EQUAL(z, "12");
+}
+
+#ifdef BOOST_HAS_VARIADIC_TMPL
+BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_lcm1, uint_type, UIntTypes)
+{
+  const uint_type a("120");
+  const uint_type b("204");
+  const uint_type c("136");
+  const uint_type z = boost::mp_math::lcm(a,b,c);
+  BOOST_CHECK_EQUAL(z, "2040");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(variadic_lcm2, uint_type, UIntTypes)
+{
+  const uint_type a("12010");
+  const uint_type b("3299");
+  const uint_type c("84780");
+  const uint_type d("15");
+  const uint_type z = boost::mp_math::lcm(a,b,c,d);
+  BOOST_CHECK_EQUAL(z, "335906753220");
+}
+#endif
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/modinv.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/modinv.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,25 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modinv1, uint_type, UIntTypes)
+{
+  const uint_type a("35");
+  const uint_type m("33");
+  const uint_type i = boost::mp_math::modinv(a, m);
+  BOOST_CHECK_EQUAL(i, "17");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(modinv2, uint_type, UIntTypes)
+{
+  const uint_type a("17");
+  const uint_type m("26");
+  const uint_type i = boost::mp_math::modinv(a, m);
+  BOOST_CHECK_EQUAL(i, "23");
+}
+
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/mul.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/mul.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,398 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul1, uint_type, UIntTypes)
+{
+  const uint_type x("12");
+  const uint_type y("22459455");
+  const uint_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "269513460");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul2, uint_type, UIntTypes)
+{
+  const uint_type x("280708");
+  const uint_type y("2245945");
+  const uint_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "630454729060");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul3, uint_type, UIntTypes)
+{
+  const uint_type x("65536");
+  const uint_type y("65536");
+  const uint_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "4294967296");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul4, uint_type, UIntTypes)
+{
+  const uint_type x("1234567890123456789");
+  const uint_type y("9877771234567890123");
+  const uint_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "12194779192182653090000267987090395047");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul5, uint_type, UIntTypes)
+{
+  const uint_type x("789456120556882111687894651457623561325656871513");
+  const uint_type y("54564563128978513215");
+  const uint_type z = x * y;
+  BOOST_CHECK_EQUAL(z, "43076328327684465744675616648356768900793087398990591539995027544295");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul6, uint_type, UIntTypes)
+{
+  // x is 1023^256
+  const uint_type x(
+    "0xc759410869daaf709b5fda9eab0192ae2dadd5b7ee97f32d933b851ee0157196c574c22a"
+    "bd349465d5049007566c5dc684517a9dcdcc7026a3b060a78e37258b3bc6a22aa1a25702d7"
+    "64a575913531ccaa1a6c93bd8824a40e93e783ce1e2bd29465d2ed8dbed1748c6ac6a9cda3"
+    "b44a39dfa7fdcd8c59b3e597e7116f98fbc909e3f46f64544a5a8e7ace364efb52ce2eebfd"
+    "76739fcd104cfef49136e582b61674d7b875712ba32121cfefcbc545fc0e4e80998c380ed7"
+    "20155c23678c1a707a4660ccd3749b2051e67605d4c5f312b52b406fe4c88c3cb28c9d126d"
+    "764e91e387248cb8dc1d9b953d6ba2d6a530e980c91539dce6fb2e3110da092d4431434b75"
+    "262bc4c3720f93b662d42beb0e00803dd2a0c24d1f733f4bf4d56d4b2260ee00acbeaaf39a"
+    "481004fd5dd49b240e344f318ac2fe505637153547f7fc0001");
+
+  const uint_type y("1023");
+
+  const uint_type z = x * y;
+
+  const uint_type w(
+    "0x31c9daae09f00e312fce40aa00d5b49260889a90a027134c31f5ad8f66175b0e97f0d93e"
+    "8ca151d02ee3d3b8d525b0abc4ac198fc9963f42a681dd23d914e5f0763dec2085be7b9b45"
+    "abb3130cf439200dbbf97e262630a6b96410a27b4aa911e7f02e5e3496d8700bd1eafe08cc"
+    "12d749d44c04f3863da75e27a045eacf456285e85edc921ecd51fdf5cbe0b059e4fe5ed810"
+    "9dc580b947423aed3504a5f2555a3bcea0a1d4f3d60e1661def3f4952aa3d2bb3e59754034"
+    "da9355b317ac8dda7789f3cd280fef7e62747f1a14d430657c1f7d67f233d68668d7fe7aca"
+    "36bc3f8fc390b0e56b79a50b960711fb7be1e7519a38bd239bf05bd9612574aabe380dbea8"
+    "92388e74904cc3f45d4eddb804cf400770cb0687230ad89f08760dfbf3e615714b24ded237"
+    "585f803f079f497f514c30876f981364308861dbfea97f80403ff");
+
+  BOOST_CHECK_EQUAL(z, w);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul7, uint_type, UIntTypes)
+{
+  // this tests karatsuba multiplication for 8, 16 and 32 bit digit_type
+  const uint_type x(
+    "87500402519005030061267904448809305029512439942506161234260852587645856336"
+    "94640987107484273728362553552515383304557585868121651546490330517814007487"
+    "34682745159208158750835203309620570274592666481348052963762094268695162425"
+    "18850320172906096781969070339129822281355221058882087466637338881223511228"
+    "63144016884857141834687376804878770495858121023810198067988560350169566260"
+    "59441070673981642057711662497893572913873133654626566743289483229067287310"
+    "16863866837882738076436342057320810154710294295605465397209378421688020320"
+    "35702406032061642794728883255642074744145228324022219347019013411158803532"
+    "45994041206565648683544493690427219798945006072652042753387791345064784511"
+    "50227920502852884378111055250850357557404795594025600468996407045934090727"
+    "08041078777870387730504");
+  const uint_type y(
+    "87500402519005030061267904448809305029512439942506161234260852587645856336"
+    "94640987107484273728362553552515383304557585868121651546490330517814007487"
+    "34682745159208158750835203309620570274592666481348052963762094268695162425"
+    "18850320172906096781969070339129822281355221058882087466637338881223511228"
+    "63144016884857141834687376804878770495858121023810198067988560350169566260"
+    "59441070673981642057711662497893572913873133654626566743289483229067287310"
+    "16863866837882738076436342057320810154710294295605465397209378421688020320"
+    "35702406032061642794728883255642074744145228324022219347019013411158803532"
+    "45994041206565648683544493690427219798945006072652042753387791345064784511"
+    "50227920502852884378111055250850357557404795594025600468996407045934090727"
+    "08041078777870387730504938308922524767076619493071600607096868205642593777"
+    "83064672064693123083586511497969514956199763260628691421422356349215807298"
+    "53893432372651287096347803705731068491268031212879821570628466049198139563"
+    "07225373203247341492567070512742515269237115281940442618925655326204507165"
+    "43018685973456180521304052296263372550548657267007681462726186588489921154"
+    "03738735312309811855295260282588410141887442245474311543699839300870263148"
+    "89969642893224272388306131900850182843780525186002406202200057400419364041"
+    "12480917884571681605871307558328122948240801747503773233227317344565943160"
+    "78184811118761000119446172201197213166958413376441353073591860771242469526"
+    "34162171790217465073689788174652534961638870987430329380376975097234424950"
+    "28626203467171261194438985008578074151902043501430333019202385199270557942"
+    "82069487032265791643884311563532673152911052140807076806223793474752085674"
+    "51690168224265201474031350018449280412602665727006489664736651532321662145"
+    "22395731894311806382965185156526606660906262290677223798531105431808835740"
+    "80068277468617762211054331907328141344243411630209274782352265433366236954"
+    "62340796945506470082986574244652633468578747126384423018749343237426427830"
+    "62597495610006322516869046617226177792891514414040880511098169575819779926"
+    "53267511946096311413217967853431922008343789549408902117132966444741997352"
+    "58418657379544687590177580275674377304583931111620683151992749560156615440"
+    "09956001573216294273550652829235006290995819615078227235050765818475452342"
+    "95118077784320900839083926375344280915278665450149678774001364483022411118"
+    "86989210613864536835695555040115554865868694788922281253334356037168116291"
+    "99227045413249316876243936449829162763370534672670641521910718921661373160"
+    "93948899172794003245737017747952580428164207428777214495975431645589773283"
+    "12391742034637254884903040666536846003583703264118132242307521988982264762"
+    "13953490712153270721924306359669195669881431604926261623147833800912453474"
+    "06542388952383807976431616628717886593805647129190060659586374949333503420"
+    "5241703455510726935");
+
+  const uint_type z = x * y;
+
+  const uint_type w(
+    "76563204409879018101322737668344063995824904757312285775560614771886933079"
+    "77822556905976720912850551355328340715074887289899094852653102687850101285"
+    "85715275531977696497398396067715769512450915961775500023723324150851793075"
+    "51871751151095323159497918186624088118225730504044262785072662119470825604"
+    "40835072257208973943520251201155002832786969323087571220195329601804141972"
+    "71293425859967733061169954398382700046379970842289727254846347411792122453"
+    "98890529530611217475343335863666953662801553948341581412563112340543629531"
+    "01094529771464590172847457807673685591148055046712881378811934516545088775"
+    "38198087116656466935095055228728162461388333618793883566996616940381738437"
+    "03453867953392241443573580380271627517797446062394044787118140775664622031"
+    "49144609407766890328547643707523663509662747376486271392344480900673178645"
+    "33198519112197059826509662943577383543858946941049753393431035706592040680"
+    "43848484065292542884106550381079282660840705126574766636237650938379223350"
+    "07308780680088758625608527577521721942952700001740314426688555136034651920"
+    "92948869415921251533176579828351648585255631612516166131530519177426817087"
+    "53127165191235539369253485175856164884318259457319518574027800748530624722"
+    "30999853784133144744590149844870058500033133557974954747400058296439058233"
+    "59080109028703731380219724583279605028258137468666258706566102379192203551"
+    "90274426910716106736469216457355540125186992654301008720830993368763363204"
+    "11036960264301276622450044075944548104639523605502445335712149154791061273"
+    "09156720459736055974643337783563754269574952607968485689453462316428566668"
+    "95504701770860331979649536167161534866285341319360225416010322271645564229"
+    "97610536562445338176729838019564690253931232562709745122032537539983616770"
+    "01864876491464203683664927984801289460556480278145114367860332493722569194"
+    "34026051618152579992400234314328079213866348120156368725488604236521299603"
+    "05243915357553896356662519397274629471920043679673543282319268893065423613"
+    "03777840501083119668898860689222271939900089123195611475211708096094521743"
+    "23436842195705603262202927396682954198215622617086455718070601797199587530"
+    "86110222151397352239086193648500251298495752840008363650931395221675337916"
+    "21665907282124706187656074325458499695895652068822763794228458103499408841"
+    "68233732651102406546734395563663969020820490032431359396293047454261598159"
+    "68165818673838448637209074584819780088546111644065538550490486693301185614"
+    "61602638472505490238203390055056474763248195271964604045005807592301719483"
+    "66411676459481184297663915491569500245585996483678005964410842919747216111"
+    "69086269285356198998091850661544255466466926579668887000118948737207396398"
+    "39189399212362197497646493143022100680619252808094160907526003969639965485"
+    "31238493375062268758735445211914107215235958346264702774326161208396163240"
+    "36339482493382189215697343908873498104516190541170342091008828518924813674"
+    "46253090923280613514725437269574928515018666111820866090440006060807129643"
+    "38626199608899966829344884873038261232122027815715568990196536130996880104"
+    "97887027262726591236620461428328000537452828616386217063092509908555188454"
+    "27278763741671312528892659532960085933913140197210561287118971031419725940"
+    "70220283055606934471672907114014782099956647529889583250740029484462218658"
+    "62960901244568848989478467720707250809806379509214397878558772543587967635"
+    "96161034019645060913914198361071023036142203589230741296078930717247341831"
+    "26204308310630181474853421564903407641109879794777661716811159608177803322"
+    "61170286373919980640839261570604290919653466216587527613203517128403418424"
+    "791614399508711582164287714644181913925240");
+
+  BOOST_CHECK_EQUAL(z, w);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(mul8, uint_type, UIntTypes)
+{
+  // this tests toom cook multiplication for 8, 16 and 32 bit digit_type
+  const uint_type x(
+    "0x5004a2519b00503006126bb044af8930502951243994250616123426085258764a856336"
+    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "9464098710748f27372836255355251ae330455ffaa58681216515eeff0330517814dd7487"
+    "34682745159208158750835203309620570274592666481348052963762094268695162425"
+    "18850320172906096781969070339129822281355221058882087466637338881223511228"
+    "63144016884857141834687376804878770495858121023810198067988560350169566260"
+    "5944107067ac5771a1662497b8b93cfe57291387313365462656674328aaaaaf9067287310"
+    "ea6863ec68378827380764363420573208101547102942bf05465397209378421688020320"
+    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "18850320172906096781969070339129822281355221058882087466637338881223511228"
+    "63144016884857141834687376804878770495858121023810198067988560350169566260"
+    "59441070673981642057711662497893572913873133654626566743289483229067287310"
+    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "16863866837882738076436342057320810154710294295605465397209378421688020320"
+    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+    "f84c878148cc7020890befffaa4506cebbef9a3f7c67178f2");
+  const uint_type y(
+    "0x875aa402519005030061267904ccc8809d0502243994250616123426085258764585633a"
+    "94640987107484273728362553552515383304557585868121651546490330517814007487"
+    "34682745159208158750835203309620570274592666481348052963762094268695162425"
+    "18850320172906096781969070339129822281355221058882087466637338881223511228"
+    "63144016884857141834687376804878770495858121023810198067988560350169566260"
+    "59441070673981642057711662497893572913873133654626566743289483229067287310"
+    "16863866837882738076436342057320810154710294295605465397209378421688020320"
+    "357024060320616427947288832ff6420747dd145228324022219347019013411158803532"
+    "45994041206565648683544493690427219798945006072652042753387791345064784511"
+    "50227920502852884378111055250850357557404795594025600468996407045934090727"
+    "08041078777870387730504938308922524767076619493071600607096868205642593777"
+    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "83064672064693123083586511497969514956199763260628691421422356349215807298"
+    "53893432372651287096347803705731068491268031212879821570628466049198139563"
+    "07225373203247341492562497b8b93568861230addd281940442618925655326204507165"
+    "43018685973456180521304052296263372550548657267007681462726186588489921154"
+    "03738735312309811855295260282588410141887442245474311543699839300870263148"
+    "cdd69642893224272388306131f0a850182843780525186002406202200057400419364041"
+    "12480917884571681605871307558328122948240801747503773233227317344565943160"
+    "78184811118761000119446172201197213166958413376441353073591860771242469526"
+    "34162171790217465073689788174652534961638870987430329380376975097234424950"
+    "286262034671712611944389850085780a4151902043501430333019202385199270557942"
+    "82069487032265791643884311563532673152911052140807076806223793474752085674"
+    "51690168224265201474031350018449280412602665727006489664736651532321662145"
+    "22395731894311806382965185156526606660906262290677223798531105431808835740"
+    "80068277468617762211054331907328141344243411630209274782352265433366236954"
+    "62340796945506470082986574244652633468578747126384423018749343237426427830"
+    "62597495610006322516869046617226177792891514414040880511098169575819779926"
+    "53267511946096311413217967853431922008343789549408902117132966444741997352"
+    "5841865737954468759a177580275674377304583931111620683151992749560156615440"
+    "09956001573216294273550652829235006290995819615078227235050765818475452342"
+    "95118077784320900839083926375344280915278665450149678774001364483022411118"
+    "86989210613864536835695555040115554865868694788922281253334356037168116291"
+    "99227045413249316876243936449829162763370534672670641521910718921661373160"
+    "93948899172794003245737017747952580428164207428777214495975431645589773283"
+    "12391742034637254884903040666536846003583703264118132242307521988982264762"
+    "13953490712153270721924306359669195669881431604926261623147833800912453474"
+    "06542388952383807976431616628717886593805647129190060659586374949333503420"
+    "ffab023789d7d78f78a45a45fee789001a1a");
+
+  const uint_type z = x * y;
+
+  const uint_type w(
+    "0x2a4ec67dcaf1afdd14bf63d7cd883f269ca00be2cae5c539545352050e33af7bb008713c"
+    "63587bc02911b0cb1fb807d94cd4a937f6e19801a28500f45ba1dc90a548e8e15e0c31536b"
+    "39f3940191a76b6fd96fda83c7aa9aa675f536633917587fbdb4990f73dc4650e19af67392"
+    "712b0a94aeec78f21523bd2ae92cee0b5d42ce2ead649060ff8134dbca0790f051b132b8fd"
+    "2f0bbe66f3226f7fe7a80c0be18fcd0238ff0100e4353f4973c1cb72c40e83804192fbd008"
+    "1e3d4dfe03e1d4c8d1ed4ba8ffe7cf5d00237598de949ab89cd6f95cbc3545a4d797e425f9"
+    "041fbe52955af28221505ce3e53cb5bc12d8d9a13f39704463db4db21aaea4fc29643a2746"
+    "2e6d3b40f9eb621106bda6223bf2aaa4f027e037acb45406cd39b242c90df3b4fae1bf788a"
+    "1529dac1ce1b77f4d1557e2aa8a4adf9c6b3b0c364ce68300b5f65efc8166dae1b2e0f8443"
+    "76975b12b72c36f2dfc4a533adca3db43955265d91d15232bcfd712e46dd4cd4f63981317b"
+    "31be8e9fc0a56275da498e8a4c13419eb8560fa05d73373ff238787b77c0b45c0b44b6b042"
+    "365bfb3b3a4d96cdb3ad7cb9b9248498a02b43a16206db5cc3f52c4cdf2c58807a68a6d1b0"
+    "f24bf8daa4eaf6ffdd3e781fd52b5fe609678d045944d7ea6a6689954b82a737b136a86d32"
+    "e8de0c6b88e66300487b83deb53038fc298c2b1d1ffe64ab7ebf0e7682b285bb567c3ad4bc"
+    "69c0e0216f5c8df2681a3e84435b39dbd4a3cd5dcdf0b776bc0b5281f8806155318e70d237"
+    "4267ca699ebdc5df58e282f7a6d2a7401a3544193741e9597df7fb92c7a0c87128b53ae873"
+    "14aacf233fc20cba4ac4835579bd82b6efcadd591dbf826d470795d64bb698202e3fc5bbd3"
+    "9ca2249167520764d448a95c7a7ed00f43d2f36f4158fccacf2f5738878099da8a323e7d2c"
+    "57579da5e348b45aabe59366085532c73c2388b3a2672b08758bdaae3746364b49d0217b27"
+    "5d22b2b4916628afd5009e103803f4ba5241413200d85e119ceb4dc876c1521047a8be7650"
+    "767b0d83fcbf991c6b04a51213692867fe4c9e452b2800fe5fc57df9d8f75cab72609a49af"
+    "92b1e2407b64ea424344a626b2e86eacdf18af6a000af8c5607019df1d670307a65df3e4bf"
+    "51e9809212a3288001e1df69a6070558e24f686ff34b50e7b2daf5f3f7abc7be88fff8fb5d"
+    "f0aab1f952f91eec5c5ff7e25d2babb61db263e7381fbe40ad81b3494c323a35d3333fcadd"
+    "d6b057c88fe2f43ec1bf754de9fdbc768457d7fc44c90c2e44f79c32849f56d7d2152b96d1"
+    "4b7735e8eae29d8e9ccdd61be1f73f7d1d2e16732505448a33145a5b1d5c342f0990a0a731"
+    "a5e034cb3c0f5658e20b8ac7f4e93c249ec9badb93c4e064b59c34b11e4327d0dacb0951ac"
+    "1c13831520a06deee884613bce16fe5b92e1e0776caf6aa1a7aadccad11a741e7c08512816"
+    "e1c4a0f8910c35450a7448c180528decdc54a9af2cf5b5244c03d088be6d8b6978f2e90baa"
+    "3ce9f85456b51768f7b2d2261785f7680e62cdc420d0e62e41aba012a391c250d3579665ec"
+    "06a0e137c8d3da6ec07be1c2f0599dcbd1f6a801a06a062734ec34889edcd57ca99bc35d5b"
+    "9686b7fc073aa06d9d052ae7d762a7dbc5740e73ef730b478acdb54455d4db80e80b03bc61"
+    "aa013ab9c0b9ece6a00e4e46c16068a2771d0c9c42432f4ef1279481886c6cf890d656a8fa"
+    "e248c9c17bedb151ea802c3b8d7918296dc38a71f173c0b6fceb72611bc817429271ff1d1f"
+    "9fc29780727dbab824eb6ff07e552c8a6679c667bbb20925b7920c7307e3f553c64e1f8962"
+    "e556168cef58af8f406f9f6847719addd6083d19e351b2281bb6f8f64789cdab8f29915f71"
+    "128cd2152ba95124b935770dda3231973037cb7c1e8d22ee4bd10331c91d4db53c291cb16c"
+    "f498366646a27bc18df39aeb5790ba6e02c9904b0fe7e6127dd412daaafdc9b1548727eb05"
+    "57e191893e391f038797139cdf054dab4a208b00dbea79313c3952bcaf8384882456dace78"
+    "117550a133acd3cc883c036e2ecb133eaca4f6df4c002589436f529f3975fde6c779ab3038"
+    "85b1decf3f9b625dd31d634e98410486ba3e3dfff5e90da22c1734fbf9b52b92db6b44af70"
+    "da57859ca38220d8a24dca3251f9f65a1abfcbd2386732f3919c88af189efeb31ee6da9deb"
+    "f70e85bbaa928abb1d2ba86d3b038c1eea98c1a36d0e783a79e578cbc3b98d9a9f4a9c0392"
+    "bf51fcb31325c1b9131f762cd31583c231d786190dc92752781192a72ff75c3c8c297706a0"
+    "4d14571575e076dc13c8bf2c3202bb468ef6f20f6ae27ba91a0182af2c73a40477a9e1d23d"
+    "60fc5f57e9f3a86315b11ea7dc922ba70d38a24c18e1552e15239b2a29d6fc7517f5aabdd5"
+    "e0c800178beeac9b582c44af59f7c2cee341813eb13220d4bee3ef07e9ab8d35ccc0f684e9"
+    "902affb65f87cee827e6bd42fbc433df0070dc210d078fdc92fb7f559b577150e28f21f64a"
+    "c0edc61da523858e62cca0c85b8c16b8bd784f7ed8efb96314e75b3b9bd26ea93bdfc45565"
+    "85ea59cda0c92be16321ed27d93b9a05980574fc99dcb079e6145a0b0ab0c4cbebdc0e51af"
+    "2825278224922511ab721f412589b8a160fa95c3bc9038a3af4a330f5e796d30bf60017921"
+    "bc01a0200e87c26a0afedc292ff05a3e9d564323d0e0c738bcbf24f226d9aa59944abc109a"
+    "9916f57dad39fd1c928da18c32184a230be2eef814c47cea0baea02241c34fae2c8d025a02"
+    "0ab4faf8409cbc467333b807af12473f5dc3be988bb9ef61a60ff1672e07de7f5f6bf99583"
+    "f876305337ca3bbc6b2cc1f562d9f4b90cd9e54d85e04b8aa47dcb4dd5efb271f2a1d61922"
+    "cefdabcad5c3565f3f65a3e421e688b53c15a568c368eeed28d546e47dd53afc3944bfce69"
+    "94841555ac1a1968412a5504d68ae69b2067aaf3c8516a993ffb0657f82cfcb4950e6da431"
+    "de09b4a1d104e3190af9518bd2d10921ee2a3cbba8c25e1ef98606121d60cb48dbe91994f6"
+    "afceb6ea5187fdbd6d943b24c6a2584516d014ca5549828b1c5dcb80016f5dbe91667d03c0"
+    "ed9db277261ff9a7fe77886bb1c9c7d3e95e8a4204b984115323b3a8895ae102921e807294"
+    "131b5554246e6004541e11d1e449f017f1590b18c695ab79b098683f4693e0c6d87836feae"
+    "3db0bceca8b11f9b2190b8f61d77fdad0687ce678c31059af3771bc54170fad3171efa5eaa"
+    "39a4dc3d3fa837e868d1cd704de7c1877e4b77cd9fa44d500b74d0a52cf1b9c5ca6f031005"
+    "c6362066e930694a5d8063a2f27c899a78dd4f79f89e47c46e24c454efcb034105824c009f"
+    "9ce5f9b0eb6998ee1a61a2b83ed878ac81e50ffa48f6c5eaf225a56c9cbca51312808c0c51"
+    "7f49f131c12ecb7094f389228b77db2a305a01f69975138aa67dce71b80285fa1f21993189"
+    "b38898d0e2c5e6fddb644101107f610ac20ab744140addc41021fbf68b041b80fa3c1a3851"
+    "65038651ac3a07ef76368658c5a984d28e149981a7ab931e6fa1d87aa8756331927c54443a"
+    "54177cb8617bd8f54aba47a06af8f41f28cc47d71bd153d821c0c45adbad135170cfe68429"
+    "683a0bc06e4e7a06bd060a87fb8309e4f14c31a3732eada80079072e55fc26cb02ac710791"
+    "0a95d32111198ac6c07625c117acf23fefbbff59fb4c84bc6ac1a3fde905cf1d75693caaf7"
+    "7d2728e7c66d6005a236176e85cb3b282fb7a577e5e4c617c23b2af879810b560882c93552"
+    "27ee9670073d5288c4af9e57a0c81c7af0142670dbb0a18a2f79fe3ae3791739e732784600"
+    "fe9a9a4475ad985499e81ce7a06a04368fbdd007ddb2a222a0268c086252e73f18ef9b165a"
+    "c044c5f42af698b80eba1c1b4423c3b8d010d31ea85831fae7bbb74efe9a22283c1e238d09"
+    "6ae5d00ded7ae17744925d316b3d1c92861c58e1e6668dd52f4932c1e891ed5441f29786fd"
+    "d41a78b75730b8cc193ed85ac5a667a86ba4bbc1ad45aeddc56d32e16f410ad06f5cd2e6b8"
+    "2a31feb6585cfe987b8db1dc8dfdd3a4a8b09518f341fac8f8c7aeb8052cec62bf23eab8a1"
+    "b35cab3e3ed3acc3b64e29c1cc4d7cdeaefcd61f06c61b8a48b90a838ee0aac2cc76a2e56f"
+    "d8dda42e2ff863f75132ff39dd4241ac3ac1aa21845a66bdd02b77b4c38dd5ada02e3863e0"
+    "12b5bf5ad2eae7f6b1b85b4fdf960b915c257dc2be810ce92bb82c58bc478994a71332502c"
+    "ea5e5cf5bfc2ba0480d53dd2dec046f718001eba5088463e6598488dbca8cf07024102458c"
+    "abac35a14188323195f0bcc8a4d7b006467ad4ee46e6cc61f91243e311e0a775582ca3be74"
+    "9193f6044b573435eb7185c437ce3abb6b232f7d85d5beb68ebe859b9af9d6216a5c1a236c"
+    "499c661d705e9df96466429370c573b7c02d6b66c9725f39550e9bd8f63b69dd1d91ae3b7d"
+    "daf6e53f36111e43f185b2a19e6969c95441159ab96ba7928d9a8c66a81d8cb2967d90f5b8"
+    "65bf2b0986e7e10275476faf729ff6ff275347c3afb647cfaf80b76a7d51c1530e5e305241"
+    "e46f992416baa5e204ed1ccc29ab615e71ee06a21d29fabf1c114bcb0262a5031bbb8bf5d5"
+    "a4fcf004f0276eb27cb4007eb0cfc99fc515e858170e135707b07b5f0839f602d1f1ce9eb7"
+    "a41e02aea4c95a499f9ade35d8f1de41791d62ee88fac1e74828aa5025efa0444425f58edc"
+    "1158f0c1afa86f9cf062ef973eb852fe203a48a8cc6f9ef89bbd76e5602aa93c3af0cab8e0"
+    "0433b8beaf63024c36d652dfc1065c483ce480e6b36250d8bf4c3e8500ca1ab6457fa02206"
+    "6592d25f38e376a4e9d7b1dec77b378b6daf4a3e33e5aac75ff2a93808b163e738b62d6f32"
+    "c8526d92795fa623217fcb8c4450bd0ed300742327457928fb0ac0d9a1a47c490db6d3eb56"
+    "900e091c8e047e6f618acac52dea702c4ca72acd001f2c056291d71e8e7e49ea13afae0d3f"
+    "66a7d7dd8d6a264ca4be9eb02549bf40e61f1e2e4f01fe4ceafd7855686747eb1b1acd2c96"
+    "92fcedc94");
+
+  BOOST_CHECK_EQUAL(z, w);
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/numeric_limits.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/numeric_limits.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,18 @@
+// Copyright Kevin Sopp 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(is_signed, uint_type, UIntTypes)
+{
+  BOOST_CHECK_EQUAL(std::numeric_limits<uint_type>::is_signed, false);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(is_bounded, uint_type, UIntTypes)
+{
+  BOOST_CHECK_EQUAL(std::numeric_limits<uint_type>::is_bounded, false);
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/pow.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/pow.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,430 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+/*BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_1, uint_type, UIntTypes)
+{
+  uint_type x;
+  x.pow2(0);
+  BOOST_CHECK_EQUAL(x, "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_2, uint_type, UIntTypes)
+{
+  uint_type x;
+  x.pow2(1);
+  BOOST_CHECK_EQUAL(x, "2");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow2_3, uint_type, UIntTypes)
+{
+  uint_type x;
+  x.pow2(64);
+  BOOST_CHECK_EQUAL(x, "18446744073709551616");
+}
+*/
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow1, uint_type, UIntTypes)
+{
+  const uint_type x("2");
+  const uint_type z = pow(x, 0);
+  BOOST_CHECK_EQUAL(z, "1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow2, uint_type, UIntTypes)
+{
+  const uint_type x("2");
+  const uint_type z = pow(x, 1);
+  BOOST_CHECK_EQUAL(z, "2");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow3, uint_type, UIntTypes)
+{
+  const uint_type x("2");
+  const uint_type z = pow(x, 64);
+  BOOST_CHECK_EQUAL(z, "18446744073709551616");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow4, uint_type, UIntTypes)
+{
+  const uint_type x = pow(uint_type("301"), uint_type("259"));
+  const uint_type z(
+    "0x16becbb1b891cbbbab4825ed1335f0f4ef5250f620023061045e87ca80d80ea7daf0cda8"
+    "023aed1a969864de781297ae556f2bba6d951ae294805dc888f6de01dac2b7dd3ab47db207"
+    "b0f980f26a54f1c7dbb3ebc6cd5b952cccc67569487fd2aea057d4326cc56aad90ecd89b3c"
+    "74c1f30f6ac637a64b706087f2fe16c3bf2be3692106717387813a8a2c9da65b657a8a2a61"
+    "abdfdc6698a6f6543d8f5ae88b192293e2a76ed402d3c914ca0c40e21fb1508cb2c5a7dfe5"
+    "1a357fa58bf9e2f1d1fdd2c3e72b600a8e7390ac0ec65cda8b0636595a83dfeed163a0e161"
+    "b17acc476db2cc246bb3b14a1b33cdfd659d43437b2c4a203e07a8f297ad3a716b53d8ce28"
+    "e84f1b3ad36ba0d2f5");
+  BOOST_CHECK_EQUAL(x, z);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(pow5, uint_type, UIntTypes)
+{
+  const uint_type x = pow(uint_type("3"), uint_type("66666"));
+  const uint_type z(
+    "0x8a25f1339bf63db8e5881f75e7f89ad860d393776362040a47448cfbcb4a9402558acf60"
+    "7a590c1fa521b672329cc18a63eca1cadf87465bf8b44ef05fce12fb020ebf2c2b246d9a36"
+    "af527f947f3d238d3e2504dd5a0f3a071dc98784d1084cbfc4554fc21d72f72ae65766600a"
+    "007b364d2c182ba9b9b16011c2853a28fa2455bce4ac2af57f6c8337b85a8e01fd4086f128"
+    "bedf51902d90fb9e9a7e859e65219b46ee14d5a1660f37884801c65d2f580577f7644014a7"
+    "f26f648308b7e7852fcd1702740aeddf1c63d2e41e3a70f13347c1236f8dda54db58b1df1c"
+    "0849b96ec08286e3160db6c7c71b7488d8516af84eb08e8188a4bfbf045f3ed85ad3d63a16"
+    "79a4dab46fd15caf25543e21751c164b9e7bf0c3ca98ce518e95dc7dc9c949b114aac50935"
+    "f3744f4cea72d9f857c2aed3a1b9e682dd00d6c470365b2af4f95733c16cebdd56ca2d0f23"
+    "846be5f1b6bbf0f5fa7ce974bd310e07fe23502def57e53d495364f5b6db3b11ca05582a36"
+    "d17ffb5a409044e2352bfcb4fb721e39a530c8d9d8373c50ec0063aabacff9781e9cc6df7d"
+    "aaa44256e70ec2e3e0db73b4bdcdbc62d86406dd63dcb24551bb1719232ae07381129299c1"
+    "81c17e69b45391e668c5711112e00f90d492a428c15d93e331fc50faa7f0bf3e3de80050ae"
+    "b198df940c84501f2b419b19b03b339b86b5eaed0647808fe1094601bb6d948f2865194f8f"
+    "b661e26e60ce3a0850258ae914b6c35acf512b4ff6b8adad70eb32e649757368216a02fcfb"
+    "dbc887e9003a2edc863c23c878cb9cb84e7bf478258d0c5c297bddf56dc30b87f693efdf7c"
+    "b1c6c42d867ff7c1d953749905e90c74eb8db7c83ba48a69d4c7b5a4d49bda733fb7e18ad3"
+    "df329e4bedb322678ba5b1884509ce90db795dae188978bd1308796f6d34fb4b9b8e95ca7a"
+    "af4599dcff213ace57690345ee9cca65f870fed4d59072a9de2a9d8d523b34881c78e79f6a"
+    "1666e7f01a987d6052fc995f38c92b3412ecff1a009d4c55636afa1e11dd375f909026ad7a"
+    "caf6a593e6df0a607c5f2b231de83bf86d7817dc7f927d05dea16e3752ab18ff6fcac9031b"
+    "390036a0b3c6e89f5d880a3c31755bc9bbe3b74b7cb0ff521f0c61f4b772c1dfc7fdc834e4"
+    "aedb0b257490b0b6f926648617463aceb4b6b6f16e8145cedac27bb671f4a38986c15302e5"
+    "51e1f0e5d38b767990c944b3f2a652d71eb3d3065d2872c0816a9a59bf57b760eae8748254"
+    "54e8c3623b0515c83387318a2c9c0a8c99e497f4684fd8ec03505b4b1eb7f5f3ecb8505c2e"
+    "96c0e9d8b44af13a9197d415766f38e9dcf11c4cde6232f1d43f63765d45212535a628aa1e"
+    "354bc23e810f71058e38dbeab9e2ff3f335abcb58293f4e594d643f10be1a7669b667ab735"
+    "1899f7664015a4d5b4051ac01129710f03df6dc71146123e7d443f307341cab65f197bfe87"
+    "5313d66c8dc0338e87c52773ae8f3bdba84dbf8a1a3f4f73b3e0ef9452981521d5a30c01d6"
+    "a6827882790ed81f599371c5ae2a266167cf96d9d01431a6358a669d63f21034e998b47c32"
+    "4ddd505f27253dcef488b1c203ae3f46206769669dd1122ab00dfbf36f89c557d75a6bf7be"
+    "a889f32493efb3bd63a1432c7d7130b7502d2dcc55c85a80ec915370c90f0719328d1a87e0"
+    "2652c515b710488f3509faf0792e6d853ad1fbd5322fcc5c78bf2da284fb8ebe79304db8a2"
+    "ebb0a14e5eae45a5627b8f81714821ce0e83f742fc79804e27d8bbc38eca3994243a8f5f48"
+    "ae202e7575835c760eb05742dbd11b31111450148dbfafb29ffd28718dada8f6ae40d498fc"
+    "e7d6a24ed98e1aff5e453f70def935430a795b4daddbe4945710f5553d903f95e60b731f41"
+    "8a6e570492b52e0c8b7fb00bec64703e8f62262f32d70686a9cc9244491b8e5ef606a40787"
+    "e6b41bd08c24499abf57227b142baae204fc0b4d55a81011d9252c3f4fc5543fa0fd912d13"
+    "44da807f30d314669ef47d9cef9f7e316bd3e5b706b87237b0aa86365452116f0229d3e35c"
+    "5684db8b6ae7076d6decc75822d7ef0ff94f7ed3db1f7296cdc2465faf0ea31e4e11bfe5e9"
+    "a7a65493ea438ddedf92036914a54a20f03f3d65a91fb138714b74d6e6fdea549719e3613b"
+    "2840e277dac23aa4d466b7f895801e6ad95532e1f2c3183c8f3c2adfe96fd0c0c47e23c172"
+    "bd993fe30ac299e12941a8a60ebd499b31fed0ef7c2981a862aa5ad6486eabaf38bdd838d3"
+    "8ed62fb21fc76fdc50935c3003c02fe61000218e8507511602b29969ce1648371f8fed081e"
+    "395726af42734f3cb8910f52180d01178242dcd9093dfb7abfd3bfcbcc543f495820dcb1ee"
+    "60a1b69ff7f080fc21e39f22e4aa9643558bbe37d2e92563938e3f4a8958ff7d5becc6246c"
+    "bf2e0f24481e1593122000897d171e2cf9b18bcac4951305f0ce9e74837a4cad004b5b91c3"
+    "ecc8507758143e4df2c8d5901b8e9185241a6bada332682e764e3b9d55e06132205b257c3c"
+    "8ada391d6b6a82fa493eddfdfb141371480e04a0ba6f7ffac004aef32247e99463319aeb6b"
+    "93577df50cdd3c4189478f04cdb9861c416e6a0a05ee0d60073d7f1473b06d4cc1d064b8fc"
+    "6b14d12e414f7f532d70bb953405a04c34c0edc0a6f2dc67fcbe7643bbe0cdb8275b41074b"
+    "a5a7c332fac3947f8dda001177147e8e8f1e509aa1b602c781614977c3cc06fd48115f9382"
+    "8e60f4d57f76b1a5b2fd9bfc03616eb0fba9339e4d59f2e0556c792f6ee3afd5b1369aecf6"
+    "2fab5eb9ecd6641b710a39753edc0d8c535f95c4fbbb0d44f51e8fc63dbd3bdfc48688446e"
+    "f255f4452f68b8bb0b0cba01bb0ba41ef33ddaa2c929841b9013b201424aafca3d1a98f19d"
+    "8dfe28eff5ba2f1645252ae27d3a8378d2c50b498f449291e85ebb65a82cdca952a47c77c7"
+    "680cafb603a202998d5c422d475ebc42eeba9d26a962feb579ea01509d5e47b1cf3da3a862"
+    "7527369ed4828eb893fb07fa6fcdb5c4c4fddef59dd2b04f63c09038351d7a6b12d2eefff2"
+    "b6b98af2650d7ce99c075b4bd45fd95bb07c79398341a754701b3e3d843b757c4389226fda"
+    "645adf339cb0d7a5a9966be122e103d5ea66ba6b7e17f8537139ba7a96bcf52d04f7349861"
+    "ca52e78fa5b3dbed6fac6cfcc2b254b9f5f9997d4b874e86c54b4ba4b3291b81afa23b6028"
+    "5c63cb8a59a4d52d774371e519df25cdc6099a571c668353721f34c55c2fd9e5aed9dd3526"
+    "1fba8e180f2e179101f894849c3deb5a19636442e405f48fe2bd7d984fb036a5cb933f2ac2"
+    "e350df4235d0d1219b47c0866911864fa88f83a67970cc4b051bf6214c55afcfd8501966c0"
+    "afe34612e2edbcd6e309d8486436e7ff0515fcd9a3541ee7d7a4462e21784d8e6876240afd"
+    "b74f14cf6a1ce0cdf99c7c511e3c92bc546586615e26dd8b02cc53c24d8070122b1fe63cc2"
+    "068a8b53f9f12023057bbd30a809b880bc33cbbff07b598e1190702ad8ff32044f0d3a714e"
+    "d7d86eb0e13bcf68af313453151bdb9a0ed8c550dcb9cbe28dc78a1d267f3ef25180ab3cdd"
+    "11390ce243bb2bde0ed3b1191b0f492a258d2dc73482fbedd891af36cf1f224ad7ac1b8de4"
+    "f36606294f1a228ad7eb390043b71916e9d0409a4ef0ee0f3a50f250e633008062ff6df9db"
+    "4ed7f69b396493ba0dc5a39d6804c4b93c962b3d70d25188e3a5d5e1f5487708e8dc3d7d80"
+    "989e76b69d7405b31bf12a2d043e523804b2d7ff95ad87e84bbd27cf2ac09a8c5d9762ccf3"
+    "dea56a320ec763ff4c25f2c4d4edf89c8b7512baa662548a6848411ac486af95c2987ef5f8"
+    "16ec5ffb476e560d8fd69c8ff9870b549d6da5f262abc1e07293178d5bec9a0520fbdb5a75"
+    "1663efcfb39ac505725e4e64d63841e7431fef657e0b293d8e6b6d4f8b9c81c7022ab701eb"
+    "f671896bcf9d05aa68b3c67bea8f464a000fcea3e231298c198e511654a0af214fea046f5a"
+    "cd6f204ffef81d67d17b7e0c81fd9e9e7eb88990bb39069ba164139bb2be2c816201f59c79"
+    "957cec370f81f7350614b2b6c94bcbf5f275e301db6a5b335df9b21a6898618be21e34d7c6"
+    "8a5474610d680726661ba18b39f432b257eaa2e2fb157dd4d5f1936ea1e6edc2b92088760f"
+    "74121b8335de082c7684a151ae853e3f5156b7577444b6c8e90d772fbf18259e3ea59ad4e8"
+    "177ac10728a506be1621d0064342bbb3c5ec7553dd03efa6466b9dc9740757b5e890444540"
+    "f60e9e6f32b5d770e76e321a950aeb32aafae3857aa3265dc16c1487989a5d84b598bf45d9"
+    "faf181a6130343e87f664ddc1b844302c2311515258c6e1b9a2d09b1eccccee59c2d69d2b5"
+    "1dadfa6e28db845fb8371184e72cc1ed9ad3d8b6db5eafa84895c8ae26fa99bf69787792b6"
+    "052eb6f1178de7d0a691a249aaa2545437fe89533c8c6aaaeff32d49cad1b6d41cf45a3b04"
+    "96fe7d1b177ba3ee3cd0415a3d1b81ce355fe18f9113a8628d9c057daaa0d1ec9f2c838589"
+    "a5b90774e5d55b7bb166806ae3ff2ee4027d8c8cb4d9c00b1b03d63add86212b87c3302cc4"
+    "9c9577c77a4f55b8f2c82189c6d3b63df882b473c2a17253add07ea88be17293429827d0dc"
+    "65071cf01c3ec3bb87df788f95ef3f5472c6e595c7629b1b7d7a27efc79b91ea8b348179af"
+    "e210ddfa00d7673beb345f13f39e455cba990056355f8634576f3f49e5937a90a8dabed519"
+    "dd045e95f471185c8bde7a27fe344b25ac6d97eed9a3ffc033900e025a38b72da43747dd06"
+    "c7f4ea8639b931f2852d8a3f60be3cdd74dea49e9fc303146e26e0af20cc7897e2a0bdacee"
+    "61187eb389d77060260502d276f541b71b98ffc04abf8e199aa53d831ba348e9820c2fbcf4"
+    "b07cc37008fae656db21ce91281ea5b389c75ed7c167c133e0bed82b40ba19e1f98be20b74"
+    "9266d185b8373b451768f8f1179950056086561c47fe3cb2e8b647f0fa5d511e3291cab566"
+    "b1ec0ffbccb7940e40c5b44a28c2fa9b7d100a05d4f59158b5dacc3cad1d6f054cb648ab7d"
+    "26db6126b26d011d1d982a63bc69804381b6ce05192b4996679962027e41c453fecfc41217"
+    "fd9e83c76cf1ff4151d9d32f209dc826c511a35dab3cf7252eb80ad9ce02290edc8de51c25"
+    "0ec5d874866b6389926dcdfd953ffafe8126a6b0582df5d5cf836002e41c04a9d6ee986ca5"
+    "a68fed99a57256d1401cd4b8ab19cc6fff65b328986dd30015e4c9f609510d6b93669aa2cc"
+    "13b9d457aa6c994007bbf00907935621f576c77ae91e8fe5b3f3f3040010e1921cb2087568"
+    "fe8fc74ba65295649bc97456be30b41b8f6576d5e9aa9bfa997ac307912bf074d70efa36df"
+    "5dc309d05625778f1ec83490f8524eb6f82de3f16363321d9e335a705cc4cd6e7f83d1428f"
+    "8b52e4d7998ac1de3a6956de0cde32b7231a5a96051a4de052263f5c14332f7f2cf585adeb"
+    "1ef6d4db6f963621da8e5baa50bc911b09264ba9c05e56976eaf1f749eed3380773797b8d2"
+    "d29d6bf9ea5ed0183e883d9815f0799b984207b893ebf438ef5226db72e1e74a56a83b5be7"
+    "ec28a8efbc18ccefe0f790dd9cbe6fd4e4576ddde67442e4da0a16245e973ee8c3c6b0cbb0"
+    "ccfb445be3eaf40c2e6c748af0496857ba0aebfd7c4abdcb7faf2d511c23ef6e33e63be6bd"
+    "db711b5fbadd579be403d06776fc5f9028bfe6c0adac730b0d728380434e80a2f85b01ff68"
+    "092f5780b701217866abcde23955d4513d76eb738e4e746a32862d5bf4a7e576dc5e0733a4"
+    "ea9ddf0080a5098d7f86af82ff52a14f9b8eeb85d03bf5a4856844b6a49db23403eb36647f"
+    "2123f86fe89f240be30e47207a74e509804d3201eb06c0a33746f4efd275a358a709777b8a"
+    "d85cde65a481cf7d52d3a48137d0e3f464e5b7083bb4d56639d0e5ca5ef91265e32e1d76c2"
+    "c318505f735762d33f8da0a5a0b2ff9a0538654fd7dae9d4795f0ce2cef620933972a90637"
+    "219764fa6dc342e69059dfc73dc29a7da6cc5f0466272cb4f42d46013be2dfe8bdac4d795a"
+    "89368f473eb7335a2101f64a5a07a5cf8fd7f66245b68a7e49c57d1a1e146aaa7f33859dfd"
+    "d1762846044e5f38e246716d51321c1040540259b41d9daad868cae75580c50e3810d20228"
+    "e7cedd1097b8f91104c20d057b821ee97fc9aacd7cc225fb62e86490d3a0ce7ea1554769f2"
+    "508673b27f7195a1b5cb4d2396cb008043c54edbf03c7033fe46f2e04ab4c9d9a33cd4941a"
+    "826169216b96af7ffe43b1b00433ce8e5d0892d518eef9b1315486661abddb7224bbc7e020"
+    "0d73aa1c677a66ed5e4e9e9c24083e9d6f1729c2544679cbcca14f99709d2cd4f92d79ec53"
+    "043f2194b21378971d4109df46c34cd662edd8f783ce05bfe634b3e6ebb2b6ea4fd93b3ed4"
+    "9011b00fda3661f7447185e3cbfe18a74eb6fc0d27cf52dd5b40106d458542b3fdb16debf4"
+    "b746549226b22b1d657c7d0ace25cd4ceee9cd91f868e7abcedfe12942c069e287f64679ab"
+    "9ae9018a2c1d39a1a67f6c9fa74fb52aba56f25b49528490a97f320cdc4f723d92d5d641f2"
+    "0d9d9809661707ef09e6fae3d855dd6d944fb9f596008426cde5b74176f94504adb0b99811"
+    "cfd49f7317d712656db9034bc03ceeb18bb5d84fb03c6c9843b2e0de64db7f0d170818a7d4"
+    "009226270e52f2148b827b3874054d014072b2d6fea3bf8d3391a212b87f729b14fb5cb2b2"
+    "af51c5a1198c68836d802c77df67eee5c03a1ef3ae76d1f362377a9497603439408ffd2ff8"
+    "bb14ba82fe9127ee636856bef4f15dd93a508cba2fa17b3edd83550f4f4b726dc5bd1d3c6a"
+    "c3116b13a32464b833463468a1290c2e80b2ddc8fc0259d71e16444a7949aa35ad482fc068"
+    "d5014dfee33075c27e9a8061dc76b142aae617ac05bed9ee847e26f41014336ed24e480e08"
+    "3544df22e5dca68e081d1ff2b3732208858d9f782fedabff8d3bc83242733169d3222403a3"
+    "72d9335146a6af07d7f75aff8b1d73f4a8423a517b5d0b4c390a780e10722965b9f74d5721"
+    "17d2986b54ddc54a6b58b7e7189c4d1293446d5325912a19672d68b7237db891cf59d0b6b8"
+    "9092161991eca1563df8b2e0f1881f4900d7a41d34ba55d55bc170e9069dcb73f61a6cacad"
+    "e21b4f20a7c25eb7d0fac2033f9a372805c755f99f6b838e556a45018d7a2bcd3d60dd583d"
+    "46f35d2553beac5928f5bf4f695c0b4d328854791c0b99bfbb9f9dba732eef4275e1f6a553"
+    "182ac6471650967ff83367ecdcb61f6bf67a77e617526c67dad885413738b00f3242948c5e"
+    "3a70ec4ef77db5867a0ca673eff3602b2f242f97e98ee946ef8f8b7684991b5c14a9d31011"
+    "b9aa4d3915d84ddd798c304776f4cb50f375f46459e4d637bf3b30258ea21a7e0fb6689ad2"
+    "5f814ddae78fdd88cc59824723b063175b9ead2f2612da72e7c458049e4b68ee04a409d5b2"
+    "6e7696a4f700a1c64fdb3164cec26fa673fbbf60f72c2bc717690bdfc575d595648468c5ad"
+    "848c627130d6ebb468159536ce59f9b6d62c772e9fa23ae4413c26e8d2f0a50c95f736c246"
+    "80cc0d8fe94b8674702a92929f464504aa2404f66e76331c0b08d2e31ee04ac9e99b695a0d"
+    "8799e52fac2e21c1928cfef8c08acc7c5959a9d42c7e038177f5d7f0f64ccd5b890498ff51"
+    "549be791874928b7f43d2982db3ad1bab48ecb757b51e12a9c6626871ff177abe783a94296"
+    "e5e37baecf5a376a5212556475262172c6afcddb3d8ca8041f7fe80868c846230ec31ab5db"
+    "78f2a92b39fca377fd0000631c95c512b090e87b2291ed912593259aae0198f2895f8ae769"
+    "04c103a79aaf777d96e7c999a6a2ee92dd17f3c06021545b5801c6c0a2e5788e285cca6380"
+    "5bdbf51a4c81a290cf1796c36c9e2f5944b227c6521f681d376670488931b89f24f79357a4"
+    "7bf4af9e2303659a5c623edbe472b7a4d1ad85ee60c3adfdd1a30f7f14c455d43510a15f21"
+    "20c0fe148707cf3e777ad2102c3381013d482e2dd2b68ced555ef58955f6293ac891ea6cc1"
+    "6607b6b51c16e54671960a3c1c00b1285696bd85c458a663dd9d638814ee65e71b77fa783f"
+    "78e175e2a880ee3093aba5bfc3ff0e5b6e1b6ab7ea4f184ecf11c6621e2187f0ba112d6036"
+    "4d95e2acebc75b9255d1e681476b55d5cb9d682519212dd03521c5d00b84b97a934877b574"
+    "ff4a180d777bc446e7584cbf5f0e8ba20f04a899f0c684dedbd7c87cb33642d1828e3bbaeb"
+    "8b4c077fca8fd08e460740daa26b2a924181db0e2103f08c3862e1fd23795eb530ca6589dc"
+    "90a1f2fb893743a495a4140bff2e7b49330e5ef5584ca5b395679f479ee3802632add5b660"
+    "3e14729ed8d13666ba6ecff0f10dcf30cb820143c8e3e07c96031bc42c81c9b63842e9fdb4"
+    "c248e246c758abb4e07ecd5c89b4376e371ee862a1a8f66ee5a2a464d9366bf1b381558079"
+    "59b8705e1890a9fa46c1cc54f7310a240c88b2c36f5b9db8e710b38510d1645ee8a4a4e0e8"
+    "b14c05892371a200dad579e14af518de70f0120fdafa14f5cd62f74467c4544660b094da9e"
+    "9e00a0cb1d7a7c382d30e75cc8c5517f5e02a68e67398e505a88998593152af5a96e09e718"
+    "b6e719b4631a4cb2f8d1f64a3c673ef01e640628383004da91f1045cf47c7e0d34b437d571"
+    "a68f40e2f6b4af1a00a2c83592b11c9a736ec23ff83479d9503a562571f3dfd9f2398bbedf"
+    "825af5bcf88bda170d915b11dbb2a3749ce6908cffc0ce7819b4f6ef60f6fb5b0210a29863"
+    "998aab74607a6fd818e4cf3a0143b61570186a98864ab65c288268817201431ab2637ccfe2"
+    "a977a725cb5fffebe5b481f531f0a6857c763c226f7fba39ec939580dd28965801d68eb8c3"
+    "1605341e85d22e68bd661652b0c8a3e64a0f469a7a16debb45dbd0edf47ff7d761f99255e7"
+    "ed9e3fdea5328e26bf5fcfa789b1c7f2cd3c9234c99c030b1db4071779bd2ebd7ad8d20023"
+    "00d94cde83293dc1fa698821f7c8792397835a599fe7d359e88906df7440a3edb4b9d6b285"
+    "7b0e6fdd0f1485862e2ff3244d7821719e72899eb5f5a0bcc413f634ebf4e5ea7798e09536"
+    "be917c6d6b97646873cd30bed56972fc3abdc042463a6a606be95b9d96b4484a53ef5d5b9a"
+    "11a52fa31e268df46551789f5b7f09dc2fa09e4a958fbb76c4503a48a8e0faa4ec422aa3e3"
+    "6776327726786e18bcc17a2ff0b58979b41e7f8da369a21927bba63dab179ce341073034e3"
+    "c50ae3bf27b25dc791479904d3dbb5c3a42f00da0b0f16a89578fad646c9f8c8f93776ecdf"
+    "eb71acb61a9a7cd3be74c0a3492c529ad76c9003fa781e57f8513d92cc5b2ed1cf69880e3e"
+    "45bd298e94aa174191f294cadcddd954c431d0dd7f045032005873d943ab7172a4bf64f382"
+    "c789f6a8ac0e5a3caebbf8fbf26cbbcd9d58970ca1b22157e7929c8517bf633d28946cec27"
+    "6aebdb0a638720a1e1cb382826e4cfaa5cce5a68572904567d0a1ac7cc6be9211126de62ff"
+    "49a2164b5e7a74d49ac1c385fd8d6f7880c4fcd5e173c5d215be1a3785d8025edb7a31c0f0"
+    "9b528918a48a083133e181df412777ecc9fef1693c7c19cb79d6943b4d58617cdc6e9cf83b"
+    "7562bf4b93a8b8fd865bacc383d552450fd1571e2eca6557a27270fe21975cedcccdab20a4"
+    "ff6a754b9a0502194aafbbbd738afd2fc3ed3ff5c6190ac6ffdffd494fe5f25e7cb4ff44a0"
+    "445bcaad32d9cfc2b58de9d1d53bcc6007617f0fc713eb5b5acbd6858c999b96dfb1b46da1"
+    "6a0fe11accde3b4e011614980cca78325599de8f93a6f8e4af4126993b1f940fac19f649fe"
+    "721474cac4d32227e92a2adab1b9ff9d1e5935f806d8721d09be737ac1b024eb67750c154e"
+    "61e6bdf8cabc98755fa16d3640e80b94e4e23deb3a36a2172da28dc9eeea3675be759de36b"
+    "ee0e951fd77d7aa68ae4caee0fc80175045595957fd00ea3ec4536e666a691efba0380d05c"
+    "0c88154b4ab67f34ea6c201b600da60ff8b46ceb971a663bcdf2ba0eef26095f3783b42c60"
+    "10dd3959df46c4d631e7a89e62f5391d6857b79f9e4502cb3862586a80a7f33576820f9985"
+    "eccea22b4534a5e121db3ed2e21a2d7a9dd80a624479bbb061b91c38ae5714ecc996e4b1ee"
+    "ea6498f1b5b7aa11d0475b591b8769dc10bcb405ca2a6c5de880c7c533272dd6e3bc9b13b9"
+    "e8705b549bb50e72da1e943a0c98d313e43eb847f4e8b79a549b5cc8992a59677a473f694a"
+    "3e94f4048e0fd7164772aae1056149dc9f747be8f59f365702f24222fe0f6f320de6345a3a"
+    "00677bcdcf1a99592c45076b049616db7b447c4fe3a7937febeb392c4baed841c4e96c7cb2"
+    "a63ea3322adbc2e88078b6d0f10c7b373cca2fe3ab24cf2bfb4c0bf253222ab49011cad073"
+    "23bfb8b554b513025e4f04a61fa2218b7f2e341fdf86633cf90fcef924f8175e30f3290cc7"
+    "bab09b7cf8bc574f7dcdac67d5c59436f6762ef35d4b1327fefaac7d575314acec5af01cd7"
+    "477e13de5ba16c9798a8868767fbb2633eb152cfd1c946b500090a43abbc4c322f5639f0a1"
+    "5e8d99573860a14960e36ea8cebd1eae0a15da0494a29f80cd4912b18dd6305a093409c7ac"
+    "796a3e6a8b5e15ac469cbd8e6f60d0549e4a31713bc639dc3754d857d2a97790b7487efbf2"
+    "99ad8259a31c45e64e0cbb464b1fe0b74c4a24fd1317363103252144820b45bc0702a756fa"
+    "6e89ab4166385106051713cb6ba5cc5b4dc92819cef9c33d27b9550eda8300e3583af8b10e"
+    "7f18501c59ec2f4563792e8cce5a68b261a9b961de92edee5e5a78c4e7bad2a2484e5bb46c"
+    "ef8b1ff7c0d111e012e5d295065398f99d85a9511f3dcff5fb2a7549b0934a3af06294e43c"
+    "d8d4d6c65fcce4dd86a673bdb9f3be3fe177215187d3514f10a387b7aa22d1368d0735b200"
+    "8ac19612fe39cd0ebaee1adba3c94cbebdb21855f0fc5d9484ef26bf7c85b7c92fd1b67531"
+    "3ec37086b7bd647c0cff49f39ec2f64838e0605fc5d423b0934a6a3ba1a5de2b32d8234269"
+    "f282f2abbdb546d1186d9986cccca90a4cc781a634d797d8c89efa7af57d8584ba8d6f9a32"
+    "f7d158a940b9c7bf74e232173a573cf42a38cc3ef85b5b838846aa8de09484df405c21fb1f"
+    "492a5e30376925e49cbac45feabe81d7c5451ed3d97a458866aaeb241cc3f1257903aa854d"
+    "ec01bbefaf65338bddb7af026b3afc91b38e09775676075d343935e6f04a3a7e11f4e1fc3a"
+    "1dcd064aad3adb7ed5ce42c0905d0be146601683b2a8ac6670fb05f4ae73c18460d3f17506"
+    "4de1ed3d61cc1378edb7b0d20b7ff8d14c228c9c597b8df4cb96c37e38561bfcebcade33a8"
+    "5c1ed148b69e5362427f86b020468fc72432d2f50e5bcd73c5bea6b4f44c2a09aa7bd2c2f9"
+    "adc85be963e0770cf2f5aa38e7f5de6bfc4fcc8498b09c815abb3d90aba39b849d1dc5e2b0"
+    "906481b888ec4b50d7169caf274f22848e35a405273aa58bd4de8b92db57914bd4d88644fa"
+    "e5a2673ba8b7ce95d0d798d88ab08a5dc53b78c0be8d8f4f8804195cb2b816258ec66bde39"
+    "e22a66ad5e14931ce4de9deb8aab0237cbec2abcca45a2feed085541982eaf663316c9710f"
+    "66ced3b0f8ba1bf69106967d013323b2656de0b93ca15f4895c8ff15a339315e25ba5fb252"
+    "14a503bb688fda76a5551ef529235c5ffa09611aa59598a47b4c8ce22aa49df7217950a74b"
+    "03a0e8a0ebd9424eb170d5277b573b223289cc520b467c834b4c53f1d4e5b574380ded24bb"
+    "59cd70ed0f905f15c798952d29f9ce3c8b4a04678a58842b6b3bfb7669e5a0f2a153e02001"
+    "a7b012548050699dda11fc95f026466062bde597fd61be5c32ebaa19075636f212ceb0ff46"
+    "122e4ab88be9439d4ec653f7599dcb0caa86f26469da9f9d537793f1b890d682a84464b4f2"
+    "6a5481bc12802684c1d73dba5f7acfc4451a213645c39e0b3c7c6681623ecf255bc6c75d59"
+    "4726ce1a7318bb3ddb80cddb77806cdde22b90fb1a998d931d596bc833dcd0764993ce42bf"
+    "b40befaa469aae29b2758d584fa4804551046fe36452cce20e26e9454c9bb20e7dd9b5f63e"
+    "e35bbf7c43f772f38cb3baa2bea11e9881a8c94cd5385b75611abe8dcd17b33a5dd1c9b928"
+    "41cc08cd032c91408b475a0ae8866d4b7eb005d5f2bb227f2298444db54e8af8ff5b6e08af"
+    "5e609429ecba4c4ab5faa9669378be9308c900d0f04e2c65f0327c3e41c574dae5f96dfd66"
+    "41b96cb8923ff9ed42060e2d089ebf0dceec2d386da7f98c2726a142e0527f47be4559e0c9"
+    "f555bc6d87737f93cc82b6dbf2ab73921c57c28c0340273e8daf79a9a1db2ca7c88fa4531b"
+    "4e4b89c27f5cc4f59255d5a92656c984e2041a2eaac1cbff11e1720fa3425f9c97ce2789c0"
+    "0c6eee26e07639f47a3f0798708b4f5e3feda3b35e45504f42ddb10ab545175d82060c5eba"
+    "b9ff97fe51e33860f3edfea8c38ec927ec15398f811a0995ba948a790278c0bd2c6a398fb8"
+    "43a2646a11e0600560f729e412859cd21e1325ed505f2d06b1f77f69306e689d1b0b91b7df"
+    "1b7d97d96609bbfec187bb7a93288b37cc96fb22ec72b0493f0a60f1e00858d056970e535c"
+    "e4803c135e97c999df22c34d2524913c7a70313bf3601b07e3fcf5a257b46a87f48d58e73f"
+    "ce9447a8d10353a55e8ddbd99178e8c93e3681b16543cbf12dae84c93083111b0dc89a4f19"
+    "dba14e0b5ecb7b9793336a1768da49f72befd65bf67e13255c703bb4b7f6c9c8304d0de149"
+    "01fac221603a39941f57d9201c506e8440dad927d1e9a1f0e28d986949bdc4dc700c1998f7"
+    "1641f7d7a335f4295abedafdbb71e1ac829402443b4953386c9302d141bb6cd9d218c66d26"
+    "6c460aca44a0c49f3fcd3347fb7bd0ff8858f2bd37efa64c73ca85b4830f0181079619aaeb"
+    "675bea0e15aa2afaa62d25a5a1b3d45573705986c1a8a67ca5be85b062e77685f69313d87b"
+    "a16bfa2cc2810fc3882313f640a1f1eb0ee759b8f52f89a2a9d5853bd24e7d09c150e4b294"
+    "d65ec1d246aceb217d5a0cba04673d3c70bb2630d914e513f4f6cf30ef82e6b8f43aa4e168"
+    "6c259c76f593a3dab623ca0440d90fd99e84ea49ff376f2e300f8628ea27a9dd57b4e44219"
+    "67d7d55945be9e75c06f2be4c96fbf1b2f379cfed2c7e28cc66b205fb87f3ecc6f81081253"
+    "65ba7443907fa9129be3abf3147b9be54f7c8dea7df51330078877a0974843eb6f0667969f"
+    "73b5a64b406459f6ba6b266ec8a0032be573ff5ae53637d9d343d41af68346d974681f4cb8"
+    "922b3cd1ebbf695ed46dab551a245675f82a8f53e178684ea4da62fd817d0a9fbadfc12df5"
+    "9d18f6373fb111f0d3f9712b98ff16611f8eabc59997d0f975b67c47daaedf03521eea6beb"
+    "3dd569be0e9d14af9a6eda4650fe712789a6d59b8388997e9e0a8f1b215b5bb327ac5b4984"
+    "e1513baf6053ad05bd4eec0162ba25b5a3f37a2219230b9f940f7337a047dc2b6f71267fcc"
+    "64e2fec49cba93405125b185987f3f96276067a51b71b0668aab901ed1957c9c752c628825"
+    "04c2c2a8f81551161a1b015e36db1fdcf9520c2c5fe02c8bde49e1e422dcc7d04ba746e3f3"
+    "442a2b9a2443579058eb91bf39575f7f03fdf8d8cfdbfa22095834356ca28eddd87e174ceb"
+    "958d21d3f6af03175334f2ac43c7385701e08da369bd8d73899874a06759fdd4d747250d65"
+    "9f1a4fdf9f82ae6615cb5bc093266b5f3629d066a9094923249199fb816dc6d4f9bcf84384"
+    "569fb6ce070ae60811af0e8d88ec983b9b00d492b3a28ac0c64aff11bb9054406b7eb464ab"
+    "9f29e0947329de4811aba7546aca0f35f24d93f701ce9b58fe6c0379ed182149913a599adb"
+    "ef2f7c57a40a7654503a520e07b29a8a9e398b34ac99b4d29a5c4aa2a61abe583489c304c2"
+    "a3b708d3beea806720a179a7fd20de94c24e87fe3dd3856ce5381cb4d1ccd33d1b5323bd48"
+    "f364f8c995a3f8ab098118f66f5f111c4efa9739b69be6f8a09ea4a88c6d24d5d9ab3bb595"
+    "0ecb7fc5f3f9c3c1aac7c89c95ca75931c64651f081181f182d3235dd726329f9ec43c8c2a"
+    "fa9d8ec5058b22ef627105d6dcad48158ec6e8ad202a6c2f034d37c022342fcaec10fc9800"
+    "51c3c3d5d014e58a2be79061a78811860bf2137ee1a1510d4e72f7029252ec8e1f691ddcb0"
+    "8cfa7ab971d1f7b6e20d7c012177eb0f3f6e4a1cab589ee85e09f4c27579f3ff52c09a416b"
+    "5c585b7e6a1b7424779734820eb93e66be93044d09ee8ca34126b47358244b5bc25299b69c"
+    "5d39ed2826de5cfb285981e2ea043cbfbc603ebf6c6a885f68edcff2f0cf4addf628ad5992"
+    "84a798f3ad659f36fae28cb16fcd439ffa5a69c516dff3dad3760f663fb7ba084bc3dc66d4"
+    "6b31f3120c57bf46f7a20c6b225e867977245b3acf75e2136c39fe744999b76dbf44152043"
+    "b7af96a3a0ed4463f6b1b61d5f07a1e0c395c0051656959767e654eb163f53b80026dd5b49"
+    "b90cdbf2ab50306a23287665afc61d7e4bf0d6d5ff4c6416c07d1ca8d6390c1a69084d408e"
+    "1cb35a3afa0bca0c9fe58344d7e992c23b05c22c6cf57349b90f523e7227becdb320f39255"
+    "c3ffbf8e43b20fbd1e898cd181c6abcef5456807bf2914766bc70fb406228ae3c7c23a64ae"
+    "42b3293e17bb4dd622052f433a65fa781c221187aedcfefa816cb040ba11647c785f64ba3a"
+    "1e2eadd17bc6f8eb7e2ba480da06b6606e6f4ede7f9fdaf26fe89cc7cdb0ec08f1c53ea273"
+    "6a83a53824d1f9d05022aba64e65a59f19e6713d60e7c64f5270befed0570ac245490c77ea"
+    "af2baa4165a8cd1b268458b634df1f38c20e79b20d1fa6453e9ceb74c447c53705fab82e7f"
+    "a23251e425215c1fd55818ddcf4449f58ec238ffb1a3cb24b53caaa8430f8b01a1cfd515d9"
+    "91c6547c165b34d3608bc117207480396338645097f84499296425333bb68bf39349c59d04"
+    "dca85341a816fabed09c2d42c601c1966ad4e2baf3eea257f75524e96798b9af773169cf95"
+    "0186968f5aec8fd5906e55c9486a70f44f5435b112a47a33b782f01b5a0dd26ebb6ebb95fa"
+    "0a83d02b444416e2a340f5bade3c76a9217f993d508d48d013737da2c6ed9af245a0877ea1"
+    "b50719b77d26eb1085cd2a418f7c04b9fc413629923aea6b7ecc795958b0ecfec3b820d5b5"
+    "ea6bd1f7cb1b555c2820165f01aa85c49343f7b7005b28a28bcad9bc77999207559b60295a"
+    "e2ed8b11702e14b98c0026712400ec219ff867dd78aa2637927c9921238165292ab08409be"
+    "a2bc683b00e771510fa0db6c956603313a985e2dd1f13d0aaa1f7331aac6b8a5d5b195e8a9"
+    "3f5d5a07e4ce064258e2049f6c4eb1efcd3a7d890d881dfb080e990927d93bea148b5e7645"
+    "7c1bdf2a73d364cc30b81345edf3dcb375c5cc5bcf34536ad0481f3669ed32cb1e9c0895a5"
+    "0d2542bdb135878a8fa4fec38d46f0e3c8f9b14738ff36865d29c94b31faf6119b479b8e2f"
+    "dc9e1c838b82605809c66b08576b97b7b5d90d4865c77201c678cdcf770a7db91f2070c17c"
+    "67d4327e4d7ced8e2a73285993b1a19fe3eab29154035e4cac04d0cfada92aa5963e785f8c"
+    "a20d77e9f7e65169db4d9196abfc76c70f520b41017313d7ff8c43d129134a0f265ff6f10f"
+    "ad88054ddf128680ac133315bdd91b00d92d026a0d692f80069bb45aede03f09622237bae8"
+    "ef09462a0bfc4bbdda430833702a8481d6eb028f111b7305d33f30c8558a7d270a3aa5610c"
+    "aa8bcb39867efce7a44b0595c556c0befe0899908b82af48c07106e30c667ecd75df0df03f"
+    "9a606f680afff7c1b12625177d3f829adc2e304a5b1bb6c8788b712ebb6759629857d243d9"
+    "57b8aa44369fe3eda0474827c60ba9a042879c9e5896b71b35aa19f8d6e5ef5e0f713ed302"
+    "b8f50bc1d9083b7fd28765c8206e774ff62a522949c56dbe738b99d9e9b2eee7fce9029a92"
+    "b7c21f31cb36fdb974d237c7641060105e77a6a6a0e61d3a60aa4f792622e897e89bf6809c"
+    "d9f72674ee4aab58e636200e0de7d08efabbcbba05e408b16d9b472f8b993e0d3b5b74c105"
+    "e171ed02150e3a9c4a95a8b5cee3d35788a45bf328e2018501b86e973300221be59787fb68"
+    "1064a6f2bbaa44aa4be578bb8fa3c24e0dfcd16f8da1bcf72b9ee98c86ab8fea3913f5f3fa"
+    "c6840cf705fc1e1b945047e7301efa976135fc0bdbdc2188d9911cbb2ca2cc99f0d62b1888"
+    "cfbdff94ebd6b1583ebc07ad468ff5ca600e28438cc89e5a7ba3fa97742e51c45eddee2c21"
+    "46c29f0fd3f8ef8e2e3be6ca727e1d35ccfc5539f372103ea30803779089fb811aaf517213"
+    "ea35fb33c0d4a2464f37f286be1804030d59bf53be9bbc11fbdfa9b2fee8deb60f6ac7d6b4"
+    "070f4d666235ee4dc314b85869f339333a1b3cff2eaec781ea6a07a2440bb035b75a00ee0a"
+    "7d42672f160604a2e372c3ced65d4a556412837c8038f6a93e4eecfbcb4408a42159e76625"
+    "3b2e0f443edfb3e6f098021eb7b030f6d0d4b20243222604ea84d81e03a0f7e63a447f9bd1"
+    "a3f26485bf69912e16dcfb0222c8c5d74e7166e1f899101c74abcf4fc0558b4ae26a2c0e08"
+    "e2dc20c91d2c9fbe835d44ff15a26c6b976fcece277e4ff9fe80c0a28d5bf40bc40af5f782"
+    "13476c0b6873fe734a066fda3eb350302d7206168dd61ee4de813c8ac65a3a48cb40ccc821"
+    "c8efa14ce9320e6f0de35b5e68735bab8d03ef1185799151bb5f8a3f4d956752aec525cc73"
+    "d187665a0027189cd895f01422e59abed3bba5b655828d4aff00d77c846ea690c18a5a3f2b"
+    "86fd9da63f095da01f3778107b640a2813197a3f7023d652b2865ea8e2f93398fafa2f9af9"
+    "0ee81a8d6eba0d6671951ae831f85bb510605caf3ef2550ed0ded1fb90061857dd26eded72"
+    "5fe4399711fb2d0178a386046db054259a44896fcb795961e283fcda0d13be9b390fdc71a3"
+    "e3aadbac44dc71b9086e4b204cae1b0fa06268bd73b746807fd4c0ece38fdf877c490cdc7f"
+    "b622c8ec94b374a3b739c013476ba680edf46739c981ab095c175acc045c445ae15b208637"
+    "b13b841eae64b9b571630dc82119547ceefbab3288fa224d73b572ab1ac600258dbb7711c3"
+    "2801723744a2f80902b46286d52665d368892de15e283f30a5e3fe1d36284ad42afeb58a7f"
+    "a9850d6afd277ce4709c716160521dfabc755803932fdac96c096606be2690af795f418ba1"
+    "a3fd1e5758f570d702be4855c76c8ffeb3cf31056b47ca5d7aa498fd83302e490c61b32c8d"
+    "3586f43ea5772ad98b724cc51e2337d4674f086f915556b69ecfb837e4586c84b147cfbea8"
+    "a6427fd5cef19750866fb59dbc669de92972052b651c8d4c2f7cad2db4e2690b23db7830c1"
+    "c20658fce756d74db87eb7b93020dfbc49b86fb1ca81291f337d4642a0b330665aa8f4087f"
+    "ee34d22b190639bd02cf126ad96a34f21957e92549e0d96f54d0b1aeb904c33ea8e6733f0f"
+    "42abc821451471293415c18d4e01c044a3b96f85850c73a26aa01a382e424350f85eb5007c"
+    "d23878fd90f21c0413eeca6337a0a1b7bebf8042fbb10c6b6f6469dcd61ac494bd3efb2d5f"
+    "fbfd5e5398920d5a13e84da91a1636ae862c95b2a4d99e8e62eb43a7ce89a543db8c942926"
+    "e48b08d33b89afb9582bf56e50c5cd9d64e9e733e9a47404217b51d8854872800edcfd5426"
+    "39385e1f66242e01f97fd3a97e201eb95d16305956e57a8f9adede23791b8ee2fa3b81db49"
+    "f56cd02fa900439c2bb8b9fa7c65ee662d415164f5930a7c65769156080b3cce889e103330"
+    "a9a7934962d5ef10e8577438524c484aeccf8f556975a2006cc4e7d7143165f2f771d77a64"
+    "06d2251b8dd659c8a42aebac5d8e5513bd0527f9b6f709714bd82cceda33a18a572d7b1f28"
+    "e998a96d4fb596f021f68215356439f40ad42282bf784b954bc4900860bc07f4452ccae599"
+    "5a27afc8535b5854c5305ff02af7b876879512071f6d7aa7eb5ed7d37c0e657c00962f3441"
+    "2b23a694e75a52a60fc7a861deec2f27ce4f323dce313b98dcd9c4d419985ad696c5f58361"
+    "392563e2b0a0f72ca286e9a5a044a32685a01e4ade75983f3e53f74f4e1022b82479269ef5"
+    "279ec1765955642c27aa83847e0b9c029b63da839835575820699af9a038b587a468e556d4"
+    "26601282fbe9be24e1b33d0e1bcab5c5398f3ac6b67889f4c99b40cfa906fc2cf002868c2f"
+    "3d6f3bc73b683bf210ee4a5f5281c416898ae4cd14ced66f51e1c48a08420d275c90c3d3c7"
+    "7ca4eb22fdc5df97ff81eb1adf987118b7fc6b501b8a2c7a9be1933ab3b6f651ae93141ff9"
+    "7de2fe9ad3fc3852df6c89b2959a0fbfca0b63a7cec988e7eddc256962d58c2916f17b4981"
+    "0fe5543a37b5d74b52fa3bbb5385b7a08ad38b99b80b4744d48aaab4075c7672a45736e3d3"
+    "8c58f827472ba8550dff056e919f439796ba9c905a5a1df24e93d40958e215c59edba0886f"
+    "5c9f8c8b05dba2f2c9d4e568555ea29018cef66b10ebbbf76cfbf6d72c1795402a70bed95a"
+    "c819b0f05431b2203355e77827c72fb5b0270b1817df07cd9c99a4df89f8cbec7a87ab59e6"
+    "3cfc554d19d1f38a29206d3e5e590de1e6e329c2585d215945e9397d6762d60e23992a450b"
+    "e389e03eccdc0901808be8ebc45051b32956a1189649f25c37a09287762f5f4a5c69c54867"
+    "d63159662c6d83cfdaa0a9ffd19b356ef4aaeae58d6c481b84ede83decbbc44717f6e0be29"
+  );
+  BOOST_CHECK_EQUAL(x, z);
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/prerequisite.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/prerequisite.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,58 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/cstdint.hpp>
+#include <boost/mp_math/integer.hpp>
+#include <boost/mpl/unique.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+static const bool use_debug_mode = true;
+
+typedef boost::mpl::vector<
+  boost::mp_math::integer<
+    boost::mp_math::unbounded<
+      false,
+      std::allocator<void>,
+      boost::mp_math::unbounded_traits<
+        boost::uint8_t, boost::uint16_t, std::size_t, use_debug_mode>
+    >
+  >,
+  boost::mp_math::integer<
+    boost::mp_math::unbounded<
+      false,
+      std::allocator<void>,
+      boost::mp_math::unbounded_traits<
+        boost::uint16_t, boost::uint32_t, std::size_t, use_debug_mode>
+    >
+  >,
+#ifndef BOOST_NO_INT64_T
+  boost::mp_math::integer<
+    boost::mp_math::unbounded<
+      false,
+      std::allocator<void>,
+      boost::mp_math::unbounded_traits<
+        boost::uint32_t, boost::uint64_t, std::size_t, use_debug_mode>
+    >
+  >,
+#endif
+  boost::mp_math::integer<boost::mp_math::unbounded<false> >,
+  boost::mp_math::unbounded<false>,
+  boost::mp_math::unbounded_uint<>
+> UIntTypes2;
+
+
+struct UIntTypes
+:
+  boost::mpl::if_c<
+    use_debug_mode,
+      UIntTypes2,
+      boost::mpl::unique<
+        UIntTypes2,
+        boost::is_same<boost::mpl::_1, boost::mpl::_2>
+    >
+  >::type
+{};
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/root.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/root.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,50 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt1, uint_type, UIntTypes)
+{
+  const uint_type x("279841");
+  const uint_type y = sqrt(x);
+  BOOST_CHECK_EQUAL(y, "529");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqrt2, uint_type, UIntTypes)
+{
+  const uint_type x("78310985281");
+  const uint_type y = sqrt(x);
+  BOOST_CHECK_EQUAL(y, "279841");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root1, uint_type, UIntTypes)
+{
+  const uint_type x("130321");
+  const uint_type y = nth_root(4, x);
+  BOOST_CHECK_EQUAL(y, "19");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root2, uint_type, UIntTypes)
+{
+  const uint_type x("85766121");
+  const uint_type y = nth_root(3, x);
+  BOOST_CHECK_EQUAL(y, "441");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(nth_root3, uint_type, UIntTypes)
+{
+  const uint_type x(
+    "0x2b93d251afa09c5481f4522279f7c19ca08124199621dfd18342a16c7303b31ccea8176b"
+    "d4a7a9bf991e30d8bde1e08356a728b9f5729c35d29884050101341228c5df3f98354d42b7"
+    "a0d7fdfbe8d5270b09ee89ba1eeab61be67eb4471d92fdffa88d1ca494ed3eec58a34ff958"
+    "b518a588584a2505c9c2b19ce1eb21cba36c7a5297cb6e532884e89451f4406b993582f3cd"
+    "b75cab98f8c4c6f3837977db2a594dfa16943062187ca95babc9da78bdd73ca7233eefc047"
+    "8d882e0d4f09a5083a31b801964343d47b6ce9e937df8c44a9a02bac5101da1823373e663c"
+    "1329ece1eb89fc178355660fe1c92c7d8ff11524702fad6e2255447946442356b00810101");
+  const uint_type y = nth_root(uint_type("257"), x);
+  BOOST_CHECK_EQUAL(y, "257");
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/serialization.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/serialization.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,36 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <sstream>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+#include <boost/mp_math/integer_serialization.hpp>
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_serialization1, uint_type, UIntTypes)
+{
+  uint_type x("0x123456789abcdef25700000000003a");
+  uint_type y;
+
+  std::stringstream s;
+
+  // Wrap this in a block so that the text_oarchive dtor writes a terminating
+  // null character to the stream before opening an input archive on it.
+  // See the note on the stream_error exception in the Boost.Serialization
+  // documentation.
+  {
+    boost::archive::text_oarchive oa(s);
+    oa << x;
+  }
+
+  {
+    boost::archive::text_iarchive ia(s);
+    ia >> y;
+  }
+
+  BOOST_CHECK_EQUAL(x, y);
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/shift.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/shift.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,49 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift1, uint_type, UIntTypes)
+{
+  uint_type x("246556567891512374789511237456594795648912323213860000007849");
+  x <<= 2;
+  const uint_type y(
+      "986226271566049499158044949826379182595649292855440000031396");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(left_shift2, uint_type, UIntTypes)
+{
+  uint_type x("246556567891512374789511237456594795648912323213860000007849");
+  x <<= 99;
+  const uint_type y(
+      "156273790638943927367154966864556037925514287264587565911690950563681284"
+      "261029491729498112");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift1, uint_type, UIntTypes)
+{
+  uint_type x("246556567891512374789511237456594795648912323213860000007849");
+  x >>= 17;
+  uint_type y(
+      "1881077330715273855510797404911764493171022973738555908");
+  BOOST_CHECK_EQUAL(x, y);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift2, uint_type, UIntTypes)
+{
+  uint_type x("0");
+  x >>= 17;
+  BOOST_CHECK_EQUAL(x, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(right_shift3, uint_type, UIntTypes)
+{
+  uint_type x("14222200");
+  x >>= 8;
+  BOOST_CHECK_EQUAL(x, "55555");
+}
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/sqr.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/sqr.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,202 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr1, uint_type, UIntTypes)
+{
+  const uint_type x("123456789");
+  const uint_type y = x * x;
+  BOOST_CHECK_EQUAL(y, "15241578750190521");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr2, uint_type, UIntTypes)
+{
+  const uint_type x("25");
+  const uint_type y = x * x;
+  BOOST_CHECK_EQUAL(y, "625");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr3, uint_type, UIntTypes)
+{
+  const uint_type x("300");
+  const uint_type y = x * x;
+  const uint_type z("90000");
+  BOOST_CHECK_EQUAL(y, z);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr4, uint_type, UIntTypes)
+{
+  const uint_type x("2228218");
+  const uint_type y = x * x;
+  BOOST_CHECK_EQUAL(y, "4964955455524");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr5, uint_type, UIntTypes)
+{
+  const uint_type x("999998000001");
+  const uint_type y = x * x;
+  const uint_type z("999996000005999996000001");
+  BOOST_CHECK_EQUAL(y, z);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sqr6, uint_type, UIntTypes)
+{
+  // this tests toom squaring and karatsuba squaring for 8, 16 and 32 bit
+  // digit_type
+  const uint_type x(
+    "0x5004a2519b00503006126bb044af8930502951243994250616123426085258764a856336"
+    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "9464098710748f27372836255355251ae330455ffaa58681216515eeff0330517814dd7487"
+    "34682745159208158750835203309620570274592666481348052963762094268695162425"
+    "18850320172906096781969070339129822281355221058882087466637338881223511228"
+    "63144016884857141834687376804878770495858121023810198067988560350169566260"
+    "5944107067ac5771a1662497b8b93cfe57291387313365462656674328aaaaaf9067287310"
+    "ea6863ec68378827380764363420573208101547102942bf05465397209378421688020320"
+    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "18850320172906096781969070339129822281355221058882087466637338881223511228"
+    "63144016884857141834687376804878770495858121023810198067988560350169566260"
+    "59441070673981642057711662497893572913873133654626566743289483229067287310"
+    "35702406cff061642794728883255642074744145228324022219347019013411158803532"
+    "4599404120656564868354acc9369a42721979894500607265f042a53387791b3dd4784511"
+    "50227920502852884378111055ccff50357557404795594025600468996407045934090727"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+    "6ca63511429296727b70a852e1b21384d2c6dfc53380d13650a7354766a0abb81c2c92e927"
+    "22c85a2bfe8a1a81a664bc24b8b70c76c51a3d192e819d6990624f40e3585106aa07019a4c"
+    "1161e376c082748774c34b0bcb5391c0cb34ed8aa4a5b9cca4f682e6ff3748f82ee78a5636"
+    "08041078777870387730504addbc23489bdbd45615ca892497b8b93428a2f9871374491b5c"
+    "16863866837882738076436342057320810154710294295605465397209378421688020320"
+    "0fbcfe9b5dba53956c25b59f111f1923f82a4ab1c5ed5d807aa9812835b01243185be550c7"
+    "dc372be5d7480deb1fe9bdc06a7c19bf174e49b69c1efbe47860fc19dc6240ca1cc2de92c6"
+    "f4a7484aa5cb0a9dc76f988da983e5152a831c66db00327c8bf597fc7c6e00bf3d5a791470"
+    "f84c878148cc7020890befffaa4506cebbef9a3f7c67178f2");
+
+  const uint_type y = x * x;
+
+  const uint_type z(
+    "0x1902e5887a586c505ed49b0ef0db72e959da458fbfe7f7f1738b9da657ebc6b4f3eeda8f3"
+    "45f86a9439fb0a314af8a6d54e9002f6b9778bc217f31e1c2af869b890e50b105f2a6c8f6d4"
+    "d9f7ce008697c1ef9f6b1b3d58089517db9a209f0951f3843c9f5dd81da8082a4e79771c9fe"
+    "c7a967defed9c1d7229a9e6a78226389976caba3a3419a68d1376d7b67eb20136d1c47b480f"
+    "446428ec425ddeb779492e6e40c2318633e6783066d046486a419676066b0fcacf9c9da24ef"
+    "bb6ae2a639af668b9c732ed3ba74f4e73f28cffbc415d3a086decd149e1dd1f4265ede8666c"
+    "2963f2ef61b190fb094730110586e73afc7656f6e8e3188767ee075b98cceff2de2959b3c51"
+    "eb0cd03b5d277846536a3d5fa2baaff03d2ff90785581d170ad264d845d6e3522921afae94f"
+    "13eda75f99694a961beff0495830b53f1b282d4fc5fa665a402cc253d71aa411a16c7cf3825"
+    "6ff351d8e7f6c476d01ca3d39947a71703488cc0c85f7ce9ae7521e22ce4cb99e14dcaaaa69"
+    "d8f1390f8c8275c899e8ec14b2fb9100bd8c4e44bc2d531f049a31583e11d73070a815efad7"
+    "0e28caa18cd89a7e4bb1a17a961ae011511fe3ef495ae1c8e44653a73c6434ee77b242f7d9a"
+    "462613b92a5809da93c6d687222abf79b09a718fdf7787c7aff48b1e529da53898273abab56"
+    "00d67781a15c06e3741c79948cecbd3cd24414d40b0087844c9271bae8d470571a4e87309f9"
+    "ba510ef32c2def3e29f0f342f9a6f50fb00ee16159d0de74dfc85baf97c861a1ae63aca48b7"
+    "b2c3830ae11aa818f6da2a3cc74b5c2d0c635c9dd6d9fc5b9d35e46f8a53b93724e112a140e"
+    "cdee10eeaefa830d4678d06e1f3426abba1c9f76415ed479bee5160a8a5fcf9d5803552ca5a"
+    "810ea290fab7df557d9687af8782413fd04bf41454eae63c470ab231186c7aaf88b7e8de2ef"
+    "5e04cc8f9738f42ab5c8f993d13f8051765d4369709e54d24ec5e14138d1fe7ac81b311eb42"
+    "b0c35deebd10a3f5a60535870eeebd8662d11844ae4b39507232787d04e3c214e5b73b7b280"
+    "3395fd5a5c0c373cf2dbe76a2972e3bbaf6ff166c8134ad831ed000a4c4d5e615b74d697f8c"
+    "2be9fd8326e1aa352bcdb5ba460a0d34f750de03701e98ea43969c5b3b9de3e7bb562a320de"
+    "b10d1c8671b523611ffe7c2da353a1d3b86cf1c4d34d3347d02337e0656b9b39c8fe1f961f3"
+    "b5919df4469e895d3869590c042d6f881d9781c413613f6c5a22fd9cd24c906582e143b04b7"
+    "a09aefeed701bbf92687e995cc56578784b96c5a7a648d5c166c3b7c9a0c2df9c0166bf00b8"
+    "55c1f6e236ac96484638733eb9e84ccc4ccb33a49399e5057bd2d96ca51133496d5283a2085"
+    "56aa7f2b3264678f99f7cf5380bd61180230870ae35c00d272ec73d960ead550b29730a42a1"
+    "051e825890ec2283cf0de984af072a2125fd4ff692e47ef620b24a952c37ea379444061869c"
+    "aec75d2836afff972e54255daa9069f4c51f5bdb8ada41d3907fb5581dc7289d50577663616"
+    "464fc8b3f99676dd67bb93358a897feadd7a92336a0f4af44c9325fc53ba1d87f7b914e4847"
+    "462109cba84ad8498cd717c503d4c363b8ff405df44fa84bc9c8bed141c7f91954098b2ecb8"
+    "b59fc457ec86022bf6c395bb382f6a193e3387d52f3e1978af4576153fa7fb60d5b896cef43"
+    "e628045ec0577971b78e7ab1b3a9fa9ea6cc8e4a04f141e744f70fe0c800ce5dd3c748729c6"
+    "efa085877a7d9296ad489883ee966117e5db61bafbcd55284dc8d470646473761ec606357bb"
+    "fed899cd7c69e027656ef30b12e8a9e63868048bae95c7b67d26a843c94cec551ed5093542b"
+    "ff7437316a830e3c48f19491a81fb37aef5d89ee08b507b881e65fbf8dd3343e58b63ea3a2b"
+    "d465e02c5cb673e5c8cced17f5d3f9fad8307cd6c3abf9111e063fb197df4db52eac6092229"
+    "64e157a1b172004c1817162e688b55245c598cbdc5fd9f74db4911484feb5a390c27d0efeb3"
+    "a8bc21ff9dec02808fad5f882580facb5324a4f3a21b75c23cc311be7afe003895351fd07fa"
+    "c037d67718cc11aa5942837ee9048882e2564b625689ee3bd9487c4ec43f562508bbcd0671c"
+    "18434ca6ae92725d905210060d80e2524eb38ed600aeaf486d7b2b690a9f567d86444c35fd9"
+    "8bdf6b665dbf7e43557b281a792400274ca21fec996e5e6142780f8a7adcddbae4a2e9474a1"
+    "38931c19f96368bb2bc40aace10616bef5c975feca3c7f3e1122b41a39df9202a7a6405c647"
+    "d032f8c692e1e89838fc1dacb291d9e2d8ee90d88b6f598947d085289f9c4247548628a9e3f"
+    "6ea8ac5980e290749e39a9417b20f39dbbbed20209584a741747771020b2287007b37d17779"
+    "21303e3b7a9ee49db7b14dda965d9241548387e610758507c946eee0c49b67efaeedbe64e6b"
+    "114e3b4ddff5edd2050322d8298ae66388b1fb64435fa064364f41f129ce83a0cc563f8796e"
+    "1dd09be1a03bc5567caed9326df5714f6cf88ca247826ce93add7d17332d6870b1d0613a4fd"
+    "fd4c7d8185db385687d735d0bf22e87a045ad2a397db9c4ee0908a047f087a0fb49a27f65d0"
+    "e6e6ef0ef506d1411788ac027c29be3e93253e61ee76f951d3ce721c825bf5b883471f91f68"
+    "a37ca36d198adf93063e220a16b94e9aaca5c4691590ff2a696c1663b5ca69e3f3a11409cf9"
+    "727cf409a1f87a0a5e4805008c7488b7c9e23c42e33bfb0fab7e4f59e482ec50aa1b4d64996"
+    "4e7232c26acb75217ef1b200ebde38169d6ce7aeb2746aa29249d61af1e168a256e1848cb33"
+    "873c5457afd48194f77c786bcd8ce842605117c66b003abc05fb9b74869cc832c88df506e0e"
+    "79ebb0436443fb467269e42840a0486b3f35acca04b000876b9bf2c6a7f09ec6ff7ce198f8f"
+    "584e3e22b4a2e8279c1a043899fe0d2e5180ec1738b1cb23032374069b33a471fdd8e5f5be2"
+    "a4ff945697d9dc540878bc6a6704cb8b866914fbce94021bc2e6743dc7e160a8780912a90ff"
+    "732a81b060d97f777713881e9214474e1196ff13f07361385e19e5c5ffa24aa6b00f473cfd3"
+    "e71c42ed1c31eb9b5ec91635bf8c77e7aff696009da2163c7e1621bea9b30479a8e10906d3e"
+    "1ba06f3e64e776a62164238d18cebaf9684427fe8e5930fbd8892851c8cfa4e2c729558b909"
+    "a665f57919565d834fbebb0d64ba1721b083ca6fe55dab07546df6c1e60ab41f4836f64c27c"
+    "4f715764a472f01d947cbf8d3cd8e011129edecca4334b095edf3d37e27b7c30900eac3702c"
+    "3e09179a53462cda8dece1ecdda223d6cc32c9363f5123982b071367609b01bcfccfd4a0120"
+    "23b4dfacb5993d04434aac5a95e0192770206b4a3bdcb3a75013daedf68ed40cfca0e4bd802"
+    "4906ff8cc816d7bf556898545965b846f2b1dda3216d17d236e4ba5d2427ee799696c60297a"
+    "c720adacd63da47e2e3aeeb99c136e1b5de50cfe523823a87f94b1b4b8f6be2162ea40441dc"
+    "2f9af466c7642d0ef34429a986ae96e962e4a2cd9c12a41d71398ac03c990a15364c38a3bd9"
+    "af6605d1c9b807babd942bd66d2f6e4ccfaa2131354cf78aa09ffcec32258c9c3b53fbcc755"
+    "5bfeb11152332bef6420b08528d43f6865c5d53ade958d3b58dfe2f34391ea8d2d8fb35c32e"
+    "6a8f569d6cc9d456ff5b78fae829cc171f95f5389373a0dee3565a428237ec4e68b6e6efc3c"
+    "a5bd220699eb80bd498d2ea90d43b901881567e9c18898caea36334008b4a08e3e6cbda4e17"
+    "db7f5187d6f3284eca8c1a03faa28a2a23b27d560690642db0ea485e4be8c1c8b4441234f39"
+    "f31a6c9fe5cc7e50c777acd0746bbfb7399ee262a36a54a8ee25c334e503dcd6e00f7e9ac3a"
+    "80495156af9f9aaac62fe02c4c2373cc03d32c4be1b077d97f6167413661403a38b0df999d0"
+    "24701c5f17e5e5701cf9b9eccd9417af7637139473aab760b7ecafa863e7f049a6b98be603b"
+    "6bf0132b211b80123246c657cfdbb4b5dff7be43c364be943b5cdf03db86a6cd56a96187cb4"
+    "5b6acbf37383ca3fe7c9cc3b65a57c9ea6f4d686222801ce6d1463bb92ff5f2599619388660"
+    "99365474bbcba180f940ede8a02777bcf55d3549cfcd819aca8f055074d81af6472c3c9beaa"
+    "67b8f89066f1e02d1502aa13a4c872b9b1dc4e2a2b6d58eaa869c9e62a9f7e01efc2c87eb6a"
+    "9bc80d29c9c48a10edec1e5a799aeff2a580736525357ae40d677aa4fb6533c15b4afed1fde"
+    "f6e0e4c0a548c5be8751da42ffd8b409dcd77487437a16d769e232c95d0b780a46395ea0023"
+    "6cf19b1fafbda1c8c75aee09e06bcf0383816d0f9c364baa95a09fe2e2894693fc66166a16a"
+    "e152a24dfc5ca3646ce2cafe40a7ffbeb561ae4db74dc7ff045e85a9126a25152f0342d1f87"
+    "3ecb21bc411771eb7589f3df1be59fa97156ca5d3c93a7df10b90c525e25df36e7947614770"
+    "1f9ab2a368b179428ad005c7af2fb500fac032f0f1ff3f9694412d3c164fcc444075135fd9d"
+    "a58e2fab3ebf7b5fcaaf20256052e64b59c92db1cd3c2e0c2df41b06a540a754d349a284fa1"
+    "45a13795674240616f433d174fc67dda102db9e9e3bf23d4a8816ad130bca720ef707606206"
+    "7ab36f2061261981528dfdcaa3e21787f164e6ba318bb018f3974540ae8559790284852d31a"
+    "d8c77066f8620345f099606eced7f93e465b3a31a7b196b24e76a44d7ec6f597fb4a3a9a1a8"
+    "ba5611156e20c294b90cdde30166ee59c0c80936e992e5f3185c6396756194a7c8f1971a0b8"
+    "27477b2060dfe721fd0c2e725e25cc99d1227c6db9d5452dd70dbb0c2db67187a4e93c9bcfa"
+    "0049fad1289773ea6ffdcf6e6680a44cd577223b8f86eae3568ee5cd0b2f45a17f7b6d7531c"
+    "925e2c22b4004fd8e12ab70e2392e190dab556c0227b660cc226f5db558668bcb426a8153bc"
+    "32af18b8c7dbe3c2ad210300582f823fc5fd7aadc653c2c0b59b3e5362b158793485e56c7c4"
+    "c4");
+
+  BOOST_CHECK_EQUAL(y, z);
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/stream_io.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/stream_io.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,124 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output, uint_type, UIntTypes)
+{
+  const uint_type x("1024");
+  std::ostringstream os;
+  os << x;
+  BOOST_CHECK_EQUAL(os.str(), "1024");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_output_w_showbase, uint_type, UIntTypes)
+{
+  const uint_type x("1024");
+  std::ostringstream os;
+  os.setf(std::ios_base::showbase);
+  os << x;
+  BOOST_CHECK_EQUAL(os.str(), "1024");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output, uint_type, UIntTypes)
+{
+  const uint_type x("1024");
+  std::ostringstream os;
+  os.setf(std::ios_base::oct, std::ios_base::basefield);
+  os << x;
+  BOOST_CHECK_EQUAL(os.str(), "2000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(oct_output_w_showbase, uint_type, UIntTypes)
+{
+  const uint_type x("1024");
+  std::ostringstream os;
+  os.setf(std::ios_base::oct, std::ios_base::basefield);
+  os.setf(std::ios_base::showbase);
+  os << x;
+  BOOST_CHECK_EQUAL(os.str(), "02000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output, uint_type, UIntTypes)
+{
+  const uint_type x("1024");
+  std::ostringstream os;
+  os.setf(std::ios_base::hex, std::ios_base::basefield);
+  os << x;
+  BOOST_CHECK_EQUAL(os.str(), "400");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase, uint_type, UIntTypes)
+{
+  const uint_type x("1024");
+  std::ostringstream os;
+  os.setf(std::ios_base::hex, std::ios_base::basefield);
+  os.setf(std::ios_base::showbase);
+  os << x;
+  BOOST_CHECK_EQUAL(os.str(), "0x400");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_uppercase, uint_type, UIntTypes)
+{
+  const uint_type x("0xabcdef0");
+  std::ostringstream os;
+  os.setf(std::ios_base::hex, std::ios_base::basefield);
+  os.setf(std::ios_base::showbase | std::ios_base::uppercase);
+  os << x;
+  BOOST_CHECK_EQUAL(os.str(), "0XABCDEF0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_output_w_showbase_and_showpos, uint_type, UIntTypes)
+{
+  const uint_type x("1024");
+  std::ostringstream os;
+  os.setf(std::ios_base::hex, std::ios_base::basefield);
+  os.setf(std::ios_base::showbase | std::ios_base::showpos);
+  os << x;
+  BOOST_CHECK_EQUAL(os.str(), "+0x400");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input1, uint_type, UIntTypes)
+{
+  uint_type x;
+  std::stringstream s;
+  s << "123456";
+  s >> x;
+  BOOST_CHECK_EQUAL(x, "123456");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(dec_input2, uint_type, UIntTypes)
+{
+  uint_type x, y;
+  std::stringstream s;
+  s << "123456";
+  s << " " << "987654321";
+  s >> x;
+  BOOST_CHECK_EQUAL(x, "123456");
+  BOOST_REQUIRE(s.good());
+  s >> y;
+  BOOST_CHECK_EQUAL(y, "987654321");
+  BOOST_CHECK(s.good());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(oct_input, uint_type, UIntTypes)
+{
+  uint_type x;
+  std::stringstream s;
+  s << "0123456";
+  s >> x;
+  BOOST_CHECK_EQUAL(x, "0123456");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(hex_input, uint_type, UIntTypes)
+{
+  uint_type x;
+  std::stringstream s;
+  s << "0xFFFFAB01";
+  s >> x;
+  BOOST_CHECK_EQUAL(x, "0xFFFFAB01");
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/string_ops.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/string_ops.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,142 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string1, uint_type, UIntTypes)
+{
+  const uint_type x("0xabcdef123456789");
+  const std::string s =
+    x.template to_string<std::string>(std::ios::hex | std::ios::showbase);
+  BOOST_CHECK_EQUAL(s, "0xabcdef123456789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string2, uint_type, UIntTypes)
+{
+  const uint_type x("12345678901234567890");
+  const std::string s = x.template to_string<std::string>();
+  BOOST_CHECK_EQUAL(s, "12345678901234567890");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string3, uint_type, UIntTypes)
+{
+  const uint_type x("0xabcdef123456789");
+  const std::string s = x.template to_string<std::string>(
+      std::ios::hex | std::ios::showbase | std::ios::uppercase);
+  BOOST_CHECK_EQUAL(s, "0XABCDEF123456789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string4, uint_type, UIntTypes)
+{
+  const uint_type x("76484675");
+  const std::string s = x.template to_string<std::string>(std::ios::oct);
+  BOOST_CHECK_EQUAL(s, "443610103");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string5, uint_type, UIntTypes)
+{
+  const uint_type x("1024");
+  const std::string s = x.template to_string<std::string>(std::ios::oct);
+  BOOST_CHECK_EQUAL(s, "2000");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string6, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const std::string s =
+    x.template to_string<std::string>(
+        std::ios_base::dec | std::ios_base::showbase | std::ios_base::showpos);
+  BOOST_CHECK_EQUAL(s, "+0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string7, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const std::string s =
+    x.template to_string<std::string>(
+        std::ios_base::oct | std::ios_base::showbase | std::ios_base::showpos);
+  BOOST_CHECK_EQUAL(s, "+0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string9, uint_type, UIntTypes)
+{
+  const uint_type x("1");
+  const std::string s =
+    x.template to_string<std::string>(
+        std::ios_base::hex | std::ios_base::showbase | std::ios_base::showpos);
+  BOOST_CHECK_EQUAL(s, "+0x1");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string10, uint_type, UIntTypes)
+{
+  const uint_type x("0x95a6801ce5292b9a8410e1a59dd29967");
+  const std::string s =
+    x.template to_string<std::string>(std::ios_base::hex);
+  BOOST_CHECK_EQUAL(s, "95a6801ce5292b9a8410e1a59dd29967");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_to_string11, uint_type, UIntTypes)
+{
+  const uint_type x("0x12471fa56d6");
+  const std::string s = x.template to_string<std::string>();
+  BOOST_CHECK_EQUAL(s, "1256042682070");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign1, uint_type, UIntTypes)
+{
+  uint_type x;
+  x = "269513460";
+  BOOST_CHECK_EQUAL(x, "269513460");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign2, uint_type, UIntTypes)
+{
+  uint_type x;
+  x = "0xabcdef123456789";
+  BOOST_CHECK_EQUAL(x, "0xabcdef123456789");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign3, uint_type, UIntTypes)
+{
+  uint_type x;
+  x = "012345676543210000001";
+  BOOST_CHECK_EQUAL(x, "012345676543210000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign4, uint_type, UIntTypes)
+{
+  uint_type x;
+  x = "0";
+  BOOST_CHECK_EQUAL(!x, true);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(op_assign5, uint_type, UIntTypes)
+{
+  uint_type x("0xabcedf03030303");
+  x = "012345676543210000001";
+  BOOST_CHECK_EQUAL(x, "012345676543210000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(assign1, uint_type, UIntTypes)
+{
+  uint_type x;
+  x.assign("123456789876543210000001", std::ios::dec);
+  BOOST_CHECK_EQUAL(x, "123456789876543210000001");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(assign2, uint_type, UIntTypes)
+{
+  uint_type x;
+  x.assign("abcdefabcdef1234567890", std::ios::hex);
+  BOOST_CHECK_EQUAL(x, "0xabcdefabcdef1234567890");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(assign3, uint_type, UIntTypes)
+{
+  uint_type x("564897123123456456789789789897");
+  x.assign("1234567000000000000000000000000077", std::ios::oct);
+  BOOST_CHECK_EQUAL(x, "01234567000000000000000000000000077");
+}
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/sub.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/sub.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,68 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub1, uint_type, UIntTypes)
+{
+  const uint_type x("0");
+  const uint_type y("0");
+  const uint_type z = x - y;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub2, uint_type, UIntTypes)
+{
+  const uint_type x("955588990000001");
+  const uint_type y("9801");
+  const uint_type z = x - y;
+  BOOST_CHECK_EQUAL(z, "955588989990200");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub3, uint_type, UIntTypes)
+{
+  const uint_type x(
+    "49144609407766890328547643707523663509662747376486271392344480900673178645"
+    "33198519112197059826509662943577383543858946941049753393431035706592040680"
+    "43848484065292542884106550381079282660840705126574766636237650938379223350"
+    "073087806800887586256085275775217219429527000017403144");
+  const uint_type y(
+    "49144609407766890328547643707523663509662747376486271392344480900673178645"
+    "33198519112197059826509662943577383543858946941049753393431035706592040680"
+    "43848484065292542884106550381079282660840705126574766636237650938379223350"
+    "073087806800887586256085275775217219429527000017403144");
+  const uint_type z = x - y;
+  BOOST_CHECK_EQUAL(z, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(sub4, uint_type, UIntTypes)
+{
+  const uint_type x(
+    "21665907282124706187656074325458499695895652068822763794228458103499408841");
+  const uint_type y(
+    "173087806800887586256085275775299999999889978789789");
+  const uint_type z = x - y;
+  const uint_type w(
+    "21665907282124706187655901237651698808309395983546988494228458213520619052");
+  BOOST_CHECK_EQUAL(z, w);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement1, uint_type, UIntTypes)
+{
+  uint_type x("4");
+  for (int i = 0; i < 4; ++i)
+    --x;
+  BOOST_CHECK_EQUAL(x, "0");
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(decrement2, uint_type, UIntTypes)
+{
+  uint_type x("130");
+  for (int i = 0; i < 10; ++i)
+    --x;
+  BOOST_CHECK_EQUAL(x, "120");
+}
+
Added: sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/to_integral.cpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/libs/mp_math/test/unbounded/unsigned/to_integral.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,108 @@
+// Copyright Kevin Sopp 2008 - 2009.
+// 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)
+
+#include <boost/test/unit_test.hpp>
+#include "prerequisite.hpp"
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char1, uint_type, UIntTypes)
+{
+  uint_type x("123");
+  const char z = x.template to_integral<char>();
+  BOOST_CHECK_EQUAL(z, 123);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_int1, uint_type, UIntTypes)
+{
+  uint_type x("1023");
+  const int z = x.template to_integral<int>();
+  BOOST_CHECK_EQUAL(z, 1023);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_char_max, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<char>::max());
+  const int z = x.template to_integral<char>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<char>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_min, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<unsigned char>::min());
+  const unsigned char z = x.template to_integral<unsigned char>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned char>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_char_max, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<unsigned char>::max());
+  const unsigned char z = x.template to_integral<unsigned char>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned char>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_int_max, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<int>::max());
+  const int z = x.template to_integral<int>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_min, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<unsigned int>::min());
+  const unsigned int z = x.template to_integral<unsigned int>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_int_max, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<unsigned int>::max());
+  const unsigned int z = x.template to_integral<unsigned int>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_int_max, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<long int>::max());
+  const long int z = x.template to_integral<long int>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<long int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_min, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<unsigned long int>::min());
+  const unsigned long int z = x.template to_integral<unsigned long int>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_int_max, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<unsigned long int>::max());
+  const unsigned long int z = x.template to_integral<unsigned long int>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long int>::max());
+}
+
+#ifdef BOOST_HAS_LONG_LONG
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_long_long_int_max, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<long long int>::max());
+  const long long int z = x.template to_integral<long long int>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<long long int>::max());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_min, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<unsigned long long int>::min());
+  const unsigned long long int z = x.template to_integral<unsigned long long int>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long long int>::min());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(to_unsigned_long_long_int_max, uint_type, UIntTypes)
+{
+  uint_type x(std::numeric_limits<unsigned long long int>::max());
+  const unsigned long long int z = x.template to_integral<unsigned long long int>();
+  BOOST_CHECK_EQUAL(z, std::numeric_limits<unsigned long long int>::max());
+}
+#endif
+
Modified: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -11,7 +11,7 @@
   base(std::string("gmp"), gmp_version)
 {
   // init dst vector
-  std::fill(dst.begin(), dst.end(), mpz_class());
+  std::fill(dst.begin(), dst.end(), mp_int_type());
 }
 
 benchmark_gmp::~benchmark_gmp()
@@ -19,17 +19,17 @@
 
 void benchmark_gmp::clear_dst_vector()
 {
-  std::fill(dst.begin(), dst.end(), mpz_class());
+  std::fill(dst.begin(), dst.end(), mp_int_type());
 }
 
 void benchmark_gmp::construct_operand_1(const std::string& src, unsigned int i)
 {
-  src1[i] = mpz_class(src, 16);
+  src1[i].assign(src, std::ios::hex);
 }
 
 void benchmark_gmp::construct_operand_2(const std::string& src, unsigned int i)
 {
-  src2[i] = mpz_class(src, 16);
+  src2[i].assign(src, std::ios::hex);
 }
 
 #define bench_function_def(f)                                   \
Modified: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.hpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.hpp	(original)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_gmp.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,13 +6,22 @@
 #ifndef BOOST_MP_MATH_TOOLS_BENCHMARK_GMP_HPP
 #define BOOST_MP_MATH_TOOLS_BENCHMARK_GMP_HPP
 
-#include <gmpxx.h>
+#include <boost/mp_math/gmp.hpp>
+#include <boost/mp_math/integer.hpp>
 #include "benchmark.hpp"
 
 
-struct benchmark_gmp : benchmark<mpz_class>
+struct benchmark_gmp
+:
+  benchmark<
+    boost::mp_math::integer<
+      boost::mp_math::gmp_integer<>
+    >
+  >
 {
-  typedef benchmark<mpz_class> base;
+  typedef benchmark<
+    boost::mp_math::integer<boost::mp_math::gmp_integer<> >
+  > base;
 
   benchmark_gmp();
   ~benchmark_gmp();
@@ -38,36 +47,36 @@
   {
     base& b;
     explicit ctor_dec_op(base& ba) : b(ba) {}
-    void operator()(unsigned int i) const { b.dst[i] = mpz_class(b.dec_str[i], 10); }
+    void operator()(unsigned int i) const { b.dst[i].assign(b.dec_str[i], std::ios::dec); }
   };
 
   struct ctor_hex_op
   {
     base& b;
     explicit ctor_hex_op(base& ba) : b(ba) {}
-    void operator()(unsigned int i) const { b.dst[i] = mpz_class(b.hex_str[i], 16); }
+    void operator()(unsigned int i) const { b.dst[i].assign(b.hex_str[i], std::ios::hex); }
   };
 
   struct to_dec_op
   {
     base& b;
     explicit to_dec_op(base& ba) : b(ba) {}
-    void operator()(unsigned int i) const { b.str = b.src1[i].get_str(10); }
+    void operator()(unsigned int i) const { b.str = b.src1[i].to_string<std::string>(std::ios::dec); }
   };
 
   struct to_hex_op
   {
     base& b;
     explicit to_hex_op(base& ba) : b(ba) {}
-    void operator()(unsigned int i) const { b.str = b.src1[i].get_str(16); }
+    void operator()(unsigned int i) const { b.str = b.src1[i].to_string<std::string>(std::ios::hex); }
   };
 
-  #define bench_functor(name,op)              \
-  struct name##_op {                          \
-    base& b;                                  \
-    explicit name##_op(base& ba) : b(ba) {}   \
-    void operator()(unsigned int i) const     \
-    { b.dst[i] = b.src1[i] op b.src2[i]; }    \
+  #define bench_functor(name,op)            \
+  struct name##_op {                        \
+    base& b;                                \
+    explicit name##_op(base& ba) : b(ba) {} \
+    void operator()(unsigned int i) const   \
+    { b.dst[i] = b.src1[i] op b.src2[i]; }  \
   }
 
   bench_functor(add,+);
@@ -91,12 +100,10 @@
   struct modpow_op
   {
     base& b;
-    explicit modpow_op(base& ba) : b (ba) {}
+    explicit modpow_op(base& ba) : b(ba) {}
     void operator()(unsigned int i) const
     {
-      mpz_powm(
-          b.dst[i].get_mpz_t(),
-          b.src1[i].get_mpz_t(), b.src1[i].get_mpz_t(), b.src2[i].get_mpz_t());
+      b.dst[i] = boost::mp_math::modpow(b.src1[i], b.src1[i], b.src2[i]);
     }
   };
 };
Modified: sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.hpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.hpp	(original)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/benchmark_mp_math.hpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -6,13 +6,13 @@
 #ifndef BOOST_MP_MATH_TOOLS_BENCHMARK_MP_MATH_HPP
 #define BOOST_MP_MATH_TOOLS_BENCHMARK_MP_MATH_HPP
 
-#include <boost/mp_math/mp_int.hpp>
+#include <boost/mp_math/integer.hpp>
 #include "benchmark.hpp"
 
 
-struct benchmark_mp_math : benchmark<boost::mp_math::mp_int<> >
+struct benchmark_mp_math : benchmark<boost::mp_math::integer<> >
 {
-  typedef benchmark<boost::mp_math::mp_int<> > base;
+  typedef benchmark<boost::mp_math::integer<> > base;
 
   benchmark_mp_math();
   virtual ~benchmark_mp_math();
@@ -62,12 +62,12 @@
     void operator()(unsigned int i) const { b.str = b.src1[i].to_string<std::string>(std::ios::hex); }
   };
 
-  #define bench_functor(name,op)              \
-  struct name##_op {                          \
-    base& b;                                  \
-    explicit name##_op(base& ba) : b(ba) {}   \
-    void operator()(unsigned int i) const     \
-    { b.dst[i] = b.src1[i]; b.dst[i] op##= b.src2[i]; } \
+  #define bench_functor(name,op)            \
+  struct name##_op {                        \
+    base& b;                                \
+    explicit name##_op(base& ba) : b(ba) {} \
+    void operator()(unsigned int i) const   \
+    { b.dst[i] = b.src1[i] op b.src2[i]; }  \
   }
 
   bench_functor(add,+);
@@ -84,8 +84,7 @@
     explicit square_op(base& ba) : b(ba) {}
     void operator()(unsigned int i) const
     {
-      b.dst[i] = b.src1[i];
-      b.dst[i].sqr();
+      b.dst[i] = b.src1[i] * b.src1[i];
     }
   };
 
Modified: sandbox/mp_math/libs/mp_math/tools/benchmark/jamfile.v2
==============================================================================
--- sandbox/mp_math/libs/mp_math/tools/benchmark/jamfile.v2	(original)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/jamfile.v2	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-# Copyright Kevin Sopp 2008.
+# Copyright Kevin Sopp 2008 - 2009.
 # 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)
@@ -12,15 +12,12 @@
     <include>../../../..
     <include>.
     <link>static
+    <cxxflags>-DNDEBUG
   ;
 
-
-
 # GMP (GNU Multiple Precision Arithmetic, http://gmplib.org/) library needs to
 # be installed for the benchmark to work
-# gmpxx is the library for the C++ bindings of gmp
-lib gmpxx : : <name>gmpxx ;
-lib gmp   : : <name>gmp ;
+lib gmp : : <name>gmp ;
 
 lib tommath : tommath.cpp : <variant>release ;
 
@@ -34,7 +31,7 @@
     main.cpp
     modes.cpp
     tommath
-    gmpxx gmp
+    gmp
     boost_fs
     boost_po
   :
Modified: sandbox/mp_math/libs/mp_math/tools/benchmark/main.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/tools/benchmark/main.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/main.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -18,7 +18,7 @@
 #include "modes.hpp"
 
 
-const char* version = "0.4";
+const char* version = "0.5";
 
 
 struct config
@@ -97,9 +97,9 @@
 {
   const double mode1_time =
     sample_time * num_input_samples * ops.size() * libs.size();
-  
+
   const double mode2_time = 0.05 * ops.size() * libs.size();
-  
+
   double sum = 0.0;
   if (mode == 0 || mode == 1)
     sum += mode1_time;
@@ -115,7 +115,7 @@
   const int vec_length = 10;
   long vec[vec_length];
   double st = 0.01;
-  
+
   int verified = 0;
   for (;;)
   {
@@ -140,7 +140,7 @@
     average_deviation /= vec_length;
 
     const double error = (double)average_deviation / (double)average_value;
-    
+
     std::cout << "sample-time = " << st
               << ", current error = " << error;
     if (verified)
@@ -159,7 +159,7 @@
     if (error / max_error > 2.0)
       st += 0.01;
     else
-      st += 0.002; 
+      st += 0.002;
     if (st >= 0.05)
       return 0.05;
   }
@@ -171,7 +171,7 @@
 int main(int argc, char** argv)
 {
   typedef config::string_list string_list;
-  
+
   std::ios::sync_with_stdio(false);
 
   try
@@ -204,16 +204,16 @@
           "1 = run benchmark meant to test small numbers\n"
           "2 = run benchmark meant to test large numbers")
 
-    ("ops", 
+    ("ops",
         value(&c.ops_string),
           "the operations to benchmark")
-    
+
     ("libs",
         value(&c.libs_string),
           "the libraries to benchmark")
-    
+
     ("list-ops",  "lists available operations")
-    
+
     ("list-libs", "lists available libraries")
 
     ("x",
@@ -235,16 +235,16 @@
         value(&c.max_error)->default_value(0.1, "0.1"),
           "this value is used to calculate the sample time, you should not "
           "need to modify it")
-    
+
     ("sample-time,s",
         value(&c.sample_time)->default_value(0.035, "0.035"),
           "directly specify the sample time in seconds, it is used to reduce "
           "the error of the measurements")
-    
+
     ("range-beg,a",
         value(&c.range.first)->default_value(32),
           "range of numbers, measured in bits")
-    
+
     ("range-end,b",
         value(&c.range.second)->default_value(3072),
           "range of numbers, measured in bits")
@@ -327,7 +327,7 @@
   const std::time_t time = std::time(0);
   char timestring[32];
   std::strftime(timestring, 32, "%Y %m %d %H:%M", std::localtime(&time));
-  
+
   boost::filesystem::create_directory(timestring);
   boost::filesystem::current_path(timestring);
 
@@ -348,7 +348,7 @@
     std::cout << "calibrating sample time..." << std::endl;
     c.sample_time = calibrate_sample_time(c.max_error);
   }
-    
+
   std::cout << "Sample time is: " << c.sample_time << " sec" <<  std::endl;
 
   const unsigned long runtime =
Modified: sandbox/mp_math/libs/mp_math/tools/benchmark/modes.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/tools/benchmark/modes.cpp	(original)
+++ sandbox/mp_math/libs/mp_math/tools/benchmark/modes.cpp	2009-06-22 14:57:19 EDT (Mon, 22 Jun 2009)
@@ -1,4 +1,4 @@
-// Copyright Kevin Sopp 2008.
+// Copyright Kevin Sopp 2008 - 2009.
 // 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)
@@ -10,27 +10,26 @@
 #include <sstream>
 #include <stdexcept>
 #include <boost/random.hpp>
-#include <boost/mp_math/mp_int.hpp>
+#include <boost/mp_math/integer.hpp>
 
 #include "modes.hpp"
 
-std::string create_random_hex_string(unsigned size_in_bits)
+std::string create_random_hex_string(unsigned size_in_digits)
 {
   std::string s;
-  s.reserve(size_in_bits/4);
+  s.resize(size_in_digits);
 
   boost::mt19937 r;
   boost::uniform_smallint<char> u(0,15);
   boost::variate_generator<boost::mt19937&, boost::uniform_smallint<char> > vg(r, u);
-  // one hex digit occupies 4 bits
-  for (unsigned i = 0; i < (size_in_bits+3)/4; ++i)
+  for (unsigned i = 0; i < size_in_digits; ++i)
   {
     char tmp = vg();
     if (tmp < 10)
       tmp = '0' + tmp;
     else
       tmp = 'a' + (tmp-10);
-    s.push_back(tmp);
+    s[i] = tmp;
   }
   return s;
 }
@@ -38,15 +37,15 @@
 std::string create_random_dec_string(unsigned size_in_digits)
 {
   std::string s;
-  s.reserve(size_in_digits);
+  s.resize(size_in_digits);
 
   boost::mt19937 r;
   boost::uniform_smallint<char> u(0,9);
   boost::variate_generator<boost::mt19937&, boost::uniform_smallint<char> > vg(r, u);
-  
+
   for (unsigned i = 0; i < size_in_digits; ++i)
-    s.push_back('0' + vg());
-  
+    s[i]= '0' + vg();
+
   return s;
 }
 
@@ -63,11 +62,11 @@
     file << x_values.at(i) << "\t";
 
     std::list<column>::const_iterator it = cols.begin();
-    
+
     while (it != cols.end())
     {
       file << it->data.at(i);
-        
+
       if (++it != cols.end())
         file << "\t";
     }
@@ -97,7 +96,7 @@
             "set term png size " << x << "," << y << "\n"
             "set output \"" << modeprefix << df->op << ".png\"\n";
     file << "plot \\\n";
-    
+
     std::list<data_file::column>::const_iterator c = df->cols.begin();
     int count = 2;
     while (c != df->cols.end())
@@ -132,11 +131,11 @@
   if (!iv_file.is_open())
     throw std::runtime_error("couldn't open file mode1_input_vecs.dat");
 
-  const unsigned long min_size = 
+  const unsigned long min_size =
     std::min(get_operand1_size(0),
              get_operand2_size(0));
-  
-  const unsigned long max_size = 
+
+  const unsigned long max_size =
     std::max(get_operand1_size(num_input_samples_),
              get_operand2_size(num_input_samples_));
 
@@ -144,7 +143,7 @@
             << " operand indices for numbers between "
             << min_size << " and " << max_size << " bits."
             << std::endl;
-  
+
   const std::string hex_s = create_random_hex_string(max_size);
 
   std::cout << "creating input vectors";
@@ -161,19 +160,19 @@
   {
     const unsigned long size1 = get_operand1_size(i);
     const unsigned long size2 = get_operand2_size(i);
-    
+
     // divide by 4 because hex_s has max/4 hex digits
     vec1.push_back(hex_s.substr(0, size1/4));
     vec2.push_back(hex_s.substr(0, size2/4));
-    
+
     // output the input sizes for a graph here
     iv_file << size1 << "\t" << size2 << "\n";
-    
+
     if (((i+1) % stepsize) == 0)
     {
       std::cout << ".";
       std::cout.flush();
-    }      
+    }
   }
 
   std::cout << std::endl;
@@ -184,9 +183,9 @@
   for (unsigned int i = 0; i < num_input_samples_; ++i)
   {
     hex_str_vec.push_back(hex_s.substr(0, (get_operand1_size(i)+3)/4));
-    // use mp_int to ensure decimal string results in the same number of bits as
-    // the hex string
-    boost::mp_math::mp_int<> tmp(hex_str_vec.back(), std::ios::hex);
+    // use integer to ensure decimal string results in the same number of bits
+    // as the hex string
+    boost::mp_math::integer<> tmp(hex_str_vec.back(), std::ios::hex);
     dec_str_vec.push_back(tmp.to_string<std::string>());
   }
 }
@@ -194,7 +193,7 @@
 void mode1::create_data_files(std::list<benchmark_result>& results)
 {
   std::list<benchmark_result>::const_iterator r = results.begin();
-  
+
   // expects result list to be sorted by op name
   while (r != results.end())
   {
@@ -210,7 +209,7 @@
 
       c.libname = r->libname;
       c.data = r->ops;
-      
+
       // scale from ops per sample_time to ops per millisecond
       for (std::vector<double>::iterator it = c.data.begin();
           it != c.data.end(); ++it)
@@ -269,13 +268,13 @@
 void mode1::write_results(unsigned int x, unsigned int y) const
 {
   write_input_vector_plotfile(x, y);
-  
+
   std::cout << "writing data files..." << std::endl;
   write_data_files("mode1_", dfiles_);
-  
+
   std::cout << "writing gnuplot scripts..." << std::endl;
   write_gnuplot_scripts(x, y, "mode1_", "operand index", "ops/msec", dfiles_);
-  
+
   write_summary_file();
 }
 
@@ -293,7 +292,7 @@
   // modified sine curve
   const double pi = 3.141592654;
   const double sample_num_to_rad = num_input_samples_ / (4.5 * pi);
-  
+
   // scale sample_number into the range [0...4.5*PI]
   const double x = sample_number / sample_num_to_rad;
 
@@ -309,7 +308,7 @@
 
   // we want to scale the curve at the point p1 to be above y_top at x = 2.5*pi
   const double p1 = 2.5 * pi;
-  
+
   // here we use a function of the form y = -ax^2 + b to scale the curve at (and
   // around) p1
   const double a = 1.0/(p1 * p1);
@@ -319,7 +318,7 @@
   // stop scaling once we're past p1 and 'adjust' falls below 1.0
   if (x > p1 && adjust < 1.0)
     adjust = 1.0;
-  
+
   return static_cast<unsigned long>(y_bottom * adjust * y_val + y_bottom);
 }
 
@@ -331,19 +330,21 @@
   pow_step_(stepsize)
 {
   const unsigned long max_size = 1UL << pow_to;
-  
+
+  // one hex digit occupies 4 bits
   const std::string hex_s = create_random_hex_string((max_size+3)/4);
 
-  for (; pow_from < pow_to; pow_from += stepsize)
+  for (; pow_from <= pow_to; pow_from += stepsize)
   {
     const unsigned long size = 1UL << pow_from;
-    
+
     vec1.push_back(hex_s.substr(0, size/4));
-    
+
     hex_str_vec.push_back(hex_s.substr(0, (size+3)/4));
-    
-    boost::mp_math::mp_int<> tmp(hex_str_vec.back(), std::ios::hex);
-    dec_str_vec.push_back(tmp.to_string<std::string>());
+
+    // FIXME: this is unusably slow
+    //boost::mp_math::mp_int<> tmp(hex_str_vec.back(), std::ios::hex);
+    //dec_str_vec.push_back(tmp.to_string<std::string>());
   }
 
   vec2 = vec1;
@@ -353,13 +354,13 @@
 void mode2::create_data_files(std::list<benchmark_result>& results)
 {
   std::list<benchmark_result>::const_iterator r = results.begin();
-  
+
   // expects result list to be sorted by op name
   while (r != results.end())
   {
     data_file d;
-    
-    for (unsigned i = pow_from_; i < pow_to_; i += pow_step_)
+
+    for (unsigned i = pow_from_; i <= pow_to_; i += pow_step_)
       d.x_values.push_back(i);
 
     std::list<benchmark_result>::const_iterator cur = r;
@@ -369,7 +370,7 @@
 
       c.libname = r->libname;
       c.data = r->ops;
-      
+
       // scale from ops per sample_time to seconds per op
       for (std::vector<double>::iterator it = c.data.begin();
           it != c.data.end(); ++it)
@@ -378,7 +379,7 @@
         *it = 1.0 / *it;
       }
 
-      c.sum = std::accumulate(r->ops.begin(), r->ops.end(), 0.);
+      c.sum = std::accumulate(c.data.begin(), c.data.end(), 0.);
       d.cols.push_back(c);
       ++r;
     }
@@ -416,7 +417,7 @@
 {
   std::cout << "writing data files..." << std::endl;
   write_data_files("mode2_", dfiles_);
-  
+
   std::cout << "writing gnuplot scripts..." << std::endl;
   write_gnuplot_scripts(x, y, "mode2_", "operand size (2^x)", "seconds/op",
                         dfiles_);
@@ -424,3 +425,6 @@
   write_summary_file();
 }
 
+// TODO add mode 3 where user can specify the bits per operand directly
+// ./benchmark -m3 --op1_bits=23456789 --op2_bits=1234567
+