Boost logo

Boost-Commit :

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();
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk