Complex: mpc.hpp now compiles and passes test_arithmetic.hpp.

Disabled relational operators for complex types.
This commit is contained in:
jzmaddock
2018-03-04 17:53:38 +00:00
parent c968bb6039
commit a5ac1fbd4a
3 changed files with 251 additions and 146 deletions

View File

@@ -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;

View File

@@ -177,12 +177,12 @@ struct mpc_float_imp
if(m_data[0].re[0]._mpfr_d == 0)
mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
if(s && (*s == '{'))
if(s && (*s == '('))
{
mpfr_float_backend<digits10> a, b;
std::string part;
const char* p = ++s;
while(*p && (*p != ',') && (*p != '}'))
while(*p && (*p != ',') && (*p != ')'))
++p;
part.assign(s + 1, p);
a = part.c_str();
@@ -190,7 +190,7 @@ struct mpc_float_imp
if(*p && (*p != '}'))
{
++p;
while(*p && (*p != ',') && (*p != '}'))
while(*p && (*p != ',') && (*p != ')'))
++p;
part.assign(s + 1, p);
}
@@ -230,10 +230,10 @@ struct mpc_float_imp
mpc_real(a.data(), m_data, GMP_RNDD);
mpc_imag(b.data(), m_data, GMP_RNDD);
if(a.compare(b) == 0)
if(eval_is_zero(b))
return a.str(digits, f);
return "{" + a.str(digits, f) + "," + b.str(digits, f) + "}";
return "(" + a.str(digits, f) + "," + b.str(digits, f) + ")";
}
~mpc_float_imp() BOOST_NOEXCEPT
{

View File

@@ -77,7 +77,8 @@ int normalize_compare_result(int r)
}
template <class Real, class Val>
void test_comparisons(Val a, Val b, const boost::mpl::true_)
typename boost::disable_if_c<boost::multiprecision::number_category<Real>::value == boost::multiprecision::number_kind_complex>::type
test_comparisons(Val a, Val b, const boost::mpl::true_)
{
Real r1(a);
Real r2(b);
@@ -147,6 +148,56 @@ void test_comparisons(Val a, Val b, const boost::mpl::true_)
BOOST_CHECK_EQUAL(normalize_compare_result(r2.compare(a)), -cr);
}
template <class Real, class Val>
typename boost::enable_if_c<boost::multiprecision::number_category<Real>::value == boost::multiprecision::number_kind_complex>::type
test_comparisons(Val a, Val b, const boost::mpl::true_)
{
Real r1(a);
Real r2(b);
Real z(1);
int cr = a < b ? -1 : a > b ? 1 : 0;
BOOST_CHECK_EQUAL(r1 == r2, a == b);
BOOST_CHECK_EQUAL(r1 != r2, a != b);
BOOST_CHECK_EQUAL(r1 == b, a == b);
BOOST_CHECK_EQUAL(r1 != b, a != b);
BOOST_CHECK_EQUAL(a == r2, a == b);
BOOST_CHECK_EQUAL(a != r2, a != b);
BOOST_CHECK_EQUAL(r1*z == r2, a == b);
BOOST_CHECK_EQUAL(r1*z != r2, a != b);
BOOST_CHECK_EQUAL(r1 == r2 * z, a == b);
BOOST_CHECK_EQUAL(r1 != r2 * z, a != b);
BOOST_CHECK_EQUAL(r1*z == r2 * z, a == b);
BOOST_CHECK_EQUAL(r1*z != r2 * z, a != b);
BOOST_CHECK_EQUAL(r1*z == b, a == b);
BOOST_CHECK_EQUAL(r1*z != b, a != b);
BOOST_CHECK_EQUAL(a == r2 * z, a == b);
BOOST_CHECK_EQUAL(a != r2 * z, a != b);
if (r1 == r2)
{
BOOST_CHECK_EQUAL(normalize_compare_result(r1.compare(r2)), 0);
BOOST_CHECK_EQUAL(normalize_compare_result(r2.compare(r1)), 0);
BOOST_CHECK_EQUAL(normalize_compare_result(r1.compare(b)), 0);
BOOST_CHECK_EQUAL(normalize_compare_result(r2.compare(a)), 0);
}
else
{
BOOST_CHECK_NE(normalize_compare_result(r1.compare(r2)), 0);
BOOST_CHECK_NE(normalize_compare_result(r2.compare(r1)), 0);
BOOST_CHECK_NE(normalize_compare_result(r1.compare(b)), 0);
BOOST_CHECK_NE(normalize_compare_result(r2.compare(a)), 0);
}
}
template <class Real, class Exp>
void test_conditional(Real v, Exp e)
{
@@ -1648,6 +1699,29 @@ inline Real negate_value(const Real& val, const boost::mpl::false_&)
return val;
}
template <class Real, class Num>
void test_mixed_numeric_limits(const boost::mpl::true_&)
{
if (std::numeric_limits<Real>::has_infinity && std::numeric_limits<Num>::has_infinity)
{
d = static_cast<Real>(std::numeric_limits<Num>::infinity());
BOOST_CHECK_GT(d, (std::numeric_limits<Real>::max)());
d = static_cast<Real>(negate_value(std::numeric_limits<Num>::infinity(), boost::mpl::bool_<std::numeric_limits<Num>::is_signed>()));
BOOST_CHECK_LT(d, negate_value((std::numeric_limits<Real>::max)(), boost::mpl::bool_<std::numeric_limits<Real>::is_signed>()));
}
if (std::numeric_limits<Real>::has_quiet_NaN && std::numeric_limits<Num>::has_quiet_NaN)
{
d = static_cast<Real>(std::numeric_limits<Num>::quiet_NaN());
BOOST_CHECK(check_is_nan(d, boost::mpl::bool_<std::numeric_limits<Real>::has_quiet_NaN>()));
d = static_cast<Real>(negate_value(std::numeric_limits<Num>::quiet_NaN(), boost::mpl::bool_<std::numeric_limits<Num>::is_signed>()));
BOOST_CHECK(check_is_nan(d, boost::mpl::bool_<std::numeric_limits<Real>::has_quiet_NaN>()));
}
}
template <class Real, class Num>
void test_mixed_numeric_limits(const boost::mpl::false_&)
{
}
template <class Real, class Num>
void test_mixed(const boost::mpl::true_&)
{
@@ -1850,20 +1924,7 @@ void test_mixed(const boost::mpl::true_&)
d = b * static_cast<cast_type>(n3) - static_cast<cast_type>(n1);
BOOST_CHECK_EQUAL(d , 3 * 4 - 2);
if(std::numeric_limits<Real>::has_infinity && std::numeric_limits<Num>::has_infinity)
{
d = static_cast<Real>(std::numeric_limits<Num>::infinity());
BOOST_CHECK_GT(d, (std::numeric_limits<Real>::max)());
d = static_cast<Real>(negate_value(std::numeric_limits<Num>::infinity(), boost::mpl::bool_<std::numeric_limits<Num>::is_signed>()));
BOOST_CHECK_LT(d, negate_value((std::numeric_limits<Real>::max)(), boost::mpl::bool_<std::numeric_limits<Real>::is_signed>()));
}
if(std::numeric_limits<Real>::has_quiet_NaN && std::numeric_limits<Num>::has_quiet_NaN)
{
d = static_cast<Real>(std::numeric_limits<Num>::quiet_NaN());
BOOST_CHECK(check_is_nan(d, boost::mpl::bool_<std::numeric_limits<Real>::has_quiet_NaN>()));
d = static_cast<Real>(negate_value(std::numeric_limits<Num>::quiet_NaN(), boost::mpl::bool_<std::numeric_limits<Num>::is_signed>()));
BOOST_CHECK(check_is_nan(d, boost::mpl::bool_<std::numeric_limits<Real>::has_quiet_NaN>()));
}
test_mixed_numeric_limits<Real, Num>(boost::mpl::bool_<std::numeric_limits<Real>::is_specialized>());
}
template <class Real>
@@ -2007,6 +2068,147 @@ void test_basic_conditionals(Real a, Real b)
}
}
template <class T>
typename boost::enable_if_c<boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_complex>::type
test_relationals(T a, T b)
{
BOOST_CHECK_EQUAL((a == b), false);
BOOST_CHECK_EQUAL((a != b), true);
BOOST_CHECK_EQUAL((a + b == b), false);
BOOST_CHECK_EQUAL((a + b != b), true);
BOOST_CHECK_EQUAL((a == b + a), false);
BOOST_CHECK_EQUAL((a != b + a), true);
BOOST_CHECK_EQUAL((a + b == b + a), true);
BOOST_CHECK_EQUAL((a + b != b + a), false);
BOOST_CHECK_EQUAL((8 == b + a), false);
BOOST_CHECK_EQUAL((8 != b + a), true);
BOOST_CHECK_EQUAL((800 == b + a), false);
BOOST_CHECK_EQUAL((800 != b + a), true);
BOOST_CHECK_EQUAL((72 == b + a), true);
BOOST_CHECK_EQUAL((72 != b + a), false);
BOOST_CHECK_EQUAL((b + a == 8), false);
BOOST_CHECK_EQUAL((b + a != 8), true);
BOOST_CHECK_EQUAL((b + a == 800), false);
BOOST_CHECK_EQUAL((b + a != 800), true);
BOOST_CHECK_EQUAL((b + a == 72), true);
BOOST_CHECK_EQUAL((b + a != 72), false);
}
template <class T>
typename boost::disable_if_c<boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_complex>::type
test_relationals(T a, T b)
{
BOOST_CHECK_EQUAL((a == b), false);
BOOST_CHECK_EQUAL((a != b), true);
BOOST_CHECK_EQUAL((a <= b), true);
BOOST_CHECK_EQUAL((a < b), true);
BOOST_CHECK_EQUAL((a >= b), false);
BOOST_CHECK_EQUAL((a > b), false);
BOOST_CHECK_EQUAL((a + b == b), false);
BOOST_CHECK_EQUAL((a + b != b), true);
BOOST_CHECK_EQUAL((a + b >= b), true);
BOOST_CHECK_EQUAL((a + b > b), true);
BOOST_CHECK_EQUAL((a + b <= b), false);
BOOST_CHECK_EQUAL((a + b < b), false);
BOOST_CHECK_EQUAL((a == b + a), false);
BOOST_CHECK_EQUAL((a != b + a), true);
BOOST_CHECK_EQUAL((a <= b + a), true);
BOOST_CHECK_EQUAL((a < b + a), true);
BOOST_CHECK_EQUAL((a >= b + a), false);
BOOST_CHECK_EQUAL((a > b + a), false);
BOOST_CHECK_EQUAL((a + b == b + a), true);
BOOST_CHECK_EQUAL((a + b != b + a), false);
BOOST_CHECK_EQUAL((a + b <= b + a), true);
BOOST_CHECK_EQUAL((a + b < b + a), false);
BOOST_CHECK_EQUAL((a + b >= b + a), true);
BOOST_CHECK_EQUAL((a + b > b + a), false);
BOOST_CHECK_EQUAL((8 == b + a), false);
BOOST_CHECK_EQUAL((8 != b + a), true);
BOOST_CHECK_EQUAL((8 <= b + a), true);
BOOST_CHECK_EQUAL((8 < b + a), true);
BOOST_CHECK_EQUAL((8 >= b + a), false);
BOOST_CHECK_EQUAL((8 > b + a), false);
BOOST_CHECK_EQUAL((800 == b + a), false);
BOOST_CHECK_EQUAL((800 != b + a), true);
BOOST_CHECK_EQUAL((800 >= b + a), true);
BOOST_CHECK_EQUAL((800 > b + a), true);
BOOST_CHECK_EQUAL((800 <= b + a), false);
BOOST_CHECK_EQUAL((800 < b + a), false);
BOOST_CHECK_EQUAL((72 == b + a), true);
BOOST_CHECK_EQUAL((72 != b + a), false);
BOOST_CHECK_EQUAL((72 <= b + a), true);
BOOST_CHECK_EQUAL((72 < b + a), false);
BOOST_CHECK_EQUAL((72 >= b + a), true);
BOOST_CHECK_EQUAL((72 > b + a), false);
BOOST_CHECK_EQUAL((b + a == 8), false);
BOOST_CHECK_EQUAL((b + a != 8), true);
BOOST_CHECK_EQUAL((b + a >= 8), true);
BOOST_CHECK_EQUAL((b + a > 8), true);
BOOST_CHECK_EQUAL((b + a <= 8), false);
BOOST_CHECK_EQUAL((b + a < 8), false);
BOOST_CHECK_EQUAL((b + a == 800), false);
BOOST_CHECK_EQUAL((b + a != 800), true);
BOOST_CHECK_EQUAL((b + a <= 800), true);
BOOST_CHECK_EQUAL((b + a < 800), true);
BOOST_CHECK_EQUAL((b + a >= 800), false);
BOOST_CHECK_EQUAL((b + a > 800), false);
BOOST_CHECK_EQUAL((b + a == 72), true);
BOOST_CHECK_EQUAL((b + a != 72), false);
BOOST_CHECK_EQUAL((b + a >= 72), true);
BOOST_CHECK_EQUAL((b + a > 72), false);
BOOST_CHECK_EQUAL((b + a <= 72), true);
BOOST_CHECK_EQUAL((b + a < 72), false);
T c;
//
// min and max overloads:
//
#if !defined(min) && !defined(max)
using std::max;
using std::min;
a = 2;
b = 5;
c = 6;
BOOST_CHECK_EQUAL(min(a, b), a);
BOOST_CHECK_EQUAL(min(b, a), a);
BOOST_CHECK_EQUAL(max(a, b), b);
BOOST_CHECK_EQUAL(max(b, a), b);
BOOST_CHECK_EQUAL(min(a, b + c), a);
BOOST_CHECK_EQUAL(min(b + c, a), a);
BOOST_CHECK_EQUAL(min(a, c - b), 1);
BOOST_CHECK_EQUAL(min(c - b, a), 1);
BOOST_CHECK_EQUAL(max(a, b + c), 11);
BOOST_CHECK_EQUAL(max(b + c, a), 11);
BOOST_CHECK_EQUAL(max(a, c - b), a);
BOOST_CHECK_EQUAL(max(c - b, a), a);
BOOST_CHECK_EQUAL(min(a + b, b + c), 7);
BOOST_CHECK_EQUAL(min(b + c, a + b), 7);
BOOST_CHECK_EQUAL(max(a + b, b + c), 11);
BOOST_CHECK_EQUAL(max(b + c, a + b), 11);
BOOST_CHECK_EQUAL(min(a + b, c - a), 4);
BOOST_CHECK_EQUAL(min(c - a, a + b), 4);
BOOST_CHECK_EQUAL(max(a + b, c - a), 7);
BOOST_CHECK_EQUAL(max(c - a, a + b), 7);
long l1(2), l2(3), l3;
l3 = min(l1, l2) + max(l1, l2) + max<long>(l1, l2) + min<long>(l1, l2);
BOOST_CHECK_EQUAL(l3, 10);
#endif
}
template <class Real>
void test()
{
@@ -2192,73 +2394,7 @@ void test()
//
// Comparisons:
//
BOOST_CHECK_EQUAL((a == b) , false);
BOOST_CHECK_EQUAL((a != b) , true);
BOOST_CHECK_EQUAL((a <= b) , true);
BOOST_CHECK_EQUAL((a < b) , true);
BOOST_CHECK_EQUAL((a >= b) , false);
BOOST_CHECK_EQUAL((a > b) , false);
BOOST_CHECK_EQUAL((a+b == b) , false);
BOOST_CHECK_EQUAL((a+b != b) , true);
BOOST_CHECK_EQUAL((a+b >= b) , true);
BOOST_CHECK_EQUAL((a+b > b) , true);
BOOST_CHECK_EQUAL((a+b <= b) , false);
BOOST_CHECK_EQUAL((a+b < b) , false);
BOOST_CHECK_EQUAL((a == b+a) , false);
BOOST_CHECK_EQUAL((a != b+a) , true);
BOOST_CHECK_EQUAL((a <= b+a) , true);
BOOST_CHECK_EQUAL((a < b+a) , true);
BOOST_CHECK_EQUAL((a >= b+a) , false);
BOOST_CHECK_EQUAL((a > b+a) , false);
BOOST_CHECK_EQUAL((a+b == b+a) , true);
BOOST_CHECK_EQUAL((a+b != b+a) , false);
BOOST_CHECK_EQUAL((a+b <= b+a) , true);
BOOST_CHECK_EQUAL((a+b < b+a) , false);
BOOST_CHECK_EQUAL((a+b >= b+a) , true);
BOOST_CHECK_EQUAL((a+b > b+a) , false);
BOOST_CHECK_EQUAL((8 == b+a) , false);
BOOST_CHECK_EQUAL((8 != b+a) , true);
BOOST_CHECK_EQUAL((8 <= b+a) , true);
BOOST_CHECK_EQUAL((8 < b+a) , true);
BOOST_CHECK_EQUAL((8 >= b+a) , false);
BOOST_CHECK_EQUAL((8 > b+a) , false);
BOOST_CHECK_EQUAL((800 == b+a) , false);
BOOST_CHECK_EQUAL((800 != b+a) , true);
BOOST_CHECK_EQUAL((800 >= b+a) , true);
BOOST_CHECK_EQUAL((800 > b+a) , true);
BOOST_CHECK_EQUAL((800 <= b+a) , false);
BOOST_CHECK_EQUAL((800 < b+a) , false);
BOOST_CHECK_EQUAL((72 == b+a) , true);
BOOST_CHECK_EQUAL((72 != b+a) , false);
BOOST_CHECK_EQUAL((72 <= b+a) , true);
BOOST_CHECK_EQUAL((72 < b+a) , false);
BOOST_CHECK_EQUAL((72 >= b+a) , true);
BOOST_CHECK_EQUAL((72 > b+a) , false);
BOOST_CHECK_EQUAL((b + a == 8), false);
BOOST_CHECK_EQUAL((b + a != 8), true);
BOOST_CHECK_EQUAL((b + a >= 8), true);
BOOST_CHECK_EQUAL((b + a > 8), true);
BOOST_CHECK_EQUAL((b + a <= 8), false);
BOOST_CHECK_EQUAL((b + a < 8), false);
BOOST_CHECK_EQUAL((b + a == 800), false);
BOOST_CHECK_EQUAL((b + a != 800), true);
BOOST_CHECK_EQUAL((b + a <= 800), true);
BOOST_CHECK_EQUAL((b + a < 800), true);
BOOST_CHECK_EQUAL((b + a >= 800), false);
BOOST_CHECK_EQUAL((b + a > 800), false);
BOOST_CHECK_EQUAL((b + a == 72), true);
BOOST_CHECK_EQUAL((b + a != 72), false);
BOOST_CHECK_EQUAL((b + a >= 72), true);
BOOST_CHECK_EQUAL((b + a > 72), false);
BOOST_CHECK_EQUAL((b + a <= 72), true);
BOOST_CHECK_EQUAL((b + a < 72), false);
test_relationals(a, b);
test_members(a);
//
// Use in Boolean context:
@@ -2359,41 +2495,6 @@ void test()
BOOST_CHECK_EQUAL(c, 20);
// Destructor of "a" checks destruction of moved-from-object...
Real m3(static_cast<Real&&>(a));
#endif
//
// min and max overloads:
//
#if !defined(min) && !defined(max)
using std::max;
using std::min;
a = 2;
b = 5;
c = 6;
BOOST_CHECK_EQUAL(min(a, b), a);
BOOST_CHECK_EQUAL(min(b, a), a);
BOOST_CHECK_EQUAL(max(a, b), b);
BOOST_CHECK_EQUAL(max(b, a), b);
BOOST_CHECK_EQUAL(min(a, b + c), a);
BOOST_CHECK_EQUAL(min(b + c, a), a);
BOOST_CHECK_EQUAL(min(a, c - b), 1);
BOOST_CHECK_EQUAL(min(c - b, a), 1);
BOOST_CHECK_EQUAL(max(a, b + c), 11);
BOOST_CHECK_EQUAL(max(b + c, a), 11);
BOOST_CHECK_EQUAL(max(a, c - b), a);
BOOST_CHECK_EQUAL(max(c - b, a), a);
BOOST_CHECK_EQUAL(min(a + b, b + c), 7);
BOOST_CHECK_EQUAL(min(b + c, a + b), 7);
BOOST_CHECK_EQUAL(max(a + b, b + c), 11);
BOOST_CHECK_EQUAL(max(b + c, a + b), 11);
BOOST_CHECK_EQUAL(min(a + b, c - a), 4);
BOOST_CHECK_EQUAL(min(c - a, a + b), 4);
BOOST_CHECK_EQUAL(max(a + b, c - a), 7);
BOOST_CHECK_EQUAL(max(c - a, a + b), 7);
long l1(2), l2(3), l3;
l3 = min(l1, l2) + max(l1, l2) + max<long>(l1, l2) + min<long>(l1, l2);
BOOST_CHECK_EQUAL(l3, 10);
#endif
//
// Bug cases, self assignment first: