1 ///////////////////////////////////////////////////////////////////////////////
2 //  Copyright 2018 John Maddock. Distributed under the Boost
3 //  Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef BOOST_MULTIPRECISION_MPC_HPP
7 #define BOOST_MULTIPRECISION_MPC_HPP
8 
9 #include <boost/multiprecision/number.hpp>
10 #include <boost/cstdint.hpp>
11 #include <boost/multiprecision/detail/digits.hpp>
12 #include <boost/multiprecision/traits/is_variable_precision.hpp>
13 #include <boost/multiprecision/mpfr.hpp>
14 #include <boost/multiprecision/logged_adaptor.hpp>
15 #include <boost/functional/hash_fwd.hpp>
16 #include <mpc.h>
17 #include <cmath>
18 #include <algorithm>
19 #include <complex>
20 
21 #ifndef BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION
22 #  define BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION 20
23 #endif
24 
25 namespace boost{
26 namespace multiprecision{
27 namespace backends{
28 
29 template <unsigned digits10>
30 struct mpc_complex_backend;
31 
32 } // namespace backends
33 
34 template <unsigned digits10>
35 struct number_category<backends::mpc_complex_backend<digits10> > : public mpl::int_<number_kind_complex>{};
36 
37 namespace backends{
38 
39 namespace detail{
40 
41 
mpc_copy_precision(mpc_t dest,const mpc_t src)42 inline void mpc_copy_precision(mpc_t dest, const mpc_t src)
43 {
44    mpfr_prec_t p_dest = mpc_get_prec(dest);
45    mpfr_prec_t p_src = mpc_get_prec(src);
46    if (p_dest != p_src)
47       mpc_set_prec(dest, p_src);
48 }
mpc_copy_precision(mpc_t dest,const mpc_t src1,const mpc_t src2)49 inline void mpc_copy_precision(mpc_t dest, const mpc_t src1, const mpc_t src2)
50 {
51    mpfr_prec_t p_dest = mpc_get_prec(dest);
52    mpfr_prec_t p_src1 = mpc_get_prec(src1);
53    mpfr_prec_t p_src2 = mpc_get_prec(src2);
54    if (p_src2 > p_src1)
55       p_src1 = p_src2;
56    if (p_dest != p_src1)
57       mpc_set_prec(dest, p_src1);
58 }
59 
60 
61 template <unsigned digits10>
62 struct mpc_complex_imp
63 {
64 #ifdef BOOST_HAS_LONG_LONG
65    typedef mpl::list<long, boost::long_long_type>                     signed_types;
66    typedef mpl::list<unsigned long, boost::ulong_long_type>   unsigned_types;
67 #else
68    typedef mpl::list<long>                                signed_types;
69    typedef mpl::list<unsigned long>                       unsigned_types;
70 #endif
71    typedef mpl::list<double, long double>                 float_types;
72    typedef long                                           exponent_type;
73 
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp74    mpc_complex_imp()
75    {
76       mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
77       mpc_set_ui(m_data, 0u, GMP_RNDN);
78    }
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp79    mpc_complex_imp(unsigned digits2)
80    {
81       mpc_init2(m_data, digits2);
82       mpc_set_ui(m_data, 0u, GMP_RNDN);
83    }
84 
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp85    mpc_complex_imp(const mpc_complex_imp& o)
86    {
87       mpc_init2(m_data, mpc_get_prec(o.m_data));
88       if(o.m_data[0].re[0]._mpfr_d)
89          mpc_set(m_data, o.m_data, GMP_RNDN);
90    }
91 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp92    mpc_complex_imp(mpc_complex_imp&& o) BOOST_NOEXCEPT
93    {
94       m_data[0] = o.m_data[0];
95       o.m_data[0].re[0]._mpfr_d = 0;
96    }
97 #endif
operator =boost::multiprecision::backends::detail::mpc_complex_imp98    mpc_complex_imp& operator = (const mpc_complex_imp& o)
99    {
100       if( (o.m_data[0].re[0]._mpfr_d) && (this != &o) )
101       {
102          if (m_data[0].re[0]._mpfr_d == 0)
103             mpc_init2(m_data, mpc_get_prec(o.m_data));
104          mpc_set(m_data, o.m_data, GMP_RNDD);
105       }
106       return *this;
107    }
108 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::detail::mpc_complex_imp109    mpc_complex_imp& operator = (mpc_complex_imp&& o) BOOST_NOEXCEPT
110    {
111       mpc_swap(m_data, o.m_data);
112       return *this;
113    }
114 #endif
115 #ifdef BOOST_HAS_LONG_LONG
116 #ifdef _MPFR_H_HAVE_INTMAX_T
operator =boost::multiprecision::backends::detail::mpc_complex_imp117    mpc_complex_imp& operator = (boost::ulong_long_type i)
118    {
119       if(m_data[0].re[0]._mpfr_d == 0)
120          mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
121       mpc_set_uj(data(), i, GMP_RNDD);
122       return *this;
123    }
operator =boost::multiprecision::backends::detail::mpc_complex_imp124    mpc_complex_imp& operator = (boost::long_long_type i)
125    {
126       if(m_data[0].re[0]._mpfr_d == 0)
127          mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
128       mpc_set_sj(data(), i, GMP_RNDD);
129       return *this;
130    }
131 #else
operator =boost::multiprecision::backends::detail::mpc_complex_imp132    mpc_complex_imp& operator = (boost::ulong_long_type i)
133    {
134       mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data));
135       f = i;
136       mpc_set_fr(this->data(), f.data(), GMP_RNDN);
137       return *this;
138    }
operator =boost::multiprecision::backends::detail::mpc_complex_imp139    mpc_complex_imp& operator = (boost::long_long_type i)
140    {
141       mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data));
142       f = i;
143       mpc_set_fr(this->data(), f.data(), GMP_RNDN);
144       return *this;
145    }
146 #endif
147 #endif
operator =boost::multiprecision::backends::detail::mpc_complex_imp148    mpc_complex_imp& operator = (unsigned long i)
149    {
150       if(m_data[0].re[0]._mpfr_d == 0)
151          mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
152       mpc_set_ui(m_data, i, GMP_RNDN);
153       return *this;
154    }
operator =boost::multiprecision::backends::detail::mpc_complex_imp155    mpc_complex_imp& operator = (long i)
156    {
157       if(m_data[0].re[0]._mpfr_d == 0)
158          mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
159       mpc_set_si(m_data, i, GMP_RNDN);
160       return *this;
161    }
operator =boost::multiprecision::backends::detail::mpc_complex_imp162    mpc_complex_imp& operator = (double d)
163    {
164       if(m_data[0].re[0]._mpfr_d == 0)
165          mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
166       mpc_set_d(m_data, d, GMP_RNDN);
167       return *this;
168    }
operator =boost::multiprecision::backends::detail::mpc_complex_imp169    mpc_complex_imp& operator = (long double d)
170    {
171       if (m_data[0].re[0]._mpfr_d == 0)
172          mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
173       mpc_set_ld(m_data, d, GMP_RNDN);
174       return *this;
175    }
operator =boost::multiprecision::backends::detail::mpc_complex_imp176    mpc_complex_imp& operator = (mpz_t i)
177    {
178       if (m_data[0].re[0]._mpfr_d == 0)
179          mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
180       mpc_set_z(m_data, i, GMP_RNDN);
181       return *this;
182    }
operator =boost::multiprecision::backends::detail::mpc_complex_imp183    mpc_complex_imp& operator = (gmp_int i)
184    {
185       if (m_data[0].re[0]._mpfr_d == 0)
186          mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
187       mpc_set_z(m_data, i.data(), GMP_RNDN);
188       return *this;
189    }
190 
operator =boost::multiprecision::backends::detail::mpc_complex_imp191    mpc_complex_imp& operator = (const char* s)
192    {
193       using default_ops::eval_fpclassify;
194 
195       if(m_data[0].re[0]._mpfr_d == 0)
196          mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
197 
198       mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data));
199 
200       if(s && (*s == '('))
201       {
202          std::string part;
203          const char* p = ++s;
204          while(*p && (*p != ',') && (*p != ')'))
205             ++p;
206          part.assign(s, p);
207          if(part.size())
208             a = part.c_str();
209          else
210             a = 0uL;
211          s = p;
212          if(*p && (*p != ')'))
213          {
214             ++p;
215             while(*p && (*p != ')'))
216                ++p;
217             part.assign(s + 1, p);
218          }
219          else
220             part.erase();
221          if(part.size())
222             b = part.c_str();
223          else
224             b = 0uL;
225       }
226       else
227       {
228          a = s;
229          b = 0uL;
230       }
231 
232       if(eval_fpclassify(a) == (int)FP_NAN)
233       {
234          mpc_set_fr(this->data(), a.data(), GMP_RNDN);
235       }
236       else if(eval_fpclassify(b) == (int)FP_NAN)
237       {
238          mpc_set_fr(this->data(), b.data(), GMP_RNDN);
239       }
240       else
241       {
242          mpc_set_fr_fr(m_data, a.data(), b.data(), GMP_RNDN);
243       }
244       return *this;
245    }
swapboost::multiprecision::backends::detail::mpc_complex_imp246    void swap(mpc_complex_imp& o) BOOST_NOEXCEPT
247    {
248       mpc_swap(m_data, o.m_data);
249    }
strboost::multiprecision::backends::detail::mpc_complex_imp250    std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
251    {
252       BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
253 
254       mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data));
255 
256       mpc_real(a.data(), m_data, GMP_RNDD);
257       mpc_imag(b.data(), m_data, GMP_RNDD);
258 
259       if(eval_is_zero(b))
260          return a.str(digits, f);
261 
262       return "(" + a.str(digits, f) + "," + b.str(digits, f) + ")";
263    }
~mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp264    ~mpc_complex_imp() BOOST_NOEXCEPT
265    {
266       if(m_data[0].re[0]._mpfr_d)
267          mpc_clear(m_data);
268    }
negateboost::multiprecision::backends::detail::mpc_complex_imp269    void negate() BOOST_NOEXCEPT
270    {
271       BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
272       mpc_neg(m_data, m_data, GMP_RNDD);
273    }
compareboost::multiprecision::backends::detail::mpc_complex_imp274    int compare(const mpc_complex_imp& o)const BOOST_NOEXCEPT
275    {
276       BOOST_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d);
277       return mpc_cmp(m_data, o.m_data);
278    }
compareboost::multiprecision::backends::detail::mpc_complex_imp279    int compare(const mpc_complex_backend<digits10>& o)const BOOST_NOEXCEPT
280    {
281       BOOST_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d);
282       return mpc_cmp(m_data, o.data());
283    }
compareboost::multiprecision::backends::detail::mpc_complex_imp284    int compare(long int i)const BOOST_NOEXCEPT
285    {
286       BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
287       return mpc_cmp_si(m_data, i);
288    }
compareboost::multiprecision::backends::detail::mpc_complex_imp289    int compare(unsigned long int i)const BOOST_NOEXCEPT
290    {
291       BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
292       static const unsigned long int max_val = (std::numeric_limits<long>::max)();
293       if (i > max_val)
294       {
295          mpc_complex_imp d(mpc_get_prec(m_data));
296          d = i;
297          return compare(d);
298       }
299       return mpc_cmp_si(m_data, (long)i);
300    }
301    template <class V>
compareboost::multiprecision::backends::detail::mpc_complex_imp302    int compare(const V& v)const BOOST_NOEXCEPT
303    {
304       mpc_complex_imp d(mpc_get_prec(m_data));
305       d = v;
306       return compare(d);
307    }
databoost::multiprecision::backends::detail::mpc_complex_imp308    mpc_t& data() BOOST_NOEXCEPT
309    {
310       BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
311       return m_data;
312    }
databoost::multiprecision::backends::detail::mpc_complex_imp313    const mpc_t& data()const BOOST_NOEXCEPT
314    {
315       BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
316       return m_data;
317    }
318 protected:
319    mpc_t m_data;
get_default_precisionboost::multiprecision::backends::detail::mpc_complex_imp320    static unsigned& get_default_precision() BOOST_NOEXCEPT
321    {
322       static unsigned val = BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION;
323       return val;
324    }
325 };
326 
327 } // namespace detail
328 
329 template <unsigned digits10>
330 struct mpc_complex_backend : public detail::mpc_complex_imp<digits10>
331 {
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend332    mpc_complex_backend() : detail::mpc_complex_imp<digits10>() {}
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend333    mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<digits10>(o) {}
334 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend335    mpc_complex_backend(mpc_complex_backend&& o) : detail::mpc_complex_imp<digits10>(static_cast<detail::mpc_complex_imp<digits10>&&>(o)) {}
336 #endif
337    template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend338    mpc_complex_backend(const mpc_complex_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
339        : detail::mpc_complex_imp<digits10>()
340    {
341       mpc_set(this->m_data, val.data(), GMP_RNDN);
342    }
343    template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend344    explicit mpc_complex_backend(const mpc_complex_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
345        : detail::mpc_complex_imp<digits10>()
346    {
347       mpc_set(this->m_data, val.data(), GMP_RNDN);
348    }
349    template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend350    mpc_complex_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
351        : detail::mpc_complex_imp<digits10>()
352    {
353       mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
354    }
355    template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend356    explicit mpc_complex_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
357        : detail::mpc_complex_imp<digits10>()
358    {
359       mpc_set(this->m_data, val.data(), GMP_RNDN);
360    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend361    mpc_complex_backend(const mpc_t val)
362        : detail::mpc_complex_imp<digits10>()
363    {
364       mpc_set(this->m_data, val, GMP_RNDN);
365    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend366    mpc_complex_backend(const std::complex<float>& val)
367        : detail::mpc_complex_imp<digits10>()
368    {
369       mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
370    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend371    mpc_complex_backend(const std::complex<double>& val)
372        : detail::mpc_complex_imp<digits10>()
373    {
374       mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
375    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend376    mpc_complex_backend(const std::complex<long double>& val)
377        : detail::mpc_complex_imp<digits10>()
378    {
379       mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
380    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend381    mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<digits10>()
382    {
383       mpc_set_z(this->m_data, val, GMP_RNDN);
384    }
operator =boost::multiprecision::backends::mpc_complex_backend385    mpc_complex_backend& operator=(mpz_srcptr val)
386    {
387       mpc_set_z(this->m_data, val, GMP_RNDN);
388       return *this;
389    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend390    mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<digits10>()
391    {
392       mpc_set_z(this->m_data, val.data(), GMP_RNDN);
393    }
operator =boost::multiprecision::backends::mpc_complex_backend394    mpc_complex_backend& operator=(gmp_int const& val)
395    {
396       mpc_set_z(this->m_data, val.data(), GMP_RNDN);
397       return *this;
398    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend399    mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<digits10>()
400    {
401       mpc_set_f(this->m_data, val, GMP_RNDN);
402    }
operator =boost::multiprecision::backends::mpc_complex_backend403    mpc_complex_backend& operator=(mpf_srcptr val)
404    {
405       mpc_set_f(this->m_data, val, GMP_RNDN);
406       return *this;
407    }
408    template <unsigned D10>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend409    mpc_complex_backend(gmp_float<D10> const& val) : detail::mpc_complex_imp<digits10>()
410    {
411       mpc_set_f(this->m_data, val.data(), GMP_RNDN);
412    }
413    template <unsigned D10>
operator =boost::multiprecision::backends::mpc_complex_backend414    mpc_complex_backend& operator=(gmp_float<D10> const& val)
415    {
416       mpc_set_f(this->m_data, val.data(), GMP_RNDN);
417       return *this;
418    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend419    mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<digits10>()
420    {
421       mpc_set_q(this->m_data, val, GMP_RNDN);
422    }
operator =boost::multiprecision::backends::mpc_complex_backend423    mpc_complex_backend& operator=(mpq_srcptr val)
424    {
425       mpc_set_q(this->m_data, val, GMP_RNDN);
426       return *this;
427    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend428    mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<digits10>()
429    {
430       mpc_set_q(this->m_data, val.data(), GMP_RNDN);
431    }
operator =boost::multiprecision::backends::mpc_complex_backend432    mpc_complex_backend& operator=(gmp_rational const& val)
433    {
434       mpc_set_q(this->m_data, val.data(), GMP_RNDN);
435       return *this;
436    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend437    mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<digits10>()
438    {
439       mpc_set_fr(this->m_data, val, GMP_RNDN);
440    }
operator =boost::multiprecision::backends::mpc_complex_backend441    mpc_complex_backend& operator=(mpfr_srcptr val)
442    {
443       mpc_set_fr(this->m_data, val, GMP_RNDN);
444       return *this;
445    }
446    template <unsigned D10, mpfr_allocation_type AllocationType>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend447    mpc_complex_backend(mpfr_float_backend<D10, AllocationType> const& val) : detail::mpc_complex_imp<digits10>()
448    {
449       mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
450    }
451    template <unsigned D10, mpfr_allocation_type AllocationType>
operator =boost::multiprecision::backends::mpc_complex_backend452    mpc_complex_backend& operator=(mpfr_float_backend<D10, AllocationType> const& val)
453    {
454       mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
455       return *this;
456    }
operator =boost::multiprecision::backends::mpc_complex_backend457    mpc_complex_backend& operator=(const mpc_complex_backend& o)
458    {
459       *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10> const&>(o);
460       return *this;
461    }
462 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::mpc_complex_backend463    mpc_complex_backend& operator=(mpc_complex_backend&& o) BOOST_NOEXCEPT
464    {
465       *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10>&&>(o);
466       return *this;
467    }
468 #endif
469    template <class V>
operator =boost::multiprecision::backends::mpc_complex_backend470    mpc_complex_backend& operator=(const V& v)
471    {
472       *static_cast<detail::mpc_complex_imp<digits10>*>(this) = v;
473       return *this;
474    }
operator =boost::multiprecision::backends::mpc_complex_backend475    mpc_complex_backend& operator=(const mpc_t val)
476    {
477       mpc_set(this->m_data, val, GMP_RNDN);
478       return *this;
479    }
operator =boost::multiprecision::backends::mpc_complex_backend480    mpc_complex_backend& operator=(const std::complex<float>& val)
481    {
482       mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
483       return *this;
484    }
operator =boost::multiprecision::backends::mpc_complex_backend485    mpc_complex_backend& operator=(const std::complex<double>& val)
486    {
487       mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
488       return *this;
489    }
operator =boost::multiprecision::backends::mpc_complex_backend490    mpc_complex_backend& operator=(const std::complex<long double>& val)
491    {
492       mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
493       return *this;
494    }
495    // We don't change our precision here, this is a fixed precision type:
496    template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend497    mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
498    {
499       mpc_set(this->m_data, val.data(), GMP_RNDN);
500       return *this;
501    }
502 };
503 
504 template <>
505 struct mpc_complex_backend<0> : public detail::mpc_complex_imp<0>
506 {
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend507    mpc_complex_backend() : detail::mpc_complex_imp<0>() {}
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend508    mpc_complex_backend(const mpc_t val)
509       : detail::mpc_complex_imp<0>(mpc_get_prec(val))
510    {
511       mpc_set(this->m_data, val, GMP_RNDN);
512    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend513    mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<0>(o) {}
514 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend515    mpc_complex_backend(mpc_complex_backend&& o) BOOST_NOEXCEPT : detail::mpc_complex_imp<0>(static_cast<detail::mpc_complex_imp<0>&&>(o)) {}
516 #endif
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend517    mpc_complex_backend(const mpc_complex_backend& o, unsigned digits10)
518       : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
519    {
520       mpc_set(this->m_data, o.data(), GMP_RNDN);
521    }
522    template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend523    mpc_complex_backend(const mpc_complex_backend<D>& val)
524       : detail::mpc_complex_imp<0>(mpc_get_prec(val.data()))
525    {
526       mpc_set(this->m_data, val.data(), GMP_RNDN);
527    }
528    template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend529    mpc_complex_backend(const mpfr_float_backend<D>& val)
530       : detail::mpc_complex_imp<0>(mpfr_get_prec(val.data()))
531    {
532       mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
533    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend534    mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<0>()
535    {
536       mpc_set_z(this->m_data, val, GMP_RNDN);
537    }
operator =boost::multiprecision::backends::mpc_complex_backend538    mpc_complex_backend& operator=(mpz_srcptr val)
539    {
540       mpc_set_z(this->m_data, val, GMP_RNDN);
541       return *this;
542    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend543    mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<0>()
544    {
545       mpc_set_z(this->m_data, val.data(), GMP_RNDN);
546    }
operator =boost::multiprecision::backends::mpc_complex_backend547    mpc_complex_backend& operator=(gmp_int const& val)
548    {
549       mpc_set_z(this->m_data, val.data(), GMP_RNDN);
550       return *this;
551    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend552    mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val))
553    {
554       mpc_set_f(this->m_data, val, GMP_RNDN);
555    }
operator =boost::multiprecision::backends::mpc_complex_backend556    mpc_complex_backend& operator=(mpf_srcptr val)
557    {
558       if (mpc_get_prec(data()) != mpf_get_prec(val))
559       {
560          mpc_complex_backend t(val);
561          t.swap(*this);
562       }
563       else
564          mpc_set_f(this->m_data, val, GMP_RNDN);
565       return *this;
566    }
567    template <unsigned digits10>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend568    mpc_complex_backend(gmp_float<digits10> const& val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val.data()))
569    {
570       mpc_set_f(this->m_data, val.data(), GMP_RNDN);
571    }
572    template <unsigned digits10>
operator =boost::multiprecision::backends::mpc_complex_backend573    mpc_complex_backend& operator=(gmp_float<digits10> const& val)
574    {
575       if (mpc_get_prec(data()) != mpf_get_prec(val.data()))
576       {
577          mpc_complex_backend t(val);
578          t.swap(*this);
579       }
580       else
581          mpc_set_f(this->m_data, val.data(), GMP_RNDN);
582       return *this;
583    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend584    mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<0>()
585    {
586       mpc_set_q(this->m_data, val, GMP_RNDN);
587    }
operator =boost::multiprecision::backends::mpc_complex_backend588    mpc_complex_backend& operator=(mpq_srcptr val)
589    {
590       mpc_set_q(this->m_data, val, GMP_RNDN);
591       return *this;
592    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend593    mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<0>()
594    {
595       mpc_set_q(this->m_data, val.data(), GMP_RNDN);
596    }
operator =boost::multiprecision::backends::mpc_complex_backend597    mpc_complex_backend& operator=(gmp_rational const& val)
598    {
599       mpc_set_q(this->m_data, val.data(), GMP_RNDN);
600       return *this;
601    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend602    mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<0>(mpfr_get_prec(val))
603    {
604       mpc_set_fr(this->m_data, val, GMP_RNDN);
605    }
operator =boost::multiprecision::backends::mpc_complex_backend606    mpc_complex_backend& operator=(mpfr_srcptr val)
607    {
608       if (mpc_get_prec(data()) != mpfr_get_prec(val))
609       {
610          mpc_complex_backend t(val);
611          t.swap(*this);
612       }
613       else
614          mpc_set_fr(this->m_data, val, GMP_RNDN);
615       return *this;
616    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend617    mpc_complex_backend(const std::complex<float>& val)
618       : detail::mpc_complex_imp<0>()
619    {
620       mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
621    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend622    mpc_complex_backend(const std::complex<double>& val)
623       : detail::mpc_complex_imp<0>()
624    {
625       mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
626    }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend627    mpc_complex_backend(const std::complex<long double>& val)
628       : detail::mpc_complex_imp<0>()
629    {
630       mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
631    }
632    // Construction with precision:
633    template <class T, class U>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend634    mpc_complex_backend(const T& a, const U& b, unsigned digits10)
635       : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
636    {
637       // We can't use assign_components here because it copies the precision of
638       // a and b, not digits10....
639       mpfr_float ca(a), cb(b);
640       mpc_set_fr_fr(this->data(), ca.backend().data(), cb.backend().data(), GMP_RNDN);
641    }
642    template <unsigned N>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend643    mpc_complex_backend(const mpfr_float_backend<N>& a, const mpfr_float_backend<N>& b, unsigned digits10)
644       : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
645    {
646       mpc_set_fr_fr(this->data(), a.data(), b.data(), GMP_RNDN);
647    }
648 
operator =boost::multiprecision::backends::mpc_complex_backend649    mpc_complex_backend& operator=(const mpc_complex_backend& o)
650    {
651       if (this != &o)
652       {
653          detail::mpc_copy_precision(this->m_data, o.data());
654          mpc_set(this->m_data, o.data(), GMP_RNDN);
655       }
656       return *this;
657    }
658 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::mpc_complex_backend659    mpc_complex_backend& operator=(mpc_complex_backend&& o) BOOST_NOEXCEPT
660    {
661       *static_cast<detail::mpc_complex_imp<0>*>(this) = static_cast<detail::mpc_complex_imp<0> &&>(o);
662       return *this;
663    }
664 #endif
665    template <class V>
operator =boost::multiprecision::backends::mpc_complex_backend666    mpc_complex_backend& operator=(const V& v)
667    {
668       *static_cast<detail::mpc_complex_imp<0>*>(this) = v;
669       return *this;
670    }
operator =boost::multiprecision::backends::mpc_complex_backend671    mpc_complex_backend& operator=(const mpc_t val)
672    {
673       mpc_set_prec(this->m_data, mpc_get_prec(val));
674       mpc_set(this->m_data, val, GMP_RNDN);
675       return *this;
676    }
677    template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend678    mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
679    {
680       mpc_set_prec(this->m_data, mpc_get_prec(val.data()));
681       mpc_set(this->m_data, val.data(), GMP_RNDN);
682       return *this;
683    }
684    template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend685    mpc_complex_backend& operator=(const mpfr_float_backend<D>& val)
686    {
687       mpc_set_prec(this->m_data, mpfr_get_prec(val.data()));
688       mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
689       return *this;
690    }
operator =boost::multiprecision::backends::mpc_complex_backend691    mpc_complex_backend& operator=(const std::complex<float>& val)
692    {
693       mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
694       return *this;
695    }
operator =boost::multiprecision::backends::mpc_complex_backend696    mpc_complex_backend& operator=(const std::complex<double>& val)
697    {
698       mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
699       return *this;
700    }
operator =boost::multiprecision::backends::mpc_complex_backend701    mpc_complex_backend& operator=(const std::complex<long double>& val)
702    {
703       mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
704       return *this;
705    }
default_precisionboost::multiprecision::backends::mpc_complex_backend706    static unsigned default_precision() BOOST_NOEXCEPT
707    {
708       return get_default_precision();
709    }
default_precisionboost::multiprecision::backends::mpc_complex_backend710    static void default_precision(unsigned v) BOOST_NOEXCEPT
711    {
712       get_default_precision() = v;
713    }
precisionboost::multiprecision::backends::mpc_complex_backend714    unsigned precision()const BOOST_NOEXCEPT
715    {
716       return multiprecision::detail::digits2_2_10(mpc_get_prec(this->m_data));
717    }
precisionboost::multiprecision::backends::mpc_complex_backend718    void precision(unsigned digits10) BOOST_NOEXCEPT
719    {
720       mpfr_prec_round(mpc_realref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
721       mpfr_prec_round(mpc_imagref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
722    }
723 };
724 
725 template <unsigned digits10, class T>
eval_eq(const mpc_complex_backend<digits10> & a,const T & b)726 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
727 {
728    return a.compare(b) == 0;
729 }
730 template <unsigned digits10, class T>
eval_lt(const mpc_complex_backend<digits10> & a,const T & b)731 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
732 {
733    return a.compare(b) < 0;
734 }
735 template <unsigned digits10, class T>
eval_gt(const mpc_complex_backend<digits10> & a,const T & b)736 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
737 {
738    return a.compare(b) > 0;
739 }
740 
741 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)742 inline void eval_add(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
743 {
744    mpc_add(result.data(), result.data(), o.data(), GMP_RNDD);
745 }
746 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)747 inline void eval_add(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
748 {
749    mpc_add_fr(result.data(), result.data(), o.data(), GMP_RNDD);
750 }
751 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)752 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
753 {
754    mpc_sub(result.data(), result.data(), o.data(), GMP_RNDD);
755 }
756 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)757 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
758 {
759    mpc_sub_fr(result.data(), result.data(), o.data(), GMP_RNDD);
760 }
761 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)762 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
763 {
764    if((void*)&result == (void*)&o)
765       mpc_sqr(result.data(), o.data(), GMP_RNDN);
766    else
767       mpc_mul(result.data(), result.data(), o.data(), GMP_RNDN);
768 }
769 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)770 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
771 {
772    mpc_mul_fr(result.data(), result.data(), o.data(), GMP_RNDN);
773 }
774 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)775 inline void eval_divide(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
776 {
777    mpc_div(result.data(), result.data(), o.data(), GMP_RNDD);
778 }
779 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)780 inline void eval_divide(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
781 {
782    mpc_div_fr(result.data(), result.data(), o.data(), GMP_RNDD);
783 }
784 template <unsigned digits10>
eval_add(mpc_complex_backend<digits10> & result,unsigned long i)785 inline void eval_add(mpc_complex_backend<digits10>& result, unsigned long i)
786 {
787    mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
788 }
789 template <unsigned digits10>
eval_subtract(mpc_complex_backend<digits10> & result,unsigned long i)790 inline void eval_subtract(mpc_complex_backend<digits10>& result, unsigned long i)
791 {
792    mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
793 }
794 template <unsigned digits10>
eval_multiply(mpc_complex_backend<digits10> & result,unsigned long i)795 inline void eval_multiply(mpc_complex_backend<digits10>& result, unsigned long i)
796 {
797    mpc_mul_ui(result.data(), result.data(), i, GMP_RNDN);
798 }
799 template <unsigned digits10>
eval_divide(mpc_complex_backend<digits10> & result,unsigned long i)800 inline void eval_divide(mpc_complex_backend<digits10>& result, unsigned long i)
801 {
802    mpc_div_ui(result.data(), result.data(), i, GMP_RNDN);
803 }
804 template <unsigned digits10>
eval_add(mpc_complex_backend<digits10> & result,long i)805 inline void eval_add(mpc_complex_backend<digits10>& result, long i)
806 {
807    if(i > 0)
808       mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
809    else
810       mpc_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
811 }
812 template <unsigned digits10>
eval_subtract(mpc_complex_backend<digits10> & result,long i)813 inline void eval_subtract(mpc_complex_backend<digits10>& result, long i)
814 {
815    if(i > 0)
816       mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
817    else
818       mpc_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
819 }
820 template <unsigned digits10>
eval_multiply(mpc_complex_backend<digits10> & result,long i)821 inline void eval_multiply(mpc_complex_backend<digits10>& result, long i)
822 {
823    mpc_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
824    if(i < 0)
825       mpc_neg(result.data(), result.data(), GMP_RNDN);
826 }
827 template <unsigned digits10>
eval_divide(mpc_complex_backend<digits10> & result,long i)828 inline void eval_divide(mpc_complex_backend<digits10>& result, long i)
829 {
830    mpc_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
831    if(i < 0)
832       mpc_neg(result.data(), result.data(), GMP_RNDN);
833 }
834 //
835 // Specialised 3 arg versions of the basic operators:
836 //
837 template <unsigned D1, unsigned D2, unsigned D3>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpc_complex_backend<D3> & y)838 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
839 {
840    mpc_add(a.data(), x.data(), y.data(), GMP_RNDD);
841 }
842 template <unsigned D1, unsigned D2, unsigned D3>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpfr_float_backend<D3> & y)843 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
844 {
845    mpc_add_fr(a.data(), x.data(), y.data(), GMP_RNDD);
846 }
847 template <unsigned D1, unsigned D2, unsigned D3>
eval_add(mpc_complex_backend<D1> & a,const mpfr_float_backend<D2> & x,const mpc_complex_backend<D3> & y)848 inline void eval_add(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
849 {
850    mpc_add_fr(a.data(), y.data(), x.data(), GMP_RNDD);
851 }
852 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)853 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
854 {
855    mpc_add_ui(a.data(), x.data(), y, GMP_RNDD);
856 }
857 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)858 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
859 {
860    if(y < 0)
861       mpc_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
862    else
863       mpc_add_ui(a.data(), x.data(), y, GMP_RNDD);
864 }
865 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)866 inline void eval_add(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
867 {
868    mpc_add_ui(a.data(), y.data(), x, GMP_RNDD);
869 }
870 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)871 inline void eval_add(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
872 {
873    if(x < 0)
874    {
875       mpc_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
876       mpc_neg(a.data(), a.data(), GMP_RNDD);
877    }
878    else
879       mpc_add_ui(a.data(), y.data(), x, GMP_RNDD);
880 }
881 template <unsigned D1, unsigned D2, unsigned D3>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpc_complex_backend<D3> & y)882 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
883 {
884    mpc_sub(a.data(), x.data(), y.data(), GMP_RNDD);
885 }
886 template <unsigned D1, unsigned D2, unsigned D3>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpfr_float_backend<D3> & y)887 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
888 {
889    mpc_sub_fr(a.data(), x.data(), y.data(), GMP_RNDD);
890 }
891 template <unsigned D1, unsigned D2, unsigned D3>
eval_subtract(mpc_complex_backend<D1> & a,const mpfr_float_backend<D2> & x,const mpc_complex_backend<D3> & y)892 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
893 {
894    mpc_fr_sub(a.data(), x.data(), y.data(), GMP_RNDD);
895 }
896 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)897 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
898 {
899    mpc_sub_ui(a.data(), x.data(), y, GMP_RNDD);
900 }
901 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)902 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
903 {
904    if(y < 0)
905       mpc_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
906    else
907       mpc_sub_ui(a.data(), x.data(), y, GMP_RNDD);
908 }
909 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)910 inline void eval_subtract(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
911 {
912    mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
913 }
914 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)915 inline void eval_subtract(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
916 {
917    if(x < 0)
918    {
919       mpc_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDD);
920       mpc_neg(a.data(), a.data(), GMP_RNDD);
921    }
922    else
923       mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
924 }
925 
926 template <unsigned D1, unsigned D2, unsigned D3>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpc_complex_backend<D3> & y)927 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
928 {
929    if((void*)&x == (void*)&y)
930       mpc_sqr(a.data(), x.data(), GMP_RNDD);
931    else
932       mpc_mul(a.data(), x.data(), y.data(), GMP_RNDD);
933 }
934 template <unsigned D1, unsigned D2, unsigned D3>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpfr_float_backend<D3> & y)935 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
936 {
937    mpc_mul_fr(a.data(), x.data(), y.data(), GMP_RNDD);
938 }
939 template <unsigned D1, unsigned D2, unsigned D3>
eval_multiply(mpc_complex_backend<D1> & a,const mpfr_float_backend<D2> & x,const mpc_complex_backend<D3> & y)940 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
941 {
942    mpc_mul_fr(a.data(), y.data(), x.data(), GMP_RNDD);
943 }
944 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)945 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
946 {
947    mpc_mul_ui(a.data(), x.data(), y, GMP_RNDD);
948 }
949 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)950 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
951 {
952    if(y < 0)
953    {
954       mpc_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
955       a.negate();
956    }
957    else
958       mpc_mul_ui(a.data(), x.data(), y, GMP_RNDD);
959 }
960 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)961 inline void eval_multiply(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
962 {
963    mpc_mul_ui(a.data(), y.data(), x, GMP_RNDD);
964 }
965 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)966 inline void eval_multiply(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
967 {
968    if(x < 0)
969    {
970       mpc_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDD);
971       mpc_neg(a.data(), a.data(), GMP_RNDD);
972    }
973    else
974       mpc_mul_ui(a.data(), y.data(), x, GMP_RNDD);
975 }
976 
977 template <unsigned D1, unsigned D2, unsigned D3>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpc_complex_backend<D3> & y)978 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
979 {
980    mpc_div(a.data(), x.data(), y.data(), GMP_RNDD);
981 }
982 template <unsigned D1, unsigned D2, unsigned D3>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,const mpfr_float_backend<D3> & y)983 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
984 {
985    mpc_div_fr(a.data(), x.data(), y.data(), GMP_RNDD);
986 }
987 template <unsigned D1, unsigned D2, unsigned D3>
eval_divide(mpc_complex_backend<D1> & a,const mpfr_float_backend<D2> & x,const mpc_complex_backend<D3> & y)988 inline void eval_divide(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
989 {
990    mpc_fr_div(a.data(), x.data(), y.data(), GMP_RNDD);
991 }
992 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)993 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
994 {
995    mpc_div_ui(a.data(), x.data(), y, GMP_RNDD);
996 }
997 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)998 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
999 {
1000    if(y < 0)
1001    {
1002       mpc_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
1003       a.negate();
1004    }
1005    else
1006       mpc_div_ui(a.data(), x.data(), y, GMP_RNDD);
1007 }
1008 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)1009 inline void eval_divide(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
1010 {
1011    mpc_ui_div(a.data(), x, y.data(), GMP_RNDD);
1012 }
1013 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)1014 inline void eval_divide(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
1015 {
1016    if(x < 0)
1017    {
1018       mpc_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDD);
1019       mpc_neg(a.data(), a.data(), GMP_RNDD);
1020    }
1021    else
1022       mpc_ui_div(a.data(), x, y.data(), GMP_RNDD);
1023 }
1024 
1025 template <unsigned digits10>
eval_is_zero(const mpc_complex_backend<digits10> & val)1026 inline bool eval_is_zero(const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1027 {
1028    return (0 != mpfr_zero_p(mpc_realref(val.data()))) && (0 != mpfr_zero_p(mpc_imagref(val.data())));
1029 }
1030 template <unsigned digits10>
eval_get_sign(const mpc_complex_backend<digits10> &)1031 inline int eval_get_sign(const mpc_complex_backend<digits10>&)
1032 {
1033    BOOST_STATIC_ASSERT_MSG(digits10 == UINT_MAX, "Complex numbers have no sign bit."); // designed to always fail
1034    return 0;
1035 }
1036 
1037 template <unsigned digits10>
eval_convert_to(unsigned long * result,const mpc_complex_backend<digits10> & val)1038 inline void eval_convert_to(unsigned long* result, const mpc_complex_backend<digits10>& val)
1039 {
1040    if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1041    {
1042       BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1043    }
1044    mpfr_float_backend<digits10> t;
1045    mpc_real(t.data(), val.data(), GMP_RNDN);
1046    eval_convert_to(result, t);
1047 }
1048 template <unsigned digits10>
eval_convert_to(long * result,const mpc_complex_backend<digits10> & val)1049 inline void eval_convert_to(long* result, const mpc_complex_backend<digits10>& val)
1050 {
1051    if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1052    {
1053       BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1054    }
1055    mpfr_float_backend<digits10> t;
1056    mpc_real(t.data(), val.data(), GMP_RNDN);
1057    eval_convert_to(result, t);
1058 }
1059 #ifdef _MPFR_H_HAVE_INTMAX_T
1060 template <unsigned digits10>
eval_convert_to(boost::ulong_long_type * result,const mpc_complex_backend<digits10> & val)1061 inline void eval_convert_to(boost::ulong_long_type* result, const mpc_complex_backend<digits10>& val)
1062 {
1063    if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1064    {
1065       BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1066    }
1067    mpfr_float_backend<digits10> t;
1068    mpc_real(t.data(), val.data(), GMP_RNDN);
1069    eval_convert_to(result, t);
1070 }
1071 template <unsigned digits10>
eval_convert_to(boost::long_long_type * result,const mpc_complex_backend<digits10> & val)1072 inline void eval_convert_to(boost::long_long_type* result, const mpc_complex_backend<digits10>& val)
1073 {
1074    if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1075    {
1076       BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1077    }
1078    mpfr_float_backend<digits10> t;
1079    mpc_real(t.data(), val.data(), GMP_RNDN);
1080    eval_convert_to(result, t);
1081 }
1082 #endif
1083 template <unsigned digits10>
eval_convert_to(double * result,const mpc_complex_backend<digits10> & val)1084 inline void eval_convert_to(double* result, const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1085 {
1086    if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1087    {
1088       BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1089    }
1090    mpfr_float_backend<digits10> t;
1091    mpc_real(t.data(), val.data(), GMP_RNDN);
1092    eval_convert_to(result, t);
1093 }
1094 template <unsigned digits10>
eval_convert_to(long double * result,const mpc_complex_backend<digits10> & val)1095 inline void eval_convert_to(long double* result, const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1096 {
1097    if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1098    {
1099       BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1100    }
1101    mpfr_float_backend<digits10> t;
1102    mpc_real(t.data(), val.data(), GMP_RNDN);
1103    eval_convert_to(result, t);
1104 }
1105 
1106 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2,AllocationType> & a,const mpfr_float_backend<D2,AllocationType> & b)1107 inline void assign_components(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
1108 {
1109    //
1110    // This is called from class number's constructors, so if we have variable
1111    // precision, then copy the precision of the source variables.
1112    //
1113    if (!D1)
1114    {
1115       unsigned long prec = std::max(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
1116       mpc_set_prec(result.data(), prec);
1117    }
1118    using default_ops::eval_fpclassify;
1119    if(eval_fpclassify(a) == (int)FP_NAN)
1120    {
1121       mpc_set_fr(result.data(), a.data(), GMP_RNDN);
1122    }
1123    else if(eval_fpclassify(b) == (int)FP_NAN)
1124    {
1125       mpc_set_fr(result.data(), b.data(), GMP_RNDN);
1126    }
1127    else
1128    {
1129       mpc_set_fr_fr(result.data(), a.data(), b.data(), GMP_RNDN);
1130    }
1131 }
1132 
1133 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,unsigned long a,unsigned long b)1134 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long a, unsigned long b)
1135 {
1136    mpc_set_ui_ui(result.data(), a, b, GMP_RNDN);
1137 }
1138 
1139 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long a,long b)1140 inline void assign_components(mpc_complex_backend<D1>& result, long a, long b)
1141 {
1142    mpc_set_si_si(result.data(), a, b, GMP_RNDN);
1143 }
1144 
1145 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1146 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,unsigned long long a,unsigned long long b)1147 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long long a, unsigned long long b)
1148 {
1149    mpc_set_uj_uj(result.data(), a, b, GMP_RNDN);
1150 }
1151 
1152 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long long a,long long b)1153 inline void assign_components(mpc_complex_backend<D1>& result, long long a, long long b)
1154 {
1155    mpc_set_sj_sj(result.data(), a, b, GMP_RNDN);
1156 }
1157 #endif
1158 
1159 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,double a,double b)1160 inline void assign_components(mpc_complex_backend<D1>& result, double a, double b)
1161 {
1162    if ((boost::math::isnan)(a))
1163    {
1164       mpc_set_d(result.data(), a, GMP_RNDN);
1165    }
1166    else if ((boost::math::isnan)(b))
1167    {
1168       mpc_set_d(result.data(), b, GMP_RNDN);
1169    }
1170    else
1171    {
1172       mpc_set_d_d(result.data(), a, b, GMP_RNDN);
1173    }
1174 }
1175 
1176 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long double a,long double b)1177 inline void assign_components(mpc_complex_backend<D1>& result, long double a, long double b)
1178 {
1179    if ((boost::math::isnan)(a))
1180    {
1181       mpc_set_d(result.data(), a, GMP_RNDN);
1182    }
1183    else if ((boost::math::isnan)(b))
1184    {
1185       mpc_set_d(result.data(), b, GMP_RNDN);
1186    }
1187    else
1188    {
1189       mpc_set_ld_ld(result.data(), a, b, GMP_RNDN);
1190    }
1191 }
1192 
1193 //
1194 // Native non-member operations:
1195 //
1196 template <unsigned Digits10>
eval_sqrt(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & val)1197 inline void eval_sqrt(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& val)
1198 {
1199    mpc_sqrt(result.data(), val.data(), GMP_RNDN);
1200 }
1201 
1202 template <unsigned Digits10>
eval_pow(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & b,const mpc_complex_backend<Digits10> & e)1203 inline void eval_pow(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& b, const mpc_complex_backend<Digits10>& e)
1204 {
1205    mpc_pow(result.data(), b.data(), e.data(), GMP_RNDN);
1206 }
1207 
1208 template <unsigned Digits10>
eval_exp(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1209 inline void eval_exp(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1210 {
1211    mpc_exp(result.data(), arg.data(), GMP_RNDN);
1212 }
1213 
1214 template <unsigned Digits10>
eval_log(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1215 inline void eval_log(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1216 {
1217    mpc_log(result.data(), arg.data(), GMP_RNDN);
1218 }
1219 
1220 template <unsigned Digits10>
eval_log10(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1221 inline void eval_log10(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1222 {
1223    mpc_log10(result.data(), arg.data(), GMP_RNDN);
1224 }
1225 
1226 template <unsigned Digits10>
eval_sin(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1227 inline void eval_sin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1228 {
1229    mpc_sin(result.data(), arg.data(), GMP_RNDN);
1230 }
1231 
1232 template <unsigned Digits10>
eval_cos(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1233 inline void eval_cos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1234 {
1235    mpc_cos(result.data(), arg.data(), GMP_RNDN);
1236 }
1237 
1238 template <unsigned Digits10>
eval_tan(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1239 inline void eval_tan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1240 {
1241    mpc_tan(result.data(), arg.data(), GMP_RNDN);
1242 }
1243 
1244 template <unsigned Digits10>
eval_asin(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1245 inline void eval_asin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1246 {
1247    mpc_asin(result.data(), arg.data(), GMP_RNDN);
1248 }
1249 
1250 template <unsigned Digits10>
eval_acos(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1251 inline void eval_acos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1252 {
1253    mpc_acos(result.data(), arg.data(), GMP_RNDN);
1254 }
1255 
1256 template <unsigned Digits10>
eval_atan(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1257 inline void eval_atan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1258 {
1259    mpc_atan(result.data(), arg.data(), GMP_RNDN);
1260 }
1261 
1262 template <unsigned Digits10>
eval_sinh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1263 inline void eval_sinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1264 {
1265    mpc_sinh(result.data(), arg.data(), GMP_RNDN);
1266 }
1267 
1268 template <unsigned Digits10>
eval_cosh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1269 inline void eval_cosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1270 {
1271    mpc_cosh(result.data(), arg.data(), GMP_RNDN);
1272 }
1273 
1274 template <unsigned Digits10>
eval_tanh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1275 inline void eval_tanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1276 {
1277    mpc_tanh(result.data(), arg.data(), GMP_RNDN);
1278 }
1279 
1280 template <unsigned Digits10>
eval_asinh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1281 inline void eval_asinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1282 {
1283    mpc_asinh(result.data(), arg.data(), GMP_RNDN);
1284 }
1285 
1286 template <unsigned Digits10>
eval_acosh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1287 inline void eval_acosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1288 {
1289    mpc_acosh(result.data(), arg.data(), GMP_RNDN);
1290 }
1291 
1292 template <unsigned Digits10>
eval_atanh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1293 inline void eval_atanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1294 {
1295    mpc_atanh(result.data(), arg.data(), GMP_RNDN);
1296 }
1297 
1298 template <unsigned Digits10>
eval_conj(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1299 inline void eval_conj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1300 {
1301    mpc_conj(result.data(), arg.data(), GMP_RNDN);
1302 }
1303 
1304 template <unsigned Digits10>
eval_proj(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1305 inline void eval_proj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1306 {
1307    mpc_proj(result.data(), arg.data(), GMP_RNDN);
1308 }
1309 
1310 template <unsigned Digits10>
eval_real(mpfr_float_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1311 inline void eval_real(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1312 {
1313    mpfr_set_prec(result.data(), mpfr_get_prec(mpc_realref(arg.data())));
1314    mpfr_set(result.data(), mpc_realref(arg.data()), GMP_RNDN);
1315 }
1316 template <unsigned Digits10>
eval_imag(mpfr_float_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1317 inline void eval_imag(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1318 {
1319    mpfr_set_prec(result.data(), mpfr_get_prec(mpc_imagref(arg.data())));
1320    mpfr_set(result.data(), mpc_imagref(arg.data()), GMP_RNDN);
1321 }
1322 
1323 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const mpfr_float_backend<Digits10> & arg)1324 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1325 {
1326    mpfr_set(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1327 }
1328 
1329 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const mpfr_float_backend<Digits10> & arg)1330 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1331 {
1332    mpfr_set(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1333 }
1334 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const gmp_int & arg)1335 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1336 {
1337    mpfr_set_z(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1338 }
1339 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const gmp_rational & arg)1340 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1341 {
1342    mpfr_set_q(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1343 }
1344 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned & arg)1345 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1346 {
1347    mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1348 }
1349 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned long & arg)1350 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1351 {
1352    mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1353 }
1354 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const int & arg)1355 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const int& arg)
1356 {
1357    mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1358 }
1359 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long & arg)1360 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long& arg)
1361 {
1362    mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1363 }
1364 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const float & arg)1365 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const float& arg)
1366 {
1367    mpfr_set_flt(mpc_realref(result.data()), arg, GMP_RNDN);
1368 }
1369 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const double & arg)1370 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const double& arg)
1371 {
1372    mpfr_set_d(mpc_realref(result.data()), arg, GMP_RNDN);
1373 }
1374 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long double & arg)1375 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long double& arg)
1376 {
1377    mpfr_set_ld(mpc_realref(result.data()), arg, GMP_RNDN);
1378 }
1379 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1380 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned long long & arg)1381 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1382 {
1383    mpfr_set_uj(mpc_realref(result.data()), arg, GMP_RNDN);
1384 }
1385 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long long & arg)1386 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long long& arg)
1387 {
1388    mpfr_set_sj(mpc_realref(result.data()), arg, GMP_RNDN);
1389 }
1390 #endif
1391 
1392 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const gmp_int & arg)1393 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1394 {
1395    mpfr_set_z(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1396 }
1397 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const gmp_rational & arg)1398 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1399 {
1400    mpfr_set_q(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1401 }
1402 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned & arg)1403 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1404 {
1405    mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1406 }
1407 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned long & arg)1408 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1409 {
1410    mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1411 }
1412 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const int & arg)1413 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const int& arg)
1414 {
1415    mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1416 }
1417 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long & arg)1418 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long& arg)
1419 {
1420    mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1421 }
1422 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const float & arg)1423 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const float& arg)
1424 {
1425    mpfr_set_flt(mpc_imagref(result.data()), arg, GMP_RNDN);
1426 }
1427 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const double & arg)1428 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const double& arg)
1429 {
1430    mpfr_set_d(mpc_imagref(result.data()), arg, GMP_RNDN);
1431 }
1432 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long double & arg)1433 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long double& arg)
1434 {
1435    mpfr_set_ld(mpc_imagref(result.data()), arg, GMP_RNDN);
1436 }
1437 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1438 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned long long & arg)1439 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1440 {
1441    mpfr_set_uj(mpc_imagref(result.data()), arg, GMP_RNDN);
1442 }
1443 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long long & arg)1444 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long long& arg)
1445 {
1446    mpfr_set_sj(mpc_imagref(result.data()), arg, GMP_RNDN);
1447 }
1448 #endif
1449 
1450 template <unsigned Digits10>
hash_value(const mpc_complex_backend<Digits10> & val)1451 inline std::size_t hash_value(const mpc_complex_backend<Digits10>& val)
1452 {
1453    std::size_t result = 0;
1454    std::size_t len = val.data()[0].re[0]._mpfr_prec / mp_bits_per_limb;
1455    if(val.data()[0].re[0]._mpfr_prec % mp_bits_per_limb)
1456       ++len;
1457    for(std::size_t i = 0; i < len; ++i)
1458       boost::hash_combine(result, val.data()[0].re[0]._mpfr_d[i]);
1459    boost::hash_combine(result, val.data()[0].re[0]._mpfr_exp);
1460    boost::hash_combine(result, val.data()[0].re[0]._mpfr_sign);
1461 
1462    len = val.data()[0].im[0]._mpfr_prec / mp_bits_per_limb;
1463    if(val.data()[0].im[0]._mpfr_prec % mp_bits_per_limb)
1464       ++len;
1465    for(std::size_t i = 0; i < len; ++i)
1466       boost::hash_combine(result, val.data()[0].im[0]._mpfr_d[i]);
1467    boost::hash_combine(result, val.data()[0].im[0]._mpfr_exp);
1468    boost::hash_combine(result, val.data()[0].im[0]._mpfr_sign);
1469    return result;
1470 }
1471 
1472 } // namespace backends
1473 
1474 #ifdef BOOST_NO_SFINAE_EXPR
1475 
1476 namespace detail{
1477 
1478 template<unsigned D1, unsigned D2>
1479 struct is_explicitly_convertible<backends::mpc_complex_backend<D1>, backends::mpc_complex_backend<D2> > : public mpl::true_ {};
1480 
1481 }
1482 #endif
1483 
1484 namespace detail
1485 {
1486    template<>
1487    struct is_variable_precision<backends::mpc_complex_backend<0> > : public true_type {};
1488 }
1489 
1490 template<>
1491 struct number_category<detail::canonical<mpc_t, backends::mpc_complex_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
1492 
1493 using boost::multiprecision::backends::mpc_complex_backend;
1494 
1495 typedef number<mpc_complex_backend<50> >    mpc_complex_50;
1496 typedef number<mpc_complex_backend<100> >   mpc_complex_100;
1497 typedef number<mpc_complex_backend<500> >   mpc_complex_500;
1498 typedef number<mpc_complex_backend<1000> >  mpc_complex_1000;
1499 typedef number<mpc_complex_backend<0> >     mpc_complex;
1500 
1501 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1502 struct component_type<number<mpc_complex_backend<Digits10>, ExpressionTemplates> >
1503 {
1504    typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1505 };
1506 
1507 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1508 struct component_type<number<logged_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates> >
1509 {
1510    typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1511 };
1512 
1513 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1514 struct complex_result_from_scalar<number<mpfr_float_backend<Digits10>, ExpressionTemplates> >
1515 {
1516    typedef number<mpc_complex_backend<Digits10>, ExpressionTemplates> type;
1517 };
1518 
1519 } // namespace multiprecision
1520 
1521 }  // namespaces
1522 
1523 #endif
1524