#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/detail/bitscan.hpp>
-namespace boost{
-namespace multiprecision{
+namespace boost {
+namespace multiprecision {
template <class Integer, class I2>
-typename enable_if_c<is_integral<Integer>::value && is_integral<I2>::value, Integer&>::type
- multiply(Integer& result, const I2& a, const I2& b)
+inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value && is_integral<I2>::value, Integer&>::type
+multiply(Integer& result, const I2& a, const I2& b)
{
return result = static_cast<Integer>(a) * static_cast<Integer>(b);
}
template <class Integer, class I2>
-typename enable_if_c<is_integral<Integer>::value && is_integral<I2>::value, Integer&>::type
- add(Integer& result, const I2& a, const I2& b)
+inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value && is_integral<I2>::value, Integer&>::type
+add(Integer& result, const I2& a, const I2& b)
{
return result = static_cast<Integer>(a) + static_cast<Integer>(b);
}
template <class Integer, class I2>
-typename enable_if_c<is_integral<Integer>::value && is_integral<I2>::value, Integer&>::type
- subtract(Integer& result, const I2& a, const I2& b)
+inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value && is_integral<I2>::value, Integer&>::type
+subtract(Integer& result, const I2& a, const I2& b)
{
return result = static_cast<Integer>(a) - static_cast<Integer>(b);
}
template <class Integer>
-typename enable_if_c<is_integral<Integer>::value>::type divide_qr(const Integer& x, const Integer& y, Integer& q, Integer& r)
+inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value>::type divide_qr(const Integer& x, const Integer& y, Integer& q, Integer& r)
{
q = x / y;
r = x % y;
}
template <class I1, class I2>
-typename enable_if_c<is_integral<I1>::value && is_integral<I2>::value, I2>::type integer_modulus(const I1& x, I2 val)
+inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<I1>::value && is_integral<I2>::value, I2>::type integer_modulus(const I1& x, I2 val)
{
return static_cast<I2>(x % val);
}
-namespace detail{
+namespace detail {
//
// Figure out the kind of integer that has twice as many bits as some builtin
// integer type I. Use a native type if we can (including types which may not
struct double_integer
{
static const unsigned int_t_digits =
- 2 * sizeof(I) <= sizeof(boost::long_long_type) ? std::numeric_limits<I>::digits * 2 : 1;
+ 2 * sizeof(I) <= sizeof(boost::long_long_type) ? std::numeric_limits<I>::digits * 2 : 1;
typedef typename mpl::if_c<
- 2 * sizeof(I) <= sizeof(boost::long_long_type),
- typename mpl::if_c<
- is_signed<I>::value,
- typename boost::int_t<int_t_digits>::least,
- typename boost::uint_t<int_t_digits>::least
- >::type,
- typename mpl::if_c<
- 2 * sizeof(I) <= sizeof(double_limb_type),
- typename mpl::if_c<
- is_signed<I>::value,
- signed_double_limb_type,
- double_limb_type
- >::type,
- number<cpp_int_backend<sizeof(I)*CHAR_BIT*2, sizeof(I)*CHAR_BIT*2, (is_signed<I>::value ? signed_magnitude : unsigned_magnitude), unchecked, void> >
- >::type
- >::type type;
+ 2 * sizeof(I) <= sizeof(boost::long_long_type),
+ typename mpl::if_c<
+ is_signed<I>::value,
+ typename boost::int_t<int_t_digits>::least,
+ typename boost::uint_t<int_t_digits>::least>::type,
+ typename mpl::if_c<
+ 2 * sizeof(I) <= sizeof(double_limb_type),
+ typename mpl::if_c<
+ is_signed<I>::value,
+ signed_double_limb_type,
+ double_limb_type>::type,
+ number<cpp_int_backend<sizeof(I) * CHAR_BIT * 2, sizeof(I) * CHAR_BIT * 2, (is_signed<I>::value ? signed_magnitude : unsigned_magnitude), unchecked, void> > >::type>::type type;
};
-}
+} // namespace detail
template <class I1, class I2, class I3>
-typename enable_if_c<is_integral<I1>::value && is_unsigned<I2>::value && is_integral<I3>::value, I1>::type
- powm(const I1& a, I2 b, I3 c)
+BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<I1>::value && is_unsigned<I2>::value && is_integral<I3>::value, I1>::type
+powm(const I1& a, I2 b, I3 c)
{
typedef typename detail::double_integer<I1>::type double_type;
- I1 x(1), y(a);
- double_type result;
+ I1 x(1), y(a);
+ double_type result(0);
- while(b > 0)
+ while (b > 0)
{
- if(b & 1)
+ if (b & 1)
{
multiply(result, x, y);
x = integer_modulus(result, c);
}
template <class I1, class I2, class I3>
-inline typename enable_if_c<is_integral<I1>::value && is_signed<I2>::value && is_integral<I3>::value, I1>::type
- powm(const I1& a, I2 b, I3 c)
+inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<I1>::value && is_signed<I2>::value && is_integral<I3>::value, I1>::type
+powm(const I1& a, I2 b, I3 c)
{
- if(b < 0)
+ if (b < 0)
{
BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
}
}
template <class Integer>
-typename enable_if_c<is_integral<Integer>::value, unsigned>::type lsb(const Integer& val)
+BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value, unsigned>::type lsb(const Integer& val)
{
- if(val <= 0)
+ if (val <= 0)
{
- if(val == 0)
+ if (val == 0)
{
BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
}
}
template <class Integer>
-typename enable_if_c<is_integral<Integer>::value, unsigned>::type msb(Integer val)
+BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value, unsigned>::type msb(Integer val)
{
- if(val <= 0)
+ if (val <= 0)
{
- if(val == 0)
+ if (val == 0)
{
BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
}
}
template <class Integer>
-typename enable_if_c<is_integral<Integer>::value, bool>::type bit_test(const Integer& val, unsigned index)
+BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value, bool>::type bit_test(const Integer& val, unsigned index)
{
Integer mask = 1;
- if(index >= sizeof(Integer) * CHAR_BIT)
+ if (index >= sizeof(Integer) * CHAR_BIT)
return 0;
- if(index)
+ if (index)
mask <<= index;
return val & mask ? true : false;
}
template <class Integer>
-typename enable_if_c<is_integral<Integer>::value, Integer&>::type bit_set(Integer& val, unsigned index)
+BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value, Integer&>::type bit_set(Integer& val, unsigned index)
{
Integer mask = 1;
- if(index >= sizeof(Integer) * CHAR_BIT)
+ if (index >= sizeof(Integer) * CHAR_BIT)
return val;
- if(index)
+ if (index)
mask <<= index;
val |= mask;
return val;
}
template <class Integer>
-typename enable_if_c<is_integral<Integer>::value, Integer&>::type bit_unset(Integer& val, unsigned index)
+BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value, Integer&>::type bit_unset(Integer& val, unsigned index)
{
Integer mask = 1;
- if(index >= sizeof(Integer) * CHAR_BIT)
+ if (index >= sizeof(Integer) * CHAR_BIT)
return val;
- if(index)
+ if (index)
mask <<= index;
val &= ~mask;
return val;
}
template <class Integer>
-typename enable_if_c<is_integral<Integer>::value, Integer&>::type bit_flip(Integer& val, unsigned index)
+BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value, Integer&>::type bit_flip(Integer& val, unsigned index)
{
Integer mask = 1;
- if(index >= sizeof(Integer) * CHAR_BIT)
+ if (index >= sizeof(Integer) * CHAR_BIT)
return val;
- if(index)
+ if (index)
mask <<= index;
val ^= mask;
return val;
}
template <class Integer>
-typename enable_if_c<is_integral<Integer>::value, Integer>::type sqrt(const Integer& x, Integer& r)
+BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value, Integer>::type sqrt(const Integer& x, Integer& r)
{
//
// This is slow bit-by-bit integer square root, see for example
// at some point.
//
Integer s = 0;
- if(x == 0)
+ if (x == 0)
{
r = 0;
return s;
}
int g = msb(x);
- if(g == 0)
+ if (g == 0)
{
r = 1;
return s;
}
-
+
Integer t = 0;
- r = x;
+ r = x;
g /= 2;
bit_set(s, g);
bit_set(t, 2 * g);
t = s;
t <<= g + 1;
bit_set(t, 2 * g);
- if(t <= r)
+ if (t <= r)
{
bit_set(s, g);
r -= t;
}
--g;
- }
- while(g >= 0);
+ } while (g >= 0);
return s;
}
template <class Integer>
-typename enable_if_c<is_integral<Integer>::value, Integer>::type sqrt(const Integer& x)
+BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<is_integral<Integer>::value, Integer>::type sqrt(const Integer& x)
{
- Integer r;
+ Integer r(0);
return sqrt(x, r);
}
-}} // namespaces
+}} // namespace boost::multiprecision
#endif