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
38 namespace backends {
39
40 namespace detail {
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 template <unsigned digits10>
61 struct mpc_complex_imp
62 {
63 #ifdef BOOST_HAS_LONG_LONG
64 typedef mpl::list<long, boost::long_long_type> signed_types;
65 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
66 #else
67 typedef mpl::list<long> signed_types;
68 typedef mpl::list<unsigned long> unsigned_types;
69 #endif
70 typedef mpl::list<double, long double> float_types;
71 typedef long exponent_type;
72
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp73 mpc_complex_imp()
74 {
75 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
76 mpc_set_ui(m_data, 0u, GMP_RNDN);
77 }
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp78 mpc_complex_imp(unsigned digits2)
79 {
80 mpc_init2(m_data, digits2);
81 mpc_set_ui(m_data, 0u, GMP_RNDN);
82 }
83
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp84 mpc_complex_imp(const mpc_complex_imp& o)
85 {
86 mpc_init2(m_data, mpc_get_prec(o.m_data));
87 if (o.m_data[0].re[0]._mpfr_d)
88 mpc_set(m_data, o.m_data, GMP_RNDN);
89 }
90 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp91 mpc_complex_imp(mpc_complex_imp&& o) BOOST_NOEXCEPT
92 {
93 m_data[0] = o.m_data[0];
94 o.m_data[0].re[0]._mpfr_d = 0;
95 }
96 #endif
operator =boost::multiprecision::backends::detail::mpc_complex_imp97 mpc_complex_imp& operator=(const mpc_complex_imp& o)
98 {
99 if ((o.m_data[0].re[0]._mpfr_d) && (this != &o))
100 {
101 if (m_data[0].re[0]._mpfr_d == 0)
102 mpc_init2(m_data, mpc_get_prec(o.m_data));
103 mpc_set(m_data, o.m_data, GMP_RNDD);
104 }
105 return *this;
106 }
107 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::detail::mpc_complex_imp108 mpc_complex_imp& operator=(mpc_complex_imp&& o) BOOST_NOEXCEPT
109 {
110 mpc_swap(m_data, o.m_data);
111 return *this;
112 }
113 #endif
114 #ifdef BOOST_HAS_LONG_LONG
115 #ifdef _MPFR_H_HAVE_INTMAX_T
operator =boost::multiprecision::backends::detail::mpc_complex_imp116 mpc_complex_imp& operator=(boost::ulong_long_type i)
117 {
118 if (m_data[0].re[0]._mpfr_d == 0)
119 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
120 mpc_set_uj(data(), i, GMP_RNDD);
121 return *this;
122 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp123 mpc_complex_imp& operator=(boost::long_long_type i)
124 {
125 if (m_data[0].re[0]._mpfr_d == 0)
126 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
127 mpc_set_sj(data(), i, GMP_RNDD);
128 return *this;
129 }
130 #else
operator =boost::multiprecision::backends::detail::mpc_complex_imp131 mpc_complex_imp& operator=(boost::ulong_long_type i)
132 {
133 mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data));
134 f = i;
135 mpc_set_fr(this->data(), f.data(), GMP_RNDN);
136 return *this;
137 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp138 mpc_complex_imp& operator=(boost::long_long_type i)
139 {
140 mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data));
141 f = i;
142 mpc_set_fr(this->data(), f.data(), GMP_RNDN);
143 return *this;
144 }
145 #endif
146 #endif
operator =boost::multiprecision::backends::detail::mpc_complex_imp147 mpc_complex_imp& operator=(unsigned long i)
148 {
149 if (m_data[0].re[0]._mpfr_d == 0)
150 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
151 mpc_set_ui(m_data, i, GMP_RNDN);
152 return *this;
153 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp154 mpc_complex_imp& operator=(long i)
155 {
156 if (m_data[0].re[0]._mpfr_d == 0)
157 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
158 mpc_set_si(m_data, i, GMP_RNDN);
159 return *this;
160 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp161 mpc_complex_imp& operator=(double d)
162 {
163 if (m_data[0].re[0]._mpfr_d == 0)
164 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
165 mpc_set_d(m_data, d, GMP_RNDN);
166 return *this;
167 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp168 mpc_complex_imp& operator=(long double d)
169 {
170 if (m_data[0].re[0]._mpfr_d == 0)
171 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
172 mpc_set_ld(m_data, d, GMP_RNDN);
173 return *this;
174 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp175 mpc_complex_imp& operator=(mpz_t i)
176 {
177 if (m_data[0].re[0]._mpfr_d == 0)
178 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
179 mpc_set_z(m_data, i, GMP_RNDN);
180 return *this;
181 }
operator =boost::multiprecision::backends::detail::mpc_complex_imp182 mpc_complex_imp& operator=(gmp_int i)
183 {
184 if (m_data[0].re[0]._mpfr_d == 0)
185 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
186 mpc_set_z(m_data, i.data(), GMP_RNDN);
187 return *this;
188 }
189
operator =boost::multiprecision::backends::detail::mpc_complex_imp190 mpc_complex_imp& operator=(const char* s)
191 {
192 using default_ops::eval_fpclassify;
193
194 if (m_data[0].re[0]._mpfr_d == 0)
195 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
196
197 mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data));
198
199 if (s && (*s == '('))
200 {
201 std::string part;
202 const char* p = ++s;
203 while (*p && (*p != ',') && (*p != ')'))
204 ++p;
205 part.assign(s, p);
206 if (part.size())
207 a = part.c_str();
208 else
209 a = 0uL;
210 s = p;
211 if (*p && (*p != ')'))
212 {
213 ++p;
214 while (*p && (*p != ')'))
215 ++p;
216 part.assign(s + 1, p);
217 }
218 else
219 part.erase();
220 if (part.size())
221 b = part.c_str();
222 else
223 b = 0uL;
224 }
225 else
226 {
227 a = s;
228 b = 0uL;
229 }
230
231 if (eval_fpclassify(a) == (int)FP_NAN)
232 {
233 mpc_set_fr(this->data(), a.data(), GMP_RNDN);
234 }
235 else if (eval_fpclassify(b) == (int)FP_NAN)
236 {
237 mpc_set_fr(this->data(), b.data(), GMP_RNDN);
238 }
239 else
240 {
241 mpc_set_fr_fr(m_data, a.data(), b.data(), GMP_RNDN);
242 }
243 return *this;
244 }
swapboost::multiprecision::backends::detail::mpc_complex_imp245 void swap(mpc_complex_imp& o) BOOST_NOEXCEPT
246 {
247 mpc_swap(m_data, o.m_data);
248 }
strboost::multiprecision::backends::detail::mpc_complex_imp249 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
250 {
251 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
252
253 mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data));
254
255 mpc_real(a.data(), m_data, GMP_RNDD);
256 mpc_imag(b.data(), m_data, GMP_RNDD);
257
258 if (eval_is_zero(b))
259 return a.str(digits, f);
260
261 return "(" + a.str(digits, f) + "," + b.str(digits, f) + ")";
262 }
~mpc_complex_impboost::multiprecision::backends::detail::mpc_complex_imp263 ~mpc_complex_imp() BOOST_NOEXCEPT
264 {
265 if (m_data[0].re[0]._mpfr_d)
266 mpc_clear(m_data);
267 }
negateboost::multiprecision::backends::detail::mpc_complex_imp268 void negate() BOOST_NOEXCEPT
269 {
270 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
271 mpc_neg(m_data, m_data, GMP_RNDD);
272 }
compareboost::multiprecision::backends::detail::mpc_complex_imp273 int compare(const mpc_complex_imp& o) const BOOST_NOEXCEPT
274 {
275 BOOST_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d);
276 return mpc_cmp(m_data, o.m_data);
277 }
compareboost::multiprecision::backends::detail::mpc_complex_imp278 int compare(const mpc_complex_backend<digits10>& o) const BOOST_NOEXCEPT
279 {
280 BOOST_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d);
281 return mpc_cmp(m_data, o.data());
282 }
compareboost::multiprecision::backends::detail::mpc_complex_imp283 int compare(long int i) const BOOST_NOEXCEPT
284 {
285 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
286 return mpc_cmp_si(m_data, i);
287 }
compareboost::multiprecision::backends::detail::mpc_complex_imp288 int compare(unsigned long int i) const BOOST_NOEXCEPT
289 {
290 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
291 static const unsigned long int max_val = (std::numeric_limits<long>::max)();
292 if (i > max_val)
293 {
294 mpc_complex_imp d(mpc_get_prec(m_data));
295 d = i;
296 return compare(d);
297 }
298 return mpc_cmp_si(m_data, (long)i);
299 }
300 template <class V>
compareboost::multiprecision::backends::detail::mpc_complex_imp301 int compare(const V& v) const BOOST_NOEXCEPT
302 {
303 mpc_complex_imp d(mpc_get_prec(m_data));
304 d = v;
305 return compare(d);
306 }
databoost::multiprecision::backends::detail::mpc_complex_imp307 mpc_t& data() BOOST_NOEXCEPT
308 {
309 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
310 return m_data;
311 }
databoost::multiprecision::backends::detail::mpc_complex_imp312 const mpc_t& data() const BOOST_NOEXCEPT
313 {
314 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
315 return m_data;
316 }
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 {}
337 #endif
338 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend339 mpc_complex_backend(const mpc_complex_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
340 : detail::mpc_complex_imp<digits10>()
341 {
342 mpc_set(this->m_data, val.data(), GMP_RNDN);
343 }
344 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend345 explicit mpc_complex_backend(const mpc_complex_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
346 : detail::mpc_complex_imp<digits10>()
347 {
348 mpc_set(this->m_data, val.data(), GMP_RNDN);
349 }
350 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend351 mpc_complex_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
352 : detail::mpc_complex_imp<digits10>()
353 {
354 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
355 }
356 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend357 explicit mpc_complex_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
358 : detail::mpc_complex_imp<digits10>()
359 {
360 mpc_set(this->m_data, val.data(), GMP_RNDN);
361 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend362 mpc_complex_backend(const mpc_t val)
363 : detail::mpc_complex_imp<digits10>()
364 {
365 mpc_set(this->m_data, val, GMP_RNDN);
366 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend367 mpc_complex_backend(const std::complex<float>& val)
368 : detail::mpc_complex_imp<digits10>()
369 {
370 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
371 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend372 mpc_complex_backend(const std::complex<double>& val)
373 : detail::mpc_complex_imp<digits10>()
374 {
375 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
376 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend377 mpc_complex_backend(const std::complex<long double>& val)
378 : detail::mpc_complex_imp<digits10>()
379 {
380 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
381 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend382 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<digits10>()
383 {
384 mpc_set_z(this->m_data, val, GMP_RNDN);
385 }
operator =boost::multiprecision::backends::mpc_complex_backend386 mpc_complex_backend& operator=(mpz_srcptr val)
387 {
388 mpc_set_z(this->m_data, val, GMP_RNDN);
389 return *this;
390 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend391 mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<digits10>()
392 {
393 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
394 }
operator =boost::multiprecision::backends::mpc_complex_backend395 mpc_complex_backend& operator=(gmp_int const& val)
396 {
397 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
398 return *this;
399 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend400 mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<digits10>()
401 {
402 mpc_set_f(this->m_data, val, GMP_RNDN);
403 }
operator =boost::multiprecision::backends::mpc_complex_backend404 mpc_complex_backend& operator=(mpf_srcptr val)
405 {
406 mpc_set_f(this->m_data, val, GMP_RNDN);
407 return *this;
408 }
409 template <unsigned D10>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend410 mpc_complex_backend(gmp_float<D10> const& val) : detail::mpc_complex_imp<digits10>()
411 {
412 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
413 }
414 template <unsigned D10>
operator =boost::multiprecision::backends::mpc_complex_backend415 mpc_complex_backend& operator=(gmp_float<D10> const& val)
416 {
417 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
418 return *this;
419 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend420 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<digits10>()
421 {
422 mpc_set_q(this->m_data, val, GMP_RNDN);
423 }
operator =boost::multiprecision::backends::mpc_complex_backend424 mpc_complex_backend& operator=(mpq_srcptr val)
425 {
426 mpc_set_q(this->m_data, val, GMP_RNDN);
427 return *this;
428 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend429 mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<digits10>()
430 {
431 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
432 }
operator =boost::multiprecision::backends::mpc_complex_backend433 mpc_complex_backend& operator=(gmp_rational const& val)
434 {
435 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
436 return *this;
437 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend438 mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<digits10>()
439 {
440 mpc_set_fr(this->m_data, val, GMP_RNDN);
441 }
operator =boost::multiprecision::backends::mpc_complex_backend442 mpc_complex_backend& operator=(mpfr_srcptr val)
443 {
444 mpc_set_fr(this->m_data, val, GMP_RNDN);
445 return *this;
446 }
447 template <unsigned D10, mpfr_allocation_type AllocationType>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend448 mpc_complex_backend(mpfr_float_backend<D10, AllocationType> const& val) : detail::mpc_complex_imp<digits10>()
449 {
450 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
451 }
452 template <unsigned D10, mpfr_allocation_type AllocationType>
operator =boost::multiprecision::backends::mpc_complex_backend453 mpc_complex_backend& operator=(mpfr_float_backend<D10, AllocationType> const& val)
454 {
455 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
456 return *this;
457 }
operator =boost::multiprecision::backends::mpc_complex_backend458 mpc_complex_backend& operator=(const mpc_complex_backend& o)
459 {
460 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10> const&>(o);
461 return *this;
462 }
463 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::mpc_complex_backend464 mpc_complex_backend& operator=(mpc_complex_backend&& o) BOOST_NOEXCEPT
465 {
466 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10>&&>(o);
467 return *this;
468 }
469 #endif
470 template <class V>
operator =boost::multiprecision::backends::mpc_complex_backend471 mpc_complex_backend& operator=(const V& v)
472 {
473 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = v;
474 return *this;
475 }
operator =boost::multiprecision::backends::mpc_complex_backend476 mpc_complex_backend& operator=(const mpc_t val)
477 {
478 mpc_set(this->m_data, val, GMP_RNDN);
479 return *this;
480 }
operator =boost::multiprecision::backends::mpc_complex_backend481 mpc_complex_backend& operator=(const std::complex<float>& val)
482 {
483 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
484 return *this;
485 }
operator =boost::multiprecision::backends::mpc_complex_backend486 mpc_complex_backend& operator=(const std::complex<double>& val)
487 {
488 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
489 return *this;
490 }
operator =boost::multiprecision::backends::mpc_complex_backend491 mpc_complex_backend& operator=(const std::complex<long double>& val)
492 {
493 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
494 return *this;
495 }
496 // We don't change our precision here, this is a fixed precision type:
497 template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend498 mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
499 {
500 mpc_set(this->m_data, val.data(), GMP_RNDN);
501 return *this;
502 }
503 };
504
505 template <>
506 struct mpc_complex_backend<0> : public detail::mpc_complex_imp<0>
507 {
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend508 mpc_complex_backend() : detail::mpc_complex_imp<0>() {}
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend509 mpc_complex_backend(const mpc_t val)
510 : detail::mpc_complex_imp<0>(mpc_get_prec(val))
511 {
512 mpc_set(this->m_data, val, GMP_RNDN);
513 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend514 mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<0>(o) {}
515 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend516 mpc_complex_backend(mpc_complex_backend&& o) BOOST_NOEXCEPT : detail::mpc_complex_imp<0>(static_cast<detail::mpc_complex_imp<0>&&>(o))
517 {}
518 #endif
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend519 mpc_complex_backend(const mpc_complex_backend& o, unsigned digits10)
520 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
521 {
522 mpc_set(this->m_data, o.data(), GMP_RNDN);
523 }
524 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend525 mpc_complex_backend(const mpc_complex_backend<D>& val)
526 : detail::mpc_complex_imp<0>(mpc_get_prec(val.data()))
527 {
528 mpc_set(this->m_data, val.data(), GMP_RNDN);
529 }
530 template <unsigned D>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend531 mpc_complex_backend(const mpfr_float_backend<D>& val)
532 : detail::mpc_complex_imp<0>(mpfr_get_prec(val.data()))
533 {
534 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
535 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend536 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<0>()
537 {
538 mpc_set_z(this->m_data, val, GMP_RNDN);
539 }
operator =boost::multiprecision::backends::mpc_complex_backend540 mpc_complex_backend& operator=(mpz_srcptr val)
541 {
542 mpc_set_z(this->m_data, val, GMP_RNDN);
543 return *this;
544 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend545 mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<0>()
546 {
547 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
548 }
operator =boost::multiprecision::backends::mpc_complex_backend549 mpc_complex_backend& operator=(gmp_int const& val)
550 {
551 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
552 return *this;
553 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend554 mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val))
555 {
556 mpc_set_f(this->m_data, val, GMP_RNDN);
557 }
operator =boost::multiprecision::backends::mpc_complex_backend558 mpc_complex_backend& operator=(mpf_srcptr val)
559 {
560 if ((mp_bitcnt_t)mpc_get_prec(data()) != mpf_get_prec(val))
561 {
562 mpc_complex_backend t(val);
563 t.swap(*this);
564 }
565 else
566 mpc_set_f(this->m_data, val, GMP_RNDN);
567 return *this;
568 }
569 template <unsigned digits10>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend570 mpc_complex_backend(gmp_float<digits10> const& val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val.data()))
571 {
572 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
573 }
574 template <unsigned digits10>
operator =boost::multiprecision::backends::mpc_complex_backend575 mpc_complex_backend& operator=(gmp_float<digits10> const& val)
576 {
577 if (mpc_get_prec(data()) != (mpfr_prec_t)mpf_get_prec(val.data()))
578 {
579 mpc_complex_backend t(val);
580 t.swap(*this);
581 }
582 else
583 mpc_set_f(this->m_data, val.data(), GMP_RNDN);
584 return *this;
585 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend586 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<0>()
587 {
588 mpc_set_q(this->m_data, val, GMP_RNDN);
589 }
operator =boost::multiprecision::backends::mpc_complex_backend590 mpc_complex_backend& operator=(mpq_srcptr val)
591 {
592 mpc_set_q(this->m_data, val, GMP_RNDN);
593 return *this;
594 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend595 mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<0>()
596 {
597 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
598 }
operator =boost::multiprecision::backends::mpc_complex_backend599 mpc_complex_backend& operator=(gmp_rational const& val)
600 {
601 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
602 return *this;
603 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend604 mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<0>(mpfr_get_prec(val))
605 {
606 mpc_set_fr(this->m_data, val, GMP_RNDN);
607 }
operator =boost::multiprecision::backends::mpc_complex_backend608 mpc_complex_backend& operator=(mpfr_srcptr val)
609 {
610 if (mpc_get_prec(data()) != mpfr_get_prec(val))
611 {
612 mpc_complex_backend t(val);
613 t.swap(*this);
614 }
615 else
616 mpc_set_fr(this->m_data, val, GMP_RNDN);
617 return *this;
618 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend619 mpc_complex_backend(const std::complex<float>& val)
620 : detail::mpc_complex_imp<0>()
621 {
622 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
623 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend624 mpc_complex_backend(const std::complex<double>& val)
625 : detail::mpc_complex_imp<0>()
626 {
627 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
628 }
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend629 mpc_complex_backend(const std::complex<long double>& val)
630 : detail::mpc_complex_imp<0>()
631 {
632 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
633 }
634 // Construction with precision:
635 template <class T, class U>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend636 mpc_complex_backend(const T& a, const U& b, unsigned digits10)
637 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
638 {
639 // We can't use assign_components here because it copies the precision of
640 // a and b, not digits10....
641 mpfr_float ca(a), cb(b);
642 mpc_set_fr_fr(this->data(), ca.backend().data(), cb.backend().data(), GMP_RNDN);
643 }
644 template <unsigned N>
mpc_complex_backendboost::multiprecision::backends::mpc_complex_backend645 mpc_complex_backend(const mpfr_float_backend<N>& a, const mpfr_float_backend<N>& b, unsigned digits10)
646 : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10))
647 {
648 mpc_set_fr_fr(this->data(), a.data(), b.data(), GMP_RNDN);
649 }
650
operator =boost::multiprecision::backends::mpc_complex_backend651 mpc_complex_backend& operator=(const mpc_complex_backend& o)
652 {
653 if (this != &o)
654 {
655 detail::mpc_copy_precision(this->m_data, o.data());
656 mpc_set(this->m_data, o.data(), GMP_RNDN);
657 }
658 return *this;
659 }
660 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator =boost::multiprecision::backends::mpc_complex_backend661 mpc_complex_backend& operator=(mpc_complex_backend&& o) BOOST_NOEXCEPT
662 {
663 *static_cast<detail::mpc_complex_imp<0>*>(this) = static_cast<detail::mpc_complex_imp<0>&&>(o);
664 return *this;
665 }
666 #endif
667 template <class V>
operator =boost::multiprecision::backends::mpc_complex_backend668 mpc_complex_backend& operator=(const V& v)
669 {
670 *static_cast<detail::mpc_complex_imp<0>*>(this) = v;
671 return *this;
672 }
operator =boost::multiprecision::backends::mpc_complex_backend673 mpc_complex_backend& operator=(const mpc_t val)
674 {
675 mpc_set_prec(this->m_data, mpc_get_prec(val));
676 mpc_set(this->m_data, val, GMP_RNDN);
677 return *this;
678 }
679 template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend680 mpc_complex_backend& operator=(const mpc_complex_backend<D>& val)
681 {
682 mpc_set_prec(this->m_data, mpc_get_prec(val.data()));
683 mpc_set(this->m_data, val.data(), GMP_RNDN);
684 return *this;
685 }
686 template <unsigned D>
operator =boost::multiprecision::backends::mpc_complex_backend687 mpc_complex_backend& operator=(const mpfr_float_backend<D>& val)
688 {
689 mpc_set_prec(this->m_data, mpfr_get_prec(val.data()));
690 mpc_set_fr(this->m_data, val.data(), GMP_RNDN);
691 return *this;
692 }
operator =boost::multiprecision::backends::mpc_complex_backend693 mpc_complex_backend& operator=(const std::complex<float>& val)
694 {
695 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
696 return *this;
697 }
operator =boost::multiprecision::backends::mpc_complex_backend698 mpc_complex_backend& operator=(const std::complex<double>& val)
699 {
700 mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN);
701 return *this;
702 }
operator =boost::multiprecision::backends::mpc_complex_backend703 mpc_complex_backend& operator=(const std::complex<long double>& val)
704 {
705 mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN);
706 return *this;
707 }
default_precisionboost::multiprecision::backends::mpc_complex_backend708 static unsigned default_precision() BOOST_NOEXCEPT
709 {
710 return get_default_precision();
711 }
default_precisionboost::multiprecision::backends::mpc_complex_backend712 static void default_precision(unsigned v) BOOST_NOEXCEPT
713 {
714 get_default_precision() = v;
715 }
precisionboost::multiprecision::backends::mpc_complex_backend716 unsigned precision() const BOOST_NOEXCEPT
717 {
718 return multiprecision::detail::digits2_2_10(mpc_get_prec(this->m_data));
719 }
precisionboost::multiprecision::backends::mpc_complex_backend720 void precision(unsigned digits10) BOOST_NOEXCEPT
721 {
722 mpfr_prec_round(mpc_realref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
723 mpfr_prec_round(mpc_imagref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
724 }
725 };
726
727 template <unsigned digits10, class T>
eval_eq(const mpc_complex_backend<digits10> & a,const T & b)728 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
729 {
730 return a.compare(b) == 0;
731 }
732 template <unsigned digits10, class T>
eval_lt(const mpc_complex_backend<digits10> & a,const T & b)733 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
734 {
735 return a.compare(b) < 0;
736 }
737 template <unsigned digits10, class T>
eval_gt(const mpc_complex_backend<digits10> & a,const T & b)738 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpc_complex_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
739 {
740 return a.compare(b) > 0;
741 }
742
743 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)744 inline void eval_add(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
745 {
746 mpc_add(result.data(), result.data(), o.data(), GMP_RNDD);
747 }
748 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)749 inline void eval_add(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
750 {
751 mpc_add_fr(result.data(), result.data(), o.data(), GMP_RNDD);
752 }
753 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)754 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
755 {
756 mpc_sub(result.data(), result.data(), o.data(), GMP_RNDD);
757 }
758 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)759 inline void eval_subtract(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
760 {
761 mpc_sub_fr(result.data(), result.data(), o.data(), GMP_RNDD);
762 }
763 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)764 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
765 {
766 if ((void*)&result == (void*)&o)
767 mpc_sqr(result.data(), o.data(), GMP_RNDN);
768 else
769 mpc_mul(result.data(), result.data(), o.data(), GMP_RNDN);
770 }
771 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)772 inline void eval_multiply(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
773 {
774 mpc_mul_fr(result.data(), result.data(), o.data(), GMP_RNDN);
775 }
776 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & result,const mpc_complex_backend<D2> & o)777 inline void eval_divide(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o)
778 {
779 mpc_div(result.data(), result.data(), o.data(), GMP_RNDD);
780 }
781 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & result,const mpfr_float_backend<D2> & o)782 inline void eval_divide(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o)
783 {
784 mpc_div_fr(result.data(), result.data(), o.data(), GMP_RNDD);
785 }
786 template <unsigned digits10>
eval_add(mpc_complex_backend<digits10> & result,unsigned long i)787 inline void eval_add(mpc_complex_backend<digits10>& result, unsigned long i)
788 {
789 mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
790 }
791 template <unsigned digits10>
eval_subtract(mpc_complex_backend<digits10> & result,unsigned long i)792 inline void eval_subtract(mpc_complex_backend<digits10>& result, unsigned long i)
793 {
794 mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
795 }
796 template <unsigned digits10>
eval_multiply(mpc_complex_backend<digits10> & result,unsigned long i)797 inline void eval_multiply(mpc_complex_backend<digits10>& result, unsigned long i)
798 {
799 mpc_mul_ui(result.data(), result.data(), i, GMP_RNDN);
800 }
801 template <unsigned digits10>
eval_divide(mpc_complex_backend<digits10> & result,unsigned long i)802 inline void eval_divide(mpc_complex_backend<digits10>& result, unsigned long i)
803 {
804 mpc_div_ui(result.data(), result.data(), i, GMP_RNDN);
805 }
806 template <unsigned digits10>
eval_add(mpc_complex_backend<digits10> & result,long i)807 inline void eval_add(mpc_complex_backend<digits10>& result, long i)
808 {
809 if (i > 0)
810 mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
811 else
812 mpc_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
813 }
814 template <unsigned digits10>
eval_subtract(mpc_complex_backend<digits10> & result,long i)815 inline void eval_subtract(mpc_complex_backend<digits10>& result, long i)
816 {
817 if (i > 0)
818 mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
819 else
820 mpc_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
821 }
822 template <unsigned digits10>
eval_multiply(mpc_complex_backend<digits10> & result,long i)823 inline void eval_multiply(mpc_complex_backend<digits10>& result, long i)
824 {
825 mpc_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
826 if (i < 0)
827 mpc_neg(result.data(), result.data(), GMP_RNDN);
828 }
829 template <unsigned digits10>
eval_divide(mpc_complex_backend<digits10> & result,long i)830 inline void eval_divide(mpc_complex_backend<digits10>& result, long i)
831 {
832 mpc_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
833 if (i < 0)
834 mpc_neg(result.data(), result.data(), GMP_RNDN);
835 }
836 //
837 // Specialised 3 arg versions of the basic operators:
838 //
839 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)840 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
841 {
842 mpc_add(a.data(), x.data(), y.data(), GMP_RNDD);
843 }
844 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)845 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
846 {
847 mpc_add_fr(a.data(), x.data(), y.data(), GMP_RNDD);
848 }
849 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)850 inline void eval_add(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
851 {
852 mpc_add_fr(a.data(), y.data(), x.data(), GMP_RNDD);
853 }
854 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)855 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
856 {
857 mpc_add_ui(a.data(), x.data(), y, GMP_RNDD);
858 }
859 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)860 inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
861 {
862 if (y < 0)
863 mpc_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
864 else
865 mpc_add_ui(a.data(), x.data(), y, GMP_RNDD);
866 }
867 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)868 inline void eval_add(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
869 {
870 mpc_add_ui(a.data(), y.data(), x, GMP_RNDD);
871 }
872 template <unsigned D1, unsigned D2>
eval_add(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)873 inline void eval_add(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
874 {
875 if (x < 0)
876 {
877 mpc_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
878 mpc_neg(a.data(), a.data(), GMP_RNDD);
879 }
880 else
881 mpc_add_ui(a.data(), y.data(), x, GMP_RNDD);
882 }
883 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)884 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
885 {
886 mpc_sub(a.data(), x.data(), y.data(), GMP_RNDD);
887 }
888 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)889 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
890 {
891 mpc_sub_fr(a.data(), x.data(), y.data(), GMP_RNDD);
892 }
893 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)894 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
895 {
896 mpc_fr_sub(a.data(), x.data(), y.data(), GMP_RNDD);
897 }
898 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)899 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
900 {
901 mpc_sub_ui(a.data(), x.data(), y, GMP_RNDD);
902 }
903 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)904 inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
905 {
906 if (y < 0)
907 mpc_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
908 else
909 mpc_sub_ui(a.data(), x.data(), y, GMP_RNDD);
910 }
911 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)912 inline void eval_subtract(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
913 {
914 mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
915 }
916 template <unsigned D1, unsigned D2>
eval_subtract(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)917 inline void eval_subtract(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
918 {
919 if (x < 0)
920 {
921 mpc_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDD);
922 mpc_neg(a.data(), a.data(), GMP_RNDD);
923 }
924 else
925 mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN);
926 }
927
928 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)929 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
930 {
931 if ((void*)&x == (void*)&y)
932 mpc_sqr(a.data(), x.data(), GMP_RNDD);
933 else
934 mpc_mul(a.data(), x.data(), y.data(), GMP_RNDD);
935 }
936 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)937 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
938 {
939 mpc_mul_fr(a.data(), x.data(), y.data(), GMP_RNDD);
940 }
941 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)942 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
943 {
944 mpc_mul_fr(a.data(), y.data(), x.data(), GMP_RNDD);
945 }
946 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)947 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
948 {
949 mpc_mul_ui(a.data(), x.data(), y, GMP_RNDD);
950 }
951 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)952 inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
953 {
954 if (y < 0)
955 {
956 mpc_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
957 a.negate();
958 }
959 else
960 mpc_mul_ui(a.data(), x.data(), y, GMP_RNDD);
961 }
962 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)963 inline void eval_multiply(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
964 {
965 mpc_mul_ui(a.data(), y.data(), x, GMP_RNDD);
966 }
967 template <unsigned D1, unsigned D2>
eval_multiply(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)968 inline void eval_multiply(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
969 {
970 if (x < 0)
971 {
972 mpc_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDD);
973 mpc_neg(a.data(), a.data(), GMP_RNDD);
974 }
975 else
976 mpc_mul_ui(a.data(), y.data(), x, GMP_RNDD);
977 }
978
979 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)980 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y)
981 {
982 mpc_div(a.data(), x.data(), y.data(), GMP_RNDD);
983 }
984 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)985 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y)
986 {
987 mpc_div_fr(a.data(), x.data(), y.data(), GMP_RNDD);
988 }
989 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)990 inline void eval_divide(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y)
991 {
992 mpc_fr_div(a.data(), x.data(), y.data(), GMP_RNDD);
993 }
994 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,unsigned long y)995 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y)
996 {
997 mpc_div_ui(a.data(), x.data(), y, GMP_RNDD);
998 }
999 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,const mpc_complex_backend<D2> & x,long y)1000 inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y)
1001 {
1002 if (y < 0)
1003 {
1004 mpc_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDD);
1005 a.negate();
1006 }
1007 else
1008 mpc_div_ui(a.data(), x.data(), y, GMP_RNDD);
1009 }
1010 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,unsigned long x,const mpc_complex_backend<D2> & y)1011 inline void eval_divide(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y)
1012 {
1013 mpc_ui_div(a.data(), x, y.data(), GMP_RNDD);
1014 }
1015 template <unsigned D1, unsigned D2>
eval_divide(mpc_complex_backend<D1> & a,long x,const mpc_complex_backend<D2> & y)1016 inline void eval_divide(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y)
1017 {
1018 if (x < 0)
1019 {
1020 mpc_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDD);
1021 mpc_neg(a.data(), a.data(), GMP_RNDD);
1022 }
1023 else
1024 mpc_ui_div(a.data(), x, y.data(), GMP_RNDD);
1025 }
1026
1027 template <unsigned digits10>
eval_is_zero(const mpc_complex_backend<digits10> & val)1028 inline bool eval_is_zero(const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1029 {
1030 return (0 != mpfr_zero_p(mpc_realref(val.data()))) && (0 != mpfr_zero_p(mpc_imagref(val.data())));
1031 }
1032 template <unsigned digits10>
eval_get_sign(const mpc_complex_backend<digits10> &)1033 inline int eval_get_sign(const mpc_complex_backend<digits10>&)
1034 {
1035 BOOST_STATIC_ASSERT_MSG(digits10 == UINT_MAX, "Complex numbers have no sign bit."); // designed to always fail
1036 return 0;
1037 }
1038
1039 template <unsigned digits10>
eval_convert_to(unsigned long * result,const mpc_complex_backend<digits10> & val)1040 inline void eval_convert_to(unsigned long* result, const mpc_complex_backend<digits10>& val)
1041 {
1042 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1043 {
1044 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1045 }
1046 mpfr_float_backend<digits10> t;
1047 mpc_real(t.data(), val.data(), GMP_RNDN);
1048 eval_convert_to(result, t);
1049 }
1050 template <unsigned digits10>
eval_convert_to(long * result,const mpc_complex_backend<digits10> & val)1051 inline void eval_convert_to(long* result, const mpc_complex_backend<digits10>& val)
1052 {
1053 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1054 {
1055 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1056 }
1057 mpfr_float_backend<digits10> t;
1058 mpc_real(t.data(), val.data(), GMP_RNDN);
1059 eval_convert_to(result, t);
1060 }
1061 #ifdef _MPFR_H_HAVE_INTMAX_T
1062 template <unsigned digits10>
eval_convert_to(boost::ulong_long_type * result,const mpc_complex_backend<digits10> & val)1063 inline void eval_convert_to(boost::ulong_long_type* result, const mpc_complex_backend<digits10>& val)
1064 {
1065 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1066 {
1067 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1068 }
1069 mpfr_float_backend<digits10> t;
1070 mpc_real(t.data(), val.data(), GMP_RNDN);
1071 eval_convert_to(result, t);
1072 }
1073 template <unsigned digits10>
eval_convert_to(boost::long_long_type * result,const mpc_complex_backend<digits10> & val)1074 inline void eval_convert_to(boost::long_long_type* result, const mpc_complex_backend<digits10>& val)
1075 {
1076 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1077 {
1078 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1079 }
1080 mpfr_float_backend<digits10> t;
1081 mpc_real(t.data(), val.data(), GMP_RNDN);
1082 eval_convert_to(result, t);
1083 }
1084 #endif
1085 template <unsigned digits10>
eval_convert_to(double * result,const mpc_complex_backend<digits10> & val)1086 inline void eval_convert_to(double* result, const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1087 {
1088 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1089 {
1090 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1091 }
1092 mpfr_float_backend<digits10> t;
1093 mpc_real(t.data(), val.data(), GMP_RNDN);
1094 eval_convert_to(result, t);
1095 }
1096 template <unsigned digits10>
eval_convert_to(long double * result,const mpc_complex_backend<digits10> & val)1097 inline void eval_convert_to(long double* result, const mpc_complex_backend<digits10>& val) BOOST_NOEXCEPT
1098 {
1099 if (0 == mpfr_zero_p(mpc_imagref(val.data())))
1100 {
1101 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar."));
1102 }
1103 mpfr_float_backend<digits10> t;
1104 mpc_real(t.data(), val.data(), GMP_RNDN);
1105 eval_convert_to(result, t);
1106 }
1107
1108 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)1109 inline void assign_components(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
1110 {
1111 //
1112 // This is called from class number's constructors, so if we have variable
1113 // precision, then copy the precision of the source variables.
1114 //
1115 if (!D1)
1116 {
1117 unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data()));
1118 mpc_set_prec(result.data(), prec);
1119 }
1120 using default_ops::eval_fpclassify;
1121 if (eval_fpclassify(a) == (int)FP_NAN)
1122 {
1123 mpc_set_fr(result.data(), a.data(), GMP_RNDN);
1124 }
1125 else if (eval_fpclassify(b) == (int)FP_NAN)
1126 {
1127 mpc_set_fr(result.data(), b.data(), GMP_RNDN);
1128 }
1129 else
1130 {
1131 mpc_set_fr_fr(result.data(), a.data(), b.data(), GMP_RNDN);
1132 }
1133 }
1134
1135 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,unsigned long a,unsigned long b)1136 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long a, unsigned long b)
1137 {
1138 mpc_set_ui_ui(result.data(), a, b, GMP_RNDN);
1139 }
1140
1141 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long a,long b)1142 inline void assign_components(mpc_complex_backend<D1>& result, long a, long b)
1143 {
1144 mpc_set_si_si(result.data(), a, b, GMP_RNDN);
1145 }
1146
1147 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1148 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,unsigned long long a,unsigned long long b)1149 inline void assign_components(mpc_complex_backend<D1>& result, unsigned long long a, unsigned long long b)
1150 {
1151 mpc_set_uj_uj(result.data(), a, b, GMP_RNDN);
1152 }
1153
1154 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long long a,long long b)1155 inline void assign_components(mpc_complex_backend<D1>& result, long long a, long long b)
1156 {
1157 mpc_set_sj_sj(result.data(), a, b, GMP_RNDN);
1158 }
1159 #endif
1160
1161 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,double a,double b)1162 inline void assign_components(mpc_complex_backend<D1>& result, double a, double b)
1163 {
1164 if ((boost::math::isnan)(a))
1165 {
1166 mpc_set_d(result.data(), a, GMP_RNDN);
1167 }
1168 else if ((boost::math::isnan)(b))
1169 {
1170 mpc_set_d(result.data(), b, GMP_RNDN);
1171 }
1172 else
1173 {
1174 mpc_set_d_d(result.data(), a, b, GMP_RNDN);
1175 }
1176 }
1177
1178 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
assign_components(mpc_complex_backend<D1> & result,long double a,long double b)1179 inline void assign_components(mpc_complex_backend<D1>& result, long double a, long double b)
1180 {
1181 if ((boost::math::isnan)(a))
1182 {
1183 mpc_set_d(result.data(), a, GMP_RNDN);
1184 }
1185 else if ((boost::math::isnan)(b))
1186 {
1187 mpc_set_d(result.data(), b, GMP_RNDN);
1188 }
1189 else
1190 {
1191 mpc_set_ld_ld(result.data(), a, b, GMP_RNDN);
1192 }
1193 }
1194
1195 //
1196 // Native non-member operations:
1197 //
1198 template <unsigned Digits10>
eval_sqrt(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & val)1199 inline void eval_sqrt(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& val)
1200 {
1201 mpc_sqrt(result.data(), val.data(), GMP_RNDN);
1202 }
1203
1204 template <unsigned Digits10>
eval_pow(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & b,const mpc_complex_backend<Digits10> & e)1205 inline void eval_pow(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& b, const mpc_complex_backend<Digits10>& e)
1206 {
1207 mpc_pow(result.data(), b.data(), e.data(), GMP_RNDN);
1208 }
1209
1210 template <unsigned Digits10>
eval_exp(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1211 inline void eval_exp(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1212 {
1213 mpc_exp(result.data(), arg.data(), GMP_RNDN);
1214 }
1215
1216 template <unsigned Digits10>
eval_log(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1217 inline void eval_log(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1218 {
1219 mpc_log(result.data(), arg.data(), GMP_RNDN);
1220 }
1221
1222 template <unsigned Digits10>
eval_log10(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1223 inline void eval_log10(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1224 {
1225 mpc_log10(result.data(), arg.data(), GMP_RNDN);
1226 }
1227
1228 template <unsigned Digits10>
eval_sin(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1229 inline void eval_sin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1230 {
1231 mpc_sin(result.data(), arg.data(), GMP_RNDN);
1232 }
1233
1234 template <unsigned Digits10>
eval_cos(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1235 inline void eval_cos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1236 {
1237 mpc_cos(result.data(), arg.data(), GMP_RNDN);
1238 }
1239
1240 template <unsigned Digits10>
eval_tan(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1241 inline void eval_tan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1242 {
1243 mpc_tan(result.data(), arg.data(), GMP_RNDN);
1244 }
1245
1246 template <unsigned Digits10>
eval_asin(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1247 inline void eval_asin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1248 {
1249 mpc_asin(result.data(), arg.data(), GMP_RNDN);
1250 }
1251
1252 template <unsigned Digits10>
eval_acos(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1253 inline void eval_acos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1254 {
1255 mpc_acos(result.data(), arg.data(), GMP_RNDN);
1256 }
1257
1258 template <unsigned Digits10>
eval_atan(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1259 inline void eval_atan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1260 {
1261 mpc_atan(result.data(), arg.data(), GMP_RNDN);
1262 }
1263
1264 template <unsigned Digits10>
eval_sinh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1265 inline void eval_sinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1266 {
1267 mpc_sinh(result.data(), arg.data(), GMP_RNDN);
1268 }
1269
1270 template <unsigned Digits10>
eval_cosh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1271 inline void eval_cosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1272 {
1273 mpc_cosh(result.data(), arg.data(), GMP_RNDN);
1274 }
1275
1276 template <unsigned Digits10>
eval_tanh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1277 inline void eval_tanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1278 {
1279 mpc_tanh(result.data(), arg.data(), GMP_RNDN);
1280 }
1281
1282 template <unsigned Digits10>
eval_asinh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1283 inline void eval_asinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1284 {
1285 mpc_asinh(result.data(), arg.data(), GMP_RNDN);
1286 }
1287
1288 template <unsigned Digits10>
eval_acosh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1289 inline void eval_acosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1290 {
1291 mpc_acosh(result.data(), arg.data(), GMP_RNDN);
1292 }
1293
1294 template <unsigned Digits10>
eval_atanh(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1295 inline void eval_atanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1296 {
1297 mpc_atanh(result.data(), arg.data(), GMP_RNDN);
1298 }
1299
1300 template <unsigned Digits10>
eval_conj(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1301 inline void eval_conj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1302 {
1303 mpc_conj(result.data(), arg.data(), GMP_RNDN);
1304 }
1305
1306 template <unsigned Digits10>
eval_proj(mpc_complex_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1307 inline void eval_proj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1308 {
1309 mpc_proj(result.data(), arg.data(), GMP_RNDN);
1310 }
1311
1312 template <unsigned Digits10>
eval_real(mpfr_float_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1313 inline void eval_real(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1314 {
1315 mpfr_set_prec(result.data(), mpfr_get_prec(mpc_realref(arg.data())));
1316 mpfr_set(result.data(), mpc_realref(arg.data()), GMP_RNDN);
1317 }
1318 template <unsigned Digits10>
eval_imag(mpfr_float_backend<Digits10> & result,const mpc_complex_backend<Digits10> & arg)1319 inline void eval_imag(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg)
1320 {
1321 mpfr_set_prec(result.data(), mpfr_get_prec(mpc_imagref(arg.data())));
1322 mpfr_set(result.data(), mpc_imagref(arg.data()), GMP_RNDN);
1323 }
1324
1325 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const mpfr_float_backend<Digits10> & arg)1326 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1327 {
1328 mpfr_set(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1329 }
1330
1331 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const mpfr_float_backend<Digits10> & arg)1332 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg)
1333 {
1334 mpfr_set(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1335 }
1336 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const gmp_int & arg)1337 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1338 {
1339 mpfr_set_z(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1340 }
1341 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const gmp_rational & arg)1342 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1343 {
1344 mpfr_set_q(mpc_realref(result.data()), arg.data(), GMP_RNDN);
1345 }
1346 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned & arg)1347 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1348 {
1349 mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1350 }
1351 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned long & arg)1352 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1353 {
1354 mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN);
1355 }
1356 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const int & arg)1357 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const int& arg)
1358 {
1359 mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1360 }
1361 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long & arg)1362 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long& arg)
1363 {
1364 mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN);
1365 }
1366 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const float & arg)1367 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const float& arg)
1368 {
1369 mpfr_set_flt(mpc_realref(result.data()), arg, GMP_RNDN);
1370 }
1371 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const double & arg)1372 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const double& arg)
1373 {
1374 mpfr_set_d(mpc_realref(result.data()), arg, GMP_RNDN);
1375 }
1376 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long double & arg)1377 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long double& arg)
1378 {
1379 mpfr_set_ld(mpc_realref(result.data()), arg, GMP_RNDN);
1380 }
1381 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1382 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const unsigned long long & arg)1383 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1384 {
1385 mpfr_set_uj(mpc_realref(result.data()), arg, GMP_RNDN);
1386 }
1387 template <unsigned Digits10>
eval_set_real(mpc_complex_backend<Digits10> & result,const long long & arg)1388 inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long long& arg)
1389 {
1390 mpfr_set_sj(mpc_realref(result.data()), arg, GMP_RNDN);
1391 }
1392 #endif
1393
1394 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const gmp_int & arg)1395 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_int& arg)
1396 {
1397 mpfr_set_z(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1398 }
1399 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const gmp_rational & arg)1400 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_rational& arg)
1401 {
1402 mpfr_set_q(mpc_imagref(result.data()), arg.data(), GMP_RNDN);
1403 }
1404 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned & arg)1405 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned& arg)
1406 {
1407 mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1408 }
1409 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned long & arg)1410 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long& arg)
1411 {
1412 mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN);
1413 }
1414 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const int & arg)1415 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const int& arg)
1416 {
1417 mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1418 }
1419 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long & arg)1420 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long& arg)
1421 {
1422 mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN);
1423 }
1424 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const float & arg)1425 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const float& arg)
1426 {
1427 mpfr_set_flt(mpc_imagref(result.data()), arg, GMP_RNDN);
1428 }
1429 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const double & arg)1430 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const double& arg)
1431 {
1432 mpfr_set_d(mpc_imagref(result.data()), arg, GMP_RNDN);
1433 }
1434 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long double & arg)1435 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long double& arg)
1436 {
1437 mpfr_set_ld(mpc_imagref(result.data()), arg, GMP_RNDN);
1438 }
1439 #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T)
1440 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const unsigned long long & arg)1441 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long long& arg)
1442 {
1443 mpfr_set_uj(mpc_imagref(result.data()), arg, GMP_RNDN);
1444 }
1445 template <unsigned Digits10>
eval_set_imag(mpc_complex_backend<Digits10> & result,const long long & arg)1446 inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long long& arg)
1447 {
1448 mpfr_set_sj(mpc_imagref(result.data()), arg, GMP_RNDN);
1449 }
1450 #endif
1451
1452 template <unsigned Digits10>
hash_value(const mpc_complex_backend<Digits10> & val)1453 inline std::size_t hash_value(const mpc_complex_backend<Digits10>& val)
1454 {
1455 std::size_t result = 0;
1456 std::size_t len = val.data()[0].re[0]._mpfr_prec / mp_bits_per_limb;
1457 if (val.data()[0].re[0]._mpfr_prec % mp_bits_per_limb)
1458 ++len;
1459 for (std::size_t i = 0; i < len; ++i)
1460 boost::hash_combine(result, val.data()[0].re[0]._mpfr_d[i]);
1461 boost::hash_combine(result, val.data()[0].re[0]._mpfr_exp);
1462 boost::hash_combine(result, val.data()[0].re[0]._mpfr_sign);
1463
1464 len = val.data()[0].im[0]._mpfr_prec / mp_bits_per_limb;
1465 if (val.data()[0].im[0]._mpfr_prec % mp_bits_per_limb)
1466 ++len;
1467 for (std::size_t i = 0; i < len; ++i)
1468 boost::hash_combine(result, val.data()[0].im[0]._mpfr_d[i]);
1469 boost::hash_combine(result, val.data()[0].im[0]._mpfr_exp);
1470 boost::hash_combine(result, val.data()[0].im[0]._mpfr_sign);
1471 return result;
1472 }
1473
1474 } // namespace backends
1475
1476 #ifdef BOOST_NO_SFINAE_EXPR
1477
1478 namespace detail {
1479
1480 template <unsigned D1, unsigned D2>
1481 struct is_explicitly_convertible<backends::mpc_complex_backend<D1>, backends::mpc_complex_backend<D2> > : public mpl::true_
1482 {};
1483
1484 } // namespace detail
1485 #endif
1486
1487 namespace detail {
1488 template <>
1489 struct is_variable_precision<backends::mpc_complex_backend<0> > : public true_type
1490 {};
1491 } // namespace detail
1492
1493 template <>
1494 struct number_category<detail::canonical<mpc_t, backends::mpc_complex_backend<0> >::type> : public mpl::int_<number_kind_floating_point>
1495 {};
1496
1497 using boost::multiprecision::backends::mpc_complex_backend;
1498
1499 typedef number<mpc_complex_backend<50> > mpc_complex_50;
1500 typedef number<mpc_complex_backend<100> > mpc_complex_100;
1501 typedef number<mpc_complex_backend<500> > mpc_complex_500;
1502 typedef number<mpc_complex_backend<1000> > mpc_complex_1000;
1503 typedef number<mpc_complex_backend<0> > mpc_complex;
1504
1505 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1506 struct component_type<number<mpc_complex_backend<Digits10>, ExpressionTemplates> >
1507 {
1508 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1509 };
1510
1511 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1512 struct component_type<number<logged_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates> >
1513 {
1514 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1515 };
1516
1517 template <unsigned Digits10, expression_template_option ExpressionTemplates>
1518 struct complex_result_from_scalar<number<mpfr_float_backend<Digits10>, ExpressionTemplates> >
1519 {
1520 typedef number<mpc_complex_backend<Digits10>, ExpressionTemplates> type;
1521 };
1522
1523 }
1524
1525 } // namespace boost::multiprecision
1526
1527 #endif
1528