$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r54224 - in sandbox/mp_math: boost/mp_math/integer boost/mp_math/integer/detail/base/asm/asm boost/mp_math/integer/detail/base/asm/x86 libs/mp_math/test/unbounded/signed
From: baraclese_at_[hidden]
Date: 2009-06-22 15:50:44
Author: baraclese
Date: 2009-06-22 15:50:42 EDT (Mon, 22 Jun 2009)
New Revision: 54224
URL: http://svn.boost.org/trac/boost/changeset/54224
Log:
* fix svn commit glitches of last commit
Added:
   sandbox/mp_math/boost/mp_math/integer/detail/base/asm/x86/
   sandbox/mp_math/boost/mp_math/integer/detail/base/asm/x86/gnu_386_primitive_ops.hpp   (contents, props changed)
Removed:
   sandbox/mp_math/boost/mp_math/integer/detail/base/asm/asm/
   sandbox/mp_math/libs/mp_math/test/unbounded/signed/traits.cpp
Text files modified: 
   sandbox/mp_math/boost/mp_math/integer/prime.hpp  |   117 +++++++++++++--------------             
   sandbox/mp_math/boost/mp_math/integer/random.hpp |   166 ++++++++++++++++++++--------------------
   2 files changed, 139 insertions(+), 144 deletions(-)
Added: sandbox/mp_math/boost/mp_math/integer/detail/base/asm/x86/gnu_386_primitive_ops.hpp
==============================================================================
--- (empty file)
+++ sandbox/mp_math/boost/mp_math/integer/detail/base/asm/x86/gnu_386_primitive_ops.hpp	2009-06-22 15:50:42 EDT (Mon, 22 Jun 2009)
@@ -0,0 +1,76 @@
+// 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, unsigned int>
+:
+  basic_primitive_ops<unsigned int,unsigned int,unsigned int>
+{
+  typedef unsigned int dword;
+  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<>
+inline
+unsigned int
+primitive_ops<unsigned int, unsigned int, unsigned int>::
+add_digits(dword* x, const dword* y, dword n)
+{
+  dword carry = 0;
+
+  __asm__ __volatile__(
+      "clc                \n\t"
+    "0:                   \n\t"
+      "mov (%[y]), %%eax  \n\t"
+      "adc %%eax, (%[x])  \n\t"
+      "lea 4(%[y]), %[y]  \n\t" // increment pointer
+      "lea 4(%[x]), %[x]  \n\t" // increment pointer
+    "loop 0b              \n\t"
+      "adc $0, %[carry]       "
+    :
+      [carry] "=m" (carry)
+    :
+      [y] "r" (y),
+      [x] "r" (x),
+      [n] "c" (n)
+    :
+      "cc", "memory", "%eax"
+    );
+
+  return carry;
+}
+
+template<>
+inline
+unsigned int
+primitive_ops<unsigned int, unsigned int, unsigned int>::
+subtract_digits(dword* x, const dword* y, dword n)
+{
+  dword carry = 0;
+
+  __asm__ __volatile__(
+      "clc                \n\t"
+    "0:                   \n\t"
+      "mov (%[y]), %%eax  \n\t"
+      "sbb %%eax, (%[x])  \n\t"
+      "lea 4(%[y]), %[y]  \n\t"
+      "lea 4(%[x]), %[x]  \n\t"
+    "loop 0b              \n\t"
+      "adc $0, %[carry]       "
+    :
+      [carry] "=m" (carry)
+    :
+      [y] "r" (y),
+      [x] "r" (x),
+      [n] "c" (n)
+    :
+      "cc", "memory", "%eax"
+    );
+
+  return carry;
+}
+
Modified: sandbox/mp_math/boost/mp_math/integer/prime.hpp
==============================================================================
--- sandbox/mp_math/boost/mp_math/integer/prime.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/prime.hpp	2009-06-22 15:50:42 EDT (Mon, 22 Jun 2009)
@@ -1,13 +1,14 @@
-// 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_PRIME_HPP
-#define BOOST_MP_MATH_MP_INT_PRIME_HPP
+#ifndef BOOST_MP_MATH_INTEGER_PRIME_HPP
+#define BOOST_MP_MATH_INTEGER_PRIME_HPP
 
-#include <boost/mp_math/mp_int/mp_int_fwd.hpp>
-#include <boost/mp_math/mp_int/detail/prime_tab.hpp>
+#include <boost/mp_math/integer/random.hpp>
+#include <boost/mp_math/integer/detail/multiplier.hpp>
+#include <boost/mp_math/integer/detail/prime_tab.hpp>
 
 
 namespace boost {
@@ -23,17 +24,16 @@
 {
   typedef bool result_type;
 
-  template<class A, class T>
-  bool operator()(const mp_int<A,T>& p) const;
+  template<class ApInt>
+  bool operator()(const ApInt& p) const;
 };
 
 
-template<class A, class T>
-bool primality_division_test::operator()(const mp_int<A,T>& p) const
+template<class ApInt>
+bool primality_division_test::operator()(const ApInt& p) const
 {
-  typedef typename mp_int<A,T>::traits_type traits;
-  typedef typename traits::digit_type       digit_type;
-  typedef detail::prime_tab<digit_type>     prime_tab;
+  typedef typename ApInt::digit_type digit_type;
+  typedef detail::prime_tab<digit_type>      prime_tab;
 
   if (p.is_even())
   {
@@ -43,19 +43,14 @@
       return true;
   }
 
-  mp_int<A,T> tmp;
   for (int i = 0; i < prime_tab::num_primes; ++i)
   {
-    /* what is x mod prime_tab[i] */
-    tmp = p;
-    const digit_type r =
-      tmp.divide_by_digit(
-          static_cast<digit_type>(prime_tab::values[i]));
+    const digit_type small_prime = static_cast<digit_type>(prime_tab::values[i]);
+    const ApInt remainder = p % small_prime;
 
-    /* is the residue zero? */
-    if (r == 0)
+    if (remainder == digit_type(0))
     {
-      if (p != prime_tab::values[i])
+      if (p != small_prime)
         return false;
       else
         return true; // definitely prime
@@ -77,12 +72,12 @@
 // returns true if p is probably prime
 // NOTE: may return true for carmichael numbers
 template<
-  class Distribution = uniform_mp_int<>
+  class Distribution = uniform_integer<>
 >
 class primality_fermat_test
 {
   const unsigned int rounds_;
-  
+
 public:
 
   typedef Distribution distribution_type;
@@ -93,37 +88,37 @@
     rounds_(rounds)
   {}
 
-  template<class Engine, class A, class T>
-  bool operator()(Engine& e, const mp_int<A,T>& p) const;
+  template<class Engine, class ApInt>
+  bool operator()(Engine& e, const ApInt& p) const;
 };
 
 
 template<class Distribution>
-template<class Engine, class A, class T>
+template<class Engine, class ApInt>
 bool
 primality_fermat_test<Distribution>::operator()
-  (Engine& eng, const mp_int<A,T>& p) const
+  (Engine& eng, const ApInt& p) const
 {
-  typedef typename mp_int<A,T>::digit_type digit_type;
-  
+  typedef typename ApInt::digit_type digit_type;
+
   const digit_type one = 1;
-  const mp_int<A,T> p1(p-one);
-  
+  const ApInt p1(p-one);
+
   distribution_type rng(digit_type(2), p1);
 
-  modpow_ctx<A,T> ctx;
+  modpow_ctx<ApInt> ctx;
   for (unsigned int i = 0; i < rounds_; ++i)
   {
-    mp_int<A,T> base = rng(eng);
+    ApInt base = rng(eng);
+
+    base |= one; // test only odd bases
 
-    base.set_least_significant_bit(); // test only odd bases
-    
-    const mp_int<A,T> tmp = modpow(base, p1, p, &ctx);
+    const ApInt tmp = modpow(base, p1, p, &ctx);
 
     if (tmp != one)
       return false; // definitely composite!
   }
-  
+
   return true;
 }
 
@@ -134,7 +129,7 @@
 // The probability that a composite number is reported as prime
 // is less than 1/(4**k) where k is the number of rounds
 template<
-  class Distribution = uniform_mp_int<>
+  class Distribution = uniform_integer<>
 >
 class primality_miller_rabin_test
 {
@@ -156,8 +151,8 @@
   {}
 
   // p must be odd
-  template<class Engine, class A, class T>
-  bool operator()(Engine& e, const mp_int<A,T>& p) const;
+  template<class Engine, class ApInt>
+  bool operator()(Engine& e, const ApInt& p) const;
 
   // return the recommended number of rounds for numbers of size 'bits'
   // so that the probability of error is lower than 2^-96
@@ -182,10 +177,10 @@
 
 
 template<class Distribution>
-template<class Engine, class A, class T>
+template<class Engine, class ApInt>
 bool
 primality_miller_rabin_test<Distribution>::operator()
-  (Engine& eng, const mp_int<A,T>& p) const
+  (Engine& eng, const ApInt& p) const
 {
   assert(p.is_odd());
 
@@ -194,27 +189,27 @@
     r = rounds_;
   else
     r = recommended_number_of_rounds(p.precision());
-  
-  mp_int<A,T> n = abs(p);
+
+  ApInt n = abs(p);
   --n;
 
-  const typename mp_int<A,T>::size_type s = n.count_lsb();
+  const typename ApInt::size_type s = n.count_trailing_zero_bits();
   n >>= s; // p-1 / 2**s
 
-  const typename mp_int<A,T>::digit_type one = 1;
-  const mp_int<A,T> p_minus_one(p-one);
+  const typename ApInt::digit_type one = 1;
+  const ApInt p_minus_one(p - one);
   distribution_type rng(one, p_minus_one);
 
-  modpow_ctx<A,T> ctx;
+  modpow_ctx<ApInt> ctx;
   for (unsigned int i = 0; i < r; ++i)
   {
-    const mp_int<A,T> base = rng(eng);
-    mp_int<A,T> y = modpow(base, n, p, &ctx);
-    
-    for (typename mp_int<A,T>::size_type j = 0; j < s; ++j)
+    const ApInt base = rng(eng);
+    ApInt y = modpow(base, n, p, &ctx);
+
+    for (typename ApInt::size_type j = 0; j < s; ++j)
     {
       const bool b = (y != one) && (y != p_minus_one);
-      y.sqr();
+      y *= y;
       y %= p;
       if (b && (y == one))
         return false;
@@ -227,8 +222,8 @@
 
 template<class Distribution>
 unsigned int
-primality_miller_rabin_test<Distribution>::recommended_number_of_rounds(
-                                                                  unsigned bits)
+primality_miller_rabin_test<Distribution>::
+recommended_number_of_rounds(unsigned bits)
 {
   int i;
 
@@ -246,8 +241,8 @@
 
 
 
-template<class A, class T, class PrimalityTest>
-inline bool is_prime(const mp_int<A,T>& x, PrimalityTest f = PrimalityTest())
+template<class ApInt, class PrimalityTest>
+inline bool is_prime(const ApInt& x, PrimalityTest f = PrimalityTest())
 {
   return f(x);
 }
@@ -255,7 +250,7 @@
 
 template<
   class PrimalityTest,
-  class Dist = uniform_mp_int_bits<>
+  class Dist = uniform_integer_bits<>
 >
 struct prime_generator
 {
@@ -287,7 +282,7 @@
   do
   {
     candidate = dist(eng);
-    candidate.set_least_significant_bit(); // make odd
+    candidate |= typename result_type::digit_type(1); // make odd
   } while (!is_prime(candidate, test_));
 
   return candidate;
@@ -297,7 +292,7 @@
 // A prime p is called safe if (p-1)/2 is also prime
 template<
   class PrimalityTest,
-  class Dist = uniform_mp_int_bits<>
+  class Dist = uniform_integer_bits<>
 >
 struct safe_prime_generator
 {
@@ -332,7 +327,7 @@
     do
     {
       p = prime_gen(eng);
-      p.multiply_by_2();
+      detail::multiplier<result_type>::multiply_by_2(p);
       ++p;
     } while (!is_prime(p, test_));
   // Catch extremely rare case, this occurs if the carry from ++p ripples
Modified: sandbox/mp_math/boost/mp_math/integer/random.hpp
==============================================================================
--- sandbox/mp_math/boost/mp_math/integer/random.hpp	(original)
+++ sandbox/mp_math/boost/mp_math/integer/random.hpp	2009-06-22 15:50:42 EDT (Mon, 22 Jun 2009)
@@ -1,185 +1,185 @@
-// 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_RANDOM_HPP
-#define BOOST_MP_MATH_MP_INT_RANDOM_HPP
+#ifndef BOOST_MP_MATH_INTEGER_RANDOM_HPP
+#define BOOST_MP_MATH_INTEGER_RANDOM_HPP
+
+#include <boost/random.hpp>
+#include <boost/mp_math/integer/integer_fwd.hpp>
 
 namespace boost {
 namespace mp_math {
 
-template<class A, class T>
-struct mp_int;
-
-*/
-
 // this class is modeled after boost::uniform_int
 // in fact it uses boost::uniform_int internally
-template<class MpInt = mp_int<> >
-struct uniform_mp_int
+template<class Integer = integer<> >
+struct uniform_integer
 {
-  typedef MpInt input_type;
-  typedef MpInt result_type;
+  typedef Integer input_type;
+  typedef Integer result_type;
 
   // is min() and max() known at compile time?
   static const bool has_fixed_range = false;
 
-  uniform_mp_int(const MpInt& min, const MpInt& max)
+  uniform_integer(const Integer& min, const Integer& max)
   :
     min_(min),
     max_(max),
-    d_(0, MpInt::digit_max)
+    d_(0, Integer::traits_type::max_digit_value)
   {}
 
   result_type min() const { return min_; }
   result_type max() const { return max_; }
 
   void reset() { d_.reset(); }
-  
+
   template<class Engine>
   result_type operator()(Engine& e);
-  
+
 private:
 
-  MpInt min_, max_;
-  uniform_int<typename MpInt::digit_type> d_;
+  Integer min_, max_;
+  uniform_int<typename Integer::digit_type> d_;
 };
 
-template<class MpInt>
-const bool uniform_mp_int<MpInt>::has_fixed_range;
+template<class Integer>
+const bool uniform_integer<Integer>::has_fixed_range;
 
 
-template<class MpInt>
+template<class Integer>
 template<class Engine>
-typename uniform_mp_int<MpInt>::result_type
-uniform_mp_int<MpInt>::operator()(Engine& e)
+typename uniform_integer<Integer>::result_type
+uniform_integer<Integer>::operator()(Engine& e)
 {
   result_type tmp;
-  tmp.grow_capacity(max_.size());
-    
+  tmp.reserve(max_.size());
+
   for (typename result_type::size_type i = 0; i < max_.size(); ++i)
     tmp[i] = d_(e);
-    
+
   tmp.set_size(max_.size());
   tmp.clamp();
-    
+
   if (tmp > max_)
-    tmp %= max_;
+    tmp %= max_; // TODO tmp.truncate(max_.precision()), tmp -= max_!
 
   return tmp;
 }
 
 
-template<class MpInt = mp_int<> >
-struct uniform_mp_int_bits
+template<class Integer = integer<> >
+struct uniform_integer_bits
 {
-  typedef MpInt input_type;
-  typedef MpInt result_type;
+  typedef Integer input_type;
+  typedef Integer result_type;
+  typedef typename Integer::size_type size_type;
 
   static const bool has_fixed_range = false;
 
-  explicit uniform_mp_int_bits(typename MpInt::size_type bits)
+  explicit uniform_integer_bits(size_type bits)
   :
-    d_(0, MpInt::digit_max),
+    d_(0, Integer::traits_type::max_digit_value),
     bits_(bits)
   {}
 
   result_type min() const;
   result_type max() const;
 
-  typename MpInt::size_type precision() const { return bits_; }
+  size_type precision() const { return bits_; }
 
   void reset() { d_.reset(); }
-  
+
   template<class Engine>
   result_type operator()(Engine& e);
-  
+
 private:
 
-  uniform_int<typename MpInt::digit_type> d_;
-  typename MpInt::size_type bits_;
+  uniform_int<typename Integer::digit_type> d_;
+  size_type bits_;
 };
 
-template<class MpInt>
-const bool uniform_mp_int_bits<MpInt>::has_fixed_range;
+template<class Integer>
+const bool uniform_integer_bits<Integer>::has_fixed_range;
 
 
-template<class MpInt>
+template<class Integer>
 template<class Engine>
-typename uniform_mp_int_bits<MpInt>::result_type
-uniform_mp_int_bits<MpInt>::operator()(Engine& e)
+typename uniform_integer_bits<Integer>::result_type
+uniform_integer_bits<Integer>::operator()(Engine& e)
 {
   result_type tmp;
 
-  const typename MpInt::size_type offset = bits_ / MpInt::valid_bits + 1;
+  const size_type offset = bits_ / Integer::traits_type::radix_bits + 1;
 
-  tmp.grow_capacity(offset);
+  tmp.reserve(offset);
 
-  for (typename result_type::size_type i = 0; i < offset; ++i)
+  for (size_type i = 0; i < offset; ++i)
     tmp[i] = d_(e);
-  
+
   tmp.set_size(offset);
 
-  const typename MpInt::digit_type mask =
-      (~typename MpInt::digit_type(0))
-    << (bits_ % MpInt::valid_bits);
+  const typename Integer::digit_type mask =
+      (~typename Integer::digit_type(0))
+    << (bits_ % Integer::traits_type::radix_bits);
 
   tmp[offset-1] &= ~mask;
-  
+
   tmp.set_bit(bits_-1); // make exactly bits_ bits long
-  
+  tmp.clamp_high_digit();
+
   return tmp;
 }
 
-template<class MpInt>
-typename uniform_mp_int_bits<MpInt>::result_type
-uniform_mp_int_bits<MpInt>::min() const
+template<class Integer>
+typename uniform_integer_bits<Integer>::result_type
+uniform_integer_bits<Integer>::min() const
 {
   result_type tmp;
-  
-  const typename MpInt::size_type offset =
-    bits_ / MpInt::valid_bits + 1;
-  
-  tmp.grow_capacity(offset);
-  
+
+  const size_type offset = bits_ / Integer::traits_type::radix_bits + 1;
+
+  tmp.reserve(offset);
+
   std::memset(tmp.digits(), 0,
-      offset * sizeof(typename MpInt::digit_type));
-  
+      offset * sizeof(typename Integer::digit_type));
+
   tmp.set_size(offset);
   tmp.set_bit(bits_ - 1);
-  
+  tmp.clamp_high_digit();
+
   return tmp;
 }
 
-template<class MpInt>
-typename uniform_mp_int_bits<MpInt>::result_type
-uniform_mp_int_bits<MpInt>::max() const
+template<class Integer>
+typename uniform_integer_bits<Integer>::result_type
+uniform_integer_bits<Integer>::max() const
 {
   result_type tmp;
-  const typename MpInt::size_type offset =
-    bits_ / MpInt::valid_bits + 1;
-  
-  tmp.grow_capacity(offset);
-  
-  for (typename result_type::size_type i = 0; i < offset; ++i)
-    tmp[i] = MpInt::digit_max;
-  
+  const typename Integer::size_type offset =
+    bits_ / Integer::traits_type::radix_bits + 1;
+
+  tmp.reserve(offset);
+
+  for (size_type i = 0; i < offset; ++i)
+    tmp[i] = Integer::traits_type::max_digit_value;
+
   tmp.set_size(offset);
 
-  const typename MpInt::digit_type mask =
-      (~typename MpInt::digit_type(0))
-    << (bits_ % MpInt::valid_bits);
+  const typename Integer::digit_type mask =
+      (~typename Integer::digit_type(0))
+    << (bits_ % Integer::traits_type::radix_bits);
 
   tmp[offset-1] &= ~mask;
+  tmp.clamp_high_digit();
 
   return tmp;
 }
 
 
-/*
-} // namespace boost
-} // namespace mp_math
+}
+}
 
 #endif
-*/
+
Deleted: sandbox/mp_math/libs/mp_math/test/unbounded/signed/traits.cpp
==============================================================================
--- sandbox/mp_math/libs/mp_math/test/unbounded/signed/traits.cpp	2009-06-22 15:50:42 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);
-}
-