mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-02-12 00:02:36 +00:00
complex/mpc: another attempt at getting real/imag working with gcc.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user