]>
Commit | Line | Data |
---|---|---|
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 | ||
1e59de90 TL |
9 | #include <cstdint> |
10 | #include <boost/multiprecision/detail/standalone_config.hpp> | |
11 | #include <boost/multiprecision/detail/fpclassify.hpp> | |
92f5a8d4 | 12 | #include <boost/multiprecision/number.hpp> |
92f5a8d4 | 13 | #include <boost/multiprecision/detail/digits.hpp> |
f67539c2 | 14 | #include <boost/multiprecision/detail/atomic.hpp> |
92f5a8d4 TL |
15 | #include <boost/multiprecision/traits/is_variable_precision.hpp> |
16 | #include <boost/multiprecision/mpfr.hpp> | |
1e59de90 TL |
17 | #include <boost/multiprecision/detail/hash.hpp> |
18 | #include <boost/multiprecision/detail/no_exceptions_support.hpp> | |
19 | #include <boost/multiprecision/detail/assert.hpp> | |
92f5a8d4 TL |
20 | #include <mpc.h> |
21 | #include <cmath> | |
22 | #include <algorithm> | |
23 | #include <complex> | |
24 | ||
25 | #ifndef BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION | |
26 | #define BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION 20 | |
27 | #endif | |
28 | ||
29 | namespace boost { | |
30 | namespace multiprecision { | |
31 | namespace backends { | |
32 | ||
33 | template <unsigned digits10> | |
34 | struct mpc_complex_backend; | |
35 | ||
1e59de90 TL |
36 | template <class Backend> |
37 | struct logged_adaptor; | |
38 | template <class Backend> | |
39 | struct debug_adaptor; | |
40 | ||
92f5a8d4 TL |
41 | } // namespace backends |
42 | ||
43 | template <unsigned digits10> | |
1e59de90 | 44 | struct number_category<backends::mpc_complex_backend<digits10> > : public std::integral_constant<int, number_kind_complex> |
92f5a8d4 TL |
45 | {}; |
46 | ||
47 | namespace backends { | |
48 | ||
49 | namespace detail { | |
50 | ||
51 | inline void mpc_copy_precision(mpc_t dest, const mpc_t src) | |
52 | { | |
53 | mpfr_prec_t p_dest = mpc_get_prec(dest); | |
54 | mpfr_prec_t p_src = mpc_get_prec(src); | |
55 | if (p_dest != p_src) | |
56 | mpc_set_prec(dest, p_src); | |
57 | } | |
58 | inline void mpc_copy_precision(mpc_t dest, const mpc_t src1, const mpc_t src2) | |
59 | { | |
60 | mpfr_prec_t p_dest = mpc_get_prec(dest); | |
61 | mpfr_prec_t p_src1 = mpc_get_prec(src1); | |
62 | mpfr_prec_t p_src2 = mpc_get_prec(src2); | |
63 | if (p_src2 > p_src1) | |
64 | p_src1 = p_src2; | |
65 | if (p_dest != p_src1) | |
66 | mpc_set_prec(dest, p_src1); | |
67 | } | |
68 | ||
69 | template <unsigned digits10> | |
70 | struct mpc_complex_imp | |
71 | { | |
72 | #ifdef BOOST_HAS_LONG_LONG | |
1e59de90 TL |
73 | using signed_types = std::tuple<long, long long> ; |
74 | using unsigned_types = std::tuple<unsigned long, unsigned long long>; | |
92f5a8d4 | 75 | #else |
1e59de90 TL |
76 | using signed_types = std::tuple<long> ; |
77 | using unsigned_types = std::tuple<unsigned long>; | |
92f5a8d4 | 78 | #endif |
1e59de90 TL |
79 | using float_types = std::tuple<double, long double>; |
80 | using exponent_type = long ; | |
92f5a8d4 TL |
81 | |
82 | mpc_complex_imp() | |
83 | { | |
f67539c2 | 84 | mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision())); |
92f5a8d4 TL |
85 | mpc_set_ui(m_data, 0u, GMP_RNDN); |
86 | } | |
87 | mpc_complex_imp(unsigned digits2) | |
88 | { | |
89 | mpc_init2(m_data, digits2); | |
90 | mpc_set_ui(m_data, 0u, GMP_RNDN); | |
91 | } | |
92 | ||
93 | mpc_complex_imp(const mpc_complex_imp& o) | |
94 | { | |
1e59de90 | 95 | mpc_init2(m_data, preserve_source_precision() ? mpc_get_prec(o.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision())); |
92f5a8d4 TL |
96 | if (o.m_data[0].re[0]._mpfr_d) |
97 | mpc_set(m_data, o.m_data, GMP_RNDN); | |
98 | } | |
1e59de90 TL |
99 | // rvalue copy |
100 | mpc_complex_imp(mpc_complex_imp&& o) noexcept | |
92f5a8d4 | 101 | { |
1e59de90 TL |
102 | mpfr_prec_t binary_default_precision = boost::multiprecision::detail::digits10_2_2(get_default_precision()); |
103 | if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpc_get_prec(o.data()) == binary_default_precision)) | |
104 | { | |
105 | m_data[0] = o.m_data[0]; | |
106 | o.m_data[0].re[0]._mpfr_d = 0; | |
107 | } | |
108 | else | |
109 | { | |
110 | // NOTE: C allocation interface must not throw: | |
111 | mpc_init2(m_data, binary_default_precision); | |
112 | if (o.m_data[0].re[0]._mpfr_d) | |
113 | mpc_set(m_data, o.m_data, GMP_RNDN); | |
114 | } | |
92f5a8d4 | 115 | } |
92f5a8d4 TL |
116 | mpc_complex_imp& operator=(const mpc_complex_imp& o) |
117 | { | |
118 | if ((o.m_data[0].re[0]._mpfr_d) && (this != &o)) | |
119 | { | |
120 | if (m_data[0].re[0]._mpfr_d == 0) | |
1e59de90 TL |
121 | mpc_init2(m_data, preserve_source_precision() ? mpc_get_prec(o.m_data) : boost::multiprecision::detail::digits10_2_2(get_default_precision())); |
122 | else if (preserve_source_precision() && (mpc_get_prec(o.data()) != mpc_get_prec(data()))) | |
123 | { | |
124 | mpc_set_prec(m_data, mpc_get_prec(o.m_data)); | |
125 | } | |
126 | mpc_set(m_data, o.m_data, GMP_RNDN); | |
92f5a8d4 TL |
127 | } |
128 | return *this; | |
129 | } | |
1e59de90 TL |
130 | // rvalue assign |
131 | mpc_complex_imp& operator=(mpc_complex_imp&& o) noexcept | |
92f5a8d4 | 132 | { |
1e59de90 TL |
133 | if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpc_get_prec(o.data()) == mpc_get_prec(data()))) |
134 | mpc_swap(m_data, o.m_data); | |
135 | else | |
136 | *this = static_cast<const mpc_complex_imp&>(o); | |
92f5a8d4 TL |
137 | return *this; |
138 | } | |
92f5a8d4 TL |
139 | #ifdef BOOST_HAS_LONG_LONG |
140 | #ifdef _MPFR_H_HAVE_INTMAX_T | |
1e59de90 | 141 | mpc_complex_imp& operator=(unsigned long long i) |
92f5a8d4 TL |
142 | { |
143 | if (m_data[0].re[0]._mpfr_d == 0) | |
f67539c2 | 144 | mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision())); |
1e59de90 | 145 | mpc_set_uj(data(), i, GMP_RNDN); |
92f5a8d4 TL |
146 | return *this; |
147 | } | |
1e59de90 | 148 | mpc_complex_imp& operator=(long long i) |
92f5a8d4 TL |
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())); |
1e59de90 | 152 | mpc_set_sj(data(), i, GMP_RNDN); |
92f5a8d4 TL |
153 | return *this; |
154 | } | |
155 | #else | |
1e59de90 | 156 | mpc_complex_imp& operator=(unsigned long long i) |
92f5a8d4 TL |
157 | { |
158 | mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data)); | |
159 | f = i; | |
160 | mpc_set_fr(this->data(), f.data(), GMP_RNDN); | |
161 | return *this; | |
162 | } | |
1e59de90 | 163 | mpc_complex_imp& operator=(long long i) |
92f5a8d4 TL |
164 | { |
165 | mpfr_float_backend<digits10> f(0uL, mpc_get_prec(m_data)); | |
166 | f = i; | |
167 | mpc_set_fr(this->data(), f.data(), GMP_RNDN); | |
168 | return *this; | |
169 | } | |
170 | #endif | |
171 | #endif | |
172 | mpc_complex_imp& operator=(unsigned long i) | |
173 | { | |
174 | if (m_data[0].re[0]._mpfr_d == 0) | |
f67539c2 | 175 | mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision())); |
92f5a8d4 TL |
176 | mpc_set_ui(m_data, i, GMP_RNDN); |
177 | return *this; | |
178 | } | |
179 | mpc_complex_imp& operator=(long i) | |
180 | { | |
181 | if (m_data[0].re[0]._mpfr_d == 0) | |
f67539c2 | 182 | mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision())); |
92f5a8d4 TL |
183 | mpc_set_si(m_data, i, GMP_RNDN); |
184 | return *this; | |
185 | } | |
186 | mpc_complex_imp& operator=(double d) | |
187 | { | |
188 | if (m_data[0].re[0]._mpfr_d == 0) | |
f67539c2 | 189 | mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision())); |
92f5a8d4 TL |
190 | mpc_set_d(m_data, d, GMP_RNDN); |
191 | return *this; | |
192 | } | |
193 | mpc_complex_imp& operator=(long double d) | |
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 | mpc_set_ld(m_data, d, GMP_RNDN); |
198 | return *this; | |
199 | } | |
200 | mpc_complex_imp& operator=(mpz_t i) | |
201 | { | |
202 | if (m_data[0].re[0]._mpfr_d == 0) | |
f67539c2 | 203 | mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision())); |
92f5a8d4 TL |
204 | mpc_set_z(m_data, i, GMP_RNDN); |
205 | return *this; | |
206 | } | |
207 | mpc_complex_imp& operator=(gmp_int i) | |
208 | { | |
209 | if (m_data[0].re[0]._mpfr_d == 0) | |
f67539c2 | 210 | mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision())); |
92f5a8d4 TL |
211 | mpc_set_z(m_data, i.data(), GMP_RNDN); |
212 | return *this; | |
213 | } | |
1e59de90 TL |
214 | #ifdef BOOST_HAS_INT128 |
215 | mpc_complex_imp& operator=(int128_type val) | |
216 | { | |
217 | gmp_int i; | |
218 | i = val; | |
219 | return *this = i.data(); | |
220 | } | |
221 | mpc_complex_imp& operator=(uint128_type val) | |
222 | { | |
223 | gmp_int i; | |
224 | i = val; | |
225 | return *this = i.data(); | |
226 | } | |
227 | #endif | |
228 | #ifdef BOOST_HAS_FLOAT128 | |
229 | mpc_complex_imp& operator=(float128_type val) | |
230 | { | |
231 | mpfr_float_backend<digits10> f; | |
232 | f = val; | |
233 | mpc_set_fr(this->m_data, f.data(), GMP_RNDN); | |
234 | return *this; | |
235 | } | |
236 | #endif | |
92f5a8d4 TL |
237 | |
238 | mpc_complex_imp& operator=(const char* s) | |
239 | { | |
240 | using default_ops::eval_fpclassify; | |
241 | ||
242 | if (m_data[0].re[0]._mpfr_d == 0) | |
f67539c2 | 243 | mpc_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision())); |
92f5a8d4 TL |
244 | |
245 | mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data)); | |
246 | ||
247 | if (s && (*s == '(')) | |
248 | { | |
249 | std::string part; | |
250 | const char* p = ++s; | |
251 | while (*p && (*p != ',') && (*p != ')')) | |
252 | ++p; | |
253 | part.assign(s, p); | |
254 | if (part.size()) | |
255 | a = part.c_str(); | |
256 | else | |
257 | a = 0uL; | |
258 | s = p; | |
259 | if (*p && (*p != ')')) | |
260 | { | |
261 | ++p; | |
262 | while (*p && (*p != ')')) | |
263 | ++p; | |
264 | part.assign(s + 1, p); | |
265 | } | |
266 | else | |
267 | part.erase(); | |
268 | if (part.size()) | |
269 | b = part.c_str(); | |
270 | else | |
271 | b = 0uL; | |
272 | } | |
273 | else | |
274 | { | |
275 | a = s; | |
276 | b = 0uL; | |
277 | } | |
278 | ||
1e59de90 | 279 | if (eval_fpclassify(a) == static_cast<int>(FP_NAN)) |
92f5a8d4 TL |
280 | { |
281 | mpc_set_fr(this->data(), a.data(), GMP_RNDN); | |
282 | } | |
1e59de90 | 283 | else if (eval_fpclassify(b) == static_cast<int>(FP_NAN)) |
92f5a8d4 TL |
284 | { |
285 | mpc_set_fr(this->data(), b.data(), GMP_RNDN); | |
286 | } | |
287 | else | |
288 | { | |
289 | mpc_set_fr_fr(m_data, a.data(), b.data(), GMP_RNDN); | |
290 | } | |
291 | return *this; | |
292 | } | |
1e59de90 | 293 | void swap(mpc_complex_imp& o) noexcept |
92f5a8d4 TL |
294 | { |
295 | mpc_swap(m_data, o.m_data); | |
296 | } | |
297 | std::string str(std::streamsize digits, std::ios_base::fmtflags f) const | |
298 | { | |
1e59de90 | 299 | BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d); |
92f5a8d4 TL |
300 | |
301 | mpfr_float_backend<digits10> a(0uL, mpc_get_prec(m_data)), b(0uL, mpc_get_prec(m_data)); | |
302 | ||
1e59de90 TL |
303 | mpc_real(a.data(), m_data, GMP_RNDN); |
304 | mpc_imag(b.data(), m_data, GMP_RNDN); | |
92f5a8d4 TL |
305 | |
306 | if (eval_is_zero(b)) | |
307 | return a.str(digits, f); | |
308 | ||
309 | return "(" + a.str(digits, f) + "," + b.str(digits, f) + ")"; | |
310 | } | |
1e59de90 | 311 | ~mpc_complex_imp() noexcept |
92f5a8d4 TL |
312 | { |
313 | if (m_data[0].re[0]._mpfr_d) | |
314 | mpc_clear(m_data); | |
315 | } | |
1e59de90 | 316 | void negate() noexcept |
92f5a8d4 | 317 | { |
1e59de90 TL |
318 | BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d); |
319 | mpc_neg(m_data, m_data, GMP_RNDN); | |
92f5a8d4 | 320 | } |
1e59de90 | 321 | int compare(const mpc_complex_imp& o) const noexcept |
92f5a8d4 | 322 | { |
1e59de90 | 323 | BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d); |
92f5a8d4 TL |
324 | return mpc_cmp(m_data, o.m_data); |
325 | } | |
1e59de90 | 326 | int compare(const mpc_complex_backend<digits10>& o) const noexcept |
92f5a8d4 | 327 | { |
1e59de90 | 328 | BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d && o.m_data[0].re[0]._mpfr_d); |
92f5a8d4 TL |
329 | return mpc_cmp(m_data, o.data()); |
330 | } | |
1e59de90 | 331 | int compare(long int i) const noexcept |
92f5a8d4 | 332 | { |
1e59de90 | 333 | BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d); |
92f5a8d4 TL |
334 | return mpc_cmp_si(m_data, i); |
335 | } | |
1e59de90 | 336 | int compare(unsigned long int i) const noexcept |
92f5a8d4 | 337 | { |
1e59de90 TL |
338 | BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d); |
339 | constexpr const unsigned long int max_val = (std::numeric_limits<long>::max)(); | |
92f5a8d4 TL |
340 | if (i > max_val) |
341 | { | |
342 | mpc_complex_imp d(mpc_get_prec(m_data)); | |
343 | d = i; | |
344 | return compare(d); | |
345 | } | |
1e59de90 | 346 | return mpc_cmp_si(m_data, static_cast<long>(i)); |
92f5a8d4 TL |
347 | } |
348 | template <class V> | |
1e59de90 | 349 | int compare(const V& v) const noexcept |
92f5a8d4 TL |
350 | { |
351 | mpc_complex_imp d(mpc_get_prec(m_data)); | |
352 | d = v; | |
353 | return compare(d); | |
354 | } | |
1e59de90 | 355 | mpc_t& data() noexcept |
92f5a8d4 | 356 | { |
1e59de90 | 357 | BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d); |
92f5a8d4 TL |
358 | return m_data; |
359 | } | |
1e59de90 | 360 | const mpc_t& data() const noexcept |
92f5a8d4 | 361 | { |
1e59de90 | 362 | BOOST_MP_ASSERT(m_data[0].re[0]._mpfr_d); |
92f5a8d4 TL |
363 | return m_data; |
364 | } | |
365 | ||
366 | protected: | |
367 | mpc_t m_data; | |
1e59de90 | 368 | static boost::multiprecision::detail::precision_type& get_global_default_precision() noexcept |
92f5a8d4 | 369 | { |
f67539c2 | 370 | static boost::multiprecision::detail::precision_type val(BOOST_MULTIPRECISION_MPFI_DEFAULT_PRECISION); |
92f5a8d4 TL |
371 | return val; |
372 | } | |
1e59de90 TL |
373 | static unsigned& get_default_precision() noexcept |
374 | { | |
375 | static BOOST_MP_THREAD_LOCAL unsigned val(get_global_default_precision()); | |
376 | return val; | |
377 | } | |
378 | #ifndef BOOST_MT_NO_ATOMIC_INT | |
379 | static std::atomic<variable_precision_options>& get_global_default_options() noexcept | |
380 | #else | |
381 | static variable_precision_options& get_global_default_options() noexcept | |
382 | #endif | |
383 | { | |
384 | #ifndef BOOST_MT_NO_ATOMIC_INT | |
385 | static std::atomic<variable_precision_options> val{variable_precision_options::preserve_related_precision}; | |
386 | #else | |
387 | static variable_precision_options val{variable_precision_options::preserve_related_precision}; | |
388 | #endif | |
389 | return val; | |
390 | } | |
391 | static variable_precision_options& get_default_options() noexcept | |
392 | { | |
393 | static BOOST_MP_THREAD_LOCAL variable_precision_options val(get_global_default_options()); | |
394 | return val; | |
395 | } | |
396 | static bool preserve_source_precision() noexcept | |
397 | { | |
398 | return get_default_options() >= variable_precision_options::preserve_source_precision; | |
399 | } | |
400 | static bool preserve_component_precision() noexcept | |
401 | { | |
402 | return get_default_options() >= variable_precision_options::preserve_component_precision; | |
403 | } | |
404 | static bool preserve_related_precision() noexcept | |
405 | { | |
406 | return get_default_options() >= variable_precision_options::preserve_related_precision; | |
407 | } | |
408 | static bool preserve_all_precision() noexcept | |
409 | { | |
410 | return get_default_options() >= variable_precision_options::preserve_all_precision; | |
411 | } | |
92f5a8d4 TL |
412 | }; |
413 | ||
414 | } // namespace detail | |
415 | ||
416 | template <unsigned digits10> | |
417 | struct mpc_complex_backend : public detail::mpc_complex_imp<digits10> | |
418 | { | |
419 | mpc_complex_backend() : detail::mpc_complex_imp<digits10>() {} | |
420 | mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<digits10>(o) {} | |
1e59de90 | 421 | // rvalue copy |
92f5a8d4 TL |
422 | mpc_complex_backend(mpc_complex_backend&& o) : detail::mpc_complex_imp<digits10>(static_cast<detail::mpc_complex_imp<digits10>&&>(o)) |
423 | {} | |
92f5a8d4 | 424 | template <unsigned D> |
1e59de90 | 425 | mpc_complex_backend(const mpc_complex_backend<D>& val, typename std::enable_if<D <= digits10>::type* = 0) |
92f5a8d4 TL |
426 | : detail::mpc_complex_imp<digits10>() |
427 | { | |
428 | mpc_set(this->m_data, val.data(), GMP_RNDN); | |
429 | } | |
430 | template <unsigned D> | |
1e59de90 | 431 | explicit mpc_complex_backend(const mpc_complex_backend<D>& val, typename std::enable_if<!(D <= digits10)>::type* = 0) |
92f5a8d4 TL |
432 | : detail::mpc_complex_imp<digits10>() |
433 | { | |
434 | mpc_set(this->m_data, val.data(), GMP_RNDN); | |
435 | } | |
436 | mpc_complex_backend(const mpc_t val) | |
437 | : detail::mpc_complex_imp<digits10>() | |
438 | { | |
439 | mpc_set(this->m_data, val, GMP_RNDN); | |
440 | } | |
441 | mpc_complex_backend(const std::complex<float>& val) | |
442 | : detail::mpc_complex_imp<digits10>() | |
443 | { | |
444 | mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
445 | } | |
446 | mpc_complex_backend(const std::complex<double>& val) | |
447 | : detail::mpc_complex_imp<digits10>() | |
448 | { | |
449 | mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
450 | } | |
451 | mpc_complex_backend(const std::complex<long double>& val) | |
452 | : detail::mpc_complex_imp<digits10>() | |
453 | { | |
454 | mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
455 | } | |
456 | mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<digits10>() | |
457 | { | |
458 | mpc_set_z(this->m_data, val, GMP_RNDN); | |
459 | } | |
460 | mpc_complex_backend& operator=(mpz_srcptr val) | |
461 | { | |
462 | mpc_set_z(this->m_data, val, GMP_RNDN); | |
463 | return *this; | |
464 | } | |
465 | mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<digits10>() | |
466 | { | |
467 | mpc_set_z(this->m_data, val.data(), GMP_RNDN); | |
468 | } | |
469 | mpc_complex_backend& operator=(gmp_int const& val) | |
470 | { | |
471 | mpc_set_z(this->m_data, val.data(), GMP_RNDN); | |
472 | return *this; | |
473 | } | |
474 | mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<digits10>() | |
475 | { | |
476 | mpc_set_f(this->m_data, val, GMP_RNDN); | |
477 | } | |
478 | mpc_complex_backend& operator=(mpf_srcptr val) | |
479 | { | |
480 | mpc_set_f(this->m_data, val, GMP_RNDN); | |
481 | return *this; | |
482 | } | |
483 | template <unsigned D10> | |
484 | mpc_complex_backend(gmp_float<D10> const& val) : detail::mpc_complex_imp<digits10>() | |
485 | { | |
486 | mpc_set_f(this->m_data, val.data(), GMP_RNDN); | |
487 | } | |
488 | template <unsigned D10> | |
489 | mpc_complex_backend& operator=(gmp_float<D10> const& val) | |
490 | { | |
491 | mpc_set_f(this->m_data, val.data(), GMP_RNDN); | |
492 | return *this; | |
493 | } | |
494 | mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<digits10>() | |
495 | { | |
496 | mpc_set_q(this->m_data, val, GMP_RNDN); | |
497 | } | |
498 | mpc_complex_backend& operator=(mpq_srcptr val) | |
499 | { | |
500 | mpc_set_q(this->m_data, val, GMP_RNDN); | |
501 | return *this; | |
502 | } | |
503 | mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<digits10>() | |
504 | { | |
505 | mpc_set_q(this->m_data, val.data(), GMP_RNDN); | |
506 | } | |
507 | mpc_complex_backend& operator=(gmp_rational const& val) | |
508 | { | |
509 | mpc_set_q(this->m_data, val.data(), GMP_RNDN); | |
510 | return *this; | |
511 | } | |
512 | mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<digits10>() | |
513 | { | |
514 | mpc_set_fr(this->m_data, val, GMP_RNDN); | |
515 | } | |
516 | mpc_complex_backend& operator=(mpfr_srcptr val) | |
517 | { | |
518 | mpc_set_fr(this->m_data, val, GMP_RNDN); | |
519 | return *this; | |
520 | } | |
521 | template <unsigned D10, mpfr_allocation_type AllocationType> | |
1e59de90 TL |
522 | mpc_complex_backend(mpfr_float_backend<D10, AllocationType> const& val, typename std::enable_if<D10 <= digits10>::type* = 0) : detail::mpc_complex_imp<digits10>() |
523 | { | |
524 | mpc_set_fr(this->m_data, val.data(), GMP_RNDN); | |
525 | } | |
526 | template <unsigned D10, mpfr_allocation_type AllocationType> | |
527 | explicit mpc_complex_backend(mpfr_float_backend<D10, AllocationType> const& val, typename std::enable_if<!(D10 <= digits10)>::type* = 0) : detail::mpc_complex_imp<digits10>() | |
92f5a8d4 TL |
528 | { |
529 | mpc_set_fr(this->m_data, val.data(), GMP_RNDN); | |
530 | } | |
531 | template <unsigned D10, mpfr_allocation_type AllocationType> | |
532 | mpc_complex_backend& operator=(mpfr_float_backend<D10, AllocationType> const& val) | |
533 | { | |
534 | mpc_set_fr(this->m_data, val.data(), GMP_RNDN); | |
535 | return *this; | |
536 | } | |
537 | mpc_complex_backend& operator=(const mpc_complex_backend& o) | |
538 | { | |
539 | *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10> const&>(o); | |
540 | return *this; | |
541 | } | |
1e59de90 TL |
542 | // rvalue assign |
543 | mpc_complex_backend& operator=(mpc_complex_backend&& o) noexcept | |
92f5a8d4 TL |
544 | { |
545 | *static_cast<detail::mpc_complex_imp<digits10>*>(this) = static_cast<detail::mpc_complex_imp<digits10>&&>(o); | |
546 | return *this; | |
547 | } | |
92f5a8d4 | 548 | template <class V> |
1e59de90 | 549 | typename std::enable_if<std::is_assignable<detail::mpc_complex_imp<digits10>, V>::value, mpc_complex_backend&>::type operator=(const V& v) |
92f5a8d4 TL |
550 | { |
551 | *static_cast<detail::mpc_complex_imp<digits10>*>(this) = v; | |
552 | return *this; | |
553 | } | |
554 | mpc_complex_backend& operator=(const mpc_t val) | |
555 | { | |
556 | mpc_set(this->m_data, val, GMP_RNDN); | |
557 | return *this; | |
558 | } | |
559 | mpc_complex_backend& operator=(const std::complex<float>& val) | |
560 | { | |
561 | mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
562 | return *this; | |
563 | } | |
564 | mpc_complex_backend& operator=(const std::complex<double>& val) | |
565 | { | |
566 | mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
567 | return *this; | |
568 | } | |
569 | mpc_complex_backend& operator=(const std::complex<long double>& val) | |
570 | { | |
571 | mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
572 | return *this; | |
573 | } | |
574 | // We don't change our precision here, this is a fixed precision type: | |
575 | template <unsigned D> | |
576 | mpc_complex_backend& operator=(const mpc_complex_backend<D>& val) | |
577 | { | |
578 | mpc_set(this->m_data, val.data(), GMP_RNDN); | |
579 | return *this; | |
580 | } | |
581 | }; | |
582 | ||
583 | template <> | |
584 | struct mpc_complex_backend<0> : public detail::mpc_complex_imp<0> | |
585 | { | |
586 | mpc_complex_backend() : detail::mpc_complex_imp<0>() {} | |
587 | mpc_complex_backend(const mpc_t val) | |
588 | : detail::mpc_complex_imp<0>(mpc_get_prec(val)) | |
589 | { | |
590 | mpc_set(this->m_data, val, GMP_RNDN); | |
591 | } | |
592 | mpc_complex_backend(const mpc_complex_backend& o) : detail::mpc_complex_imp<0>(o) {} | |
1e59de90 TL |
593 | // rvalue copy |
594 | mpc_complex_backend(mpc_complex_backend&& o) noexcept : detail::mpc_complex_imp<0>(static_cast<detail::mpc_complex_imp<0>&&>(o)) | |
92f5a8d4 | 595 | {} |
92f5a8d4 TL |
596 | mpc_complex_backend(const mpc_complex_backend& o, unsigned digits10) |
597 | : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10)) | |
598 | { | |
599 | mpc_set(this->m_data, o.data(), GMP_RNDN); | |
600 | } | |
601 | template <unsigned D> | |
602 | mpc_complex_backend(const mpc_complex_backend<D>& val) | |
1e59de90 | 603 | : detail::mpc_complex_imp<0>(preserve_related_precision() ? mpc_get_prec(val.data()) : multiprecision::detail::digits10_2_2(get_default_precision())) |
92f5a8d4 TL |
604 | { |
605 | mpc_set(this->m_data, val.data(), GMP_RNDN); | |
606 | } | |
607 | template <unsigned D> | |
608 | mpc_complex_backend(const mpfr_float_backend<D>& val) | |
1e59de90 | 609 | : detail::mpc_complex_imp<0>((D == 0 ? this->preserve_component_precision() : this->preserve_related_precision()) ? mpfr_get_prec(val.data()) : multiprecision::detail::digits10_2_2(this->get_default_precision())) |
92f5a8d4 TL |
610 | { |
611 | mpc_set_fr(this->m_data, val.data(), GMP_RNDN); | |
612 | } | |
613 | mpc_complex_backend(mpz_srcptr val) : detail::mpc_complex_imp<0>() | |
614 | { | |
615 | mpc_set_z(this->m_data, val, GMP_RNDN); | |
616 | } | |
617 | mpc_complex_backend& operator=(mpz_srcptr val) | |
618 | { | |
619 | mpc_set_z(this->m_data, val, GMP_RNDN); | |
620 | return *this; | |
621 | } | |
1e59de90 | 622 | mpc_complex_backend(gmp_int const& val) : detail::mpc_complex_imp<0>(preserve_all_precision() ? used_gmp_int_bits(val) : boost::multiprecision::detail::digits10_2_2(thread_default_precision())) |
92f5a8d4 TL |
623 | { |
624 | mpc_set_z(this->m_data, val.data(), GMP_RNDN); | |
625 | } | |
626 | mpc_complex_backend& operator=(gmp_int const& val) | |
627 | { | |
1e59de90 TL |
628 | if (this->m_data[0].im->_mpfr_d == 0) |
629 | { | |
630 | unsigned requested_precision = this->thread_default_precision(); | |
631 | if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision) | |
632 | { | |
633 | unsigned d2 = used_gmp_int_bits(val); | |
634 | unsigned d10 = 1 + multiprecision::detail::digits2_2_10(d2); | |
635 | if (d10 > requested_precision) | |
636 | requested_precision = d10; | |
637 | } | |
638 | mpc_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision)); | |
639 | } | |
640 | else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision) | |
641 | { | |
642 | unsigned requested_precision = this->thread_default_precision(); | |
643 | unsigned d2 = used_gmp_int_bits(val); | |
644 | unsigned d10 = 1 + multiprecision::detail::digits2_2_10(d2); | |
645 | if (d10 > requested_precision) | |
646 | this->precision(d10); | |
647 | } | |
92f5a8d4 TL |
648 | mpc_set_z(this->m_data, val.data(), GMP_RNDN); |
649 | return *this; | |
650 | } | |
651 | mpc_complex_backend(mpf_srcptr val) : detail::mpc_complex_imp<0>((unsigned)mpf_get_prec(val)) | |
652 | { | |
653 | mpc_set_f(this->m_data, val, GMP_RNDN); | |
654 | } | |
655 | mpc_complex_backend& operator=(mpf_srcptr val) | |
656 | { | |
657 | if ((mp_bitcnt_t)mpc_get_prec(data()) != mpf_get_prec(val)) | |
658 | { | |
659 | mpc_complex_backend t(val); | |
660 | t.swap(*this); | |
661 | } | |
662 | else | |
663 | mpc_set_f(this->m_data, val, GMP_RNDN); | |
664 | return *this; | |
665 | } | |
666 | template <unsigned digits10> | |
1e59de90 | 667 | mpc_complex_backend(gmp_float<digits10> const& val) : detail::mpc_complex_imp<0>(preserve_all_precision() ? (unsigned)mpf_get_prec(val.data()) : multiprecision::detail::digits10_2_2(get_default_precision())) |
92f5a8d4 TL |
668 | { |
669 | mpc_set_f(this->m_data, val.data(), GMP_RNDN); | |
670 | } | |
671 | template <unsigned digits10> | |
672 | mpc_complex_backend& operator=(gmp_float<digits10> const& val) | |
673 | { | |
1e59de90 | 674 | if (preserve_all_precision() && (mpc_get_prec(data()) != (mpfr_prec_t)mpf_get_prec(val.data()))) |
92f5a8d4 TL |
675 | { |
676 | mpc_complex_backend t(val); | |
677 | t.swap(*this); | |
678 | } | |
679 | else | |
680 | mpc_set_f(this->m_data, val.data(), GMP_RNDN); | |
681 | return *this; | |
682 | } | |
683 | mpc_complex_backend(mpq_srcptr val) : detail::mpc_complex_imp<0>() | |
684 | { | |
685 | mpc_set_q(this->m_data, val, GMP_RNDN); | |
686 | } | |
687 | mpc_complex_backend& operator=(mpq_srcptr val) | |
688 | { | |
689 | mpc_set_q(this->m_data, val, GMP_RNDN); | |
690 | return *this; | |
691 | } | |
1e59de90 | 692 | mpc_complex_backend(gmp_rational const& val) : detail::mpc_complex_imp<0>(preserve_all_precision() ? used_gmp_rational_bits(val) : boost::multiprecision::detail::digits10_2_2(thread_default_precision())) |
92f5a8d4 TL |
693 | { |
694 | mpc_set_q(this->m_data, val.data(), GMP_RNDN); | |
695 | } | |
696 | mpc_complex_backend& operator=(gmp_rational const& val) | |
697 | { | |
1e59de90 TL |
698 | if (this->m_data[0].im->_mpfr_d == 0) |
699 | { | |
700 | unsigned requested_precision = this->get_default_precision(); | |
701 | if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision) | |
702 | { | |
703 | unsigned d10 = 1 + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)); | |
704 | if (d10 > requested_precision) | |
705 | requested_precision = d10; | |
706 | } | |
707 | mpc_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision)); | |
708 | } | |
709 | else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision) | |
710 | { | |
711 | unsigned requested_precision = this->get_default_precision(); | |
712 | unsigned d10 = 1 + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val)); | |
713 | if (d10 > requested_precision) | |
714 | this->precision(d10); | |
715 | } | |
92f5a8d4 TL |
716 | mpc_set_q(this->m_data, val.data(), GMP_RNDN); |
717 | return *this; | |
718 | } | |
719 | mpc_complex_backend(mpfr_srcptr val) : detail::mpc_complex_imp<0>(mpfr_get_prec(val)) | |
720 | { | |
721 | mpc_set_fr(this->m_data, val, GMP_RNDN); | |
722 | } | |
723 | mpc_complex_backend& operator=(mpfr_srcptr val) | |
724 | { | |
725 | if (mpc_get_prec(data()) != mpfr_get_prec(val)) | |
726 | { | |
727 | mpc_complex_backend t(val); | |
728 | t.swap(*this); | |
729 | } | |
730 | else | |
731 | mpc_set_fr(this->m_data, val, GMP_RNDN); | |
732 | return *this; | |
733 | } | |
734 | mpc_complex_backend(const std::complex<float>& val) | |
735 | : detail::mpc_complex_imp<0>() | |
736 | { | |
737 | mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
738 | } | |
739 | mpc_complex_backend(const std::complex<double>& val) | |
740 | : detail::mpc_complex_imp<0>() | |
741 | { | |
742 | mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
743 | } | |
744 | mpc_complex_backend(const std::complex<long double>& val) | |
745 | : detail::mpc_complex_imp<0>() | |
746 | { | |
747 | mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
748 | } | |
749 | // Construction with precision: | |
750 | template <class T, class U> | |
751 | mpc_complex_backend(const T& a, const U& b, unsigned digits10) | |
752 | : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10)) | |
753 | { | |
754 | // We can't use assign_components here because it copies the precision of | |
755 | // a and b, not digits10.... | |
1e59de90 TL |
756 | boost::multiprecision::detail::scoped_precision_options<mpfr_float> scoped(*this); |
757 | (void)scoped; | |
92f5a8d4 TL |
758 | mpfr_float ca(a), cb(b); |
759 | mpc_set_fr_fr(this->data(), ca.backend().data(), cb.backend().data(), GMP_RNDN); | |
760 | } | |
761 | template <unsigned N> | |
762 | mpc_complex_backend(const mpfr_float_backend<N>& a, const mpfr_float_backend<N>& b, unsigned digits10) | |
763 | : detail::mpc_complex_imp<0>(multiprecision::detail::digits10_2_2(digits10)) | |
764 | { | |
765 | mpc_set_fr_fr(this->data(), a.data(), b.data(), GMP_RNDN); | |
766 | } | |
767 | ||
1e59de90 TL |
768 | mpc_complex_backend& operator=(const mpc_complex_backend& o) = default; |
769 | // rvalue assign | |
770 | mpc_complex_backend& operator=(mpc_complex_backend&& o) noexcept = default; | |
771 | ||
92f5a8d4 TL |
772 | template <class V> |
773 | mpc_complex_backend& operator=(const V& v) | |
774 | { | |
1e59de90 TL |
775 | constexpr unsigned d10 = std::is_floating_point<V>::value ? |
776 | std::numeric_limits<V>::digits10 : | |
777 | std::numeric_limits<V>::digits10 ? 1 + std::numeric_limits<V>::digits10 : | |
778 | 1 + boost::multiprecision::detail::digits2_2_10(std::numeric_limits<V>::digits); | |
779 | ||
780 | if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision) | |
781 | { | |
782 | BOOST_IF_CONSTEXPR(std::is_floating_point<V>::value) | |
783 | { | |
784 | if (std::numeric_limits<V>::digits > mpc_get_prec(this->data())) | |
785 | mpc_set_prec(this->data(), std::numeric_limits<V>::digits); | |
786 | } | |
787 | else | |
788 | { | |
789 | if (precision() < d10) | |
790 | this->precision(d10); | |
791 | } | |
792 | } | |
793 | ||
92f5a8d4 TL |
794 | *static_cast<detail::mpc_complex_imp<0>*>(this) = v; |
795 | return *this; | |
796 | } | |
797 | mpc_complex_backend& operator=(const mpc_t val) | |
798 | { | |
799 | mpc_set_prec(this->m_data, mpc_get_prec(val)); | |
800 | mpc_set(this->m_data, val, GMP_RNDN); | |
801 | return *this; | |
802 | } | |
803 | template <unsigned D> | |
804 | mpc_complex_backend& operator=(const mpc_complex_backend<D>& val) | |
805 | { | |
806 | mpc_set_prec(this->m_data, mpc_get_prec(val.data())); | |
807 | mpc_set(this->m_data, val.data(), GMP_RNDN); | |
808 | return *this; | |
809 | } | |
810 | template <unsigned D> | |
811 | mpc_complex_backend& operator=(const mpfr_float_backend<D>& val) | |
812 | { | |
1e59de90 TL |
813 | if (D == 0 ? this->preserve_component_precision() : this->preserve_related_precision()) |
814 | mpc_set_prec(this->m_data, mpfr_get_prec(val.data())); | |
92f5a8d4 TL |
815 | mpc_set_fr(this->m_data, val.data(), GMP_RNDN); |
816 | return *this; | |
817 | } | |
818 | mpc_complex_backend& operator=(const std::complex<float>& val) | |
819 | { | |
820 | mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
821 | return *this; | |
822 | } | |
823 | mpc_complex_backend& operator=(const std::complex<double>& val) | |
824 | { | |
825 | mpc_set_d_d(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
826 | return *this; | |
827 | } | |
828 | mpc_complex_backend& operator=(const std::complex<long double>& val) | |
829 | { | |
830 | mpc_set_ld_ld(this->m_data, val.real(), val.imag(), GMP_RNDN); | |
831 | return *this; | |
832 | } | |
1e59de90 TL |
833 | static unsigned default_precision() noexcept |
834 | { | |
835 | return get_global_default_precision(); | |
836 | } | |
837 | static void default_precision(unsigned v) noexcept | |
838 | { | |
839 | get_global_default_precision() = v; | |
840 | } | |
841 | static unsigned thread_default_precision() noexcept | |
92f5a8d4 TL |
842 | { |
843 | return get_default_precision(); | |
844 | } | |
1e59de90 | 845 | static void thread_default_precision(unsigned v) noexcept |
92f5a8d4 TL |
846 | { |
847 | get_default_precision() = v; | |
848 | } | |
1e59de90 | 849 | unsigned precision() const noexcept |
92f5a8d4 TL |
850 | { |
851 | return multiprecision::detail::digits2_2_10(mpc_get_prec(this->m_data)); | |
852 | } | |
1e59de90 | 853 | void precision(unsigned digits10) noexcept |
92f5a8d4 TL |
854 | { |
855 | mpfr_prec_round(mpc_realref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN); | |
856 | mpfr_prec_round(mpc_imagref(this->m_data), multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN); | |
857 | } | |
1e59de90 TL |
858 | // |
859 | // Variable precision options: | |
860 | // | |
861 | static variable_precision_options default_variable_precision_options() noexcept | |
862 | { | |
863 | return get_global_default_options(); | |
864 | } | |
865 | static variable_precision_options thread_default_variable_precision_options() noexcept | |
866 | { | |
867 | return get_default_options(); | |
868 | } | |
869 | static void default_variable_precision_options(variable_precision_options opts) | |
870 | { | |
871 | get_global_default_options() = opts; | |
872 | } | |
873 | static void thread_default_variable_precision_options(variable_precision_options opts) | |
874 | { | |
875 | get_default_options() = opts; | |
876 | } | |
92f5a8d4 TL |
877 | }; |
878 | ||
879 | template <unsigned digits10, class T> | |
1e59de90 | 880 | inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_eq(const mpc_complex_backend<digits10>& a, const T& b) noexcept |
92f5a8d4 TL |
881 | { |
882 | return a.compare(b) == 0; | |
883 | } | |
884 | template <unsigned digits10, class T> | |
1e59de90 | 885 | inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_lt(const mpc_complex_backend<digits10>& a, const T& b) noexcept |
92f5a8d4 TL |
886 | { |
887 | return a.compare(b) < 0; | |
888 | } | |
889 | template <unsigned digits10, class T> | |
1e59de90 | 890 | inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_gt(const mpc_complex_backend<digits10>& a, const T& b) noexcept |
92f5a8d4 TL |
891 | { |
892 | return a.compare(b) > 0; | |
893 | } | |
894 | ||
895 | template <unsigned D1, unsigned D2> | |
896 | inline void eval_add(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o) | |
897 | { | |
1e59de90 | 898 | mpc_add(result.data(), result.data(), o.data(), GMP_RNDN); |
92f5a8d4 TL |
899 | } |
900 | template <unsigned D1, unsigned D2> | |
901 | inline void eval_add(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o) | |
902 | { | |
1e59de90 | 903 | mpc_add_fr(result.data(), result.data(), o.data(), GMP_RNDN); |
92f5a8d4 TL |
904 | } |
905 | template <unsigned D1, unsigned D2> | |
906 | inline void eval_subtract(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o) | |
907 | { | |
1e59de90 | 908 | mpc_sub(result.data(), result.data(), o.data(), GMP_RNDN); |
92f5a8d4 TL |
909 | } |
910 | template <unsigned D1, unsigned D2> | |
911 | inline void eval_subtract(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o) | |
912 | { | |
1e59de90 | 913 | mpc_sub_fr(result.data(), result.data(), o.data(), GMP_RNDN); |
92f5a8d4 TL |
914 | } |
915 | template <unsigned D1, unsigned D2> | |
916 | inline void eval_multiply(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o) | |
917 | { | |
918 | if ((void*)&result == (void*)&o) | |
919 | mpc_sqr(result.data(), o.data(), GMP_RNDN); | |
920 | else | |
921 | mpc_mul(result.data(), result.data(), o.data(), GMP_RNDN); | |
922 | } | |
923 | template <unsigned D1, unsigned D2> | |
924 | inline void eval_multiply(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o) | |
925 | { | |
926 | mpc_mul_fr(result.data(), result.data(), o.data(), GMP_RNDN); | |
927 | } | |
928 | template <unsigned D1, unsigned D2> | |
929 | inline void eval_divide(mpc_complex_backend<D1>& result, const mpc_complex_backend<D2>& o) | |
930 | { | |
1e59de90 | 931 | mpc_div(result.data(), result.data(), o.data(), GMP_RNDN); |
92f5a8d4 TL |
932 | } |
933 | template <unsigned D1, unsigned D2> | |
934 | inline void eval_divide(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2>& o) | |
935 | { | |
1e59de90 | 936 | mpc_div_fr(result.data(), result.data(), o.data(), GMP_RNDN); |
92f5a8d4 TL |
937 | } |
938 | template <unsigned digits10> | |
939 | inline void eval_add(mpc_complex_backend<digits10>& result, unsigned long i) | |
940 | { | |
941 | mpc_add_ui(result.data(), result.data(), i, GMP_RNDN); | |
942 | } | |
943 | template <unsigned digits10> | |
944 | inline void eval_subtract(mpc_complex_backend<digits10>& result, unsigned long i) | |
945 | { | |
946 | mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN); | |
947 | } | |
948 | template <unsigned digits10> | |
949 | inline void eval_multiply(mpc_complex_backend<digits10>& result, unsigned long i) | |
950 | { | |
951 | mpc_mul_ui(result.data(), result.data(), i, GMP_RNDN); | |
952 | } | |
953 | template <unsigned digits10> | |
954 | inline void eval_divide(mpc_complex_backend<digits10>& result, unsigned long i) | |
955 | { | |
956 | mpc_div_ui(result.data(), result.data(), i, GMP_RNDN); | |
957 | } | |
958 | template <unsigned digits10> | |
959 | inline void eval_add(mpc_complex_backend<digits10>& result, long i) | |
960 | { | |
961 | if (i > 0) | |
962 | mpc_add_ui(result.data(), result.data(), i, GMP_RNDN); | |
963 | else | |
964 | mpc_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); | |
965 | } | |
966 | template <unsigned digits10> | |
967 | inline void eval_subtract(mpc_complex_backend<digits10>& result, long i) | |
968 | { | |
969 | if (i > 0) | |
970 | mpc_sub_ui(result.data(), result.data(), i, GMP_RNDN); | |
971 | else | |
972 | mpc_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); | |
973 | } | |
974 | template <unsigned digits10> | |
975 | inline void eval_multiply(mpc_complex_backend<digits10>& result, long i) | |
976 | { | |
977 | mpc_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); | |
978 | if (i < 0) | |
979 | mpc_neg(result.data(), result.data(), GMP_RNDN); | |
980 | } | |
981 | template <unsigned digits10> | |
982 | inline void eval_divide(mpc_complex_backend<digits10>& result, long i) | |
983 | { | |
984 | mpc_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN); | |
985 | if (i < 0) | |
986 | mpc_neg(result.data(), result.data(), GMP_RNDN); | |
987 | } | |
988 | // | |
989 | // Specialised 3 arg versions of the basic operators: | |
990 | // | |
991 | template <unsigned D1, unsigned D2, unsigned D3> | |
992 | inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y) | |
993 | { | |
1e59de90 | 994 | mpc_add(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
995 | } |
996 | template <unsigned D1, unsigned D2, unsigned D3> | |
997 | inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y) | |
998 | { | |
1e59de90 | 999 | mpc_add_fr(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
1000 | } |
1001 | template <unsigned D1, unsigned D2, unsigned D3> | |
1002 | inline void eval_add(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y) | |
1003 | { | |
1e59de90 | 1004 | mpc_add_fr(a.data(), y.data(), x.data(), GMP_RNDN); |
92f5a8d4 TL |
1005 | } |
1006 | template <unsigned D1, unsigned D2> | |
1007 | inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y) | |
1008 | { | |
1e59de90 | 1009 | mpc_add_ui(a.data(), x.data(), y, GMP_RNDN); |
92f5a8d4 TL |
1010 | } |
1011 | template <unsigned D1, unsigned D2> | |
1012 | inline void eval_add(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y) | |
1013 | { | |
1014 | if (y < 0) | |
1e59de90 | 1015 | mpc_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); |
92f5a8d4 | 1016 | else |
1e59de90 | 1017 | mpc_add_ui(a.data(), x.data(), y, GMP_RNDN); |
92f5a8d4 TL |
1018 | } |
1019 | template <unsigned D1, unsigned D2> | |
1020 | inline void eval_add(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y) | |
1021 | { | |
1e59de90 | 1022 | mpc_add_ui(a.data(), y.data(), x, GMP_RNDN); |
92f5a8d4 TL |
1023 | } |
1024 | template <unsigned D1, unsigned D2> | |
1025 | inline void eval_add(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y) | |
1026 | { | |
1027 | if (x < 0) | |
1028 | { | |
1029 | mpc_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN); | |
1e59de90 | 1030 | mpc_neg(a.data(), a.data(), GMP_RNDN); |
92f5a8d4 TL |
1031 | } |
1032 | else | |
1e59de90 | 1033 | mpc_add_ui(a.data(), y.data(), x, GMP_RNDN); |
92f5a8d4 TL |
1034 | } |
1035 | template <unsigned D1, unsigned D2, unsigned D3> | |
1036 | inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y) | |
1037 | { | |
1e59de90 | 1038 | mpc_sub(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
1039 | } |
1040 | template <unsigned D1, unsigned D2, unsigned D3> | |
1041 | inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y) | |
1042 | { | |
1e59de90 | 1043 | mpc_sub_fr(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
1044 | } |
1045 | template <unsigned D1, unsigned D2, unsigned D3> | |
1046 | inline void eval_subtract(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y) | |
1047 | { | |
1e59de90 | 1048 | mpc_fr_sub(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
1049 | } |
1050 | template <unsigned D1, unsigned D2> | |
1051 | inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y) | |
1052 | { | |
1e59de90 | 1053 | mpc_sub_ui(a.data(), x.data(), y, GMP_RNDN); |
92f5a8d4 TL |
1054 | } |
1055 | template <unsigned D1, unsigned D2> | |
1056 | inline void eval_subtract(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y) | |
1057 | { | |
1058 | if (y < 0) | |
1e59de90 | 1059 | mpc_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); |
92f5a8d4 | 1060 | else |
1e59de90 | 1061 | mpc_sub_ui(a.data(), x.data(), y, GMP_RNDN); |
92f5a8d4 TL |
1062 | } |
1063 | template <unsigned D1, unsigned D2> | |
1064 | inline void eval_subtract(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y) | |
1065 | { | |
1066 | mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN); | |
1067 | } | |
1068 | template <unsigned D1, unsigned D2> | |
1069 | inline void eval_subtract(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y) | |
1070 | { | |
1071 | if (x < 0) | |
1072 | { | |
1e59de90 TL |
1073 | mpc_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN); |
1074 | mpc_neg(a.data(), a.data(), GMP_RNDN); | |
92f5a8d4 TL |
1075 | } |
1076 | else | |
1077 | mpc_ui_sub(a.data(), x, y.data(), GMP_RNDN); | |
1078 | } | |
1079 | ||
1080 | template <unsigned D1, unsigned D2, unsigned D3> | |
1081 | inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y) | |
1082 | { | |
1083 | if ((void*)&x == (void*)&y) | |
1e59de90 | 1084 | mpc_sqr(a.data(), x.data(), GMP_RNDN); |
92f5a8d4 | 1085 | else |
1e59de90 | 1086 | mpc_mul(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
1087 | } |
1088 | template <unsigned D1, unsigned D2, unsigned D3> | |
1089 | inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y) | |
1090 | { | |
1e59de90 | 1091 | mpc_mul_fr(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
1092 | } |
1093 | template <unsigned D1, unsigned D2, unsigned D3> | |
1094 | inline void eval_multiply(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y) | |
1095 | { | |
1e59de90 | 1096 | mpc_mul_fr(a.data(), y.data(), x.data(), GMP_RNDN); |
92f5a8d4 TL |
1097 | } |
1098 | template <unsigned D1, unsigned D2> | |
1099 | inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y) | |
1100 | { | |
1e59de90 | 1101 | mpc_mul_ui(a.data(), x.data(), y, GMP_RNDN); |
92f5a8d4 TL |
1102 | } |
1103 | template <unsigned D1, unsigned D2> | |
1104 | inline void eval_multiply(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y) | |
1105 | { | |
1106 | if (y < 0) | |
1107 | { | |
1e59de90 | 1108 | mpc_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); |
92f5a8d4 TL |
1109 | a.negate(); |
1110 | } | |
1111 | else | |
1e59de90 | 1112 | mpc_mul_ui(a.data(), x.data(), y, GMP_RNDN); |
92f5a8d4 TL |
1113 | } |
1114 | template <unsigned D1, unsigned D2> | |
1115 | inline void eval_multiply(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y) | |
1116 | { | |
1e59de90 | 1117 | mpc_mul_ui(a.data(), y.data(), x, GMP_RNDN); |
92f5a8d4 TL |
1118 | } |
1119 | template <unsigned D1, unsigned D2> | |
1120 | inline void eval_multiply(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y) | |
1121 | { | |
1122 | if (x < 0) | |
1123 | { | |
1e59de90 TL |
1124 | mpc_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN); |
1125 | mpc_neg(a.data(), a.data(), GMP_RNDN); | |
92f5a8d4 TL |
1126 | } |
1127 | else | |
1e59de90 | 1128 | mpc_mul_ui(a.data(), y.data(), x, GMP_RNDN); |
92f5a8d4 TL |
1129 | } |
1130 | ||
1131 | template <unsigned D1, unsigned D2, unsigned D3> | |
1132 | inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpc_complex_backend<D3>& y) | |
1133 | { | |
1e59de90 | 1134 | mpc_div(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
1135 | } |
1136 | template <unsigned D1, unsigned D2, unsigned D3> | |
1137 | inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, const mpfr_float_backend<D3>& y) | |
1138 | { | |
1e59de90 | 1139 | mpc_div_fr(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
1140 | } |
1141 | template <unsigned D1, unsigned D2, unsigned D3> | |
1142 | inline void eval_divide(mpc_complex_backend<D1>& a, const mpfr_float_backend<D2>& x, const mpc_complex_backend<D3>& y) | |
1143 | { | |
1e59de90 | 1144 | mpc_fr_div(a.data(), x.data(), y.data(), GMP_RNDN); |
92f5a8d4 TL |
1145 | } |
1146 | template <unsigned D1, unsigned D2> | |
1147 | inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, unsigned long y) | |
1148 | { | |
1e59de90 | 1149 | mpc_div_ui(a.data(), x.data(), y, GMP_RNDN); |
92f5a8d4 TL |
1150 | } |
1151 | template <unsigned D1, unsigned D2> | |
1152 | inline void eval_divide(mpc_complex_backend<D1>& a, const mpc_complex_backend<D2>& x, long y) | |
1153 | { | |
1154 | if (y < 0) | |
1155 | { | |
1e59de90 | 1156 | mpc_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN); |
92f5a8d4 TL |
1157 | a.negate(); |
1158 | } | |
1159 | else | |
1e59de90 | 1160 | mpc_div_ui(a.data(), x.data(), y, GMP_RNDN); |
92f5a8d4 TL |
1161 | } |
1162 | template <unsigned D1, unsigned D2> | |
1163 | inline void eval_divide(mpc_complex_backend<D1>& a, unsigned long x, const mpc_complex_backend<D2>& y) | |
1164 | { | |
1e59de90 | 1165 | mpc_ui_div(a.data(), x, y.data(), GMP_RNDN); |
92f5a8d4 TL |
1166 | } |
1167 | template <unsigned D1, unsigned D2> | |
1168 | inline void eval_divide(mpc_complex_backend<D1>& a, long x, const mpc_complex_backend<D2>& y) | |
1169 | { | |
1170 | if (x < 0) | |
1171 | { | |
1e59de90 TL |
1172 | mpc_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN); |
1173 | mpc_neg(a.data(), a.data(), GMP_RNDN); | |
92f5a8d4 TL |
1174 | } |
1175 | else | |
1e59de90 | 1176 | mpc_ui_div(a.data(), x, y.data(), GMP_RNDN); |
92f5a8d4 TL |
1177 | } |
1178 | ||
1179 | template <unsigned digits10> | |
1e59de90 | 1180 | inline bool eval_is_zero(const mpc_complex_backend<digits10>& val) noexcept |
92f5a8d4 TL |
1181 | { |
1182 | return (0 != mpfr_zero_p(mpc_realref(val.data()))) && (0 != mpfr_zero_p(mpc_imagref(val.data()))); | |
1183 | } | |
1184 | template <unsigned digits10> | |
1185 | inline int eval_get_sign(const mpc_complex_backend<digits10>&) | |
1186 | { | |
1e59de90 | 1187 | static_assert(digits10 == UINT_MAX, "Complex numbers have no sign bit."); // designed to always fail |
92f5a8d4 TL |
1188 | return 0; |
1189 | } | |
1190 | ||
1191 | template <unsigned digits10> | |
1192 | inline void eval_convert_to(unsigned long* result, const mpc_complex_backend<digits10>& val) | |
1193 | { | |
1194 | if (0 == mpfr_zero_p(mpc_imagref(val.data()))) | |
1195 | { | |
1e59de90 | 1196 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); |
92f5a8d4 TL |
1197 | } |
1198 | mpfr_float_backend<digits10> t; | |
1199 | mpc_real(t.data(), val.data(), GMP_RNDN); | |
1200 | eval_convert_to(result, t); | |
1201 | } | |
1202 | template <unsigned digits10> | |
1203 | inline void eval_convert_to(long* result, const mpc_complex_backend<digits10>& val) | |
1204 | { | |
1205 | if (0 == mpfr_zero_p(mpc_imagref(val.data()))) | |
1206 | { | |
1e59de90 | 1207 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); |
92f5a8d4 TL |
1208 | } |
1209 | mpfr_float_backend<digits10> t; | |
1210 | mpc_real(t.data(), val.data(), GMP_RNDN); | |
1211 | eval_convert_to(result, t); | |
1212 | } | |
1213 | #ifdef _MPFR_H_HAVE_INTMAX_T | |
1214 | template <unsigned digits10> | |
1e59de90 | 1215 | inline void eval_convert_to(unsigned long long* result, const mpc_complex_backend<digits10>& val) |
92f5a8d4 TL |
1216 | { |
1217 | if (0 == mpfr_zero_p(mpc_imagref(val.data()))) | |
1218 | { | |
1e59de90 | 1219 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); |
92f5a8d4 TL |
1220 | } |
1221 | mpfr_float_backend<digits10> t; | |
1222 | mpc_real(t.data(), val.data(), GMP_RNDN); | |
1223 | eval_convert_to(result, t); | |
1224 | } | |
1225 | template <unsigned digits10> | |
1e59de90 | 1226 | inline void eval_convert_to(long long* result, const mpc_complex_backend<digits10>& val) |
92f5a8d4 TL |
1227 | { |
1228 | if (0 == mpfr_zero_p(mpc_imagref(val.data()))) | |
1229 | { | |
1e59de90 | 1230 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); |
92f5a8d4 TL |
1231 | } |
1232 | mpfr_float_backend<digits10> t; | |
1233 | mpc_real(t.data(), val.data(), GMP_RNDN); | |
1234 | eval_convert_to(result, t); | |
1235 | } | |
1236 | #endif | |
1237 | template <unsigned digits10> | |
1e59de90 TL |
1238 | inline void eval_convert_to(double* result, const mpc_complex_backend<digits10>& val) noexcept |
1239 | { | |
1240 | if (0 == mpfr_zero_p(mpc_imagref(val.data()))) | |
1241 | { | |
1242 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); | |
1243 | } | |
1244 | mpfr_float_backend<digits10> t; | |
1245 | mpc_real(t.data(), val.data(), GMP_RNDN); | |
1246 | eval_convert_to(result, t); | |
1247 | } | |
1248 | template <unsigned digits10> | |
1249 | inline void eval_convert_to(long double* result, const mpc_complex_backend<digits10>& val) noexcept | |
1250 | { | |
1251 | if (0 == mpfr_zero_p(mpc_imagref(val.data()))) | |
1252 | { | |
1253 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); | |
1254 | } | |
1255 | mpfr_float_backend<digits10> t; | |
1256 | mpc_real(t.data(), val.data(), GMP_RNDN); | |
1257 | eval_convert_to(result, t); | |
1258 | } | |
1259 | #ifdef BOOST_HAS_INT128 | |
1260 | template <unsigned digits10> | |
1261 | inline void eval_convert_to(uint128_type* result, const mpc_complex_backend<digits10>& val) | |
92f5a8d4 | 1262 | { |
1e59de90 | 1263 | using default_ops::eval_convert_to; |
92f5a8d4 TL |
1264 | if (0 == mpfr_zero_p(mpc_imagref(val.data()))) |
1265 | { | |
1e59de90 | 1266 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); |
92f5a8d4 TL |
1267 | } |
1268 | mpfr_float_backend<digits10> t; | |
1269 | mpc_real(t.data(), val.data(), GMP_RNDN); | |
1270 | eval_convert_to(result, t); | |
1271 | } | |
1272 | template <unsigned digits10> | |
1e59de90 | 1273 | inline void eval_convert_to(int128_type* result, const mpc_complex_backend<digits10>& val) |
92f5a8d4 | 1274 | { |
1e59de90 | 1275 | using default_ops::eval_convert_to; |
92f5a8d4 TL |
1276 | if (0 == mpfr_zero_p(mpc_imagref(val.data()))) |
1277 | { | |
1e59de90 | 1278 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); |
92f5a8d4 TL |
1279 | } |
1280 | mpfr_float_backend<digits10> t; | |
1281 | mpc_real(t.data(), val.data(), GMP_RNDN); | |
1282 | eval_convert_to(result, t); | |
1283 | } | |
1e59de90 TL |
1284 | #endif |
1285 | #ifdef BOOST_HAS_FLOAT128 | |
1286 | template <unsigned digits10> | |
1287 | inline void eval_convert_to(float128_type* result, const mpc_complex_backend<digits10>& val) | |
1288 | { | |
1289 | using default_ops::eval_convert_to; | |
1290 | if (0 == mpfr_zero_p(mpc_imagref(val.data()))) | |
1291 | { | |
1292 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert imaginary number to scalar.")); | |
1293 | } | |
1294 | mpfr_float_backend<digits10> t; | |
1295 | mpc_real(t.data(), val.data(), GMP_RNDN); | |
1296 | eval_convert_to(result, t); | |
1297 | } | |
1298 | #endif | |
1299 | ||
1300 | template <mpfr_allocation_type AllocationType> | |
1301 | inline void assign_components_set_precision(mpc_complex_backend<0>& result, const mpfr_float_backend<0, AllocationType>& a, const mpfr_float_backend<0, AllocationType>& b) | |
1302 | { | |
1303 | if (result.thread_default_variable_precision_options() >= variable_precision_options::preserve_component_precision) | |
1304 | { | |
1305 | unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data())); | |
1306 | mpc_set_prec(result.data(), prec); | |
1307 | } | |
1308 | } | |
1309 | template <unsigned D2, mpfr_allocation_type AllocationType> | |
1310 | inline void assign_components_set_precision(mpc_complex_backend<0>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b) | |
1311 | { | |
1312 | if (result.thread_default_variable_precision_options() >= variable_precision_options::preserve_related_precision) | |
1313 | { | |
1314 | unsigned long prec = (std::max)(mpfr_get_prec(a.data()), mpfr_get_prec(b.data())); | |
1315 | mpc_set_prec(result.data(), prec); | |
1316 | } | |
1317 | } | |
1318 | template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType> | |
1319 | inline void assign_components_set_precision(mpc_complex_backend<D1>&, const mpfr_float_backend<D2, AllocationType>&, const mpfr_float_backend<D2, AllocationType>&) | |
1320 | { | |
1321 | } | |
92f5a8d4 TL |
1322 | |
1323 | template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType> | |
1324 | inline void assign_components(mpc_complex_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b) | |
1325 | { | |
1326 | // | |
1327 | // This is called from class number's constructors, so if we have variable | |
1328 | // precision, then copy the precision of the source variables. | |
1329 | // | |
1e59de90 | 1330 | assign_components_set_precision(result, a, b); |
92f5a8d4 | 1331 | using default_ops::eval_fpclassify; |
1e59de90 | 1332 | if (eval_fpclassify(a) == static_cast<int>(FP_NAN)) |
92f5a8d4 TL |
1333 | { |
1334 | mpc_set_fr(result.data(), a.data(), GMP_RNDN); | |
1335 | } | |
1e59de90 | 1336 | else if (eval_fpclassify(b) == static_cast<int>(FP_NAN)) |
92f5a8d4 TL |
1337 | { |
1338 | mpc_set_fr(result.data(), b.data(), GMP_RNDN); | |
1339 | } | |
1340 | else | |
1341 | { | |
1342 | mpc_set_fr_fr(result.data(), a.data(), b.data(), GMP_RNDN); | |
1343 | } | |
1344 | } | |
1345 | ||
1346 | template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType> | |
1347 | inline void assign_components(mpc_complex_backend<D1>& result, unsigned long a, unsigned long b) | |
1348 | { | |
1349 | mpc_set_ui_ui(result.data(), a, b, GMP_RNDN); | |
1350 | } | |
1351 | ||
1352 | template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType> | |
1353 | inline void assign_components(mpc_complex_backend<D1>& result, long a, long b) | |
1354 | { | |
1355 | mpc_set_si_si(result.data(), a, b, GMP_RNDN); | |
1356 | } | |
1357 | ||
1358 | #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T) | |
1359 | template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType> | |
1360 | inline void assign_components(mpc_complex_backend<D1>& result, unsigned long long a, unsigned long long b) | |
1361 | { | |
1362 | mpc_set_uj_uj(result.data(), a, b, GMP_RNDN); | |
1363 | } | |
1364 | ||
1365 | template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType> | |
1366 | inline void assign_components(mpc_complex_backend<D1>& result, long long a, long long b) | |
1367 | { | |
1368 | mpc_set_sj_sj(result.data(), a, b, GMP_RNDN); | |
1369 | } | |
1370 | #endif | |
1371 | ||
1372 | template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType> | |
1373 | inline void assign_components(mpc_complex_backend<D1>& result, double a, double b) | |
1374 | { | |
1e59de90 | 1375 | if (BOOST_MP_ISNAN(a)) |
92f5a8d4 TL |
1376 | { |
1377 | mpc_set_d(result.data(), a, GMP_RNDN); | |
1378 | } | |
1e59de90 | 1379 | else if (BOOST_MP_ISNAN(b)) |
92f5a8d4 TL |
1380 | { |
1381 | mpc_set_d(result.data(), b, GMP_RNDN); | |
1382 | } | |
1383 | else | |
1384 | { | |
1385 | mpc_set_d_d(result.data(), a, b, GMP_RNDN); | |
1386 | } | |
1387 | } | |
1388 | ||
1389 | template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType> | |
1390 | inline void assign_components(mpc_complex_backend<D1>& result, long double a, long double b) | |
1391 | { | |
1e59de90 | 1392 | if (BOOST_MP_ISNAN(a)) |
92f5a8d4 TL |
1393 | { |
1394 | mpc_set_d(result.data(), a, GMP_RNDN); | |
1395 | } | |
1e59de90 | 1396 | else if (BOOST_MP_ISNAN(b)) |
92f5a8d4 TL |
1397 | { |
1398 | mpc_set_d(result.data(), b, GMP_RNDN); | |
1399 | } | |
1400 | else | |
1401 | { | |
1402 | mpc_set_ld_ld(result.data(), a, b, GMP_RNDN); | |
1403 | } | |
1404 | } | |
1405 | ||
1406 | // | |
1407 | // Native non-member operations: | |
1408 | // | |
1409 | template <unsigned Digits10> | |
1410 | inline void eval_sqrt(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& val) | |
1411 | { | |
1412 | mpc_sqrt(result.data(), val.data(), GMP_RNDN); | |
1413 | } | |
1414 | ||
1415 | template <unsigned Digits10> | |
1416 | inline void eval_pow(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& b, const mpc_complex_backend<Digits10>& e) | |
1417 | { | |
1418 | mpc_pow(result.data(), b.data(), e.data(), GMP_RNDN); | |
1419 | } | |
1420 | ||
1421 | template <unsigned Digits10> | |
1422 | inline void eval_exp(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1423 | { | |
1424 | mpc_exp(result.data(), arg.data(), GMP_RNDN); | |
1425 | } | |
1426 | ||
1427 | template <unsigned Digits10> | |
1428 | inline void eval_log(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1429 | { | |
1430 | mpc_log(result.data(), arg.data(), GMP_RNDN); | |
1431 | } | |
1432 | ||
1433 | template <unsigned Digits10> | |
1434 | inline void eval_log10(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1435 | { | |
1436 | mpc_log10(result.data(), arg.data(), GMP_RNDN); | |
1437 | } | |
1438 | ||
1439 | template <unsigned Digits10> | |
1440 | inline void eval_sin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1441 | { | |
1442 | mpc_sin(result.data(), arg.data(), GMP_RNDN); | |
1443 | } | |
1444 | ||
1445 | template <unsigned Digits10> | |
1446 | inline void eval_cos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1447 | { | |
1448 | mpc_cos(result.data(), arg.data(), GMP_RNDN); | |
1449 | } | |
1450 | ||
1451 | template <unsigned Digits10> | |
1452 | inline void eval_tan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1453 | { | |
1454 | mpc_tan(result.data(), arg.data(), GMP_RNDN); | |
1455 | } | |
1456 | ||
1457 | template <unsigned Digits10> | |
1458 | inline void eval_asin(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1459 | { | |
1460 | mpc_asin(result.data(), arg.data(), GMP_RNDN); | |
1461 | } | |
1462 | ||
1463 | template <unsigned Digits10> | |
1464 | inline void eval_acos(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1465 | { | |
1466 | mpc_acos(result.data(), arg.data(), GMP_RNDN); | |
1467 | } | |
1468 | ||
1469 | template <unsigned Digits10> | |
1470 | inline void eval_atan(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1471 | { | |
1472 | mpc_atan(result.data(), arg.data(), GMP_RNDN); | |
1473 | } | |
1474 | ||
1475 | template <unsigned Digits10> | |
1476 | inline void eval_sinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1477 | { | |
1478 | mpc_sinh(result.data(), arg.data(), GMP_RNDN); | |
1479 | } | |
1480 | ||
1481 | template <unsigned Digits10> | |
1482 | inline void eval_cosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1483 | { | |
1484 | mpc_cosh(result.data(), arg.data(), GMP_RNDN); | |
1485 | } | |
1486 | ||
1487 | template <unsigned Digits10> | |
1488 | inline void eval_tanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1489 | { | |
1490 | mpc_tanh(result.data(), arg.data(), GMP_RNDN); | |
1491 | } | |
1492 | ||
1493 | template <unsigned Digits10> | |
1494 | inline void eval_asinh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1495 | { | |
1496 | mpc_asinh(result.data(), arg.data(), GMP_RNDN); | |
1497 | } | |
1498 | ||
1499 | template <unsigned Digits10> | |
1500 | inline void eval_acosh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1501 | { | |
1502 | mpc_acosh(result.data(), arg.data(), GMP_RNDN); | |
1503 | } | |
1504 | ||
1505 | template <unsigned Digits10> | |
1506 | inline void eval_atanh(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1507 | { | |
1508 | mpc_atanh(result.data(), arg.data(), GMP_RNDN); | |
1509 | } | |
1510 | ||
1511 | template <unsigned Digits10> | |
1512 | inline void eval_conj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1513 | { | |
1514 | mpc_conj(result.data(), arg.data(), GMP_RNDN); | |
1515 | } | |
1516 | ||
1517 | template <unsigned Digits10> | |
1518 | inline void eval_proj(mpc_complex_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1519 | { | |
1520 | mpc_proj(result.data(), arg.data(), GMP_RNDN); | |
1521 | } | |
1522 | ||
1523 | template <unsigned Digits10> | |
1524 | inline void eval_real(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1525 | { | |
1526 | mpfr_set_prec(result.data(), mpfr_get_prec(mpc_realref(arg.data()))); | |
1527 | mpfr_set(result.data(), mpc_realref(arg.data()), GMP_RNDN); | |
1528 | } | |
1529 | template <unsigned Digits10> | |
1530 | inline void eval_imag(mpfr_float_backend<Digits10>& result, const mpc_complex_backend<Digits10>& arg) | |
1531 | { | |
1532 | mpfr_set_prec(result.data(), mpfr_get_prec(mpc_imagref(arg.data()))); | |
1533 | mpfr_set(result.data(), mpc_imagref(arg.data()), GMP_RNDN); | |
1534 | } | |
1535 | ||
1536 | template <unsigned Digits10> | |
1537 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg) | |
1538 | { | |
1539 | mpfr_set(mpc_imagref(result.data()), arg.data(), GMP_RNDN); | |
1540 | } | |
1541 | ||
1542 | template <unsigned Digits10> | |
1543 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const mpfr_float_backend<Digits10>& arg) | |
1544 | { | |
1545 | mpfr_set(mpc_realref(result.data()), arg.data(), GMP_RNDN); | |
1546 | } | |
1547 | template <unsigned Digits10> | |
1548 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_int& arg) | |
1549 | { | |
1550 | mpfr_set_z(mpc_realref(result.data()), arg.data(), GMP_RNDN); | |
1551 | } | |
1552 | template <unsigned Digits10> | |
1553 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const gmp_rational& arg) | |
1554 | { | |
1555 | mpfr_set_q(mpc_realref(result.data()), arg.data(), GMP_RNDN); | |
1556 | } | |
1557 | template <unsigned Digits10> | |
1558 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned& arg) | |
1559 | { | |
1560 | mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN); | |
1561 | } | |
1562 | template <unsigned Digits10> | |
1563 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long& arg) | |
1564 | { | |
1565 | mpfr_set_ui(mpc_realref(result.data()), arg, GMP_RNDN); | |
1566 | } | |
1567 | template <unsigned Digits10> | |
1568 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const int& arg) | |
1569 | { | |
1570 | mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN); | |
1571 | } | |
1572 | template <unsigned Digits10> | |
1573 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long& arg) | |
1574 | { | |
1575 | mpfr_set_si(mpc_realref(result.data()), arg, GMP_RNDN); | |
1576 | } | |
1577 | template <unsigned Digits10> | |
1578 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const float& arg) | |
1579 | { | |
1580 | mpfr_set_flt(mpc_realref(result.data()), arg, GMP_RNDN); | |
1581 | } | |
1582 | template <unsigned Digits10> | |
1583 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const double& arg) | |
1584 | { | |
1585 | mpfr_set_d(mpc_realref(result.data()), arg, GMP_RNDN); | |
1586 | } | |
1587 | template <unsigned Digits10> | |
1588 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long double& arg) | |
1589 | { | |
1590 | mpfr_set_ld(mpc_realref(result.data()), arg, GMP_RNDN); | |
1591 | } | |
1592 | #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T) | |
1593 | template <unsigned Digits10> | |
1594 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const unsigned long long& arg) | |
1595 | { | |
1596 | mpfr_set_uj(mpc_realref(result.data()), arg, GMP_RNDN); | |
1597 | } | |
1598 | template <unsigned Digits10> | |
1599 | inline void eval_set_real(mpc_complex_backend<Digits10>& result, const long long& arg) | |
1600 | { | |
1601 | mpfr_set_sj(mpc_realref(result.data()), arg, GMP_RNDN); | |
1602 | } | |
1603 | #endif | |
1604 | ||
1605 | template <unsigned Digits10> | |
1606 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_int& arg) | |
1607 | { | |
1608 | mpfr_set_z(mpc_imagref(result.data()), arg.data(), GMP_RNDN); | |
1609 | } | |
1610 | template <unsigned Digits10> | |
1611 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const gmp_rational& arg) | |
1612 | { | |
1613 | mpfr_set_q(mpc_imagref(result.data()), arg.data(), GMP_RNDN); | |
1614 | } | |
1615 | template <unsigned Digits10> | |
1616 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned& arg) | |
1617 | { | |
1618 | mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN); | |
1619 | } | |
1620 | template <unsigned Digits10> | |
1621 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long& arg) | |
1622 | { | |
1623 | mpfr_set_ui(mpc_imagref(result.data()), arg, GMP_RNDN); | |
1624 | } | |
1625 | template <unsigned Digits10> | |
1626 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const int& arg) | |
1627 | { | |
1628 | mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN); | |
1629 | } | |
1630 | template <unsigned Digits10> | |
1631 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long& arg) | |
1632 | { | |
1633 | mpfr_set_si(mpc_imagref(result.data()), arg, GMP_RNDN); | |
1634 | } | |
1635 | template <unsigned Digits10> | |
1636 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const float& arg) | |
1637 | { | |
1638 | mpfr_set_flt(mpc_imagref(result.data()), arg, GMP_RNDN); | |
1639 | } | |
1640 | template <unsigned Digits10> | |
1641 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const double& arg) | |
1642 | { | |
1643 | mpfr_set_d(mpc_imagref(result.data()), arg, GMP_RNDN); | |
1644 | } | |
1645 | template <unsigned Digits10> | |
1646 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long double& arg) | |
1647 | { | |
1648 | mpfr_set_ld(mpc_imagref(result.data()), arg, GMP_RNDN); | |
1649 | } | |
1650 | #if defined(BOOST_HAS_LONG_LONG) && defined(_MPFR_H_HAVE_INTMAX_T) | |
1651 | template <unsigned Digits10> | |
1652 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const unsigned long long& arg) | |
1653 | { | |
1654 | mpfr_set_uj(mpc_imagref(result.data()), arg, GMP_RNDN); | |
1655 | } | |
1656 | template <unsigned Digits10> | |
1657 | inline void eval_set_imag(mpc_complex_backend<Digits10>& result, const long long& arg) | |
1658 | { | |
1659 | mpfr_set_sj(mpc_imagref(result.data()), arg, GMP_RNDN); | |
1660 | } | |
1661 | #endif | |
1662 | ||
1663 | template <unsigned Digits10> | |
1664 | inline std::size_t hash_value(const mpc_complex_backend<Digits10>& val) | |
1665 | { | |
1666 | std::size_t result = 0; | |
1667 | std::size_t len = val.data()[0].re[0]._mpfr_prec / mp_bits_per_limb; | |
1668 | if (val.data()[0].re[0]._mpfr_prec % mp_bits_per_limb) | |
1669 | ++len; | |
1670 | for (std::size_t i = 0; i < len; ++i) | |
1e59de90 TL |
1671 | boost::multiprecision::detail::hash_combine(result, val.data()[0].re[0]._mpfr_d[i]); |
1672 | boost::multiprecision::detail::hash_combine(result, val.data()[0].re[0]._mpfr_exp, val.data()[0].re[0]._mpfr_sign); | |
92f5a8d4 TL |
1673 | |
1674 | len = val.data()[0].im[0]._mpfr_prec / mp_bits_per_limb; | |
1675 | if (val.data()[0].im[0]._mpfr_prec % mp_bits_per_limb) | |
1676 | ++len; | |
1677 | for (std::size_t i = 0; i < len; ++i) | |
1e59de90 TL |
1678 | boost::multiprecision::detail::hash_combine(result, val.data()[0].im[0]._mpfr_d[i]); |
1679 | boost::multiprecision::detail::hash_combine(result, val.data()[0].im[0]._mpfr_exp, val.data()[0].im[0]._mpfr_sign); | |
92f5a8d4 TL |
1680 | return result; |
1681 | } | |
1682 | ||
1683 | } // namespace backends | |
1684 | ||
92f5a8d4 TL |
1685 | namespace detail { |
1686 | template <> | |
1e59de90 | 1687 | struct is_variable_precision<backends::mpc_complex_backend<0> > : public std::integral_constant<bool, true> |
92f5a8d4 TL |
1688 | {}; |
1689 | } // namespace detail | |
1690 | ||
1691 | template <> | |
1e59de90 | 1692 | struct number_category<detail::canonical<mpc_t, backends::mpc_complex_backend<0> >::type> : public std::integral_constant<int, number_kind_floating_point> |
92f5a8d4 TL |
1693 | {}; |
1694 | ||
1695 | using boost::multiprecision::backends::mpc_complex_backend; | |
1696 | ||
1e59de90 TL |
1697 | using mpc_complex_50 = number<mpc_complex_backend<50> > ; |
1698 | using mpc_complex_100 = number<mpc_complex_backend<100> > ; | |
1699 | using mpc_complex_500 = number<mpc_complex_backend<500> > ; | |
1700 | using mpc_complex_1000 = number<mpc_complex_backend<1000> >; | |
1701 | using mpc_complex = number<mpc_complex_backend<0> > ; | |
92f5a8d4 TL |
1702 | |
1703 | template <unsigned Digits10, expression_template_option ExpressionTemplates> | |
1704 | struct component_type<number<mpc_complex_backend<Digits10>, ExpressionTemplates> > | |
1705 | { | |
1e59de90 | 1706 | using type = number<mpfr_float_backend<Digits10>, ExpressionTemplates>; |
92f5a8d4 TL |
1707 | }; |
1708 | ||
1709 | template <unsigned Digits10, expression_template_option ExpressionTemplates> | |
1e59de90 | 1710 | struct component_type<number<backends::logged_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates> > |
92f5a8d4 | 1711 | { |
1e59de90 TL |
1712 | using type = number<mpfr_float_backend<Digits10>, ExpressionTemplates>; |
1713 | }; | |
1714 | template <unsigned Digits10, expression_template_option ExpressionTemplates> | |
1715 | struct component_type<number<backends::debug_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates> > | |
1716 | { | |
1717 | using type = number<backends::debug_adaptor<mpfr_float_backend<Digits10> >, ExpressionTemplates>; | |
92f5a8d4 TL |
1718 | }; |
1719 | ||
1720 | template <unsigned Digits10, expression_template_option ExpressionTemplates> | |
1721 | struct complex_result_from_scalar<number<mpfr_float_backend<Digits10>, ExpressionTemplates> > | |
1722 | { | |
1e59de90 TL |
1723 | using type = number<mpc_complex_backend<Digits10>, ExpressionTemplates>; |
1724 | }; | |
1725 | template <unsigned Digits10, expression_template_option ExpressionTemplates> | |
1726 | struct complex_result_from_scalar<number<backends::logged_adaptor<mpfr_float_backend<Digits10>>, ExpressionTemplates> > | |
1727 | { | |
1728 | using type = number<mpc_complex_backend<Digits10>, ExpressionTemplates>; | |
1729 | }; | |
1730 | template <unsigned Digits10, expression_template_option ExpressionTemplates> | |
1731 | struct complex_result_from_scalar<number<backends::debug_adaptor<mpfr_float_backend<Digits10>>, ExpressionTemplates> > | |
1732 | { | |
1733 | using type = number<backends::debug_adaptor<mpc_complex_backend<Digits10> >, ExpressionTemplates>; | |
92f5a8d4 TL |
1734 | }; |
1735 | ||
1736 | } | |
1737 | ||
1738 | } // namespace boost::multiprecision | |
1739 | ||
1740 | #endif |