update boost on linux
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
#ifndef BOOST_MP_DETAIL_BITSCAN_HPP
|
||||
#define BOOST_MP_DETAIL_BITSCAN_HPP
|
||||
|
||||
#include <boost/detail/endian.hpp>
|
||||
#include <boost/predef/other/endian.h>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#if (defined(BOOST_MSVC) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#include <intrin.h>
|
||||
@@ -143,11 +144,14 @@ BOOST_FORCEINLINE unsigned find_msb(boost::ulong_long_type mask, mpl::int_<3> co
|
||||
return sizeof(boost::ulong_long_type) * CHAR_BIT - 1 - __builtin_clzll(mask);
|
||||
}
|
||||
#ifdef BOOST_HAS_INT128
|
||||
BOOST_FORCEINLINE unsigned find_msb(unsigned __int128 mask, mpl::int_<0> const&)
|
||||
|
||||
__extension__ typedef unsigned __int128 uint128_type;
|
||||
|
||||
BOOST_FORCEINLINE unsigned find_msb(uint128_type mask, mpl::int_<0> const&)
|
||||
{
|
||||
union { unsigned __int128 v; boost::uint64_t sv[2]; } val;
|
||||
union { uint128_type v; boost::uint64_t sv[2]; } val;
|
||||
val.v = mask;
|
||||
#ifdef BOOST_LITTLE_ENDIAN
|
||||
#if BOOST_ENDIAN_LITTLE_BYTE
|
||||
if(val.sv[1])
|
||||
return find_msb(val.sv[1], mpl::int_<3>()) + 64;
|
||||
return find_msb(val.sv[0], mpl::int_<3>());
|
||||
@@ -157,11 +161,11 @@ BOOST_FORCEINLINE unsigned find_msb(unsigned __int128 mask, mpl::int_<0> const&)
|
||||
return find_msb(val.sv[1], mpl::int_<3>());
|
||||
#endif
|
||||
}
|
||||
BOOST_FORCEINLINE unsigned find_lsb(unsigned __int128 mask, mpl::int_<0> const&)
|
||||
BOOST_FORCEINLINE unsigned find_lsb(uint128_type mask, mpl::int_<0> const&)
|
||||
{
|
||||
union { unsigned __int128 v; boost::uint64_t sv[2]; } val;
|
||||
union { uint128_type v; boost::uint64_t sv[2]; } val;
|
||||
val.v = mask;
|
||||
#ifdef BOOST_LITTLE_ENDIAN
|
||||
#if BOOST_ENDIAN_LITTLE_BYTE
|
||||
if(val.sv[0] == 0)
|
||||
return find_lsb(val.sv[1], mpl::int_<3>()) + 64;
|
||||
return find_lsb(val.sv[0], mpl::int_<3>());
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -242,38 +242,45 @@ template <class T>
|
||||
const T& get_constant_ln2()
|
||||
{
|
||||
static BOOST_MP_THREAD_LOCAL T result;
|
||||
static BOOST_MP_THREAD_LOCAL long digits = 0;
|
||||
#ifndef BOOST_MP_USING_THREAD_LOCAL
|
||||
static BOOST_MP_THREAD_LOCAL bool b = false;
|
||||
static BOOST_MP_THREAD_LOCAL long digits = boost::multiprecision::detail::digits2<number<T> >::value();
|
||||
constant_initializer<T, &get_constant_ln2<T> >::do_nothing();
|
||||
|
||||
if(!b || (digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
calc_log2(result, boost::multiprecision::detail::digits2<number<T, et_on> >::value());
|
||||
b = true;
|
||||
#else
|
||||
if ((digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
#endif
|
||||
calc_log2(result, boost::multiprecision::detail::digits2<number<T, et_on> >::value());
|
||||
digits = boost::multiprecision::detail::digits2<number<T> >::value();
|
||||
}
|
||||
|
||||
constant_initializer<T, &get_constant_ln2<T> >::do_nothing();
|
||||
|
||||
return result;
|
||||
}
|
||||
#ifndef BOOST_MP_THREAD_LOCAL
|
||||
#error 1
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
const T& get_constant_e()
|
||||
{
|
||||
static BOOST_MP_THREAD_LOCAL T result;
|
||||
static BOOST_MP_THREAD_LOCAL long digits = 0;
|
||||
#ifndef BOOST_MP_USING_THREAD_LOCAL
|
||||
static BOOST_MP_THREAD_LOCAL bool b = false;
|
||||
static BOOST_MP_THREAD_LOCAL long digits = boost::multiprecision::detail::digits2<number<T> >::value();
|
||||
if(!b || (digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
constant_initializer<T, &get_constant_e<T> >::do_nothing();
|
||||
|
||||
if (!b || (digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
calc_e(result, boost::multiprecision::detail::digits2<number<T, et_on> >::value());
|
||||
b = true;
|
||||
#else
|
||||
if ((digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
#endif
|
||||
calc_e(result, boost::multiprecision::detail::digits2<number<T, et_on> >::value());
|
||||
digits = boost::multiprecision::detail::digits2<number<T> >::value();
|
||||
}
|
||||
|
||||
constant_initializer<T, &get_constant_e<T> >::do_nothing();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -281,17 +288,46 @@ template <class T>
|
||||
const T& get_constant_pi()
|
||||
{
|
||||
static BOOST_MP_THREAD_LOCAL T result;
|
||||
static BOOST_MP_THREAD_LOCAL long digits = 0;
|
||||
#ifndef BOOST_MP_USING_THREAD_LOCAL
|
||||
static BOOST_MP_THREAD_LOCAL bool b = false;
|
||||
static BOOST_MP_THREAD_LOCAL long digits = boost::multiprecision::detail::digits2<number<T> >::value();
|
||||
if(!b || (digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
constant_initializer<T, &get_constant_pi<T> >::do_nothing();
|
||||
|
||||
if (!b || (digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
calc_pi(result, boost::multiprecision::detail::digits2<number<T, et_on> >::value());
|
||||
b = true;
|
||||
#else
|
||||
if ((digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
#endif
|
||||
calc_pi(result, boost::multiprecision::detail::digits2<number<T, et_on> >::value());
|
||||
digits = boost::multiprecision::detail::digits2<number<T> >::value();
|
||||
}
|
||||
|
||||
constant_initializer<T, &get_constant_pi<T> >::do_nothing();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& get_constant_one_over_epsilon()
|
||||
{
|
||||
static BOOST_MP_THREAD_LOCAL T result;
|
||||
static BOOST_MP_THREAD_LOCAL long digits = 0;
|
||||
#ifndef BOOST_MP_USING_THREAD_LOCAL
|
||||
static BOOST_MP_THREAD_LOCAL bool b = false;
|
||||
constant_initializer<T, &get_constant_one_over_epsilon<T> >::do_nothing();
|
||||
|
||||
if (!b || (digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
b = true;
|
||||
#else
|
||||
if ((digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
#endif
|
||||
typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
|
||||
result = static_cast<ui_type>(1u);
|
||||
eval_divide(result, std::numeric_limits<number<T> >::epsilon().backend());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ inline void pow_imp(T& result, const T& t, const U& p, const mpl::true_&)
|
||||
} // namespace detail
|
||||
|
||||
template<typename T, typename U>
|
||||
inline typename enable_if<is_integral<U> >::type eval_pow(T& result, const T& t, const U& p)
|
||||
inline typename enable_if_c<is_integral<U>::value>::type eval_pow(T& result, const T& t, const U& p)
|
||||
{
|
||||
detail::pow_imp(result, t, p, boost::is_signed<U>());
|
||||
}
|
||||
@@ -303,6 +303,16 @@ void eval_exp(T& result, const T& x)
|
||||
exp_type n;
|
||||
eval_convert_to(&n, result);
|
||||
|
||||
if (n == (std::numeric_limits<exp_type>::max)())
|
||||
{
|
||||
// Exponent is too large to fit in our exponent type:
|
||||
if (isneg)
|
||||
result = ui_type(0);
|
||||
else
|
||||
result = std::numeric_limits<number<T> >::has_infinity ? std::numeric_limits<number<T> >::infinity().backend() : (std::numeric_limits<number<T> >::max)().backend();
|
||||
return;
|
||||
}
|
||||
|
||||
// The scaling is 2^11 = 2048.
|
||||
const si_type p2 = static_cast<si_type>(si_type(1) << 11);
|
||||
|
||||
@@ -414,20 +424,25 @@ template <class T>
|
||||
const T& get_constant_log10()
|
||||
{
|
||||
static BOOST_MP_THREAD_LOCAL T result;
|
||||
static BOOST_MP_THREAD_LOCAL long digits = 0;
|
||||
#ifndef BOOST_MP_USING_THREAD_LOCAL
|
||||
static BOOST_MP_THREAD_LOCAL bool b = false;
|
||||
static BOOST_MP_THREAD_LOCAL long digits = boost::multiprecision::detail::digits2<number<T> >::value();
|
||||
if(!b || (digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
constant_initializer<T, &get_constant_log10<T> >::do_nothing();
|
||||
|
||||
if (!b || (digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
b = true;
|
||||
#else
|
||||
if ((digits != boost::multiprecision::detail::digits2<number<T> >::value()))
|
||||
{
|
||||
#endif
|
||||
typedef typename boost::multiprecision::detail::canonical<unsigned, T>::type ui_type;
|
||||
T ten;
|
||||
ten = ui_type(10u);
|
||||
eval_log(result, ten);
|
||||
b = true;
|
||||
digits = boost::multiprecision::detail::digits2<number<T> >::value();
|
||||
}
|
||||
|
||||
constant_initializer<T, &get_constant_log10<T> >::do_nothing();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -522,6 +537,7 @@ inline void eval_pow(T& result, const T& x, const T& a)
|
||||
{
|
||||
// fallthrough..
|
||||
}
|
||||
BOOST_FALLTHROUGH;
|
||||
}
|
||||
default:
|
||||
if(eval_signbit(a))
|
||||
@@ -705,7 +721,12 @@ inline void eval_pow(T& result, const T& x, const T& a)
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename enable_if<is_floating_point<A>, void>::type eval_pow(T& result, const T& x, const A& a)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1800)
|
||||
inline typename enable_if_c<!is_integral<A>::value, void>::type
|
||||
#else
|
||||
inline typename enable_if_c<is_compatible_arithmetic_type<A, number<T> >::value && !is_integral<A>::value, void>::type
|
||||
#endif
|
||||
eval_pow(T& result, const T& x, const A& a)
|
||||
{
|
||||
// Note this one is restricted to float arguments since pow.hpp already has a version for
|
||||
// integer powers....
|
||||
@@ -717,7 +738,12 @@ inline typename enable_if<is_floating_point<A>, void>::type eval_pow(T& result,
|
||||
}
|
||||
|
||||
template<class T, class A>
|
||||
inline typename enable_if<is_arithmetic<A>, void>::type eval_pow(T& result, const A& x, const T& a)
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1800)
|
||||
inline void
|
||||
#else
|
||||
inline typename enable_if_c<is_compatible_arithmetic_type<A, number<T> >::value, void>::type
|
||||
#endif
|
||||
eval_pow(T& result, const A& x, const T& a)
|
||||
{
|
||||
typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
|
||||
typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
|
||||
|
||||
@@ -128,7 +128,13 @@ void eval_sin(T& result, const T& x)
|
||||
eval_fmod(t, n_pi, t);
|
||||
const bool b_n_pi_is_even = eval_get_sign(t) == 0;
|
||||
eval_multiply(n_pi, get_constant_pi<T>());
|
||||
eval_subtract(xx, n_pi);
|
||||
if (n_pi.compare(get_constant_one_over_epsilon<T>()) > 0)
|
||||
{
|
||||
result = ui_type(0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
eval_subtract(xx, n_pi);
|
||||
|
||||
BOOST_MATH_INSTRUMENT_CODE(xx.str(0, std::ios_base::scientific));
|
||||
BOOST_MATH_INSTRUMENT_CODE(n_pi.str(0, std::ios_base::scientific));
|
||||
@@ -276,7 +282,20 @@ void eval_cos(T& result, const T& x)
|
||||
BOOST_MATH_INSTRUMENT_CODE(n_pi.str(0, std::ios_base::scientific));
|
||||
eval_multiply(t, n_pi, get_constant_pi<T>());
|
||||
BOOST_MATH_INSTRUMENT_CODE(t.str(0, std::ios_base::scientific));
|
||||
eval_subtract(xx, t);
|
||||
//
|
||||
// If t is so large that all digits cancel the result of this subtraction
|
||||
// is completely meaningless, just assume the result is zero for now...
|
||||
//
|
||||
// TODO We should of course do much better, see:
|
||||
// "ARGUMENT REDUCTION FOR HUGE ARGUMENTS" K C Ng 1992
|
||||
//
|
||||
if (n_pi.compare(get_constant_one_over_epsilon<T>()) > 0)
|
||||
{
|
||||
result = ui_type(1);
|
||||
return;
|
||||
}
|
||||
else
|
||||
eval_subtract(xx, t);
|
||||
BOOST_MATH_INSTRUMENT_CODE(xx.str(0, std::ios_base::scientific));
|
||||
|
||||
// Adjust signs if the multiple of pi is not even.
|
||||
|
||||
@@ -429,6 +429,13 @@ void generic_interconvert_float2rational(To& to, const From& from, const mpl::in
|
||||
typename From::exponent_type e;
|
||||
typename component_type<number<To> >::type num, denom;
|
||||
number<From> val(from);
|
||||
|
||||
if (!val)
|
||||
{
|
||||
to = ui_type(0u);
|
||||
return;
|
||||
}
|
||||
|
||||
e = ilogb(val);
|
||||
val = scalbn(val, -e);
|
||||
while(val)
|
||||
@@ -474,9 +481,15 @@ void generic_interconvert_float2int(To& to, const From& from, const mpl::int_<2>
|
||||
number<To> num(0u);
|
||||
number<From> val(from);
|
||||
val = frexp(val, &e);
|
||||
bool neg = false;
|
||||
if (val.sign() < 0)
|
||||
{
|
||||
val.backend().negate();
|
||||
neg = true;
|
||||
}
|
||||
while(e > 0)
|
||||
{
|
||||
int s = (std::min)(e, shift);
|
||||
exponent_type s = (std::min)(e, shift);
|
||||
val = ldexp(val, s);
|
||||
e -= s;
|
||||
boost::long_long_type ll = boost::math::lltrunc(val);
|
||||
@@ -485,6 +498,8 @@ void generic_interconvert_float2int(To& to, const From& from, const mpl::int_<2>
|
||||
num += ll;
|
||||
}
|
||||
to = num.backend();
|
||||
if (neg)
|
||||
to.negate();
|
||||
}
|
||||
|
||||
template <class To, class From, int Radix>
|
||||
@@ -518,6 +533,59 @@ void generic_interconvert(To& to, const From& from, const mpl::int_<number_kind_
|
||||
generic_interconvert_float2int(to, from, mpl::int_<std::numeric_limits<number<From> >::radix>());
|
||||
}
|
||||
|
||||
template <class To, class From, class tag>
|
||||
void generic_interconvert_complex_to_scalar(To& to, const From& from, const mpl::true_&, const tag&)
|
||||
{
|
||||
// We just want the real part, and "to" is the correct type already:
|
||||
eval_real(to, from);
|
||||
|
||||
To im;
|
||||
eval_imag(im, from);
|
||||
if(!eval_is_zero(im))
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
|
||||
}
|
||||
template <class To, class From>
|
||||
void generic_interconvert_complex_to_scalar(To& to, const From& from, const mpl::false_&, const mpl::true_&)
|
||||
{
|
||||
typedef typename component_type<number<From> >::type component_number;
|
||||
typedef typename component_number::backend_type component_backend;
|
||||
//
|
||||
// Get the real part and copy-construct the result from it:
|
||||
//
|
||||
component_backend r;
|
||||
generic_interconvert_complex_to_scalar(r, from, mpl::true_(), mpl::true_());
|
||||
to = r;
|
||||
}
|
||||
template <class To, class From>
|
||||
void generic_interconvert_complex_to_scalar(To& to, const From& from, const mpl::false_&, const mpl::false_&)
|
||||
{
|
||||
typedef typename component_type<number<From> >::type component_number;
|
||||
typedef typename component_number::backend_type component_backend;
|
||||
//
|
||||
// Get the real part and use a generic_interconvert to type To:
|
||||
//
|
||||
component_backend r;
|
||||
generic_interconvert_complex_to_scalar(r, from, mpl::true_(), mpl::true_());
|
||||
generic_interconvert(to, r, mpl::int_<number_category<To>::value>(), mpl::int_<number_category<To>::value>());
|
||||
}
|
||||
|
||||
template <class To, class From>
|
||||
void generic_interconvert(To& to, const From& from, const mpl::int_<number_kind_floating_point>& /*to_type*/, const mpl::int_<number_kind_complex>& /*from_type*/)
|
||||
{
|
||||
typedef typename component_type<number<From> >::type component_number;
|
||||
typedef typename component_number::backend_type component_backend;
|
||||
|
||||
generic_interconvert_complex_to_scalar(to, from, mpl::bool_<boost::is_same<component_backend, To>::value>(), mpl::bool_<boost::is_constructible<To, const component_backend&>::value>());
|
||||
}
|
||||
template <class To, class From>
|
||||
void generic_interconvert(To& to, const From& from, const mpl::int_<number_kind_integer>& /*to_type*/, const mpl::int_<number_kind_complex>& /*from_type*/)
|
||||
{
|
||||
typedef typename component_type<number<From> >::type component_number;
|
||||
typedef typename component_number::backend_type component_backend;
|
||||
|
||||
generic_interconvert_complex_to_scalar(to, from, mpl::bool_<boost::is_same<component_backend, To>::value>(), mpl::bool_<boost::is_constructible<To, const component_backend&>::value>());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // namespaces
|
||||
|
||||
@@ -23,16 +23,18 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator - (const number<B, et_off>& v)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(is_signed_number<B>::value, "Negating an unsigned type results in ill-defined behavior.");
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(v);
|
||||
number<B, et_off> result(v);
|
||||
result.backend().negate();
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator ~ (const number<B, et_off>& v)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(v);
|
||||
number<B, et_off> result;
|
||||
eval_complement(result.backend(), v.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// Addition:
|
||||
@@ -40,28 +42,31 @@ BOOST_MP_FORCEINLINE number<B, et_off> operator ~ (const number<B, et_off>& v)
|
||||
template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator + (const number<B, et_off>& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_add;
|
||||
eval_add(result.backend(), a.backend(), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B, class V>
|
||||
BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
||||
operator + (const number<B, et_off>& a, const V& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_add;
|
||||
eval_add(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class V, class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
||||
operator + (const V& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_add;
|
||||
eval_add(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// Subtraction:
|
||||
@@ -69,28 +74,31 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator - (const number<B, et_off>& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_subtract;
|
||||
eval_subtract(result.backend(), a.backend(), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B, class V>
|
||||
BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
||||
operator - (const number<B, et_off>& a, const V& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_subtract;
|
||||
eval_subtract(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class V, class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
||||
operator - (const V& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_subtract;
|
||||
eval_subtract(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// Multiply:
|
||||
@@ -98,28 +106,31 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator * (const number<B, et_off>& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_multiply;
|
||||
eval_multiply(result.backend(), a.backend(), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B, class V>
|
||||
BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
||||
operator * (const number<B, et_off>& a, const V& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_multiply;
|
||||
eval_multiply(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class V, class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
||||
operator * (const V& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_multiply;
|
||||
eval_multiply(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// divide:
|
||||
@@ -127,28 +138,31 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator / (const number<B, et_off>& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_divide;
|
||||
eval_divide(result.backend(), a.backend(), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B, class V>
|
||||
BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
||||
operator / (const number<B, et_off>& a, const V& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_divide;
|
||||
eval_divide(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class V, class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<B, et_off> >, number<B, et_off> >::type
|
||||
operator / (const V& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_divide;
|
||||
eval_divide(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// modulus:
|
||||
@@ -156,28 +170,31 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
template <class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator % (const number<B, et_off>& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_modulus;
|
||||
eval_modulus(result.backend(), a.backend(), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B, class V>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
||||
operator % (const number<B, et_off>& a, const V& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_modulus;
|
||||
eval_modulus(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class V, class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
||||
operator % (const V& a, const number<B, et_off>& b)
|
||||
{
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(b);
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_modulus;
|
||||
eval_modulus(result.backend(), number<B, et_off>::canonical_value(a), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// Bitwise or:
|
||||
@@ -188,7 +205,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_ki
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_bitwise_or;
|
||||
eval_bitwise_or(result.backend(), a.backend(), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B, class V>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
||||
@@ -197,7 +214,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, numbe
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_bitwise_or;
|
||||
eval_bitwise_or(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class V, class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
||||
@@ -206,7 +223,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, numbe
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_bitwise_or;
|
||||
eval_bitwise_or(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// Bitwise xor:
|
||||
@@ -217,7 +234,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_ki
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_bitwise_xor;
|
||||
eval_bitwise_xor(result.backend(), a.backend(), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B, class V>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
||||
@@ -226,7 +243,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, numbe
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_bitwise_xor;
|
||||
eval_bitwise_xor(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class V, class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
||||
@@ -235,7 +252,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, numbe
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_bitwise_xor;
|
||||
eval_bitwise_xor(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// Bitwise and:
|
||||
@@ -246,7 +263,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_ki
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_bitwise_and;
|
||||
eval_bitwise_and(result.backend(), a.backend(), b.backend());
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B, class V>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
||||
@@ -255,7 +272,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, numbe
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_bitwise_and;
|
||||
eval_bitwise_and(result.backend(), a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class V, class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, number<B, et_off> >::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
||||
@@ -264,7 +281,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, numbe
|
||||
number<B, et_off> result;
|
||||
using default_ops::eval_bitwise_and;
|
||||
eval_bitwise_and(result.backend(), b.backend(), number<B, et_off>::canonical_value(a));
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// shifts:
|
||||
@@ -277,7 +294,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_integral<I>::value && (number_categ
|
||||
using default_ops::eval_left_shift;
|
||||
detail::check_shift_range(b, mpl::bool_<(sizeof(I) > sizeof(std::size_t))>(), is_signed<I>());
|
||||
eval_left_shift(result.backend(), b);
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
template <class B, class I>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<is_integral<I>::value && (number_category<B>::value == number_kind_integer), number<B, et_off> >::type
|
||||
@@ -287,7 +304,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_integral<I>::value && (number_categ
|
||||
using default_ops::eval_right_shift;
|
||||
detail::check_shift_range(b, mpl::bool_<(sizeof(I) > sizeof(std::size_t))>(), is_signed<I>());
|
||||
eval_right_shift(result.backend(), b);
|
||||
return BOOST_MP_MOVE(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !(defined(__GNUC__) && ((__GNUC__ == 4) && (__GNUC_MINOR__ < 5)))
|
||||
@@ -322,6 +339,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator + (number<B, et_off>&& a, const number<B, et_off>& b)
|
||||
{
|
||||
using default_ops::eval_add;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_add(a.backend(), b.backend());
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -329,6 +347,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator + (const number<B, et_off>& a, number<B, et_off>&& b)
|
||||
{
|
||||
using default_ops::eval_add;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_add(b.backend(), a.backend());
|
||||
return static_cast<number<B, et_off>&&>(b);
|
||||
}
|
||||
@@ -336,6 +355,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator + (number<B, et_off>&& a, number<B, et_off>&& b)
|
||||
{
|
||||
using default_ops::eval_add;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_add(a.backend(), b.backend());
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -344,6 +364,7 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
operator + (number<B, et_off>&& a, const V& b)
|
||||
{
|
||||
using default_ops::eval_add;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_add(a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -352,6 +373,7 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
operator + (const V& a, number<B, et_off>&& b)
|
||||
{
|
||||
using default_ops::eval_add;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_add(b.backend(), number<B, et_off>::canonical_value(a));
|
||||
return static_cast<number<B, et_off>&&>(b);
|
||||
}
|
||||
@@ -362,6 +384,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator - (number<B, et_off>&& a, const number<B, et_off>& b)
|
||||
{
|
||||
using default_ops::eval_subtract;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_subtract(a.backend(), b.backend());
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -369,6 +392,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if<is_signed_number<B>, number<B, et_off> >::type operator - (const number<B, et_off>& a, number<B, et_off>&& b)
|
||||
{
|
||||
using default_ops::eval_subtract;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_subtract(b.backend(), a.backend());
|
||||
b.backend().negate();
|
||||
return static_cast<number<B, et_off>&&>(b);
|
||||
@@ -377,6 +401,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator - (number<B, et_off>&& a, number<B, et_off>&& b)
|
||||
{
|
||||
using default_ops::eval_subtract;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_subtract(a.backend(), b.backend());
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -385,6 +410,7 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
operator - (number<B, et_off>&& a, const V& b)
|
||||
{
|
||||
using default_ops::eval_subtract;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_subtract(a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -393,6 +419,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<(is_compatible_arithmetic_type<V, numb
|
||||
operator - (const V& a, number<B, et_off>&& b)
|
||||
{
|
||||
using default_ops::eval_subtract;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_subtract(b.backend(), number<B, et_off>::canonical_value(a));
|
||||
b.backend().negate();
|
||||
return static_cast<number<B, et_off>&&>(b);
|
||||
@@ -404,6 +431,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator * (number<B, et_off>&& a, const number<B, et_off>& b)
|
||||
{
|
||||
using default_ops::eval_multiply;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_multiply(a.backend(), b.backend());
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -411,6 +439,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator * (const number<B, et_off>& a, number<B, et_off>&& b)
|
||||
{
|
||||
using default_ops::eval_multiply;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_multiply(b.backend(), a.backend());
|
||||
return static_cast<number<B, et_off>&&>(b);
|
||||
}
|
||||
@@ -418,6 +447,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator * (number<B, et_off>&& a, number<B, et_off>&& b)
|
||||
{
|
||||
using default_ops::eval_multiply;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_multiply(a.backend(), b.backend());
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -426,6 +456,7 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
operator * (number<B, et_off>&& a, const V& b)
|
||||
{
|
||||
using default_ops::eval_multiply;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_multiply(a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -434,6 +465,7 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
operator * (const V& a, number<B, et_off>&& b)
|
||||
{
|
||||
using default_ops::eval_multiply;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_multiply(b.backend(), number<B, et_off>::canonical_value(a));
|
||||
return static_cast<number<B, et_off>&&>(b);
|
||||
}
|
||||
@@ -444,6 +476,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE number<B, et_off> operator / (number<B, et_off>&& a, const number<B, et_off>& b)
|
||||
{
|
||||
using default_ops::eval_divide;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_divide(a.backend(), b.backend());
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -452,6 +485,7 @@ BOOST_MP_FORCEINLINE typename enable_if<is_compatible_arithmetic_type<V, number<
|
||||
operator / (number<B, et_off>&& a, const V& b)
|
||||
{
|
||||
using default_ops::eval_divide;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_divide(a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -462,6 +496,7 @@ template <class B>
|
||||
BOOST_MP_FORCEINLINE typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, et_off> >::type operator % (number<B, et_off>&& a, const number<B, et_off>& b)
|
||||
{
|
||||
using default_ops::eval_modulus;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_modulus(a.backend(), b.backend());
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
@@ -470,6 +505,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c<is_compatible_arithmetic_type<V, numbe
|
||||
operator % (number<B, et_off>&& a, const V& b)
|
||||
{
|
||||
using default_ops::eval_modulus;
|
||||
detail::scoped_default_precision<multiprecision::number<B, et_off> > precision_guard(a, b);
|
||||
eval_modulus(a.backend(), number<B, et_off>::canonical_value(b));
|
||||
return static_cast<number<B, et_off>&&>(a);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
# define BOOST_MP_FORCEINLINE inline
|
||||
#endif
|
||||
|
||||
#if (defined(BOOST_GCC) && (BOOST_GCC <= 40700)) || BOOST_WORKAROUND(__SUNPRO_CC, < 0x5140)
|
||||
#if (defined(BOOST_GCC) && (BOOST_GCC <= 40700)) || BOOST_WORKAROUND(__SUNPRO_CC, < 0x5140) || (defined(__clang_major__) && (__clang_major__ == 3) && (__clang_minor__ < 5))
|
||||
# define BOOST_MP_NOEXCEPT_IF(x)
|
||||
#else
|
||||
# define BOOST_MP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x)
|
||||
@@ -38,9 +38,11 @@
|
||||
|
||||
//
|
||||
// Thread local storage:
|
||||
// Note fails on Mingw, see https://sourceforge.net/p/mingw-w64/bugs/527/
|
||||
//
|
||||
#if !defined(BOOST_NO_CXX11_THREAD_LOCAL) && !defined(BOOST_INTEL)
|
||||
#if !defined(BOOST_NO_CXX11_THREAD_LOCAL) && !defined(BOOST_INTEL) && !defined(__MINGW32__)
|
||||
# define BOOST_MP_THREAD_LOCAL thread_local
|
||||
# define BOOST_MP_USING_THREAD_LOCAL
|
||||
#else
|
||||
# define BOOST_MP_THREAD_LOCAL
|
||||
#endif
|
||||
@@ -51,6 +53,15 @@
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace serialization
|
||||
{
|
||||
template <class T>
|
||||
struct nvp;
|
||||
template<class T>
|
||||
const nvp< T > make_nvp(const char * name, T & t);
|
||||
}
|
||||
|
||||
namespace multiprecision{
|
||||
|
||||
enum expression_template_option
|
||||
@@ -364,12 +375,21 @@ struct unmentionable
|
||||
|
||||
typedef unmentionable* (unmentionable::*unmentionable_type)();
|
||||
|
||||
template <class T>
|
||||
struct expression_storage
|
||||
template <class T, bool b>
|
||||
struct expression_storage_base
|
||||
{
|
||||
typedef const T& type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct expression_storage_base<T, true>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct expression_storage : public expression_storage_base<T, boost::is_arithmetic<T>::value> {};
|
||||
|
||||
template <class T>
|
||||
struct expression_storage<T*>
|
||||
{
|
||||
@@ -399,6 +419,114 @@ struct expression<tag, Arg1, void, void, void>
|
||||
|
||||
explicit expression(const Arg1& a) : arg(a) {}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_STATIC_ASSERT
|
||||
//
|
||||
// If we have static_assert we can give a more useful error message
|
||||
// than if we simply have no operator defined at all:
|
||||
//
|
||||
template <class Other>
|
||||
expression& operator=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator+=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator-=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator*=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator/=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator%=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator|=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator&=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator^=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator<<=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator>>=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
left_type left()const { return left_type(arg); }
|
||||
|
||||
const Arg1& left_ref()const BOOST_NOEXCEPT { return arg; }
|
||||
@@ -470,6 +598,114 @@ struct expression<terminal, Arg1, void, void, void>
|
||||
|
||||
explicit expression(const Arg1& a) : arg(a) {}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_STATIC_ASSERT
|
||||
//
|
||||
// If we have static_assert we can give a more useful error message
|
||||
// than if we simply have no operator defined at all:
|
||||
//
|
||||
template <class Other>
|
||||
expression& operator=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator+=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator-=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator*=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator/=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator%=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator|=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator&=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator^=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator<<=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator>>=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
const Arg1& value()const BOOST_NOEXCEPT { return arg; }
|
||||
|
||||
static const unsigned depth = 0;
|
||||
@@ -543,6 +779,114 @@ struct expression<tag, Arg1, Arg2, void, void>
|
||||
|
||||
expression(const Arg1& a1, const Arg2& a2) : arg1(a1), arg2(a2) {}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_STATIC_ASSERT
|
||||
//
|
||||
// If we have static_assert we can give a more useful error message
|
||||
// than if we simply have no operator defined at all:
|
||||
//
|
||||
template <class Other>
|
||||
expression& operator=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator+=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator-=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator*=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator/=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator%=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator|=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator&=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator^=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator<<=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator>>=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
left_type left()const { return left_type(arg1); }
|
||||
right_type right()const { return right_type(arg2); }
|
||||
const Arg1& left_ref()const BOOST_NOEXCEPT { return arg1; }
|
||||
@@ -626,6 +970,114 @@ struct expression<tag, Arg1, Arg2, Arg3, void>
|
||||
|
||||
expression(const Arg1& a1, const Arg2& a2, const Arg3& a3) : arg1(a1), arg2(a2), arg3(a3) {}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_STATIC_ASSERT
|
||||
//
|
||||
// If we have static_assert we can give a more useful error message
|
||||
// than if we simply have no operator defined at all:
|
||||
//
|
||||
template <class Other>
|
||||
expression& operator=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator+=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator-=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator*=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator/=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator%=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator|=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator&=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator^=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator<<=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator>>=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
left_type left()const { return left_type(arg1); }
|
||||
middle_type middle()const { return middle_type(arg2); }
|
||||
right_type right()const { return right_type(arg3); }
|
||||
@@ -718,6 +1170,114 @@ struct expression
|
||||
|
||||
expression(const Arg1& a1, const Arg2& a2, const Arg3& a3, const Arg4& a4) : arg1(a1), arg2(a2), arg3(a3), arg4(a4) {}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_STATIC_ASSERT
|
||||
//
|
||||
// If we have static_assert we can give a more useful error message
|
||||
// than if we simply have no operator defined at all:
|
||||
//
|
||||
template <class Other>
|
||||
expression& operator=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not assign to a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator++(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not increment a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--()
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
expression& operator--(int)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(*this) == INT_MAX, "You can not decrement a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator+=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator+= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator-=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator-= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator*=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator*= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator/=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator/= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator%=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator%= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator|=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator|= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator&=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator&= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator^=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator^= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator<<=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator<<= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
template <class Other>
|
||||
expression& operator>>=(const Other&)
|
||||
{
|
||||
// This should always fail:
|
||||
static_assert(sizeof(Other) == INT_MAX, "You can not use operator>>= on a Boost.Multiprecision expression template: did you inadvertantly store an expression template in a \"auto\" variable? Or pass an expression to a template function with deduced temnplate arguments?");
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
left_type left()const { return left_type(arg1); }
|
||||
left_middle_type left_middle()const { return left_middle_type(arg2); }
|
||||
right_middle_type right_middle()const { return right_middle_type(arg3); }
|
||||
@@ -968,6 +1528,12 @@ void check_shift_range(V val, const mpl::true_&, const mpl::false_&)
|
||||
template <class V>
|
||||
void check_shift_range(V, const mpl::false_&, const mpl::false_&) BOOST_NOEXCEPT{}
|
||||
|
||||
template <class T>
|
||||
const T& evaluate_if_expression(const T& val) { return val; }
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
|
||||
typename expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type evaluate_if_expression(const expression<tag, Arg1, Arg2, Arg3, Arg4>& val) { return val; }
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
@@ -979,23 +1545,49 @@ enum number_category_type
|
||||
number_kind_integer = 0,
|
||||
number_kind_floating_point = 1,
|
||||
number_kind_rational = 2,
|
||||
number_kind_fixed_point = 3
|
||||
number_kind_fixed_point = 3,
|
||||
number_kind_complex = 4
|
||||
};
|
||||
|
||||
template <class Num, bool, bool>
|
||||
struct number_category_base : public mpl::int_<number_kind_unknown> {};
|
||||
template <class Num>
|
||||
struct number_category : public mpl::int_<std::numeric_limits<Num>::is_integer ? number_kind_integer : (std::numeric_limits<Num>::max_exponent ? number_kind_floating_point : number_kind_unknown)> {};
|
||||
struct number_category_base<Num, true, false> : public mpl::int_<std::numeric_limits<Num>::is_integer ? number_kind_integer : (std::numeric_limits<Num>::max_exponent ? number_kind_floating_point : number_kind_unknown)> {};
|
||||
template <class Num>
|
||||
struct number_category : public number_category_base<Num, boost::is_class<Num>::value || boost::is_arithmetic<Num>::value, boost::is_abstract<Num>::value> {};
|
||||
template <class Backend, expression_template_option ExpressionTemplates>
|
||||
struct number_category<number<Backend, ExpressionTemplates> > : public number_category<Backend>{};
|
||||
template <class tag, class A1, class A2, class A3, class A4>
|
||||
struct number_category<detail::expression<tag, A1, A2, A3, A4> > : public number_category<typename detail::expression<tag, A1, A2, A3, A4>::result_type>{};
|
||||
//
|
||||
// Specializations for types which do not always have numberic_limits specializations:
|
||||
//
|
||||
#ifdef BOOST_HAS_INT128
|
||||
template <>
|
||||
struct number_category<boost::int128_type> : public mpl::int_<number_kind_integer> {};
|
||||
template <>
|
||||
struct number_category<boost::uint128_type> : public mpl::int_<number_kind_integer> {};
|
||||
#endif
|
||||
#ifdef BOOST_HAS_FLOAT128
|
||||
template <>
|
||||
struct number_category<__float128> : public mpl::int_<number_kind_floating_point> {};
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct component_type;
|
||||
template <class T, expression_template_option ExpressionTemplates>
|
||||
struct component_type<number<T, ExpressionTemplates> > : public component_type<T>{};
|
||||
struct component_type { typedef T type; };
|
||||
template <class tag, class A1, class A2, class A3, class A4>
|
||||
struct component_type<detail::expression<tag, A1, A2, A3, A4> > : public component_type<typename detail::expression<tag, A1, A2, A3, A4>::result_type>{};
|
||||
|
||||
template <class T>
|
||||
struct scalar_result_from_possible_complex
|
||||
{
|
||||
typedef typename mpl::if_c<number_category<T>::value == number_kind_complex,
|
||||
typename component_type<T>::type, T>::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct complex_result_from_scalar; // individual backends must specialize this trait.
|
||||
|
||||
template <class T>
|
||||
struct is_unsigned_number : public mpl::false_{};
|
||||
template <class Backend, expression_template_option ExpressionTemplates>
|
||||
@@ -1056,5 +1648,3 @@ namespace constants{
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MATH_BIG_NUM_BASE_HPP
|
||||
|
||||
|
||||
|
||||
@@ -258,14 +258,15 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
|
||||
}
|
||||
|
||||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
||||
inline bool operator < (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
||||
inline typename boost::enable_if_c<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type
|
||||
operator < (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
||||
{
|
||||
using default_ops::eval_lt;
|
||||
if(detail::is_unordered_comparison(a, b)) return false;
|
||||
return eval_lt(a.backend(), b.backend());
|
||||
}
|
||||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex), bool>::type
|
||||
operator < (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
||||
{
|
||||
using default_ops::eval_lt;
|
||||
@@ -273,7 +274,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
|
||||
return eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
|
||||
}
|
||||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex), bool>::type
|
||||
operator < (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
||||
{
|
||||
using default_ops::eval_gt;
|
||||
@@ -281,7 +282,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
|
||||
return eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
|
||||
}
|
||||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator < (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
||||
{
|
||||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
||||
@@ -291,7 +292,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
|
||||
return eval_gt(t.backend(), result_type::canonical_value(a));
|
||||
}
|
||||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator < (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
||||
{
|
||||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
||||
@@ -301,7 +302,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
|
||||
return eval_lt(t.backend(), result_type::canonical_value(b));
|
||||
}
|
||||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
||||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
|
||||
inline typename enable_if_c<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator < (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
||||
{
|
||||
using default_ops::eval_lt;
|
||||
@@ -312,14 +313,15 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
|
||||
}
|
||||
|
||||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
||||
inline bool operator > (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
||||
inline typename boost::enable_if_c<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type
|
||||
operator > (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
||||
{
|
||||
using default_ops::eval_gt;
|
||||
if(detail::is_unordered_comparison(a, b)) return false;
|
||||
return eval_gt(a.backend(), b.backend());
|
||||
}
|
||||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex), bool>::type
|
||||
operator > (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
||||
{
|
||||
using default_ops::eval_gt;
|
||||
@@ -327,7 +329,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
|
||||
return eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
|
||||
}
|
||||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex), bool>::type
|
||||
operator > (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
||||
{
|
||||
using default_ops::eval_lt;
|
||||
@@ -335,7 +337,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
|
||||
return eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
|
||||
}
|
||||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator > (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
||||
{
|
||||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
||||
@@ -345,7 +347,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
|
||||
return a > t;
|
||||
}
|
||||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator > (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
||||
{
|
||||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
||||
@@ -355,7 +357,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
|
||||
return t > b;
|
||||
}
|
||||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
||||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
|
||||
inline typename enable_if_c<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator > (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
||||
{
|
||||
using default_ops::eval_gt;
|
||||
@@ -366,14 +368,15 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
|
||||
}
|
||||
|
||||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
||||
inline bool operator <= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
||||
inline typename boost::enable_if_c<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type
|
||||
operator <= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
||||
{
|
||||
using default_ops::eval_gt;
|
||||
if(detail::is_unordered_comparison(a, b)) return false;
|
||||
return !eval_gt(a.backend(), b.backend());
|
||||
}
|
||||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex), bool>::type
|
||||
operator <= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
||||
{
|
||||
using default_ops::eval_gt;
|
||||
@@ -381,7 +384,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
|
||||
return !eval_gt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
|
||||
}
|
||||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex), bool>::type
|
||||
operator <= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
||||
{
|
||||
using default_ops::eval_lt;
|
||||
@@ -389,7 +392,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
|
||||
return !eval_lt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
|
||||
}
|
||||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator <= (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
||||
{
|
||||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
||||
@@ -401,7 +404,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
|
||||
return !eval_lt(t.backend(), result_type::canonical_value(a));
|
||||
}
|
||||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator <= (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
||||
{
|
||||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
||||
@@ -411,7 +414,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
|
||||
return !eval_gt(t.backend(), result_type::canonical_value(b));
|
||||
}
|
||||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
||||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
|
||||
inline typename enable_if_c<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator <= (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
||||
{
|
||||
using default_ops::eval_gt;
|
||||
@@ -422,14 +425,15 @@ inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A
|
||||
}
|
||||
|
||||
template <class Backend, expression_template_option ExpressionTemplates, class Backend2, expression_template_option ExpressionTemplates2>
|
||||
inline bool operator >= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
||||
inline typename boost::enable_if_c<(number_category<Backend>::value != number_kind_complex) && (number_category<Backend2>::value != number_kind_complex), bool>::type
|
||||
operator >= (const number<Backend, ExpressionTemplates>& a, const number<Backend2, ExpressionTemplates2>& b)
|
||||
{
|
||||
using default_ops::eval_lt;
|
||||
if(detail::is_unordered_comparison(a, b)) return false;
|
||||
return !eval_lt(a.backend(), b.backend());
|
||||
}
|
||||
template <class Backend, expression_template_option ExpressionTemplates, class Arithmetic>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex), bool>::type
|
||||
operator >= (const number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
|
||||
{
|
||||
using default_ops::eval_lt;
|
||||
@@ -437,7 +441,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
|
||||
return !eval_lt(a.backend(), number<Backend, ExpressionTemplates>::canonical_value(b));
|
||||
}
|
||||
template <class Arithmetic, class Backend, expression_template_option ExpressionTemplates>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, ExpressionTemplates>, Arithmetic>::value && (number_category<Backend>::value != number_kind_complex), bool>::type
|
||||
operator >= (const Arithmetic& a, const number<Backend, ExpressionTemplates>& b)
|
||||
{
|
||||
using default_ops::eval_gt;
|
||||
@@ -445,7 +449,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<number<Backend, Expre
|
||||
return !eval_gt(b.backend(), number<Backend, ExpressionTemplates>::canonical_value(a));
|
||||
}
|
||||
template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator >= (const Arithmetic& a, const detail::expression<Tag, A1, A2, A3, A4>& b)
|
||||
{
|
||||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
||||
@@ -455,7 +459,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
|
||||
return !eval_gt(t.backend(), result_type::canonical_value(a));
|
||||
}
|
||||
template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value, bool>::type
|
||||
inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, Arithmetic>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator >= (const detail::expression<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
|
||||
{
|
||||
typedef typename detail::expression<Tag, A1, A2, A3, A4>::result_type result_type;
|
||||
@@ -465,7 +469,7 @@ inline typename enable_if_c<detail::is_valid_mixed_compare<typename detail::expr
|
||||
return !eval_lt(t.backend(), result_type::canonical_value(b));
|
||||
}
|
||||
template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
|
||||
inline typename enable_if<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
|
||||
inline typename enable_if_c<is_same<typename detail::expression<Tag, A1, A2, A3, A4>::result_type, typename detail::expression<Tagb, A1b, A2b, A3b, A4b>::result_type>::value && (number_category<typename detail::expression<Tag, A1, A2, A3, A4>::result_type>::value != number_kind_complex), bool>::type
|
||||
operator >= (const detail::expression<Tag, A1, A2, A3, A4>& a, const detail::expression<Tagb, A1b, A2b, A3b, A4b>& b)
|
||||
{
|
||||
using default_ops::eval_lt;
|
||||
|
||||
190
linx64/include/boost/multiprecision/detail/precision.hpp
Normal file
190
linx64/include/boost/multiprecision/detail/precision.hpp
Normal file
@@ -0,0 +1,190 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2018 John Maddock. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MP_PRECISION_HPP
|
||||
#define BOOST_MP_PRECISION_HPP
|
||||
|
||||
#include <boost/multiprecision/traits/is_variable_precision.hpp>
|
||||
#include <boost/multiprecision/detail/number_base.hpp>
|
||||
#include <boost/multiprecision/detail/digits.hpp>
|
||||
|
||||
namespace boost{ namespace multiprecision{ namespace detail{
|
||||
|
||||
template <class B, boost::multiprecision::expression_template_option ET>
|
||||
inline BOOST_CONSTEXPR unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>&, const mpl::false_&)
|
||||
{
|
||||
return std::numeric_limits<boost::multiprecision::number<B, ET> >::digits10;
|
||||
}
|
||||
template <class B, boost::multiprecision::expression_template_option ET>
|
||||
inline unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>& val, const mpl::true_&)
|
||||
{
|
||||
//
|
||||
// We have an arbitrary precision integer, take it's "precision" as the
|
||||
// location of the most-significant-bit less the location of the
|
||||
// least-significant-bit, ie the number of bits required to represent the
|
||||
// the value assuming we will have an exponent to shift things by:
|
||||
//
|
||||
return val.is_zero() ? 1 : digits2_2_10(msb(abs(val)) - lsb(abs(val)) + 1);
|
||||
}
|
||||
|
||||
|
||||
template <class B, boost::multiprecision::expression_template_option ET>
|
||||
inline unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& n, const mpl::true_&)
|
||||
{
|
||||
return n.precision();
|
||||
}
|
||||
template <class B, boost::multiprecision::expression_template_option ET>
|
||||
inline BOOST_CONSTEXPR unsigned current_precision_of_imp(const boost::multiprecision::number<B, ET>& val, const mpl::false_&)
|
||||
{
|
||||
return current_precision_of_last_chance_imp(val,
|
||||
mpl::bool_<
|
||||
std::numeric_limits<boost::multiprecision::number<B, ET> >::is_specialized
|
||||
&& std::numeric_limits<boost::multiprecision::number<B, ET> >::is_integer
|
||||
&& std::numeric_limits<boost::multiprecision::number<B, ET> >::is_exact
|
||||
&& !std::numeric_limits<boost::multiprecision::number<B, ET> >::is_modulo>());
|
||||
}
|
||||
|
||||
template <class Terminal>
|
||||
inline BOOST_CONSTEXPR unsigned current_precision_of(const Terminal&)
|
||||
{
|
||||
return std::numeric_limits<Terminal>::digits10;
|
||||
}
|
||||
|
||||
template <class Terminal, std::size_t N>
|
||||
inline BOOST_CONSTEXPR unsigned current_precision_of(const Terminal(&)[N])
|
||||
{ // For string literals:
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class B, boost::multiprecision::expression_template_option ET>
|
||||
inline BOOST_CONSTEXPR unsigned current_precision_of(const boost::multiprecision::number<B, ET>& n)
|
||||
{
|
||||
return current_precision_of_imp(n, boost::multiprecision::detail::is_variable_precision<boost::multiprecision::number<B, ET> >());
|
||||
}
|
||||
|
||||
template<class tag, class Arg1>
|
||||
inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<tag, Arg1, void, void, void>& expr)
|
||||
{
|
||||
return current_precision_of(expr.left_ref());
|
||||
}
|
||||
|
||||
template<class Arg1>
|
||||
inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<terminal, Arg1, void, void, void>& expr)
|
||||
{
|
||||
return current_precision_of(expr.value());
|
||||
}
|
||||
|
||||
template <class tag, class Arg1, class Arg2>
|
||||
inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<tag, Arg1, Arg2, void, void>& expr)
|
||||
{
|
||||
return (std::max)(current_precision_of(expr.left_ref()), current_precision_of(expr.right_ref()));
|
||||
}
|
||||
|
||||
template <class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline BOOST_CONSTEXPR unsigned current_precision_of(const expression<tag, Arg1, Arg2, Arg3, void>& expr)
|
||||
{
|
||||
return (std::max)((std::max)(current_precision_of(expr.left_ref()), current_precision_of(expr.right_ref())), current_precision_of(expr.middle_ref()));
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4130)
|
||||
#endif
|
||||
|
||||
template <class R, bool = boost::multiprecision::detail::is_variable_precision<R>::value>
|
||||
struct scoped_default_precision
|
||||
{
|
||||
template <class T>
|
||||
BOOST_CONSTEXPR scoped_default_precision(const T&) {}
|
||||
template <class T, class U>
|
||||
BOOST_CONSTEXPR scoped_default_precision(const T&, const U&) {}
|
||||
template <class T, class U, class V>
|
||||
BOOST_CONSTEXPR scoped_default_precision(const T&, const U&, const V&) {}
|
||||
|
||||
//
|
||||
// This function is never called: in C++17 it won't be compiled either:
|
||||
//
|
||||
unsigned precision()const
|
||||
{
|
||||
BOOST_ASSERT("This function should never be called!!" == 0);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class R>
|
||||
struct scoped_default_precision<R, true>
|
||||
{
|
||||
template <class T>
|
||||
BOOST_CXX14_CONSTEXPR scoped_default_precision(const T& a)
|
||||
{
|
||||
init(current_precision_of(a));
|
||||
}
|
||||
template <class T, class U>
|
||||
BOOST_CXX14_CONSTEXPR scoped_default_precision(const T& a, const U& b)
|
||||
{
|
||||
init((std::max)(current_precision_of(a), current_precision_of(b)));
|
||||
}
|
||||
template <class T, class U, class V>
|
||||
BOOST_CXX14_CONSTEXPR scoped_default_precision(const T& a, const U& b, const V& c)
|
||||
{
|
||||
init((std::max)((std::max)(current_precision_of(a), current_precision_of(b)), current_precision_of(c)));
|
||||
}
|
||||
~scoped_default_precision()
|
||||
{
|
||||
R::default_precision(m_old_prec);
|
||||
}
|
||||
BOOST_CXX14_CONSTEXPR unsigned precision()const
|
||||
{
|
||||
return m_new_prec;
|
||||
}
|
||||
private:
|
||||
BOOST_CXX14_CONSTEXPR void init(unsigned p)
|
||||
{
|
||||
m_old_prec = R::default_precision();
|
||||
if (p)
|
||||
{
|
||||
R::default_precision(p);
|
||||
m_new_prec = p;
|
||||
}
|
||||
else
|
||||
m_new_prec = m_old_prec;
|
||||
}
|
||||
unsigned m_old_prec, m_new_prec;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline void maybe_promote_precision(T*, const mpl::false_&){}
|
||||
|
||||
template <class T>
|
||||
inline void maybe_promote_precision(T* obj, const mpl::true_&)
|
||||
{
|
||||
if (obj->precision() != T::default_precision())
|
||||
{
|
||||
obj->precision(T::default_precision());
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void maybe_promote_precision(T* obj)
|
||||
{
|
||||
maybe_promote_precision(obj, boost::multiprecision::detail::is_variable_precision<T>());
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX17_IF_CONSTEXPR
|
||||
# define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) if constexpr (boost::multiprecision::detail::is_variable_precision<T>::value)
|
||||
#else
|
||||
# define BOOST_MP_CONSTEXPR_IF_VARIABLE_PRECISION(T) if(boost::multiprecision::detail::is_variable_precision<T>::value)
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_MP_IS_BACKEND_HPP
|
||||
@@ -13,7 +13,11 @@
|
||||
template <class value_type, class my_allocator>
|
||||
struct rebind
|
||||
{
|
||||
#ifndef BOOST_NO_CXX11_ALLOCATOR
|
||||
typedef typename std::allocator_traits<my_allocator>::template rebind_alloc<value_type> type;
|
||||
#else
|
||||
typedef typename my_allocator::template rebind<value_type>::other type;
|
||||
#endif
|
||||
};
|
||||
} } } } // namespace boost::multiprecision::backends::detail
|
||||
|
||||
|
||||
Reference in New Issue
Block a user