$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r80120 - in sandbox/big_number: boost/multiprecision libs/multiprecision/test
From: john_at_[hidden]
Date: 2012-08-21 14:17:58
Author: johnmaddock
Date: 2012-08-21 14:17:57 EDT (Tue, 21 Aug 2012)
New Revision: 80120
URL: http://svn.boost.org/trac/boost/changeset/80120
Log:
Fix rational_adapter's implicit/explicit constructors.
Add converting constructors for trivial cpp_int's and test.
Both fix GCC errors.
Text files modified: 
   sandbox/big_number/boost/multiprecision/cpp_int.hpp               |    61 ++++++++++++++++++++++++++++++++++++++++
   sandbox/big_number/boost/multiprecision/rational_adapter.hpp      |    27 +++++++++++++++++                       
   sandbox/big_number/libs/multiprecision/test/test_cpp_int_conv.cpp |     3 +                                       
   3 files changed, 91 insertions(+), 0 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-08-21 14:17:57 EDT (Tue, 21 Aug 2012)
@@ -1148,6 +1148,67 @@
       this->sign(i < 0);
       return *this;
    }
+
+   template <unsigned MinBits2, bool Signed2, class Allocator2>
+   cpp_int_backend(const cpp_int_backend<MinBits2, Signed2, Allocator2, true>& other, 
+      typename enable_if_c<
+         (sizeof(cpp_int_backend<MinBits2, Signed2, Allocator2, true>::local_limb_type) <= sizeof(typename cpp_int_backend::local_limb_type))
+         && (Signed || !Signed2)
+      >::type* = 0) 
+      : base_type()
+   {
+       *this = static_cast<
+            typename boost::multiprecision::detail::canonical<
+               typename cpp_int_backend<MinBits2, Signed2, Allocator2, true>::local_limb_type, 
+               cpp_int_backend<MinBits, Signed, void, true> 
+            >::type
+         >(*other.limbs());
+      this->sign(other.sign());
+   }
+   template <unsigned MinBits2, bool Signed2, class Allocator2>
+   explicit cpp_int_backend(const cpp_int_backend<MinBits2, Signed2, Allocator2, true>& other, 
+      typename disable_if_c<
+         (sizeof(cpp_int_backend<MinBits2, Signed2, Allocator2, true>::local_limb_type) <= sizeof(typename cpp_int_backend::local_limb_type))
+         && (Signed || !Signed2)
+      >::type* = 0) 
+      : base_type()
+   {
+       *this = static_cast<
+            typename boost::multiprecision::detail::canonical<
+               typename cpp_int_backend<MinBits2, Signed2, Allocator2, true>::local_limb_type, 
+               cpp_int_backend<MinBits, Signed, void, true> 
+            >::type
+         >(*other.limbs());
+      this->sign(other.sign());
+   }
+   template <unsigned MinBits2, bool Signed2, class Allocator2>
+   cpp_int_backend& operator = (const cpp_int_backend<MinBits2, Signed2, Allocator2, true>& other) 
+   {
+       *this = static_cast<
+            typename boost::multiprecision::detail::canonical<
+               typename cpp_int_backend<MinBits2, Signed2, Allocator2, true>::local_limb_type, 
+               cpp_int_backend<MinBits, Signed, void, true> 
+            >::type
+         >(*other.limbs());
+      this->sign(other.sign());
+      return *this;
+   }
+   template <unsigned MinBits2, bool Signed2, class Allocator2>
+   explicit cpp_int_backend(const cpp_int_backend<MinBits2, Signed2, Allocator2, false>& other) 
+      : base_type()
+   {
+      // We can only ever copy two limbs from other:
+      if(other.size() == 1)
+      {
+         *this->limbs() = *other.limbs();
+      }
+      else
+      {
+         *this->limbs() = static_cast<double_limb_type>(*other.limbs()) | (static_cast<double_limb_type>(other.limbs()[1]) << (sizeof(limb_type) * CHAR_BIT));
+      }
+      this->sign(other.sign());
+   }
+
    cpp_int_backend& operator = (const char* s)
    {
       try{
Modified: sandbox/big_number/boost/multiprecision/rational_adapter.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/rational_adapter.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/rational_adapter.hpp	2012-08-21 14:17:57 EDT (Tue, 21 Aug 2012)
@@ -34,6 +34,22 @@
       m_value = o.m_value;
    }
    rational_adapter(const IntBackend& o) : m_value(o) {}
+
+   template <class U>
+   rational_adapter(const U& u, typename enable_if_c<is_convertible<U, IntBackend>::value>::type* = 0) 
+      : m_value(IntBackend(u)){}
+   template <class U>
+   explicit rational_adapter(const U& u, 
+      typename enable_if_c<
+         detail::is_explicitly_convertible<U, IntBackend>::value && !is_convertible<U, IntBackend>::value
+      >::type* = 0) 
+      : m_value(IntBackend(u)){}
+   template <class U>
+   typename enable_if_c<(detail::is_explicitly_convertible<U, IntBackend>::value && !is_arithmetic<U>::value), rational_adapter&>::type operator = (const U& u) 
+   {
+      m_value = IntBackend(u);
+   }
+
 #ifndef BOOST_NO_RVALUE_REFERENCES
    rational_adapter(rational_adapter&& o) : m_value(o.m_value) {}
    rational_adapter(IntBackend&& o) : m_value(o) {}
@@ -227,6 +243,17 @@
    typedef number<T> type;
 };
 
+#ifdef BOOST_NO_SFINAE_EXPR
+
+namespace detail{
+
+template<class U, class IntBackend>
+struct is_explicitly_convertible<U, rational_adapter<IntBackend> > : public is_explicitly_convertible<U, IntBackend> {};
+
+}
+
+#endif
+
 }} // namespaces
 
 
Modified: sandbox/big_number/libs/multiprecision/test/test_cpp_int_conv.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_cpp_int_conv.cpp	(original)
+++ sandbox/big_number/libs/multiprecision/test/test_cpp_int_conv.cpp	2012-08-21 14:17:57 EDT (Tue, 21 Aug 2012)
@@ -48,6 +48,9 @@
    int128_t   i6(i4);
    BOOST_TEST(i6 == -5677334);
 
+   number<cpp_int_backend<32, true, void>, false> i7(i3);
+   BOOST_TEST(i7 == -1234567);
+
    return boost::report_errors();
 }