complex/mpc: another attempt at getting real/imag working with gcc.

This commit is contained in:
jzmaddock
2018-03-12 18:31:20 +00:00
parent 25474b49c8
commit 3a5b6c3aa6
5 changed files with 58 additions and 57 deletions

View File

@@ -1699,6 +1699,21 @@ inline int eval_signbit(const T& val)
return eval_get_sign(val) < 0 ? 1 : 0;
}
//
// Real and imaginary parts:
//
template <class To, class From>
inline void eval_real(To& to, const From& from)
{
to = from;
}
template <class To, class From>
inline void eval_imag(To& to, const From& from)
{
typedef typename mpl::front<typename To::unsigned_types>::type ui_type;
to = ui_type(0);
}
//
// These functions are implemented in separate files, but expanded inline here,
// DO NOT CHANGE THE ORDER OF THESE INCLUDES:
@@ -1830,12 +1845,27 @@ inline typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_
return copysign BOOST_PREVENT_MACRO_SUBSTITUTION(value_type(a), value_type(b));
}
//
// Complex number functions, these are overloaded at the Backend level, we just provide the
// expression template versions here:
// real and imag:
//
template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
inline typename real_and_imag_result<multiprecision::number<Backend, ExpressionTemplates> >::type
real(const multiprecision::number<Backend, ExpressionTemplates>& a)
{
typename real_and_imag_result<multiprecision::number<Backend, ExpressionTemplates> >::type result;
eval_real(result.backend(), a.backend());
return result;
}
template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
inline typename real_and_imag_result<multiprecision::number<Backend, ExpressionTemplates> >::type
imag(const multiprecision::number<Backend, ExpressionTemplates>& a)
{
typename real_and_imag_result<multiprecision::number<Backend, ExpressionTemplates> >::type result;
eval_imag(result.backend(), a.backend());
return result;
}
template <class tag, class A1, class A2, class A3, class A4>
inline typename boost::enable_if_c<number_category<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_complex,
typename component_type<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::type>::type
inline typename component_type<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::type
real(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
{
typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
@@ -1843,14 +1873,17 @@ inline typename boost::enable_if_c<number_category<typename multiprecision::deta
}
template <class tag, class A1, class A2, class A3, class A4>
inline typename boost::enable_if_c<number_category<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::value == number_kind_complex,
typename component_type<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::type>::type
inline typename component_type<typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type>::type
imag(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
{
typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
return imag(value_type(arg));
}
//
// Complex number functions, these are overloaded at the Backend level, we just provide the
// expression template versions here:
//
template <class T, expression_template_option ExpressionTemplates>
inline typename boost::lazy_enable_if_c<number_category<T>::value == number_kind_complex, component_type<number<T, ExpressionTemplates> > >::type
abs(const number<T, ExpressionTemplates>& v)

View File

@@ -1043,13 +1043,6 @@ template <class T>
struct is_interval_number : public mpl::false_ {};
template <class Backend, expression_template_option ExpressionTemplates>
struct is_interval_number<number<Backend, ExpressionTemplates> > : public is_interval_number<Backend>{};
//
// These will never be enabled, but their presence allows us to use real() and imag() for ADL later:
//
template <class T>
typename boost::enable_if_c<sizeof(T) == INT_MAX>::type real();
template <class T>
typename boost::enable_if_c<sizeof(T) == INT_MAX>::type imag();
}} // namespaces

View File

@@ -875,6 +875,17 @@ inline void eval_proj(mpc_float_backend<Digits10>& result, const mpc_float_backe
mpc_proj(result.data(), arg.data(), GMP_RNDN);
}
template <unsigned Digits10>
inline void eval_real(mpfr_float_backend<Digits10>& result, const mpc_float_backend<Digits10>& arg)
{
mpc_real(result.data(), arg.data(), GMP_RNDN);
}
template <unsigned Digits10>
inline void eval_imag(mpfr_float_backend<Digits10>& result, const mpc_float_backend<Digits10>& arg)
{
mpc_imag(result.data(), arg.data(), GMP_RNDN);
}
template <unsigned Digits10>
inline std::size_t hash_value(const mpc_float_backend<Digits10>& val)
{
@@ -928,24 +939,6 @@ struct component_type<number<mpc_float_backend<Digits10>, ExpressionTemplates> >
typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
};
template <unsigned Digits10, expression_template_option ExpressionTemplates>
inline typename component_type<boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> >::type
real(const boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates>& arg)
{
typename component_type<boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> >::type result;
mpc_real(result.backend().data(), arg.backend().data(), GMP_RNDN);
return result;
}
template <unsigned Digits10, expression_template_option ExpressionTemplates>
inline typename component_type<boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> >::type
imag(const boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates>& arg)
{
typename component_type<boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> >::type result;
mpc_imag(result.backend().data(), arg.backend().data(), GMP_RNDN);
return result;
}
template <unsigned Digits10, expression_template_option ExpressionTemplates>
number<backends::mpc_float_backend<Digits10> > polar(number<backends::mpfr_float_backend<Digits10>, ExpressionTemplates>const& r, number<backends::mpfr_float_backend<Digits10>, ExpressionTemplates> const& theta)
{

View File

@@ -709,37 +709,19 @@ public:
//
// Complex number real and imag:
//
private:
typename real_and_imag_result<number<Backend, ExpressionTemplates> >::type
real_imp(const mpl::true_&)const
{
return boost::multiprecision::real(*this); // Individual backend must overload the non-member function "real".
}
typename real_and_imag_result<number<Backend, ExpressionTemplates> >::type
imag_imp(const mpl::true_&)const
{
return boost::multiprecision::imag(*this); // Individual backend must overload the non-member function "imag".
}
typename real_and_imag_result<number<Backend, ExpressionTemplates> >::type
real_imp(const mpl::false_&)const
{
return *this;
}
typename real_and_imag_result<number<Backend, ExpressionTemplates> >::type
imag_imp(const mpl::false_&)const
{
return 0;
}
public:
typename real_and_imag_result<number<Backend, ExpressionTemplates> >::type
real()const
{
return real_imp(mpl::bool_<number_category<Backend>::value == number_kind_complex>());
typename real_and_imag_result<multiprecision::number<Backend, ExpressionTemplates> >::type result;
eval_real(result.backend(), backend());
return result;
}
typename real_and_imag_result<number<Backend, ExpressionTemplates> >::type
imag()const
{
return imag_imp(mpl::bool_<number_category<Backend>::value == number_kind_complex>());
typename real_and_imag_result<multiprecision::number<Backend, ExpressionTemplates> >::type result;
eval_imag(result.backend(), backend());
return result;
}
private:
template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>

View File

@@ -1952,12 +1952,12 @@ typename boost::enable_if_c<boost::multiprecision::number_category<Real>::value
BOOST_CHECK_EQUAL(b, 20);
Real c(2, 3);
/*
BOOST_CHECK_EQUAL(a.real(), 30);
BOOST_CHECK_EQUAL(a.imag(), 0);
BOOST_CHECK_EQUAL(c.real(), 2);
BOOST_CHECK_EQUAL(c.imag(), 3);
*/
BOOST_CHECK_EQUAL(real(a), 30);
BOOST_CHECK_EQUAL(imag(a), 0);
BOOST_CHECK_EQUAL(real(c), 2);