]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/multiprecision/mpc.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / multiprecision / mpc.hpp
CommitLineData
92f5a8d4
TL
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>
f67539c2 12#include <boost/multiprecision/detail/atomic.hpp>
92f5a8d4
TL
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
26namespace boost {
27namespace multiprecision {
28namespace backends {
29
30template <unsigned digits10>
31struct mpc_complex_backend;
32
33} // namespace backends
34
35template <unsigned digits10>
36struct number_category<backends::mpc_complex_backend<digits10> > : public mpl::int_<number_kind_complex>
37{};
38
39namespace backends {
40
41namespace detail {
42
43inline 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}
50inline 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
61template <unsigned digits10>
62struct 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
74 mpc_complex_imp()
75 {
f67539c2 76 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
77 mpc_set_ui(m_data, 0u, GMP_RNDN);
78 }
79 mpc_complex_imp(unsigned digits2)
80 {
81 mpc_init2(m_data, digits2);
82 mpc_set_ui(m_data, 0u, GMP_RNDN);
83 }
84
85 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
92 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
98 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
109 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
117 mpc_complex_imp& operator=(boost::ulong_long_type i)
118 {
119 if (m_data[0].re[0]._mpfr_d == 0)
f67539c2 120 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
121 mpc_set_uj(data(), i, GMP_RNDD);
122 return *this;
123 }
124 mpc_complex_imp& operator=(boost::long_long_type i)
125 {
126 if (m_data[0].re[0]._mpfr_d == 0)
f67539c2 127 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
128 mpc_set_sj(data(), i, GMP_RNDD);
129 return *this;
130 }
131#else
132 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 }
139 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
148 mpc_complex_imp& operator=(unsigned long i)
149 {
150 if (m_data[0].re[0]._mpfr_d == 0)
f67539c2 151 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
152 mpc_set_ui(m_data, i, GMP_RNDN);
153 return *this;
154 }
155 mpc_complex_imp& operator=(long i)
156 {
157 if (m_data[0].re[0]._mpfr_d == 0)
f67539c2 158 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
159 mpc_set_si(m_data, i, GMP_RNDN);
160 return *this;
161 }
162 mpc_complex_imp& operator=(double d)
163 {
164 if (m_data[0].re[0]._mpfr_d == 0)
f67539c2 165 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
166 mpc_set_d(m_data, d, GMP_RNDN);
167 return *this;
168 }
169 mpc_complex_imp& operator=(long double d)
170 {
171 if (m_data[0].re[0]._mpfr_d == 0)
f67539c2 172 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
173 mpc_set_ld(m_data, d, GMP_RNDN);
174 return *this;
175 }
176 mpc_complex_imp& operator=(mpz_t i)
177 {
178 if (m_data[0].re[0]._mpfr_d == 0)
f67539c2 179 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
180 mpc_set_z(m_data, i, GMP_RNDN);
181 return *this;
182 }
183 mpc_complex_imp& operator=(gmp_int i)
184 {
185 if (m_data[0].re[0]._mpfr_d == 0)
f67539c2 186 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
187 mpc_set_z(m_data, i.data(), GMP_RNDN);
188 return *this;
189 }
190
191 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)
f67539c2 196 mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4
TL
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 }
246 void swap(mpc_complex_imp& o) BOOST_NOEXCEPT
247 {
248 mpc_swap(m_data, o.m_data);
249 }
250 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 }
264 ~mpc_complex_imp() BOOST_NOEXCEPT
265 {
266 if (m_data[0].re[0]._mpfr_d)
267 mpc_clear(m_data);
268 }
269 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 }
274 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 }
279 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 }
284 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 }
289 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>
302 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 }
308 mpc_t& data() BOOST_NOEXCEPT
309 {
310 BOOST_ASSERT(m_data[0].re[0]._mpfr_d);
311 return m_data;
312 }
313 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;
f67539c2 321 static boost::multiprecision::detail::precision_type& get_default_precision() BOOST_NOEXCEPT
92f5a8d4 322 {
f67539c2 323 static boost::multiprecision::detail::precision_type val(BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION);
92f5a8d4
TL
324 return val;
325 }
326};
327
328} // namespace detail
329
330template <unsigned digits10>
331struct mpc_complex_backend : public detail::mpc_complex_imp<digits10>
332{
333 mpc_complex_backend() : detail::mpc_complex_imp<digits10>() {}
334 mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<digits10>(o) {}
335#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
336 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>
340 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>
346 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>
352 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>
358 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 }
363 mpc_complex_backend(const mpc_t val)
364 : detail::mpc_complex_imp<digits10>()
365 {
366 mpc_set(this->m_data, val, GMP_RNDN);
367 }
368 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 }
373 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 }
378 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 }
383 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<digits10>()
384 {
385 mpc_set_z(this->m_data, val, GMP_RNDN);
386 }
387 mpc_complex_backend& operator=(mpz_srcptr val)
388 {
389 mpc_set_z(this->m_data, val, GMP_RNDN);
390 return *this;
391 }
392 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 }
396 mpc_complex_backend& operator=(gmp_int const& val)
397 {
398 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
399 return *this;
400 }
401 mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<digits10>()
402 {
403 mpc_set_f(this->m_data, val, GMP_RNDN);
404 }
405 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>
411 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>
416 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 }
421 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<digits10>()
422 {
423 mpc_set_q(this->m_data, val, GMP_RNDN);
424 }
425 mpc_complex_backend& operator=(mpq_srcptr val)
426 {
427 mpc_set_q(this->m_data, val, GMP_RNDN);
428 return *this;
429 }
430 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 }
434 mpc_complex_backend& operator=(gmp_rational const& val)
435 {
436 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
437 return *this;
438 }
439 mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<digits10>()
440 {
441 mpc_set_fr(this->m_data, val, GMP_RNDN);
442 }
443 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>
449 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>
454 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 }
459 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
465 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>
472 mpc_complex_backend& operator=(const V& v)
473 {
474 *static_cast<detail::mpc_complex_imp<digits10>*>(this) = v;
475 return *this;
476 }
477 mpc_complex_backend& operator=(const mpc_t val)
478 {
479 mpc_set(this->m_data, val, GMP_RNDN);
480 return *this;
481 }
482 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 }
487 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 }
492 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>
499 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
506template <>
507struct mpc_complex_backend<0> : public detail::mpc_complex_imp<0>
508{
509 mpc_complex_backend() : detail::mpc_complex_imp<0>() {}
510 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 }
515 mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<0>(o) {}
516#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
517 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
520 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>
526 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>
532 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 }
537 mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<0>()
538 {
539 mpc_set_z(this->m_data, val, GMP_RNDN);
540 }
541 mpc_complex_backend& operator=(mpz_srcptr val)
542 {
543 mpc_set_z(this->m_data, val, GMP_RNDN);
544 return *this;
545 }
546 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 }
550 mpc_complex_backend& operator=(gmp_int const& val)
551 {
552 mpc_set_z(this->m_data, val.data(), GMP_RNDN);
553 return *this;
554 }
555 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 }
559 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>
571 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>
576 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 }
587 mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<0>()
588 {
589 mpc_set_q(this->m_data, val, GMP_RNDN);
590 }
591 mpc_complex_backend& operator=(mpq_srcptr val)
592 {
593 mpc_set_q(this->m_data, val, GMP_RNDN);
594 return *this;
595 }
596 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 }
600 mpc_complex_backend& operator=(gmp_rational const& val)
601 {
602 mpc_set_q(this->m_data, val.data(), GMP_RNDN);
603 return *this;
604 }
605 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 }
609 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 }
620 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 }
625 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 }
630 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>
637 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>
646 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
652 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
662 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>
669 mpc_complex_backend& operator=(const V& v)
670 {
671 *static_cast<detail::mpc_complex_imp<0>*>(this) = v;
672 return *this;
673 }
674 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>
681 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>
688 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 }
694 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 }
699 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 }
704 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 }
709 static unsigned default_precision() BOOST_NOEXCEPT
710 {
711 return get_default_precision();
712 }
713 static void default_precision(unsigned v) BOOST_NOEXCEPT
714 {
715 get_default_precision() = v;
716 }
717 unsigned precision() const BOOST_NOEXCEPT
718 {
719 return multiprecision::detail::digits2_2_10(mpc_get_prec(this->m_data));
720 }
721 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
728template <unsigned digits10, class T>
729inline 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}
733template <unsigned digits10, class T>
734inline 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}
738template <unsigned digits10, class T>
739inline 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
744template <unsigned D1, unsigned D2>
745inline 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}
749template <unsigned D1, unsigned D2>
750inline 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}
754template <unsigned D1, unsigned D2>
755inline 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}
759template <unsigned D1, unsigned D2>
760inline 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}
764template <unsigned D1, unsigned D2>
765inline 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}
772template <unsigned D1, unsigned D2>
773inline 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}
777template <unsigned D1, unsigned D2>
778inline 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}
782template <unsigned D1, unsigned D2>
783inline 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}
787template <unsigned digits10>
788inline void eval_add(mpc_complex_backend<digits10>& result, unsigned long i)
789{
790 mpc_add_ui(result.data(), result.data(), i, GMP_RNDN);
791}
792template <unsigned digits10>
793inline void eval_subtract(mpc_complex_backend<digits10>& result, unsigned long i)
794{
795 mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN);
796}
797template <unsigned digits10>
798inline void eval_multiply(mpc_complex_backend<digits10>& result, unsigned long i)
799{
800 mpc_mul_ui(result.data(), result.data(), i, GMP_RNDN);
801}
802template <unsigned digits10>
803inline void eval_divide(mpc_complex_backend<digits10>& result, unsigned long i)
804{
805 mpc_div_ui(result.data(), result.data(), i, GMP_RNDN);
806}
807template <unsigned digits10>
808inline 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}
815template <unsigned digits10>
816inline 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}
823template <unsigned digits10>
824inline 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}
830template <unsigned digits10>
831inline 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//
840template <unsigned D1, unsigned D2, unsigned D3>
841inline 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}
845template <unsigned D1, unsigned D2, unsigned D3>
846inline 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}
850template <unsigned D1, unsigned D2, unsigned D3>
851inline 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}
855template <unsigned D1, unsigned D2>
856inline 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}
860template <unsigned D1, unsigned D2>
861inline 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}
868template <unsigned D1, unsigned D2>
869inline 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}
873template <unsigned D1, unsigned D2>
874inline 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}
884template <unsigned D1, unsigned D2, unsigned D3>
885inline 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}
889template <unsigned D1, unsigned D2, unsigned D3>
890inline 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}
894template <unsigned D1, unsigned D2, unsigned D3>
895inline 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}
899template <unsigned D1, unsigned D2>
900inline 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}
904template <unsigned D1, unsigned D2>
905inline 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}
912template <unsigned D1, unsigned D2>
913inline 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}
917template <unsigned D1, unsigned D2>
918inline 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
929template <unsigned D1, unsigned D2, unsigned D3>
930inline 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}
937template <unsigned D1, unsigned D2, unsigned D3>
938inline 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}
942template <unsigned D1, unsigned D2, unsigned D3>
943inline 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}
947template <unsigned D1, unsigned D2>
948inline 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}
952template <unsigned D1, unsigned D2>
953inline 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}
963template <unsigned D1, unsigned D2>
964inline 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}
968template <unsigned D1, unsigned D2>
969inline 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
980template <unsigned D1, unsigned D2, unsigned D3>
981inline 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}
985template <unsigned D1, unsigned D2, unsigned D3>
986inline 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}
990template <unsigned D1, unsigned D2, unsigned D3>
991inline 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}
995template <unsigned D1, unsigned D2>
996inline 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}
1000template <unsigned D1, unsigned D2>
1001inline 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}
1011template <unsigned D1, unsigned D2>
1012inline 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}
1016template <unsigned D1, unsigned D2>
1017inline 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
1028template <unsigned digits10>
1029inline 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}
1033template <unsigned digits10>
1034inline 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
1040template <unsigned digits10>
1041inline 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}
1051template <unsigned digits10>
1052inline 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
1063template <unsigned digits10>
1064inline 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}
1074template <unsigned digits10>
1075inline 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
1086template <unsigned digits10>
1087inline 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}
1097template <unsigned digits10>
1098inline 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
1109template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1110inline 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
1136template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1137inline 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
1142template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1143inline 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)
1149template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1150inline 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
1155template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1156inline 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
1162template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1163inline 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
1179template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
1180inline 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//
1199template <unsigned Digits10>
1200inline 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
1205template <unsigned Digits10>
1206inline 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
1211template <unsigned Digits10>
1212inline 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
1217template <unsigned Digits10>
1218inline 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
1223template <unsigned Digits10>
1224inline 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
1229template <unsigned Digits10>
1230inline 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
1235template <unsigned Digits10>
1236inline 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
1241template <unsigned Digits10>
1242inline 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
1247template <unsigned Digits10>
1248inline 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
1253template <unsigned Digits10>
1254inline 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
1259template <unsigned Digits10>
1260inline 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
1265template <unsigned Digits10>
1266inline 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
1271template <unsigned Digits10>
1272inline 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
1277template <unsigned Digits10>
1278inline 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
1283template <unsigned Digits10>
1284inline 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
1289template <unsigned Digits10>
1290inline 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
1295template <unsigned Digits10>
1296inline 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
1301template <unsigned Digits10>
1302inline 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
1307template <unsigned Digits10>
1308inline 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
1313template <unsigned Digits10>
1314inline 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}
1319template <unsigned Digits10>
1320inline 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
1326template <unsigned Digits10>
1327inline 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
1332template <unsigned Digits10>
1333inline 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}
1337template <unsigned Digits10>
1338inline 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}
1342template <unsigned Digits10>
1343inline 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}
1347template <unsigned Digits10>
1348inline 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}
1352template <unsigned Digits10>
1353inline 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}
1357template <unsigned Digits10>
1358inline 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}
1362template <unsigned Digits10>
1363inline 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}
1367template <unsigned Digits10>
1368inline 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}
1372template <unsigned Digits10>
1373inline 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}
1377template <unsigned Digits10>
1378inline 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)
1383template <unsigned Digits10>
1384inline 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}
1388template <unsigned Digits10>
1389inline 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
1395template <unsigned Digits10>
1396inline 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}
1400template <unsigned Digits10>
1401inline 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}
1405template <unsigned Digits10>
1406inline 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}
1410template <unsigned Digits10>
1411inline 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}
1415template <unsigned Digits10>
1416inline 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}
1420template <unsigned Digits10>
1421inline 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}
1425template <unsigned Digits10>
1426inline 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}
1430template <unsigned Digits10>
1431inline 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}
1435template <unsigned Digits10>
1436inline 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)
1441template <unsigned Digits10>
1442inline 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}
1446template <unsigned Digits10>
1447inline 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
1453template <unsigned Digits10>
1454inline 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
1479namespace detail {
1480
1481template <unsigned D1, unsigned D2>
1482struct is_explicitly_convertible<backends::mpc_complex_backend<D1>, backends::mpc_complex_backend<D2> > : public mpl::true_
1483{};
1484
1485} // namespace detail
1486#endif
1487
1488namespace detail {
1489template <>
1490struct is_variable_precision<backends::mpc_complex_backend<0> > : public true_type
1491{};
1492} // namespace detail
1493
1494template <>
1495struct number_category<detail::canonical<mpc_t, backends::mpc_complex_backend<0> >::type> : public mpl::int_<number_kind_floating_point>
1496{};
1497
1498using boost::multiprecision::backends::mpc_complex_backend;
1499
1500typedef number<mpc_complex_backend<50> > mpc_complex_50;
1501typedef number<mpc_complex_backend<100> > mpc_complex_100;
1502typedef number<mpc_complex_backend<500> > mpc_complex_500;
1503typedef number<mpc_complex_backend<1000> > mpc_complex_1000;
1504typedef number<mpc_complex_backend<0> > mpc_complex;
1505
1506template <unsigned Digits10, expression_template_option ExpressionTemplates>
1507struct component_type<number<mpc_complex_backend<Digits10>, ExpressionTemplates> >
1508{
1509 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1510};
1511
1512template <unsigned Digits10, expression_template_option ExpressionTemplates>
1513struct component_type<number<logged_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates> >
1514{
1515 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
1516};
1517
1518template <unsigned Digits10, expression_template_option ExpressionTemplates>
1519struct 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