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/detail/atomic.hpp>
13 #include <boost/multiprecision/traits/is_variable_precision.hpp>
14 #include <boost/multiprecision/mpfr.hpp>
15 #include <boost/multiprecision/logged_adaptor.hpp>
16 #include <boost/functional/hash_fwd.hpp>
17 #include <mpc.h>
18 #include <cmath>
19 #include <algorithm>
20 #include <complex>
21
22 #ifndef BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION
23 #define BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION 20
24 #endif
25
26 namespace boost {
27 namespace multiprecision {
28 namespace backends {
29
30 template <unsigned digits10>
31 struct mpc_complex_backend;
32
33 } // namespace backends
34
35 template <unsigned digits10>
36 struct number_category<backends::mpc_complex_backend<digits10> > : public mpl::int_<number_kind_complex>
37 {};
38
39 namespace backends {
40
41 namespace detail {
42
mpc_copy_precision(mpc_t dest,const mpc_t src)43 inline void mpc_copy_precision(mpc_t dest, const mpc_t src)
44 {
45 mpfr_prec_t p_dest = mpc_get_prec(dest);
46 mpfr_prec_t p_src = mpc_get_prec(src);
47 if (p_dest != p_src)
48 mpc_set_prec(dest, p_src);
49 }
mpc_copy_precision(mpc_t dest,const mpc_t src1,const mpc_t src2)50 inline void mpc_copy_precision(mpc_t dest, const mpc_t src1, const mpc_t src2)
51 {
52 mpfr_prec_t p_dest = mpc_get_prec(dest);
53 mpfr_prec_t p_src1 = mpc_get_prec(src1);
54 mpfr_prec_t p_src2 = mpc_get_prec(src2);
55 if (p_src2 > p_src1)
56 p_src1 = p_src2;
57 if (p_dest != p_src1)
58 mpc_set_prec(dest, p_src1);
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 : (unsigned)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 : (unsigned)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 : (unsigned)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 : (unsigned)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 : (unsigned)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 : (unsigned)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 : (unsigned)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 : (unsigned)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 : (unsigned)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 : (unsigned)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
319 protected:
320 mpc_t m_data;
get_default_precisionboost::multiprecision::backends::detail::mpc_complex_imp321 static boost::multiprecision::detail::precision_type& get_default_precision() BOOST_NOEXCEPT
322 {
323 static boost::multiprecision::detail::precision_type val(BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION);
324 return val;
325 }
326 };
327
328 } // namespace detail
329
330 template <unsigned digits10>
331 struct mpc_complex_backend : public detail::mpc_complex_imp<digits10>
332 {
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend333 mpc_complex_backend() : detail::mpc_complex_imp<digits10>() {}
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend334 mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<digits10>(o) {}
335 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend336 mpc_complex_backend(mpc_complex_backend&& o) : detail::mpc_complex_imp<digits10>(static_cast<detail::mpc_complex_imp<digits10>&&>(o))
337 {}
338 #endif
339 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend340 mpc_complex_backend(const mpc_complex_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
341 : detail::mpc_complex_imp<digits10>()
342 {
343 mpc_set(this->m_data, val.data(), GMP_RNDN);
344 }
345 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend346 explicit mpc_complex_backend(const mpc_complex_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
347 : detail::mpc_complex_imp<digits10>()
348 {
349 mpc_set(this->m_data, val.data(), GMP_RNDN);
350 }
351 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend352 mpc_complex_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
353 : detail::mpc_complex_imp<digits10>()
354 {
355 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
356 }
357 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend358 explicit mpc_complex_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
359 : detail::mpc_complex_imp<digits10>()
360 {
361 mpc_set(this->m_data, val.data(), GMP_RNDN);
362 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend363 mpc_complex_backend(const mpc_t val)
364 : detail::mpc_complex_imp<digits10>()
365 {
366 mpc_set(this->m_data, val, GMP_RNDN);
367 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend368 mpc_complex_backend(const std::complex<float>& val)
369 : detail::mpc_complex_imp<digits10>()
370 {
371 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
372 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend373 mpc_complex_backend(const std::complex<double>& val)
374 : detail::mpc_complex_imp<digits10>()
375 {
376 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
377 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend378 mpc_complex_backend(const std::complex<long double>& val)
379 : detail::mpc_complex_imp<digits10>()
380 {
381 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
382 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend383 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<digits10>()
384 {
385 mpc_set_z(this->m_data, val, GMP_RNDN);
386 }
operator =boost::multiprecision::backends::mpc_complex_backend387 mpc_complex_backend& operator=(mpz_srcptr val)
388 {
389 mpc_set_z(this->m_data, val, GMP_RNDN);
390 return *this;
391 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend392 mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<digits10>()
393 {
394 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
395 }
operator =boost::multiprecision::backends::mpc_complex_backend396 mpc_complex_backend& operator=(gmp_int const& val)
397 {
398 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
399 return *this;
400 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend401 mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<digits10>()
402 {
403 mpc_set_f(this->m_data, val, GMP_RNDN);
404 }
operator =boost::multiprecision::backends::mpc_complex_backend405 mpc_complex_backend& operator=(mpf_srcptr val)
406 {
407 mpc_set_f(this->m_data, val, GMP_RNDN);
408 return *this;
409 }
410 template <unsigned D10>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend411 mpc_complex_backend(gmp_float<D10> const& val) : detail::mpc_complex_imp<digits10>()
412 {
413 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
414 }
415 template <unsigned D10>
operator =boost::multiprecision::backends::mpc_complex_backend416 mpc_complex_backend& operator=(gmp_float<D10> const& val)
417 {
418 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
419 return *this;
420 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend421 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<digits10>()
422 {
423 mpc_set_q(this->m_data, val, GMP_RNDN);
424 }
operator =boost::multiprecision::backends::mpc_complex_backend425 mpc_complex_backend& operator=(mpq_srcptr val)
426 {
427 mpc_set_q(this->m_data, val, GMP_RNDN);
428 return *this;
429 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend430 mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<digits10>()
431 {
432 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
433 }
operator =boost::multiprecision::backends::mpc_complex_backend434 mpc_complex_backend& operator=(gmp_rational const& val)
435 {
436 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
437 return *this;
438 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend439 mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<digits10>()
440 {
441 mpc_set_fr(this->m_data, val, GMP_RNDN);
442 }
operator =boost::multiprecision::backends::mpc_complex_backend443 mpc_complex_backend& operator=(mpfr_srcptr val)
444 {
445 mpc_set_fr(this->m_data, val, GMP_RNDN);
446 return *this;
447 }
448 template <unsigned D10, mpfr_allocation_type AllocationType>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend449 mpc_complex_backend(mpfr_float_backend<D10, AllocationType> const& val) : detail::mpc_complex_imp<digits10>()
450 {
451 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
452 }
453 template <unsigned D10, mpfr_allocation_type AllocationType>
operator =boost::multiprecision::backends::mpc_complex_backend454 mpc_complex_backend& operator=(mpfr_float_backend<D10, AllocationType> const& val)
455 {
456 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
457 return *this;
458 }
operator =boost::multiprecision::backends::mpc_complex_backend459 mpc_complex_backend& operator=(const mpc_complex_backend& o)
460 {
461 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10> const&>(o);
462 return *this;
463 }
464 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::mpc_complex_backend465 mpc_complex_backend& operator=(mpc_complex_backend&& o) BOOST_NOEXCEPT
466 {
467 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10>&&>(o);
468 return *this;
469 }
470 #endif
471 template <class V>
operator =boost::multiprecision::backends::mpc_complex_backend472 mpc_complex_backend& operator=(const V& v)
473 {
474 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = v;
475 return *this;
476 }
operator =boost::multiprecision::backends::mpc_complex_backend477 mpc_complex_backend& operator=(const mpc_t val)
478 {
479 mpc_set(this->m_data, val, GMP_RNDN);
480 return *this;
481 }
operator =boost::multiprecision::backends::mpc_complex_backend482 mpc_complex_backend& operator=(const std::complex<float>& val)
483 {
484 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
485 return *this;
486 }
operator =boost::multiprecision::backends::mpc_complex_backend487 mpc_complex_backend& operator=(const std::complex<double>& val)
488 {
489 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
490 return *this;
491 }
operator =boost::multiprecision::backends::mpc_complex_backend492 mpc_complex_backend& operator=(const std::complex<long double>& val)
493 {
494 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
495 return *this;
496 }
497 // We don't change our precision here, this is a fixed precision type:
498 template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend499 mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
500 {
501 mpc_set(this->m_data, val.data(), GMP_RNDN);
502 return *this;
503 }
504 };
505
506 template <>
507 struct mpc_complex_backend<0> : public detail::mpc_complex_imp<0>
508 {
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend509 mpc_complex_backend() : detail::mpc_complex_imp<0>() {}
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend510 mpc_complex_backend(const mpc_t val)
511 : detail::mpc_complex_imp<0>(mpc_get_prec(val))
512 {
513 mpc_set(this->m_data, val, GMP_RNDN);
514 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend515 mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<0>(o) {}
516 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend517 mpc_complex_backend(mpc_complex_backend&& o) BOOST_NOEXCEPT : detail::mpc_complex_imp<0>(static_cast<detail::mpc_complex_imp<0>&&>(o))
518 {}
519 #endif
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend520 mpc_complex_backend(const mpc_complex_backend& o, unsigned digits10)
521 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
522 {
523 mpc_set(this->m_data, o.data(), GMP_RNDN);
524 }
525 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend526 mpc_complex_backend(const mpc_complex_backend<D>& val)
527 : detail::mpc_complex_imp<0>(mpc_get_prec(val.data()))
528 {
529 mpc_set(this->m_data, val.data(), GMP_RNDN);
530 }
531 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend532 mpc_complex_backend(const mpfr_float_backend<D>& val)
533 : detail::mpc_complex_imp<0>(mpfr_get_prec(val.data()))
534 {
535 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
536 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend537 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<0>()
538 {
539 mpc_set_z(this->m_data, val, GMP_RNDN);
540 }
operator =boost::multiprecision::backends::mpc_complex_backend541 mpc_complex_backend& operator=(mpz_srcptr val)
542 {
543 mpc_set_z(this->m_data, val, GMP_RNDN);
544 return *this;
545 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend546 mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<0>()
547 {
548 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
549 }
operator =boost::multiprecision::backends::mpc_complex_backend550 mpc_complex_backend& operator=(gmp_int const& val)
551 {
552 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
553 return *this;
554 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend555 mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val))
556 {
557 mpc_set_f(this->m_data, val, GMP_RNDN);
558 }
operator =boost::multiprecision::backends::mpc_complex_backend559 mpc_complex_backend& operator=(mpf_srcptr val)
560 {
561 if ((mp_bitcnt_t)mpc_get_prec(data()) != mpf_get_prec(val))
562 {
563 mpc_complex_backend t(val);
564 t.swap(*this);
565 }
566 else
567 mpc_set_f(this->m_data, val, GMP_RNDN);
568 return *this;
569 }
570 template <unsigned digits10>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend571 mpc_complex_backend(gmp_float<digits10> const& val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val.data()))
572 {
573 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
574 }
575 template <unsigned digits10>
operator =boost::multiprecision::backends::mpc_complex_backend576 mpc_complex_backend& operator=(gmp_float<digits10> const& val)
577 {
578 if (mpc_get_prec(data()) != (mpfr_prec_t)mpf_get_prec(val.data()))
579 {
580 mpc_complex_backend t(val);
581 t.swap(*this);
582 }
583 else
584 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
585 return *this;
586 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend587 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<0>()
588 {
589 mpc_set_q(this->m_data, val, GMP_RNDN);
590 }
operator =boost::multiprecision::backends::mpc_complex_backend591 mpc_complex_backend& operator=(mpq_srcptr val)
592 {
593 mpc_set_q(this->m_data, val, GMP_RNDN);
594 return *this;
595 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend596 mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<0>()
597 {
598 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
599 }
operator =boost::multiprecision::backends::mpc_complex_backend600 mpc_complex_backend& operator=(gmp_rational const& val)
601 {
602 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
603 return *this;
604 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend605 mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<0>(mpfr_get_prec(val))
606 {
607 mpc_set_fr(this->m_data, val, GMP_RNDN);
608 }
operator =boost::multiprecision::backends::mpc_complex_backend609 mpc_complex_backend& operator=(mpfr_srcptr val)
610 {
611 if (mpc_get_prec(data()) != mpfr_get_prec(val))
612 {
613 mpc_complex_backend t(val);
614 t.swap(*this);
615 }
616 else
617 mpc_set_fr(this->m_data, val, GMP_RNDN);
618 return *this;
619 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend620 mpc_complex_backend(const std::complex<float>& val)
621 : detail::mpc_complex_imp<0>()
622 {
623 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
624 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend625 mpc_complex_backend(const std::complex<double>& val)
626 : detail::mpc_complex_imp<0>()
627 {
628 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
629 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend630 mpc_complex_backend(const std::complex<long double>& val)
631 : detail::mpc_complex_imp<0>()
632 {
633 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
634 }
635 // Construction with precision:
636 template <class T, class U>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend637 mpc_complex_backend(const T& a, const U& b, unsigned digits10)
638 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
639 {
640 // We can't use assign_components here because it copies the precision of
641 // a and b, not digits10....
642 mpfr_float ca(a), cb(b);
643 mpc_set_fr_fr(this->data(), ca.backend().data(), cb.backend().data(), GMP_RNDN);
644 }
645 template <unsigned N>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend646 mpc_complex_backend(const mpfr_float_backend<N>& a, const mpfr_float_backend<N>& b, unsigned digits10)
647 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
648 {
649 mpc_set_fr_fr(this->data(), a.data(), b.data(), GMP_RNDN);
650 }
651
operator =boost::multiprecision::backends::mpc_complex_backend652 mpc_complex_backend& operator=(const mpc_complex_backend& o)
653 {
654 if (this != &o)
655 {
656 detail::mpc_copy_precision(this->m_data, o.data());
657 mpc_set(this->m_data, o.data(), GMP_RNDN);
658 }
659 return *this;
660 }
661 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::mpc_complex_backend662 mpc_complex_backend& operator=(mpc_complex_backend&& o) BOOST_NOEXCEPT
663 {
664 *static_cast<detail::mpc_complex_imp<0>*>(this) = static_cast<detail::mpc_complex_imp<0>&&>(o);
665 return *this;
666 }
667 #endif
668 template <class V>
operator =boost::multiprecision::backends::mpc_complex_backend669 mpc_complex_backend& operator=(const V& v)
670 {
671 *static_cast<detail::mpc_complex_imp<0>*>(this) = v;
672 return *this;
673 }
operator =boost::multiprecision::backends::mpc_complex_backend674 mpc_complex_backend& operator=(const mpc_t val)
675 {
676 mpc_set_prec(this->m_data, mpc_get_prec(val));
677 mpc_set(this->m_data, val, GMP_RNDN);
678 return *this;
679 }
680 template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend681 mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
682 {
683 mpc_set_prec(this->m_data, mpc_get_prec(val.data()));
684 mpc_set(this->m_data, val.data(), GMP_RNDN);
685 return *this;
686 }
687 template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend688 mpc_complex_backend& operator=(const mpfr_float_backend<D>& val)
689 {
690 mpc_set_prec(this->m_data, mpfr_get_prec(val.data()));
691 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
692 return *this;
693 }
operator =boost::multiprecision::backends::mpc_complex_backend694 mpc_complex_backend& operator=(const std::complex<float>& val)
695 {
696 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
697 return *this;
698 }
operator =boost::multiprecision::backends::mpc_complex_backend699 mpc_complex_backend& operator=(const std::complex<double>& val)
700 {
701 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
702 return *this;
703 }
operator =boost::multiprecision::backends::mpc_complex_backend704 mpc_complex_backend& operator=(const std::complex<long double>& val)
705 {
706 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
707 return *this;
708 }
default_precisionboost::multiprecision::backends::mpc_complex_backend709 static unsigned default_precision() BOOST_NOEXCEPT
710 {
711 return get_default_precision();
712 }
default_precisionboost::multiprecision::backends::mpc_complex_backend713 static void default_precision(unsigned v) BOOST_NOEXCEPT
714 {
715 get_default_precision() = v;
716 }
precisionboost::multiprecision::backends::mpc_complex_backend717 unsigned precision() const BOOST_NOEXCEPT
718 {
719 return multiprecision::detail::digits2_2_10(mpc_get_prec(this->m_data));
720 }
precisionboost::multiprecision::backends::mpc_complex_backend721 void precision(unsigned digits10) BOOST_NOEXCEPT
722 {
723 mpfr_prec_round(mpc_realref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
724 mpfr_prec_round(mpc_imagref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
725 }
726 };
727
728 template <unsigned digits10, class T>
eval_eq(const mpc_complex_backend<digits10> & a,const T & b)729 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
730 {
731 return a.compare(b) == 0;
732 }
733 template <unsigned digits10, class T>
eval_lt(const mpc_complex_backend<digits10> & a,const T & b)734 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
735 {
736 return a.compare(b) < 0;
737 }
738 template <unsigned digits10, class T>
eval_gt(const mpc_complex_backend<digits10> & a,const T & b)739 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
740 {
741 return a.compare(b) > 0;
742 }
743
744 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)745 inline void eval_add(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
746 {
747 mpc_add(result.data(), result.data(), o.data(), GMP_RNDD);
748 }
749 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)750 inline void eval_add(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
751 {
752 mpc_add_fr(result.data(), result.data(), o.data(), GMP_RNDD);
753 }
754 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)755 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
756 {
757 mpc_sub(result.data(), result.data(), o.data(), GMP_RNDD);
758 }
759 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)760 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
761 {
762 mpc_sub_fr(result.data(), result.data(), o.data(), GMP_RNDD);
763 }
764 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)765 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
766 {
767 if ((void*)&result == (void*)&o)
768 mpc_sqr(result.data(), o.data(), GMP_RNDN);
769 else
770 mpc_mul(result.data(), result.data(), o.data(), GMP_RNDN);
771 }
772 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)773 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
774 {
775 mpc_mul_fr(result.data(), result.data(), o.data(), GMP_RNDN);
776 }
777 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)778 inline void eval_divide(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
779 {
780 mpc_div(result.data(), result.data(), o.data(), GMP_RNDD);
781 }
782 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)783 inline void eval_divide(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
784 {
785 mpc_div_fr(result.data(), result.data(), o.data(), GMP_RNDD);
786 }
787 template <unsigned digits10>
eval_add(mpc_complex_backend<digits10> & result,unsigned long i)788 inline void eval_add(mpc_complex_backend<digits10>& result, unsigned long i)
789 {
790 mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
791 }
792 template <unsigned digits10>
eval_subtract(mpc_complex_backend<digits10> & result,unsigned long i)793 inline void eval_subtract(mpc_complex_backend<digits10>& result, unsigned long i)
794 {
795 mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
796 }
797 template <unsigned digits10>
eval_multiply(mpc_complex_backend<digits10> & result,unsigned long i)798 inline void eval_multiply(mpc_complex_backend<digits10>& result, unsigned long i)
799 {
800 mpc_mul_ui(result.data(), result.data(), i, GMP_RNDN);
801 }
802 template <unsigned digits10>
eval_divide(mpc_complex_backend<digits10> & result,unsigned long i)803 inline void eval_divide(mpc_complex_backend<digits10>& result, unsigned long i)
804 {
805 mpc_div_ui(result.data(), result.data(), i, GMP_RNDN);
806 }
807 template <unsigned digits10>
eval_add(mpc_complex_backend<digits10> & result,long i)808 inline void eval_add(mpc_complex_backend<digits10>& result, long i)
809 {
810 if (i > 0)
811 mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
812 else
813 mpc_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
814 }
815 template <unsigned digits10>
eval_subtract(mpc_complex_backend<digits10> & result,long i)816 inline void eval_subtract(mpc_complex_backend<digits10>& result, long i)
817 {
818 if (i > 0)
819 mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
820 else
821 mpc_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
822 }
823 template <unsigned digits10>
eval_multiply(mpc_complex_backend<digits10> & result,long i)824 inline void eval_multiply(mpc_complex_backend<digits10>& result, long i)
825 {
826 mpc_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
827 if (i < 0)
828 mpc_neg(result.data(), result.data(), GMP_RNDN);
829 }
830 template <unsigned digits10>
eval_divide(mpc_complex_backend<digits10> & result,long i)831 inline void eval_divide(mpc_complex_backend<digits10>& result, long i)
832 {
833 mpc_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
834 if (i < 0)
835 mpc_neg(result.data(), result.data(), GMP_RNDN);
836 }
837 //
838 // Specialised 3 arg versions of the basic operators:
839 //
840 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)841 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
842 {
843 mpc_add(a.data(), x.data(), y.data(), GMP_RNDD);
844 }
845 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)846 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
847 {
848 mpc_add_fr(a.data(), x.data(), y.data(), GMP_RNDD);
849 }
850 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)851 inline void eval_add(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
852 {
853 mpc_add_fr(a.data(), y.data(), x.data(), GMP_RNDD);
854 }
855 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)856 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
857 {
858 mpc_add_ui(a.data(), x.data(), y, GMP_RNDD);
859 }
860 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)861 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
862 {
863 if (y < 0)
864 mpc_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
865 else
866 mpc_add_ui(a.data(), x.data(), y, GMP_RNDD);
867 }
868 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)869 inline void eval_add(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
870 {
871 mpc_add_ui(a.data(), y.data(), x, GMP_RNDD);
872 }
873 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)874 inline void eval_add(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
875 {
876 if (x < 0)
877 {
878 mpc_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
879 mpc_neg(a.data(), a.data(), GMP_RNDD);
880 }
881 else
882 mpc_add_ui(a.data(), y.data(), x, GMP_RNDD);
883 }
884 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)885 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
886 {
887 mpc_sub(a.data(), x.data(), y.data(), GMP_RNDD);
888 }
889 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)890 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
891 {
892 mpc_sub_fr(a.data(), x.data(), y.data(), GMP_RNDD);
893 }
894 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)895 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
896 {
897 mpc_fr_sub(a.data(), x.data(), y.data(), GMP_RNDD);
898 }
899 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)900 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
901 {
902 mpc_sub_ui(a.data(), x.data(), y, GMP_RNDD);
903 }
904 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)905 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
906 {
907 if (y < 0)
908 mpc_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
909 else
910 mpc_sub_ui(a.data(), x.data(), y, GMP_RNDD);
911 }
912 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)913 inline void eval_subtract(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
914 {
915 mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
916 }
917 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)918 inline void eval_subtract(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
919 {
920 if (x < 0)
921 {
922 mpc_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDD);
923 mpc_neg(a.data(), a.data(), GMP_RNDD);
924 }
925 else
926 mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
927 }
928
929 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)930 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
931 {
932 if ((void*)&x == (void*)&y)
933 mpc_sqr(a.data(), x.data(), GMP_RNDD);
934 else
935 mpc_mul(a.data(), x.data(), y.data(), GMP_RNDD);
936 }
937 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)938 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
939 {
940 mpc_mul_fr(a.data(), x.data(), y.data(), GMP_RNDD);
941 }
942 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)943 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
944 {
945 mpc_mul_fr(a.data(), y.data(), x.data(), GMP_RNDD);
946 }
947 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)948 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
949 {
950 mpc_mul_ui(a.data(), x.data(), y, GMP_RNDD);
951 }
952 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)953 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
954 {
955 if (y < 0)
956 {
957 mpc_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
958 a.negate();
959 }
960 else
961 mpc_mul_ui(a.data(), x.data(), y, GMP_RNDD);
962 }
963 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)964 inline void eval_multiply(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
965 {
966 mpc_mul_ui(a.data(), y.data(), x, GMP_RNDD);
967 }
968 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)969 inline void eval_multiply(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
970 {
971 if (x < 0)
972 {
973 mpc_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDD);
974 mpc_neg(a.data(), a.data(), GMP_RNDD);
975 }
976 else
977 mpc_mul_ui(a.data(), y.data(), x, GMP_RNDD);
978 }
979
980 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)981 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
982 {
983 mpc_div(a.data(), x.data(), y.data(), GMP_RNDD);
984 }
985 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)986 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
987 {
988 mpc_div_fr(a.data(), x.data(), y.data(), GMP_RNDD);
989 }
990 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)991 inline void eval_divide(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
992 {
993 mpc_fr_div(a.data(), x.data(), y.data(), GMP_RNDD);
994 }
995 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)996 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
997 {
998 mpc_div_ui(a.data(), x.data(), y, GMP_RNDD);
999 }
1000 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)1001 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
1002 {
1003 if (y < 0)
1004 {
1005 mpc_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
1006 a.negate();
1007 }
1008 else
1009 mpc_div_ui(a.data(), x.data(), y, GMP_RNDD);
1010 }
1011 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)1012 inline void eval_divide(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
1013 {
1014 mpc_ui_div(a.data(), x, y.data(), GMP_RNDD);
1015 }
1016 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)1017 inline void eval_divide(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
1018 {
1019 if (x < 0)
1020 {
1021 mpc_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDD);
1022 mpc_neg(a.data(), a.data(), GMP_RNDD);
1023 }
1024 else
1025 mpc_ui_div(a.data(), x, y.data(), GMP_RNDD);
1026 }
1027
1028 template <unsigned digits10>
eval_is_zero(const mpc_complex_backend<digits10> & val)1029 inline bool eval_is_zero(const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1030 {
1031 return (0 != mpfr_zero_p(mpc_realref(val.data()))) && (0 != mpfr_zero_p(mpc_imagref(val.data())));
1032 }
1033 template <unsigned digits10>
eval_get_sign(const mpc_complex_backend<digits10> &)1034 inline int eval_get_sign(const mpc_complex_backend<digits10>&)
1035 {
1036 BOOST_STATIC_ASSERT_MSG(digits10 == UINT_MAX, "Complex numbers have no sign bit."); // designed to always fail
1037 return 0;
1038 }
1039
1040 template <unsigned digits10>
eval_convert_to(unsigned long * result,const mpc_complex_backend<digits10> & val)1041 inline void eval_convert_to(unsigned long* result, const mpc_complex_backend<digits10>& val)
1042 {
1043 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1044 {
1045 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1046 }
1047 mpfr_float_backend<digits10> t;
1048 mpc_real(t.data(), val.data(), GMP_RNDN);
1049 eval_convert_to(result, t);
1050 }
1051 template <unsigned digits10>
eval_convert_to(long * result,const mpc_complex_backend<digits10> & val)1052 inline void eval_convert_to(long* result, const mpc_complex_backend<digits10>& val)
1053 {
1054 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1055 {
1056 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1057 }
1058 mpfr_float_backend<digits10> t;
1059 mpc_real(t.data(), val.data(), GMP_RNDN);
1060 eval_convert_to(result, t);
1061 }
1062 #ifdef _MPFR_H_HAVE_INTMAX_T
1063 template <unsigned digits10>
eval_convert_to(boost::ulong_long_type * result,const mpc_complex_backend<digits10> & val)1064 inline void eval_convert_to(boost::ulong_long_type* result, const mpc_complex_backend<digits10>& val)
1065 {
1066 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1067 {
1068 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1069 }
1070 mpfr_float_backend<digits10> t;
1071 mpc_real(t.data(), val.data(), GMP_RNDN);
1072 eval_convert_to(result, t);
1073 }
1074 template <unsigned digits10>
eval_convert_to(boost::long_long_type * result,const mpc_complex_backend<digits10> & val)1075 inline void eval_convert_to(boost::long_long_type* result, const mpc_complex_backend<digits10>& val)
1076 {
1077 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1078 {
1079 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1080 }
1081 mpfr_float_backend<digits10> t;
1082 mpc_real(t.data(), val.data(), GMP_RNDN);
1083 eval_convert_to(result, t);
1084 }
1085 #endif
1086 template <unsigned digits10>
eval_convert_to(double * result,const mpc_complex_backend<digits10> & val)1087 inline void eval_convert_to(double* result, const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1088 {
1089 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1090 {
1091 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1092 }
1093 mpfr_float_backend<digits10> t;
1094 mpc_real(t.data(), val.data(), GMP_RNDN);
1095 eval_convert_to(result, t);
1096 }
1097 template <unsigned digits10>
eval_convert_to(long double * result,const mpc_complex_backend<digits10> & val)1098 inline void eval_convert_to(long double* result, const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1099 {
1100 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1101 {
1102 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1103 }
1104 mpfr_float_backend<digits10> t;
1105 mpc_real(t.data(), val.data(), GMP_RNDN);
1106 eval_convert_to(result, t);
1107 }
1108
1109 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)1110 inline void assign_components(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
1111 {
1112 //
1113 // This is called from class number's constructors, so if we have variable
1114 // precision, then copy the precision of the source variables.
1115 //
1116 if (!D1)
1117 {
1118 unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
1119 mpc_set_prec(result.data(), prec);
1120 }
1121 using default_ops::eval_fpclassify;
1122 if (eval_fpclassify(a) == (int)FP_NAN)
1123 {
1124 mpc_set_fr(result.data(), a.data(), GMP_RNDN);
1125 }
1126 else if (eval_fpclassify(b) == (int)FP_NAN)
1127 {
1128 mpc_set_fr(result.data(), b.data(), GMP_RNDN);
1129 }
1130 else
1131 {
1132 mpc_set_fr_fr(result.data(), a.data(), b.data(), GMP_RNDN);
1133 }
1134 }
1135
1136 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,unsigned long a,unsigned long b)1137 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long a, unsigned long b)
1138 {
1139 mpc_set_ui_ui(result.data(), a, b, GMP_RNDN);
1140 }
1141
1142 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long a,long b)1143 inline void assign_components(mpc_complex_backend<D1>& result, long a, long b)
1144 {
1145 mpc_set_si_si(result.data(), a, b, GMP_RNDN);
1146 }
1147
1148 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1149 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,unsigned long long a,unsigned long long b)1150 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long long a, unsigned long long b)
1151 {
1152 mpc_set_uj_uj(result.data(), a, b, GMP_RNDN);
1153 }
1154
1155 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long long a,long long b)1156 inline void assign_components(mpc_complex_backend<D1>& result, long long a, long long b)
1157 {
1158 mpc_set_sj_sj(result.data(), a, b, GMP_RNDN);
1159 }
1160 #endif
1161
1162 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,double a,double b)1163 inline void assign_components(mpc_complex_backend<D1>& result, double a, double b)
1164 {
1165 if ((boost::math::isnan)(a))
1166 {
1167 mpc_set_d(result.data(), a, GMP_RNDN);
1168 }
1169 else if ((boost::math::isnan)(b))
1170 {
1171 mpc_set_d(result.data(), b, GMP_RNDN);
1172 }
1173 else
1174 {
1175 mpc_set_d_d(result.data(), a, b, GMP_RNDN);
1176 }
1177 }
1178
1179 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long double a,long double b)1180 inline void assign_components(mpc_complex_backend<D1>& result, long double a, long double b)
1181 {
1182 if ((boost::math::isnan)(a))
1183 {
1184 mpc_set_d(result.data(), a, GMP_RNDN);
1185 }
1186 else if ((boost::math::isnan)(b))
1187 {
1188 mpc_set_d(result.data(), b, GMP_RNDN);
1189 }
1190 else
1191 {
1192 mpc_set_ld_ld(result.data(), a, b, GMP_RNDN);
1193 }
1194 }
1195
1196 //
1197 // Native non-member operations:
1198 //
1199 template <unsigned Digits10>
eval_sqrt(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & val)1200 inline void eval_sqrt(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& val)
1201 {
1202 mpc_sqrt(result.data(), val.data(), GMP_RNDN);
1203 }
1204
1205 template <unsigned Digits10>
eval_pow(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & b,const mpc_complex_backend<Digits10> & e)1206 inline void eval_pow(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& b, const mpc_complex_backend<Digits10>& e)
1207 {
1208 mpc_pow(result.data(), b.data(), e.data(), GMP_RNDN);
1209 }
1210
1211 template <unsigned Digits10>
eval_exp(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1212 inline void eval_exp(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1213 {
1214 mpc_exp(result.data(), arg.data(), GMP_RNDN);
1215 }
1216
1217 template <unsigned Digits10>
eval_log(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1218 inline void eval_log(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1219 {
1220 mpc_log(result.data(), arg.data(), GMP_RNDN);
1221 }
1222
1223 template <unsigned Digits10>
eval_log10(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1224 inline void eval_log10(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1225 {
1226 mpc_log10(result.data(), arg.data(), GMP_RNDN);
1227 }
1228
1229 template <unsigned Digits10>
eval_sin(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1230 inline void eval_sin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1231 {
1232 mpc_sin(result.data(), arg.data(), GMP_RNDN);
1233 }
1234
1235 template <unsigned Digits10>
eval_cos(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1236 inline void eval_cos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1237 {
1238 mpc_cos(result.data(), arg.data(), GMP_RNDN);
1239 }
1240
1241 template <unsigned Digits10>
eval_tan(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1242 inline void eval_tan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1243 {
1244 mpc_tan(result.data(), arg.data(), GMP_RNDN);
1245 }
1246
1247 template <unsigned Digits10>
eval_asin(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1248 inline void eval_asin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1249 {
1250 mpc_asin(result.data(), arg.data(), GMP_RNDN);
1251 }
1252
1253 template <unsigned Digits10>
eval_acos(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1254 inline void eval_acos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1255 {
1256 mpc_acos(result.data(), arg.data(), GMP_RNDN);
1257 }
1258
1259 template <unsigned Digits10>
eval_atan(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1260 inline void eval_atan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1261 {
1262 mpc_atan(result.data(), arg.data(), GMP_RNDN);
1263 }
1264
1265 template <unsigned Digits10>
eval_sinh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1266 inline void eval_sinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1267 {
1268 mpc_sinh(result.data(), arg.data(), GMP_RNDN);
1269 }
1270
1271 template <unsigned Digits10>
eval_cosh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1272 inline void eval_cosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1273 {
1274 mpc_cosh(result.data(), arg.data(), GMP_RNDN);
1275 }
1276
1277 template <unsigned Digits10>
eval_tanh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1278 inline void eval_tanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1279 {
1280 mpc_tanh(result.data(), arg.data(), GMP_RNDN);
1281 }
1282
1283 template <unsigned Digits10>
eval_asinh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1284 inline void eval_asinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1285 {
1286 mpc_asinh(result.data(), arg.data(), GMP_RNDN);
1287 }
1288
1289 template <unsigned Digits10>
eval_acosh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1290 inline void eval_acosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1291 {
1292 mpc_acosh(result.data(), arg.data(), GMP_RNDN);
1293 }
1294
1295 template <unsigned Digits10>
eval_atanh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1296 inline void eval_atanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1297 {
1298 mpc_atanh(result.data(), arg.data(), GMP_RNDN);
1299 }
1300
1301 template <unsigned Digits10>
eval_conj(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1302 inline void eval_conj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1303 {
1304 mpc_conj(result.data(), arg.data(), GMP_RNDN);
1305 }
1306
1307 template <unsigned Digits10>
eval_proj(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1308 inline void eval_proj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1309 {
1310 mpc_proj(result.data(), arg.data(), GMP_RNDN);
1311 }
1312
1313 template <unsigned Digits10>
eval_real(mpfr_float_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1314 inline void eval_real(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1315 {
1316 mpfr_set_prec(result.data(), mpfr_get_prec(mpc_realref(arg.data())));
1317 mpfr_set(result.data(), mpc_realref(arg.data()), GMP_RNDN);
1318 }
1319 template <unsigned Digits10>
eval_imag(mpfr_float_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1320 inline void eval_imag(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1321 {
1322 mpfr_set_prec(result.data(), mpfr_get_prec(mpc_imagref(arg.data())));
1323 mpfr_set(result.data(), mpc_imagref(arg.data()), GMP_RNDN);
1324 }
1325
1326 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const mpfr_float_backend<Digits10> & arg)1327 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1328 {
1329 mpfr_set(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1330 }
1331
1332 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const mpfr_float_backend<Digits10> & arg)1333 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1334 {
1335 mpfr_set(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1336 }
1337 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const gmp_int & arg)1338 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1339 {
1340 mpfr_set_z(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1341 }
1342 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const gmp_rational & arg)1343 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1344 {
1345 mpfr_set_q(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1346 }
1347 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned & arg)1348 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1349 {
1350 mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1351 }
1352 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned long & arg)1353 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1354 {
1355 mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1356 }
1357 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const int & arg)1358 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const int& arg)
1359 {
1360 mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1361 }
1362 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long & arg)1363 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long& arg)
1364 {
1365 mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1366 }
1367 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const float & arg)1368 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const float& arg)
1369 {
1370 mpfr_set_flt(mpc_realref(result.data()), arg, GMP_RNDN);
1371 }
1372 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const double & arg)1373 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const double& arg)
1374 {
1375 mpfr_set_d(mpc_realref(result.data()), arg, GMP_RNDN);
1376 }
1377 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long double & arg)1378 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long double& arg)
1379 {
1380 mpfr_set_ld(mpc_realref(result.data()), arg, GMP_RNDN);
1381 }
1382 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1383 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned long long & arg)1384 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1385 {
1386 mpfr_set_uj(mpc_realref(result.data()), arg, GMP_RNDN);
1387 }
1388 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long long & arg)1389 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long long& arg)
1390 {
1391 mpfr_set_sj(mpc_realref(result.data()), arg, GMP_RNDN);
1392 }
1393 #endif
1394
1395 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const gmp_int & arg)1396 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1397 {
1398 mpfr_set_z(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1399 }
1400 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const gmp_rational & arg)1401 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1402 {
1403 mpfr_set_q(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1404 }
1405 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned & arg)1406 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1407 {
1408 mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1409 }
1410 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned long & arg)1411 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1412 {
1413 mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1414 }
1415 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const int & arg)1416 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const int& arg)
1417 {
1418 mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1419 }
1420 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long & arg)1421 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long& arg)
1422 {
1423 mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1424 }
1425 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const float & arg)1426 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const float& arg)
1427 {
1428 mpfr_set_flt(mpc_imagref(result.data()), arg, GMP_RNDN);
1429 }
1430 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const double & arg)1431 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const double& arg)
1432 {
1433 mpfr_set_d(mpc_imagref(result.data()), arg, GMP_RNDN);
1434 }
1435 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long double & arg)1436 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long double& arg)
1437 {
1438 mpfr_set_ld(mpc_imagref(result.data()), arg, GMP_RNDN);
1439 }
1440 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1441 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned long long & arg)1442 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1443 {
1444 mpfr_set_uj(mpc_imagref(result.data()), arg, GMP_RNDN);
1445 }
1446 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long long & arg)1447 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long long& arg)
1448 {
1449 mpfr_set_sj(mpc_imagref(result.data()), arg, GMP_RNDN);
1450 }
1451 #endif
1452
1453 template <unsigned Digits10>
hash_value(const mpc_complex_backend<Digits10> & val)1454 inline std::size_t hash_value(const mpc_complex_backend<Digits10>& val)
1455 {
1456 std::size_t result = 0;
1457 std::size_t len = val.data()[0].re[0]._mpfr_prec / mp_bits_per_limb;
1458 if (val.data()[0].re[0]._mpfr_prec % mp_bits_per_limb)
1459 ++len;
1460 for (std::size_t i = 0; i < len; ++i)
1461 boost::hash_combine(result, val.data()[0].re[0]._mpfr_d[i]);
1462 boost::hash_combine(result, val.data()[0].re[0]._mpfr_exp);
1463 boost::hash_combine(result, val.data()[0].re[0]._mpfr_sign);
1464
1465 len = val.data()[0].im[0]._mpfr_prec / mp_bits_per_limb;
1466 if (val.data()[0].im[0]._mpfr_prec % mp_bits_per_limb)
1467 ++len;
1468 for (std::size_t i = 0; i < len; ++i)
1469 boost::hash_combine(result, val.data()[0].im[0]._mpfr_d[i]);
1470 boost::hash_combine(result, val.data()[0].im[0]._mpfr_exp);
1471 boost::hash_combine(result, val.data()[0].im[0]._mpfr_sign);
1472 return result;
1473 }
1474
1475 } // namespace backends
1476
1477 #ifdef BOOST_NO_SFINAE_EXPR
1478
1479 namespace detail {
1480
1481 template <unsigned D1, unsigned D2>
1482 struct is_explicitly_convertible<backends::mpc_complex_backend<D1>, backends::mpc_complex_backend<D2> > : public mpl::true_
1483 {};
1484
1485 } // namespace detail
1486 #endif
1487
1488 namespace detail {
1489 template <>
1490 struct is_variable_precision<backends::mpc_complex_backend<0> > : public true_type
1491 {};
1492 } // namespace detail
1493
1494 template <>
1495 struct number_category<detail::canonical<mpc_t, backends::mpc_complex_backend<0> >::type> : public mpl::int_<number_kind_floating_point>
1496 {};
1497
1498 using boost::multiprecision::backends::mpc_complex_backend;
1499
1500 typedef number<mpc_complex_backend<50> > mpc_complex_50;
1501 typedef number<mpc_complex_backend<100> > mpc_complex_100;
1502 typedef number<mpc_complex_backend<500> > mpc_complex_500;
1503 typedef number<mpc_complex_backend<1000> > mpc_complex_1000;
1504 typedef number<mpc_complex_backend<0> > mpc_complex;
1505
1506 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1507 struct component_type<number<mpc_complex_backend<Digits10>, ExpressionTemplates> >
1508 {
1509 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1510 };
1511
1512 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1513 struct component_type<number<logged_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates> >
1514 {
1515 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1516 };
1517
1518 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1519 struct complex_result_from_scalar<number<mpfr_float_backend<Digits10>, ExpressionTemplates> >
1520 {
1521 typedef number<mpc_complex_backend<Digits10>, ExpressionTemplates> type;
1522 };
1523
1524 }
1525
1526 } // namespace boost::multiprecision
1527
1528 #endif
1529