Test and allow MSVC compiled code to be used with /RTC1 /RTCc etc.

This commit is contained in:
jzmaddock
2016-06-16 13:07:10 +01:00
parent 8f5e26f921
commit c7e29b02ff
7 changed files with 89 additions and 7 deletions

View File

@@ -774,10 +774,10 @@ public:
//
template <class SI>
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
: m_data(i < 0 ? static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask) : static_cast<local_limb_type>(i)& limb_mask), m_sign(i < 0) {}
: m_data(i < 0 ? static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask) : static_cast<local_limb_type>(i & limb_mask)), m_sign(i < 0) {}
template <class SI>
BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
: m_data(i < 0 ? (static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask)) : static_cast<local_limb_type>(i)& limb_mask), m_sign(i < 0)
: m_data(i < 0 ? (static_cast<local_limb_type>(static_cast<typename make_unsigned<SI>::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask)) : static_cast<local_limb_type>(i & limb_mask)), m_sign(i < 0)
{ check_in_range(i); }
template <class UI>
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == unchecked)>::type const* = 0) BOOST_NOEXCEPT
@@ -915,6 +915,20 @@ public:
//
// Direct construction:
//
#ifdef __MSVC_RUNTIME_CHECKS
template <class SI>
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT
: m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i & limb_mask)) & limb_mask : static_cast<local_limb_type>(i & limb_mask)) {}
template <class SI>
BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<SI>())))
: m_data(i < 0 ? 1 + ~static_cast<local_limb_type>(-i & limb_mask) : static_cast<local_limb_type>(i & limb_mask)) { check_in_range(i); }
template <class UI>
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT
: m_data(static_cast<local_limb_type>(i & limb_mask)) {}
template <class UI>
BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
: m_data(static_cast<local_limb_type>(i & limb_mask)) { check_in_range(i); }
#else
template <class SI>
BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c<is_signed<SI>::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT
: m_data(i < 0 ? (1 + ~static_cast<local_limb_type>(-i)) & limb_mask : static_cast<local_limb_type>(i) & limb_mask) {}
@@ -927,6 +941,7 @@ public:
template <class UI>
BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c<is_unsigned<UI>::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval<cpp_int_base>().check_in_range(std::declval<UI>())))
: m_data(static_cast<local_limb_type>(i)) { check_in_range(i); }
#endif
template <class F>
BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if<is_floating_point<F> >::type const* = 0) BOOST_MP_NOEXCEPT_IF((Checked == unchecked))
: m_data(static_cast<local_limb_type>(std::fabs(i)) & limb_mask)
@@ -1208,7 +1223,11 @@ private:
BOOST_STATIC_ASSERT(sizeof(i) == 2 * sizeof(limb_type));
BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2);
typename base_type::limb_pointer p = this->limbs();
#ifdef __MSVC_RUNTIME_CHECKS
*p = static_cast<limb_type>(i & ~static_cast<limb_type>(0));
#else
*p = static_cast<limb_type>(i);
#endif
p[1] = static_cast<limb_type>(i >> base_type::limb_bits);
this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1);
this->sign(false);
@@ -1223,7 +1242,11 @@ private:
s = true;
ui = static_cast<double_limb_type>(boost::multiprecision::detail::unsigned_abs(i));
typename base_type::limb_pointer p = this->limbs();
#ifdef __MSVC_RUNTIME_CHECKS
*p = static_cast<limb_type>(ui & ~static_cast<limb_type>(0));
#else
*p = static_cast<limb_type>(ui);
#endif
p[1] = static_cast<limb_type>(ui >> base_type::limb_bits);
this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1);
this->sign(s);

View File

@@ -49,7 +49,11 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BO
while(pr != pr_end)
{
carry += static_cast<double_limb_type>(*pa) + static_cast<double_limb_type>(*pb);
#ifdef __MSVC_RUNTIME_CHECKS
*pr = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
#else
*pr = static_cast<limb_type>(carry);
#endif
carry >>= CppInt1::limb_bits;
++pr, ++pa, ++pb;
}
@@ -68,7 +72,11 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BO
break;
}
carry += static_cast<double_limb_type>(*pa);
#ifdef __MSVC_RUNTIME_CHECKS
*pr = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
#else
*pr = static_cast<limb_type>(carry);
#endif
carry >>= CppInt1::limb_bits;
++pr, ++pa;
}
@@ -100,7 +108,11 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o)
for(; carry && (i < result.size()); ++i)
{
carry += static_cast<double_limb_type>(pa[i]);
#ifdef __MSVC_RUNTIME_CHECKS
pr[i] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
#else
pr[i] = static_cast<limb_type>(carry);
#endif
carry >>= CppInt1::limb_bits;
}
// Just copy any remaining digits:

View File

@@ -227,12 +227,20 @@ void divide_unsigned_helper(
for(unsigned i = 0; i < y.size(); ++i)
{
carry += static_cast<double_limb_type>(py[i]) * static_cast<double_limb_type>(guess);
#ifdef __MSVC_RUNTIME_CHECKS
pt[i + shift] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
#else
pt[i + shift] = static_cast<limb_type>(carry);
#endif
carry >>= CppInt1::limb_bits;
}
if(carry && !truncated_t)
{
#ifdef __MSVC_RUNTIME_CHECKS
pt[t.size() - 1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
#else
pt[t.size() - 1] = static_cast<limb_type>(carry);
#endif
}
else if(!truncated_t)
{

View File

@@ -20,7 +20,7 @@ namespace boost {
limb_type mask = chunk_bits >= sizeof(limb_type) * CHAR_BIT ? ~static_cast<limb_type>(0u) : (static_cast<limb_type>(1u) << chunk_bits) - 1;
limb_type value = (static_cast<limb_type>(bits) & mask) << shift;
limb_type value = static_cast<limb_type>(bits & mask) << shift;
if(value)
{
if(val.size() == limb)
@@ -132,7 +132,7 @@ namespace boost {
if(byte_len % sizeof(limb_type))
++limb_len;
cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& result = val.backend();
result.resize(limb_len, limb_len); // checked types may throw here if they're not large enough to hold the data!
result.resize(static_cast<unsigned>(limb_len), static_cast<unsigned>(limb_len)); // checked types may throw here if they're not large enough to hold the data!
result.limbs()[result.size() - 1] = 0u;
std::memcpy(result.limbs(), i, std::min(byte_len, result.size() * sizeof(limb_type)));
result.normalize(); // In case data has leading zeros.
@@ -149,7 +149,7 @@ namespace boost {
if(byte_len % sizeof(result.limbs()[0]))
++limb_len;
result.limbs()[0] = 0u;
result.resize(limb_len, limb_len); // checked types may throw here if they're not large enough to hold the data!
result.resize(static_cast<unsigned>(limb_len), static_cast<unsigned>(limb_len)); // checked types may throw here if they're not large enough to hold the data!
std::memcpy(result.limbs(), i, std::min(byte_len, result.size() * sizeof(result.limbs()[0])));
result.normalize(); // In case data has leading zeros.
return val;

View File

@@ -326,7 +326,11 @@ inline double_limb_type integer_gcd_reduce(double_limb_type u, double_limb_type
break;
}
v -= u;
#ifdef __MSVC_RUNTIME_CHECKS
while((v & 1u) == 0)
#else
while((static_cast<unsigned>(v) & 1u) == 0)
#endif
v >>= 1;
} while(true);
return u;

View File

@@ -36,7 +36,11 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
while(p != pe)
{
carry += static_cast<double_limb_type>(*pa) * static_cast<double_limb_type>(val);
#ifdef __MSVC_RUNTIME_CHECKS
*p = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
#else
*p = static_cast<limb_type>(carry);
#endif
carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
++p, ++pa;
}
@@ -144,7 +148,11 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
carry += static_cast<double_limb_type>(pa[i]) * static_cast<double_limb_type>(pb[j]);
BOOST_ASSERT(!std::numeric_limits<double_limb_type>::is_specialized || ((std::numeric_limits<double_limb_type>::max)() - carry >= pr[i+j]));
carry += pr[i + j];
#ifdef __MSVC_RUNTIME_CHECKS
pr[i + j] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
#else
pr[i + j] = static_cast<limb_type>(carry);
#endif
carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
BOOST_ASSERT(carry <= (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value));
}
@@ -353,6 +361,16 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
limb_type* pr = result.limbs();
double_limb_type carry = w * y;
#ifdef __MSVC_RUNTIME_CHECKS
pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
carry += w * z + x * y;
pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
carry += x * z;
pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
pr[3] = static_cast<limb_type>(carry >> limb_bits);
#else
pr[0] = static_cast<limb_type>(carry);
carry >>= limb_bits;
carry += w * z + x * y;
@@ -361,7 +379,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
carry += x * z;
pr[2] = static_cast<limb_type>(carry);
pr[3] = static_cast<limb_type>(carry >> limb_bits);
#endif
result.sign(s);
result.normalize();
}
@@ -387,6 +405,20 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
limb_type* pr = result.limbs();
double_limb_type carry = w * y;
#ifdef __MSVC_RUNTIME_CHECKS
pr[0] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
carry += w * z;
pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry = x * y + pr[1];
pr[1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
carry >>= limb_bits;
carry += pr[2] + x * z;
pr[2] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
pr[3] = static_cast<limb_type>(carry >> limb_bits);
#else
pr[0] = static_cast<limb_type>(carry);
carry >>= limb_bits;
carry += w * z;
@@ -399,7 +431,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<
carry += pr[2] + x * z;
pr[2] = static_cast<limb_type>(carry);
pr[3] = static_cast<limb_type>(carry >> limb_bits);
#endif
result.sign(false);
result.normalize();
}

View File

@@ -36,6 +36,9 @@ project : requirements
<toolset>gcc:<cxxflags>-Wall
<toolset>gcc:<cxxflags>-Wextra
<toolset>intel:<define>SLOW_COMPILER
<toolset>msvc,<optimization>off:<cxxflags>-RTC1
<toolset>msvc,<optimization>off:<cxxflags>-RTCc
<toolset>msvc,<optimization>off:<define>_ALLOW_RTCc_IN_STL
;
local enable-specfun = [ MATCH (--enable-specfun) : [ modules.peek : ARGV ] ] ;