$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r79700 - in sandbox/big_number/boost/multiprecision: . detail
From: john_at_[hidden]
Date: 2012-07-23 13:47:45
Author: johnmaddock
Date: 2012-07-23 13:47:44 EDT (Mon, 23 Jul 2012)
New Revision: 79700
URL: http://svn.boost.org/trac/boost/changeset/79700
Log:
Fix Linux x64 failures.
Text files modified: 
   sandbox/big_number/boost/multiprecision/cpp_int.hpp                    |   110 ++++++++++++++++++++++++++++++++++++--- 
   sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp        |     3 +                                       
   sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp |     2                                         
   3 files changed, 105 insertions(+), 10 deletions(-)
Modified: sandbox/big_number/boost/multiprecision/cpp_int.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_int.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/cpp_int.hpp	2012-07-23 13:47:44 EDT (Mon, 23 Jul 2012)
@@ -425,16 +425,21 @@
    }
 };
 
+template <unsigned N, bool s>
+struct trivial_limb_type_imp
+{
+   typedef double_limb_type type;
+};
+
 template <unsigned N>
-struct trivial_limb_type
+struct trivial_limb_type_imp<N, true>
 {
-   typedef typename mpl::if_c<
-      N <= sizeof(long long) * CHAR_BIT,
-      typename boost::uint_t<N>::least,
-      double_limb_type
-   >::type type;
+   typedef typename boost::uint_t<N>::least type;
 };
 
+template <unsigned N>
+struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(long long) * CHAR_BIT> {};
+
 #ifdef BOOST_MSVC
 #pragma warning(push)
 #pragma warning(disable:4244) // loss of data in initialization
@@ -446,10 +451,10 @@
    typedef typename trivial_limb_type<MinBits>::type  local_limb_type;
    typedef local_limb_type*                           limb_pointer;
    typedef const local_limb_type*                     const_limb_pointer;
-private:
+protected:
    BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(local_limb_type) * CHAR_BIT);
    BOOST_STATIC_CONSTANT(local_limb_type, limb_mask = MinBits < limb_bits ? (local_limb_type(1) << MinBits) -1 : (~local_limb_type(0)));
-
+private:
    local_limb_type    m_data;
    bool               m_sign;
 
@@ -1058,7 +1063,8 @@
    {
       this->do_swap(o);
    }
-   std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
+private:
+   std::string str(std::ios_base::fmtflags f, const mpl::false_&)const
    {
       std::stringstream ss;
       ss.flags(f);
@@ -1069,6 +1075,92 @@
       result += ss.str();
       return result;
    }
+   std::string str(std::ios_base::fmtflags f, const mpl::true_&)const
+   {
+      // Even though we have only one limb, we can't do IO on it :-(
+      int base = 10;
+      if((f & std::ios_base::oct) == std::ios_base::oct)
+         base = 8;
+      else if((f & std::ios_base::hex) == std::ios_base::hex)
+         base = 16;
+      std::string result;
+
+      unsigned Bits = base_type::limb_bits;
+
+      if(base == 8 || base == 16)
+      {
+         if(this->sign())
+            BOOST_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
+         limb_type shift = base == 8 ? 3 : 4;
+         limb_type mask = static_cast<limb_type>((1u << shift) - 1);
+         typename base_type::local_limb_type v = *this->limbs();
+         result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0');
+         int pos = result.size() - 1;
+         for(unsigned i = 0; i < Bits / shift; ++i)
+         {
+            char c = '0' + static_cast<char>(v & mask);
+            if(c > '9')
+               c += 'A' - '9' - 1;
+            result[pos--] = c;
+            v >>= shift;
+         }
+         if(Bits % shift)
+         {
+            mask = static_cast<limb_type>((1u << (Bits % shift)) - 1);
+            char c = '0' + static_cast<char>(v & mask);
+            if(c > '9')
+               c += 'A' - '9';
+            result[pos] = c;
+         }
+         //
+         // Get rid of leading zeros:
+         //
+         std::string::size_type n = result.find_first_not_of('0');
+         if(!result.empty() && (n == std::string::npos))
+            n = result.size() - 1;
+         result.erase(0, n);
+         if(f & std::ios_base::showbase)
+         {
+            const char* pp = base == 8 ? "0" : "0x";
+            result.insert(0, pp);
+         }
+      }
+      else
+      {
+         result.assign(Bits / 3 + 1, '0');
+         int pos = result.size() - 1;
+         typename base_type::local_limb_type v(*this->limbs());
+         bool neg = false;
+         if(this->sign())
+         {
+            neg = true;
+         }
+         while(v)
+         {
+            result[pos] = (v % 10) + '0';
+            --pos;
+            v /= 10;
+         }
+         unsigned n = result.find_first_not_of('0');
+         result.erase(0, n);
+         if(result.empty())
+            result = "0";
+         if(neg)
+            result.insert(0, 1, '-');
+         else if(f & std::ios_base::showpos)
+            result.insert(0, 1, '+');
+      }
+      return result;
+   }
+public:
+   std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
+   {
+#ifdef BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
+      return str(f, mpl::bool_<is_same<typename base_type::local_limb_type, double_limb_type>::value>());
+#else
+      return str(f, mpl::bool_<false>());
+#endif
+   }
    int compare(const cpp_int_backend& o)const BOOST_NOEXCEPT
    {
       if(this->sign() != o.sign())
Modified: sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp	2012-07-23 13:47:44 EDT (Mon, 23 Jul 2012)
@@ -76,6 +76,9 @@
    return values[count];
 }
 
+// Can't do formatted IO on an __int128
+#define BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
+
 #else
 
 typedef detail::largest_unsigned_type<32>::type limb_type;
Modified: sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp	2012-07-23 13:47:44 EDT (Mon, 23 Jul 2012)
@@ -159,7 +159,7 @@
    }
    a |= b;
    bool isneg = false;
-   static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
+   static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (sizeof(typename cpp_int_backend<MinBits, true, void, true>::local_limb_type) * CHAR_BIT - 1);
    if(a & mask)
    {
       a = ~a;