]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/multiprecision/mpfr.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / multiprecision / mpfr.hpp
CommitLineData
7c673cae
FG
1///////////////////////////////////////////////////////////////////////////////
2// Copyright 2011 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_MATH_BN_MPFR_HPP
7#define BOOST_MATH_BN_MPFR_HPP
8
1e59de90 9#include <boost/multiprecision/detail/standalone_config.hpp>
7c673cae
FG
10#include <boost/multiprecision/number.hpp>
11#include <boost/multiprecision/debug_adaptor.hpp>
1e59de90 12#include <boost/multiprecision/logged_adaptor.hpp>
7c673cae 13#include <boost/multiprecision/gmp.hpp>
7c673cae 14#include <boost/multiprecision/detail/digits.hpp>
1e59de90 15#include <boost/multiprecision/detail/float128_functions.hpp>
f67539c2 16#include <boost/multiprecision/detail/atomic.hpp>
20effc67 17#include <boost/multiprecision/traits/max_digits10.hpp>
1e59de90
TL
18#include <boost/multiprecision/detail/hash.hpp>
19#include <boost/multiprecision/detail/no_exceptions_support.hpp>
20#include <boost/multiprecision/detail/assert.hpp>
21#include <boost/multiprecision/detail/fpclassify.hpp>
7c673cae
FG
22#include <mpfr.h>
23#include <cmath>
1e59de90 24#include <cstdint>
7c673cae 25#include <algorithm>
1e59de90
TL
26#include <utility>
27#include <type_traits>
28#include <atomic>
29
30#ifdef BOOST_MP_MATH_AVAILABLE
31#include <boost/math/constants/constants.hpp>
32#include <boost/math/special_functions/gamma.hpp>
33#endif
7c673cae
FG
34
35#ifndef BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION
92f5a8d4 36#define BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION 20
7c673cae
FG
37#endif
38
92f5a8d4
TL
39namespace boost {
40namespace multiprecision {
7c673cae
FG
41
42enum mpfr_allocation_type
43{
44 allocate_stack,
45 allocate_dynamic
46};
47
92f5a8d4 48namespace backends {
7c673cae
FG
49
50template <unsigned digits10, mpfr_allocation_type AllocationType = allocate_dynamic>
51struct mpfr_float_backend;
52
53template <>
54struct mpfr_float_backend<0, allocate_stack>;
55
56} // namespace backends
57
58template <unsigned digits10, mpfr_allocation_type AllocationType>
1e59de90 59struct number_category<backends::mpfr_float_backend<digits10, AllocationType> > : public std::integral_constant<int, number_kind_floating_point>
92f5a8d4 60{};
7c673cae 61
92f5a8d4 62namespace backends {
7c673cae 63
92f5a8d4 64namespace detail {
7c673cae
FG
65
66template <bool b>
67struct mpfr_cleanup
68{
1e59de90
TL
69 //
70 // There are 2 seperate cleanup objects here, one calls
71 // mpfr_free_cache on destruction to perform global cleanup
72 // the other is declared thread_local and calls
73 // mpfr_free_cache2(MPFR_FREE_LOCAL_CACHE) to free thread local data.
74 //
7c673cae
FG
75 struct initializer
76 {
77 initializer() {}
92f5a8d4
TL
78 ~initializer() { mpfr_free_cache(); }
79 void force_instantiate() const {}
7c673cae 80 };
1e59de90
TL
81#if MPFR_VERSION_MAJOR >= 4
82 struct thread_initializer
83 {
84 thread_initializer() {}
85 ~thread_initializer() { mpfr_free_cache2(MPFR_FREE_LOCAL_CACHE); }
86 void force_instantiate() const {}
87 };
88#endif
7c673cae 89 static const initializer init;
1e59de90
TL
90 static void force_instantiate()
91 {
92#if MPFR_VERSION_MAJOR >= 4
93 static const BOOST_MP_THREAD_LOCAL thread_initializer thread_init;
94 thread_init.force_instantiate();
95#endif
96 init.force_instantiate();
97 }
7c673cae
FG
98};
99
100template <bool b>
101typename mpfr_cleanup<b>::initializer const mpfr_cleanup<b>::init;
102
92f5a8d4
TL
103inline void mpfr_copy_precision(mpfr_t dest, const mpfr_t src)
104{
105 mpfr_prec_t p_dest = mpfr_get_prec(dest);
106 mpfr_prec_t p_src = mpfr_get_prec(src);
107 if (p_dest != p_src)
108 mpfr_set_prec(dest, p_src);
109}
110inline void mpfr_copy_precision(mpfr_t dest, const mpfr_t src1, const mpfr_t src2)
111{
112 mpfr_prec_t p_dest = mpfr_get_prec(dest);
113 mpfr_prec_t p_src1 = mpfr_get_prec(src1);
114 mpfr_prec_t p_src2 = mpfr_get_prec(src2);
115 if (p_src2 > p_src1)
116 p_src1 = p_src2;
117 if (p_dest != p_src1)
118 mpfr_set_prec(dest, p_src1);
119}
7c673cae
FG
120
121template <unsigned digits10, mpfr_allocation_type AllocationType>
122struct mpfr_float_imp;
123
124template <unsigned digits10>
125struct mpfr_float_imp<digits10, allocate_dynamic>
126{
127#ifdef BOOST_HAS_LONG_LONG
1e59de90
TL
128 using signed_types = std::tuple<long, long long> ;
129 using unsigned_types = std::tuple<unsigned long, unsigned long long>;
7c673cae 130#else
1e59de90
TL
131 using signed_types = std::tuple<long> ;
132 using unsigned_types = std::tuple<unsigned long>;
7c673cae 133#endif
1e59de90
TL
134 using float_types = std::tuple<double, long double>;
135 using exponent_type = long ;
7c673cae
FG
136
137 mpfr_float_imp()
138 {
f67539c2 139 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
7c673cae
FG
140 mpfr_set_ui(m_data, 0u, GMP_RNDN);
141 }
92f5a8d4 142 mpfr_float_imp(unsigned digits2)
7c673cae 143 {
92f5a8d4 144 mpfr_init2(m_data, digits2);
7c673cae
FG
145 mpfr_set_ui(m_data, 0u, GMP_RNDN);
146 }
147
148 mpfr_float_imp(const mpfr_float_imp& o)
149 {
1e59de90 150 mpfr_init2(m_data, preserve_source_precision() ? mpfr_get_prec(o.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
92f5a8d4 151 if (o.m_data[0]._mpfr_d)
7c673cae
FG
152 mpfr_set(m_data, o.m_data, GMP_RNDN);
153 }
1e59de90
TL
154 // rvalue copy
155 mpfr_float_imp(mpfr_float_imp&& o) noexcept
7c673cae 156 {
1e59de90
TL
157 mpfr_prec_t binary_default_precision = boost::multiprecision::detail::digits10_2_2(get_default_precision());
158 if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpfr_get_prec(o.data()) == binary_default_precision))
159 {
160 m_data[0] = o.m_data[0];
161 o.m_data[0]._mpfr_d = 0;
162 }
163 else
164 {
165 // NOTE: C allocation interface must not throw:
166 mpfr_init2(m_data, binary_default_precision);
167 if (o.m_data[0]._mpfr_d)
168 mpfr_set(m_data, o.m_data, GMP_RNDN);
169 }
7c673cae 170 }
92f5a8d4 171 mpfr_float_imp& operator=(const mpfr_float_imp& o)
7c673cae 172 {
92f5a8d4
TL
173 if ((o.m_data[0]._mpfr_d) && (this != &o))
174 {
175 if (m_data[0]._mpfr_d == 0)
1e59de90
TL
176 {
177 mpfr_init2(m_data, preserve_source_precision() ? mpfr_get_prec(o.m_data) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
178 }
179 else if (preserve_source_precision() && (mpfr_get_prec(o.data()) != mpfr_get_prec(data())))
180 {
181 mpfr_set_prec(m_data, mpfr_get_prec(o.m_data));
182 }
7c673cae 183 mpfr_set(m_data, o.m_data, GMP_RNDN);
92f5a8d4 184 }
7c673cae
FG
185 return *this;
186 }
1e59de90
TL
187 // rvalue assign
188 mpfr_float_imp& operator=(mpfr_float_imp&& o) noexcept
7c673cae 189 {
1e59de90
TL
190 if ((this->get_default_options() != variable_precision_options::preserve_target_precision) || (mpfr_get_prec(o.data()) == mpfr_get_prec(data())))
191 mpfr_swap(m_data, o.m_data);
192 else
193 *this = static_cast<const mpfr_float_imp&>(o);
7c673cae
FG
194 return *this;
195 }
7c673cae
FG
196#ifdef BOOST_HAS_LONG_LONG
197#ifdef _MPFR_H_HAVE_INTMAX_T
1e59de90 198 mpfr_float_imp& operator=(unsigned long long i)
7c673cae 199 {
92f5a8d4 200 if (m_data[0]._mpfr_d == 0)
f67539c2 201 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
7c673cae
FG
202 mpfr_set_uj(m_data, i, GMP_RNDN);
203 return *this;
204 }
1e59de90 205 mpfr_float_imp& operator=(long long i)
7c673cae 206 {
92f5a8d4 207 if (m_data[0]._mpfr_d == 0)
f67539c2 208 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
7c673cae
FG
209 mpfr_set_sj(m_data, i, GMP_RNDN);
210 return *this;
211 }
212#else
1e59de90 213 mpfr_float_imp& operator=(unsigned long long i)
7c673cae 214 {
92f5a8d4 215 if (m_data[0]._mpfr_d == 0)
f67539c2 216 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
1e59de90 217 unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
92f5a8d4
TL
218 unsigned shift = 0;
219 mpfr_t t;
1e59de90 220 mpfr_init2(t, (std::max)(static_cast<mpfr_prec_t>(std::numeric_limits<unsigned long long>::digits), static_cast<mpfr_prec_t>(mpfr_get_prec(m_data))));
7c673cae 221 mpfr_set_ui(m_data, 0, GMP_RNDN);
92f5a8d4 222 while (i)
7c673cae
FG
223 {
224 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
92f5a8d4 225 if (shift)
7c673cae
FG
226 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
227 mpfr_add(m_data, m_data, t, GMP_RNDN);
228 shift += std::numeric_limits<unsigned long>::digits;
229 i >>= std::numeric_limits<unsigned long>::digits;
230 }
231 mpfr_clear(t);
232 return *this;
233 }
1e59de90 234 mpfr_float_imp& operator=(long long i)
7c673cae 235 {
92f5a8d4 236 if (m_data[0]._mpfr_d == 0)
f67539c2 237 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
7c673cae 238 bool neg = i < 0;
92f5a8d4
TL
239 *this = boost::multiprecision::detail::unsigned_abs(i);
240 if (neg)
7c673cae
FG
241 mpfr_neg(m_data, m_data, GMP_RNDN);
242 return *this;
243 }
244#endif
1e59de90
TL
245#endif
246#ifdef BOOST_HAS_INT128
247 mpfr_float_imp& operator=(uint128_type i)
248 {
249 if (m_data[0]._mpfr_d == 0)
250 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
251 unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
252 unsigned shift = 0;
253 mpfr_t t;
254 mpfr_init2(t, (std::max)(static_cast<mpfr_prec_t>(std::numeric_limits<unsigned long long>::digits), static_cast<mpfr_prec_t>(mpfr_get_prec(m_data))));
255 mpfr_set_ui(m_data, 0, GMP_RNDN);
256 while (i)
257 {
258 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
259 if (shift)
260 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
261 mpfr_add(m_data, m_data, t, GMP_RNDN);
262 shift += std::numeric_limits<unsigned long>::digits;
263 i >>= std::numeric_limits<unsigned long>::digits;
264 }
265 mpfr_clear(t);
266 return *this;
267 }
268 mpfr_float_imp& operator=(int128_type i)
269 {
270 if (m_data[0]._mpfr_d == 0)
271 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
272 bool neg = i < 0;
273 *this = boost::multiprecision::detail::unsigned_abs(i);
274 if (neg)
275 mpfr_neg(m_data, m_data, GMP_RNDN);
276 return *this;
277 }
7c673cae 278#endif
92f5a8d4 279 mpfr_float_imp& operator=(unsigned long i)
7c673cae 280 {
92f5a8d4 281 if (m_data[0]._mpfr_d == 0)
f67539c2 282 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
7c673cae
FG
283 mpfr_set_ui(m_data, i, GMP_RNDN);
284 return *this;
285 }
92f5a8d4 286 mpfr_float_imp& operator=(long i)
7c673cae 287 {
92f5a8d4 288 if (m_data[0]._mpfr_d == 0)
f67539c2 289 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
7c673cae
FG
290 mpfr_set_si(m_data, i, GMP_RNDN);
291 return *this;
292 }
92f5a8d4 293 mpfr_float_imp& operator=(double d)
7c673cae 294 {
92f5a8d4 295 if (m_data[0]._mpfr_d == 0)
f67539c2 296 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
7c673cae
FG
297 mpfr_set_d(m_data, d, GMP_RNDN);
298 return *this;
299 }
92f5a8d4 300 mpfr_float_imp& operator=(long double a)
7c673cae 301 {
92f5a8d4 302 if (m_data[0]._mpfr_d == 0)
f67539c2 303 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
7c673cae
FG
304 mpfr_set_ld(m_data, a, GMP_RNDN);
305 return *this;
306 }
1e59de90
TL
307#ifdef BOOST_HAS_FLOAT128
308 mpfr_float_imp& operator=(float128_type a)
309 {
310 BOOST_MP_FLOAT128_USING
311 if (m_data[0]._mpfr_d == 0)
312 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
313
314 if (a == 0)
315 {
316 mpfr_set_si(m_data, 0, GMP_RNDN);
317 return *this;
318 }
319
320 if (a == 1)
321 {
322 mpfr_set_si(m_data, 1, GMP_RNDN);
323 return *this;
324 }
325
326 BOOST_MP_ASSERT(!BOOST_MP_ISINF(a));
327 BOOST_MP_ASSERT(!BOOST_MP_ISNAN(a));
328
329 int e;
330 float128_type f, term;
331 mpfr_set_ui(m_data, 0u, GMP_RNDN);
332
333 f = frexp(a, &e);
334
335 constexpr const int shift = std::numeric_limits<int>::digits - 1;
336
337 while (f)
338 {
339 // extract int sized bits from f:
340 f = ldexp(f, shift);
341 term = floor(f);
342 e -= shift;
343 mpfr_mul_2exp(m_data, m_data, shift, GMP_RNDN);
344 if (term > 0)
345 mpfr_add_ui(m_data, m_data, static_cast<unsigned>(term), GMP_RNDN);
346 else
347 mpfr_sub_ui(m_data, m_data, static_cast<unsigned>(-term), GMP_RNDN);
348 f -= term;
349 }
350 if (e > 0)
351 mpfr_mul_2exp(m_data, m_data, e, GMP_RNDN);
352 else if (e < 0)
353 mpfr_div_2exp(m_data, m_data, -e, GMP_RNDN);
354 return *this;
355 }
356#endif
92f5a8d4 357 mpfr_float_imp& operator=(const char* s)
7c673cae 358 {
92f5a8d4 359 if (m_data[0]._mpfr_d == 0)
f67539c2 360 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
92f5a8d4 361 if (mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
7c673cae 362 {
1e59de90 363 BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
7c673cae
FG
364 }
365 return *this;
366 }
1e59de90 367 void swap(mpfr_float_imp& o) noexcept
7c673cae
FG
368 {
369 mpfr_swap(m_data, o.m_data);
370 }
92f5a8d4 371 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
7c673cae 372 {
1e59de90 373 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
7c673cae
FG
374
375 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
376 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
377
378 std::streamsize org_digits(digits);
379
92f5a8d4 380 if (scientific && digits)
7c673cae
FG
381 ++digits;
382
383 std::string result;
92f5a8d4
TL
384 mp_exp_t e;
385 if (mpfr_inf_p(m_data))
7c673cae 386 {
92f5a8d4 387 if (mpfr_sgn(m_data) < 0)
7c673cae 388 result = "-inf";
92f5a8d4 389 else if (f & std::ios_base::showpos)
7c673cae
FG
390 result = "+inf";
391 else
392 result = "inf";
393 return result;
394 }
92f5a8d4 395 if (mpfr_nan_p(m_data))
7c673cae
FG
396 {
397 result = "nan";
398 return result;
399 }
92f5a8d4 400 if (mpfr_zero_p(m_data))
7c673cae 401 {
92f5a8d4 402 e = 0;
1e59de90
TL
403 if (mpfr_signbit(m_data))
404 result = "-0";
405 else
406 result = "0";
7c673cae 407 }
1e59de90 408 else if (fixed)
7c673cae 409 {
1e59de90 410 // We actually need a different number of digits to what one might expect:
92f5a8d4 411 char* ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
1e59de90
TL
412 --e;
413 mpfr_free_str(ps);
414 digits += e + 1;
415 if (digits == 0)
7c673cae 416 {
1e59de90
TL
417 // We need to get *all* the digits and then possibly round up,
418 // we end up with either "0" or "1" as the result.
419 ps = mpfr_get_str(0, &e, 10, 0, m_data, GMP_RNDN);
420 --e;
421 unsigned offset = *ps == '-' ? 1 : 0;
422 if (ps[offset] > '5')
7c673cae 423 {
1e59de90
TL
424 ++e;
425 ps[offset] = '1';
426 ps[offset + 1] = 0;
427 }
428 else if (ps[offset] == '5')
429 {
430 unsigned i = offset + 1;
431 bool round_up = false;
432 while (ps[i] != 0)
7c673cae 433 {
1e59de90 434 if (ps[i] != '0')
7c673cae 435 {
1e59de90
TL
436 round_up = true;
437 break;
7c673cae 438 }
1e59de90 439 ++i;
7c673cae 440 }
1e59de90 441 if (round_up)
7c673cae 442 {
1e59de90
TL
443 ++e;
444 ps[offset] = '1';
7c673cae
FG
445 ps[offset + 1] = 0;
446 }
1e59de90 447 else
92f5a8d4 448 {
1e59de90
TL
449 ps[offset] = '0';
450 ps[offset + 1] = 0;
92f5a8d4 451 }
7c673cae
FG
452 }
453 else
454 {
1e59de90
TL
455 ps[offset] = '0';
456 ps[offset + 1] = 0;
457 }
458 }
459 else if (digits > 0)
460 {
461 mp_exp_t old_e = e;
462 ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
463 --e; // To match with what our formatter expects.
464 if (old_e > e)
465 {
466 // in some cases, when we ask for more digits of precision, it will
467 // change the number of digits to the left of the decimal, if that
468 // happens, account for it here.
469 // example: cout << fixed << setprecision(3) << mpf_float_50("99.9809")
470 mpfr_free_str(ps);
471 digits -= old_e - e;
472 ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
473 --e; // To match with what our formatter expects.
7c673cae
FG
474 }
475 }
1e59de90
TL
476 else
477 {
478 ps = mpfr_get_str(0, &e, 10, 1, m_data, GMP_RNDN);
479 --e;
480 unsigned offset = *ps == '-' ? 1 : 0;
481 ps[offset] = '0';
482 ps[offset + 1] = 0;
483 }
484 result = ps ? ps : "0";
485 if (ps)
486 mpfr_free_str(ps);
487 }
488 else
489 {
490 char* ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
491 --e; // To match with what our formatter expects.
7c673cae 492 result = ps ? ps : "0";
92f5a8d4 493 if (ps)
7c673cae
FG
494 mpfr_free_str(ps);
495 }
496 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
497 return result;
498 }
1e59de90 499 ~mpfr_float_imp() noexcept
7c673cae 500 {
92f5a8d4 501 if (m_data[0]._mpfr_d)
7c673cae
FG
502 mpfr_clear(m_data);
503 detail::mpfr_cleanup<true>::force_instantiate();
504 }
1e59de90 505 void negate() noexcept
7c673cae 506 {
1e59de90 507 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
7c673cae
FG
508 mpfr_neg(m_data, m_data, GMP_RNDN);
509 }
510 template <mpfr_allocation_type AllocationType>
1e59de90 511 int compare(const mpfr_float_backend<digits10, AllocationType>& o) const
7c673cae 512 {
1e59de90 513 BOOST_MP_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d);
7c673cae
FG
514 return mpfr_cmp(m_data, o.m_data);
515 }
1e59de90 516 int compare(long i) const
7c673cae 517 {
1e59de90 518 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
7c673cae
FG
519 return mpfr_cmp_si(m_data, i);
520 }
1e59de90
TL
521 int compare(double i) const
522 {
523 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
524 return mpfr_cmp_d(m_data, i);
525 }
526 int compare(long double i) const
527 {
528 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
529 return mpfr_cmp_ld(m_data, i);
530 }
531 int compare(unsigned long i) const
7c673cae 532 {
1e59de90 533 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
7c673cae
FG
534 return mpfr_cmp_ui(m_data, i);
535 }
536 template <class V>
1e59de90 537 int compare(V v) const
7c673cae 538 {
92f5a8d4 539 mpfr_float_backend<digits10, allocate_dynamic> d(0uL, mpfr_get_prec(m_data));
7c673cae
FG
540 d = v;
541 return compare(d);
542 }
1e59de90 543 mpfr_t& data() noexcept
7c673cae 544 {
1e59de90 545 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
7c673cae
FG
546 return m_data;
547 }
1e59de90 548 const mpfr_t& data() const noexcept
7c673cae 549 {
1e59de90 550 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
7c673cae
FG
551 return m_data;
552 }
92f5a8d4
TL
553
554 protected:
555 mpfr_t m_data;
1e59de90 556 static boost::multiprecision::detail::precision_type& get_global_default_precision() noexcept
7c673cae 557 {
f67539c2 558 static boost::multiprecision::detail::precision_type val(BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION);
7c673cae
FG
559 return val;
560 }
1e59de90
TL
561 static unsigned& get_default_precision() noexcept
562 {
563 static BOOST_MP_THREAD_LOCAL unsigned val(get_global_default_precision());
564 return val;
565 }
566#ifndef BOOST_MT_NO_ATOMIC_INT
567 static std::atomic<variable_precision_options>& get_global_default_options() noexcept
568 {
569 static std::atomic<variable_precision_options> val{variable_precision_options::preserve_related_precision};
570 return val;
571 }
572#else
573 static variable_precision_options& get_global_default_options() noexcept
574 {
575 static variable_precision_options val{variable_precision_options::preserve_related_precision};
576 return val;
577 }
578#endif
579 static variable_precision_options& get_default_options()noexcept
580 {
581 static BOOST_MP_THREAD_LOCAL variable_precision_options val(get_global_default_options());
582 return val;
583 }
584 static bool preserve_source_precision() noexcept
585 {
586 return get_default_options() >= variable_precision_options::preserve_source_precision;
587 }
7c673cae
FG
588};
589
590#ifdef BOOST_MSVC
591#pragma warning(push)
92f5a8d4 592#pragma warning(disable : 4127) // Conditional expression is constant
7c673cae
FG
593#endif
594
595template <unsigned digits10>
596struct mpfr_float_imp<digits10, allocate_stack>
597{
598#ifdef BOOST_HAS_LONG_LONG
1e59de90
TL
599 using signed_types = std::tuple<long, long long> ;
600 using unsigned_types = std::tuple<unsigned long, unsigned long long>;
7c673cae 601#else
1e59de90
TL
602 using signed_types = std::tuple<long> ;
603 using unsigned_types = std::tuple<unsigned long>;
7c673cae 604#endif
1e59de90
TL
605 using float_types = std::tuple<double, long double>;
606 using exponent_type = long ;
7c673cae 607
1e59de90
TL
608 static constexpr const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u);
609 static constexpr const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t);
7c673cae 610
1e59de90 611 ~mpfr_float_imp() noexcept
7c673cae
FG
612 {
613 detail::mpfr_cleanup<true>::force_instantiate();
614 }
615 mpfr_float_imp()
616 {
617 mpfr_custom_init(m_buffer, digits2);
618 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
619 mpfr_set_ui(m_data, 0u, GMP_RNDN);
620 }
621
622 mpfr_float_imp(const mpfr_float_imp& o)
623 {
624 mpfr_custom_init(m_buffer, digits2);
625 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
626 mpfr_set(m_data, o.m_data, GMP_RNDN);
627 }
92f5a8d4 628 mpfr_float_imp& operator=(const mpfr_float_imp& o)
7c673cae
FG
629 {
630 mpfr_set(m_data, o.m_data, GMP_RNDN);
631 return *this;
632 }
633#ifdef BOOST_HAS_LONG_LONG
634#ifdef _MPFR_H_HAVE_INTMAX_T
1e59de90 635 mpfr_float_imp& operator=(unsigned long long i)
7c673cae
FG
636 {
637 mpfr_set_uj(m_data, i, GMP_RNDN);
638 return *this;
639 }
1e59de90 640 mpfr_float_imp& operator=(long long i)
7c673cae
FG
641 {
642 mpfr_set_sj(m_data, i, GMP_RNDN);
643 return *this;
644 }
645#else
1e59de90 646 mpfr_float_imp& operator=(unsigned long long i)
7c673cae 647 {
1e59de90 648 unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uL);
92f5a8d4
TL
649 unsigned shift = 0;
650 mpfr_t t;
651 mp_limb_t t_limbs[limb_count];
7c673cae
FG
652 mpfr_custom_init(t_limbs, digits2);
653 mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
654 mpfr_set_ui(m_data, 0, GMP_RNDN);
92f5a8d4 655 while (i)
7c673cae
FG
656 {
657 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
92f5a8d4 658 if (shift)
7c673cae
FG
659 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
660 mpfr_add(m_data, m_data, t, GMP_RNDN);
661 shift += std::numeric_limits<unsigned long>::digits;
662 i >>= std::numeric_limits<unsigned long>::digits;
663 }
664 return *this;
665 }
1e59de90 666 mpfr_float_imp& operator=(long long i)
7c673cae
FG
667 {
668 bool neg = i < 0;
92f5a8d4
TL
669 *this = boost::multiprecision::detail::unsigned_abs(i);
670 if (neg)
7c673cae
FG
671 mpfr_neg(m_data, m_data, GMP_RNDN);
672 return *this;
673 }
674#endif
1e59de90
TL
675#endif
676#ifdef BOOST_HAS_INT128
677 mpfr_float_imp& operator=(uint128_type i)
678 {
679 unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uL);
680 unsigned shift = 0;
681 mpfr_t t;
682 mp_limb_t t_limbs[limb_count];
683 mpfr_custom_init(t_limbs, digits2);
684 mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
685 mpfr_set_ui(m_data, 0, GMP_RNDN);
686 while (i)
687 {
688 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
689 if (shift)
690 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
691 mpfr_add(m_data, m_data, t, GMP_RNDN);
692 shift += std::numeric_limits<unsigned long>::digits;
693 i >>= std::numeric_limits<unsigned long>::digits;
694 }
695 return *this;
696 }
697 mpfr_float_imp& operator=(int128_type i)
698 {
699 bool neg = i < 0;
700 *this = boost::multiprecision::detail::unsigned_abs(i);
701 if (neg)
702 mpfr_neg(m_data, m_data, GMP_RNDN);
703 return *this;
704 }
7c673cae 705#endif
92f5a8d4 706 mpfr_float_imp& operator=(unsigned long i)
7c673cae
FG
707 {
708 mpfr_set_ui(m_data, i, GMP_RNDN);
709 return *this;
710 }
92f5a8d4 711 mpfr_float_imp& operator=(long i)
7c673cae
FG
712 {
713 mpfr_set_si(m_data, i, GMP_RNDN);
714 return *this;
715 }
92f5a8d4 716 mpfr_float_imp& operator=(double d)
7c673cae
FG
717 {
718 mpfr_set_d(m_data, d, GMP_RNDN);
719 return *this;
720 }
92f5a8d4 721 mpfr_float_imp& operator=(long double a)
7c673cae
FG
722 {
723 mpfr_set_ld(m_data, a, GMP_RNDN);
724 return *this;
725 }
1e59de90
TL
726#ifdef BOOST_HAS_FLOAT128
727 mpfr_float_imp& operator=(float128_type a)
728 {
729 BOOST_MP_FLOAT128_USING
730 if (a == 0)
731 {
732 mpfr_set_si(m_data, 0, GMP_RNDN);
733 return *this;
734 }
735
736 if (a == 1)
737 {
738 mpfr_set_si(m_data, 1, GMP_RNDN);
739 return *this;
740 }
741
742 BOOST_MP_ASSERT(!BOOST_MP_ISINF(a));
743 BOOST_MP_ASSERT(!BOOST_MP_ISNAN(a));
744
745 int e;
746 float128_type f, term;
747 mpfr_set_ui(m_data, 0u, GMP_RNDN);
748
749 f = frexp(a, &e);
750
751 constexpr const int shift = std::numeric_limits<int>::digits - 1;
752
753 while (f)
754 {
755 // extract int sized bits from f:
756 f = ldexp(f, shift);
757 term = floor(f);
758 e -= shift;
759 mpfr_mul_2exp(m_data, m_data, shift, GMP_RNDN);
760 if (term > 0)
761 mpfr_add_ui(m_data, m_data, static_cast<unsigned>(term), GMP_RNDN);
762 else
763 mpfr_sub_ui(m_data, m_data, static_cast<unsigned>(-term), GMP_RNDN);
764 f -= term;
765 }
766 if (e > 0)
767 mpfr_mul_2exp(m_data, m_data, e, GMP_RNDN);
768 else if (e < 0)
769 mpfr_div_2exp(m_data, m_data, -e, GMP_RNDN);
770 return *this;
771 }
772#endif
92f5a8d4 773 mpfr_float_imp& operator=(const char* s)
7c673cae 774 {
92f5a8d4 775 if (mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
7c673cae 776 {
1e59de90 777 BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
7c673cae
FG
778 }
779 return *this;
780 }
1e59de90 781 void swap(mpfr_float_imp& o) noexcept
7c673cae
FG
782 {
783 // We have to swap by copying:
784 mpfr_float_imp t(*this);
785 *this = o;
92f5a8d4 786 o = t;
7c673cae 787 }
92f5a8d4 788 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
7c673cae 789 {
1e59de90 790 BOOST_MP_ASSERT(m_data[0]._mpfr_d);
7c673cae
FG
791
792 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
793 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
794
795 std::streamsize org_digits(digits);
796
92f5a8d4 797 if (scientific && digits)
7c673cae
FG
798 ++digits;
799
800 std::string result;
92f5a8d4
TL
801 mp_exp_t e;
802 if (mpfr_inf_p(m_data))
7c673cae 803 {
92f5a8d4 804 if (mpfr_sgn(m_data) < 0)
7c673cae 805 result = "-inf";
92f5a8d4 806 else if (f & std::ios_base::showpos)
7c673cae
FG
807 result = "+inf";
808 else
809 result = "inf";
810 return result;
811 }
92f5a8d4 812 if (mpfr_nan_p(m_data))
7c673cae
FG
813 {
814 result = "nan";
815 return result;
816 }
92f5a8d4 817 if (mpfr_zero_p(m_data))
7c673cae 818 {
92f5a8d4 819 e = 0;
7c673cae
FG
820 result = "0";
821 }
822 else
823 {
92f5a8d4
TL
824 char* ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
825 --e; // To match with what our formatter expects.
826 if (fixed && e != -1)
7c673cae
FG
827 {
828 // Oops we actually need a different number of digits to what we asked for:
829 mpfr_free_str(ps);
830 digits += e + 1;
92f5a8d4 831 if (digits == 0)
7c673cae
FG
832 {
833 // We need to get *all* the digits and then possibly round up,
834 // we end up with either "0" or "1" as the result.
92f5a8d4 835 ps = mpfr_get_str(0, &e, 10, 0, m_data, GMP_RNDN);
7c673cae
FG
836 --e;
837 unsigned offset = *ps == '-' ? 1 : 0;
92f5a8d4 838 if (ps[offset] > '5')
7c673cae
FG
839 {
840 ++e;
92f5a8d4 841 ps[offset] = '1';
7c673cae
FG
842 ps[offset + 1] = 0;
843 }
92f5a8d4 844 else if (ps[offset] == '5')
7c673cae 845 {
92f5a8d4
TL
846 unsigned i = offset + 1;
847 bool round_up = false;
848 while (ps[i] != 0)
7c673cae 849 {
92f5a8d4 850 if (ps[i] != '0')
7c673cae
FG
851 {
852 round_up = true;
853 break;
854 }
855 }
92f5a8d4 856 if (round_up)
7c673cae
FG
857 {
858 ++e;
92f5a8d4 859 ps[offset] = '1';
7c673cae
FG
860 ps[offset + 1] = 0;
861 }
862 else
863 {
92f5a8d4 864 ps[offset] = '0';
7c673cae
FG
865 ps[offset + 1] = 0;
866 }
867 }
868 else
869 {
92f5a8d4 870 ps[offset] = '0';
7c673cae
FG
871 ps[offset + 1] = 0;
872 }
873 }
92f5a8d4 874 else if (digits > 0)
7c673cae 875 {
92f5a8d4
TL
876 ps = mpfr_get_str(0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
877 --e; // To match with what our formatter expects.
7c673cae
FG
878 }
879 else
880 {
92f5a8d4 881 ps = mpfr_get_str(0, &e, 10, 1, m_data, GMP_RNDN);
7c673cae
FG
882 --e;
883 unsigned offset = *ps == '-' ? 1 : 0;
92f5a8d4
TL
884 ps[offset] = '0';
885 ps[offset + 1] = 0;
7c673cae
FG
886 }
887 }
888 result = ps ? ps : "0";
92f5a8d4 889 if (ps)
7c673cae
FG
890 mpfr_free_str(ps);
891 }
892 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
893 return result;
894 }
1e59de90 895 void negate() noexcept
7c673cae
FG
896 {
897 mpfr_neg(m_data, m_data, GMP_RNDN);
898 }
899 template <mpfr_allocation_type AllocationType>
1e59de90 900 int compare(const mpfr_float_backend<digits10, AllocationType>& o) const
7c673cae
FG
901 {
902 return mpfr_cmp(m_data, o.m_data);
903 }
1e59de90 904 int compare(long i) const
7c673cae
FG
905 {
906 return mpfr_cmp_si(m_data, i);
907 }
1e59de90 908 int compare(unsigned long i) const
7c673cae
FG
909 {
910 return mpfr_cmp_ui(m_data, i);
911 }
1e59de90
TL
912 int compare(double i) const
913 {
914 return mpfr_cmp_d(m_data, i);
915 }
916 int compare(long double i) const
917 {
918 return mpfr_cmp_ld(m_data, i);
919 }
7c673cae 920 template <class V>
1e59de90 921 int compare(V v) const
7c673cae
FG
922 {
923 mpfr_float_backend<digits10, allocate_stack> d;
924 d = v;
925 return compare(d);
926 }
1e59de90 927 mpfr_t& data() noexcept
7c673cae
FG
928 {
929 return m_data;
930 }
1e59de90 931 const mpfr_t& data() const noexcept
7c673cae
FG
932 {
933 return m_data;
934 }
92f5a8d4
TL
935
936 protected:
937 mpfr_t m_data;
7c673cae
FG
938 mp_limb_t m_buffer[limb_count];
939};
940
941#ifdef BOOST_MSVC
942#pragma warning(pop)
943#endif
944
945} // namespace detail
946
947template <unsigned digits10, mpfr_allocation_type AllocationType>
948struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType>
949{
950 mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {}
951 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {}
1e59de90
TL
952 // rvalue copy
953 mpfr_float_backend(mpfr_float_backend&& o) noexcept : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o))
92f5a8d4 954 {}
7c673cae 955 template <unsigned D, mpfr_allocation_type AT>
1e59de90 956 mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<D <= digits10>::type* = 0)
7c673cae
FG
957 : detail::mpfr_float_imp<digits10, AllocationType>()
958 {
959 mpfr_set(this->m_data, val.data(), GMP_RNDN);
960 }
961 template <unsigned D, mpfr_allocation_type AT>
1e59de90 962 explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename std::enable_if<!(D <= digits10)>::type* = 0)
7c673cae
FG
963 : detail::mpfr_float_imp<digits10, AllocationType>()
964 {
965 mpfr_set(this->m_data, val.data(), GMP_RNDN);
966 }
967 template <unsigned D>
1e59de90 968 mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<D <= digits10>::type* = 0)
7c673cae
FG
969 : detail::mpfr_float_imp<digits10, AllocationType>()
970 {
971 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
972 }
973 template <unsigned D>
1e59de90 974 mpfr_float_backend(const gmp_float<D>& val, typename std::enable_if<!(D <= digits10)>::type* = 0)
7c673cae
FG
975 : detail::mpfr_float_imp<digits10, AllocationType>()
976 {
977 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
978 }
979 mpfr_float_backend(const gmp_int& val)
980 : detail::mpfr_float_imp<digits10, AllocationType>()
981 {
982 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
983 }
984 mpfr_float_backend(const gmp_rational& val)
985 : detail::mpfr_float_imp<digits10, AllocationType>()
986 {
987 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
988 }
989 mpfr_float_backend(const mpfr_t val)
990 : detail::mpfr_float_imp<digits10, AllocationType>()
991 {
992 mpfr_set(this->m_data, val, GMP_RNDN);
993 }
994 mpfr_float_backend(const mpf_t val)
995 : detail::mpfr_float_imp<digits10, AllocationType>()
996 {
997 mpfr_set_f(this->m_data, val, GMP_RNDN);
998 }
999 mpfr_float_backend(const mpz_t val)
1000 : detail::mpfr_float_imp<digits10, AllocationType>()
1001 {
1002 mpfr_set_z(this->m_data, val, GMP_RNDN);
1003 }
1004 mpfr_float_backend(const mpq_t val)
1005 : detail::mpfr_float_imp<digits10, AllocationType>()
1006 {
1007 mpfr_set_q(this->m_data, val, GMP_RNDN);
1008 }
92f5a8d4
TL
1009 // Construction with precision: we ignore the precision here.
1010 template <class V>
1011 mpfr_float_backend(const V& o, unsigned)
1012 {
1013 *this = o;
1014 }
7c673cae
FG
1015 mpfr_float_backend& operator=(const mpfr_float_backend& o)
1016 {
1017 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o);
1018 return *this;
1019 }
1e59de90
TL
1020 // rvalue assign
1021 mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept
7c673cae
FG
1022 {
1023 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o);
1024 return *this;
1025 }
7c673cae 1026 template <class V>
1e59de90 1027 typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<digits10, AllocationType>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
7c673cae
FG
1028 {
1029 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v;
1030 return *this;
1031 }
1032 mpfr_float_backend& operator=(const mpfr_t val)
1033 {
92f5a8d4 1034 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1035 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1036 mpfr_set(this->m_data, val, GMP_RNDN);
1037 return *this;
1038 }
1039 mpfr_float_backend& operator=(const mpf_t val)
1040 {
92f5a8d4 1041 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1042 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1043 mpfr_set_f(this->m_data, val, GMP_RNDN);
1044 return *this;
1045 }
1046 mpfr_float_backend& operator=(const mpz_t val)
1047 {
92f5a8d4 1048 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1049 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1050 mpfr_set_z(this->m_data, val, GMP_RNDN);
1051 return *this;
1052 }
1053 mpfr_float_backend& operator=(const mpq_t val)
1054 {
92f5a8d4 1055 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1056 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1057 mpfr_set_q(this->m_data, val, GMP_RNDN);
1058 return *this;
1059 }
1060 // We don't change our precision here, this is a fixed precision type:
1061 template <unsigned D, mpfr_allocation_type AT>
1062 mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
1063 {
92f5a8d4 1064 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1065 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1066 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1067 return *this;
1068 }
1069 template <unsigned D>
1070 mpfr_float_backend& operator=(const gmp_float<D>& val)
1071 {
92f5a8d4 1072 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1073 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1074 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1075 return *this;
1076 }
1077 mpfr_float_backend& operator=(const gmp_int& val)
1078 {
92f5a8d4 1079 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1080 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1081 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
1082 return *this;
1083 }
1084 mpfr_float_backend& operator=(const gmp_rational& val)
1085 {
92f5a8d4 1086 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1087 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
1088 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
1089 return *this;
1090 }
1091};
1092
1093template <>
1094struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic>
1095{
1096 mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {}
1097 mpfr_float_backend(const mpfr_t val)
1e59de90 1098 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? (unsigned)mpfr_get_prec(val) : boost::multiprecision::detail::digits10_2_2(get_default_precision()))
7c673cae
FG
1099 {
1100 mpfr_set(this->m_data, val, GMP_RNDN);
1101 }
1102 mpfr_float_backend(const mpf_t val)
1e59de90 1103 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? (unsigned)mpf_get_prec(val) : boost::multiprecision::detail::digits10_2_2(get_default_precision()))
7c673cae
FG
1104 {
1105 mpfr_set_f(this->m_data, val, GMP_RNDN);
1106 }
1107 mpfr_float_backend(const mpz_t val)
92f5a8d4 1108 : detail::mpfr_float_imp<0, allocate_dynamic>()
7c673cae
FG
1109 {
1110 mpfr_set_z(this->m_data, val, GMP_RNDN);
1111 }
1112 mpfr_float_backend(const mpq_t val)
92f5a8d4 1113 : detail::mpfr_float_imp<0, allocate_dynamic>()
7c673cae
FG
1114 {
1115 mpfr_set_q(this->m_data, val, GMP_RNDN);
1116 }
1117 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {}
1e59de90
TL
1118 // rvalue copy
1119 mpfr_float_backend(mpfr_float_backend&& o) noexcept : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<detail::mpfr_float_imp<0, allocate_dynamic>&&>(o))
92f5a8d4 1120 {}
92f5a8d4
TL
1121 template <class V>
1122 mpfr_float_backend(const V& o, unsigned digits10)
1123 : detail::mpfr_float_imp<0, allocate_dynamic>(multiprecision::detail::digits10_2_2(digits10))
7c673cae
FG
1124 {
1125 *this = o;
1126 }
92f5a8d4
TL
1127#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
1128 mpfr_float_backend(const std::string_view& o, unsigned digits10)
1129 : detail::mpfr_float_imp<0, allocate_dynamic>(multiprecision::detail::digits10_2_2(digits10))
1130 {
1131 std::string s(o);
1132 *this = s.c_str();
1133 }
1134#endif
1135 template <unsigned D>
1136 mpfr_float_backend(const gmp_float<D>& val, unsigned digits10)
1137 : detail::mpfr_float_imp<0, allocate_dynamic>(multiprecision::detail::digits10_2_2(digits10))
1138 {
1139 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1140 }
1141 template <unsigned D>
1142 mpfr_float_backend(const mpfr_float_backend<D>& val, unsigned digits10)
1143 : detail::mpfr_float_imp<0, allocate_dynamic>(multiprecision::detail::digits10_2_2(digits10))
1144 {
1145 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1146 }
7c673cae
FG
1147 template <unsigned D>
1148 mpfr_float_backend(const mpfr_float_backend<D>& val)
1e59de90 1149 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_related_precision() ? (unsigned)mpfr_get_prec(val.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()))
7c673cae
FG
1150 {
1151 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1152 }
1153 template <unsigned D>
1154 mpfr_float_backend(const gmp_float<D>& val)
1e59de90 1155 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? (unsigned)mpf_get_prec(val.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()))
7c673cae
FG
1156 {
1157 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1158 }
1159 mpfr_float_backend(const gmp_int& val)
1e59de90 1160 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? used_gmp_int_bits(val) : boost::multiprecision::detail::digits10_2_2(thread_default_precision()))
7c673cae
FG
1161 {
1162 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
1163 }
1164 mpfr_float_backend(const gmp_rational& val)
1e59de90 1165 : detail::mpfr_float_imp<0, allocate_dynamic>(preserve_all_precision() ? used_gmp_rational_bits(val) : boost::multiprecision::detail::digits10_2_2(thread_default_precision()))
7c673cae
FG
1166 {
1167 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
1168 }
1169
1e59de90
TL
1170 mpfr_float_backend& operator=(const mpfr_float_backend& o) = default;
1171 // rvalue assign
1172 mpfr_float_backend& operator=(mpfr_float_backend&& o) noexcept = default;
1173
1174 template <class V>
1175 typename std::enable_if<std::is_assignable<detail::mpfr_float_imp<0, allocate_dynamic>, V>::value, mpfr_float_backend&>::type operator=(const V& v)
7c673cae 1176 {
1e59de90
TL
1177 constexpr unsigned d10 = std::is_floating_point<V>::value ?
1178 std::numeric_limits<V>::digits10 :
1179 std::numeric_limits<V>::digits10 ? 1 + std::numeric_limits<V>::digits10 :
1180 1 + boost::multiprecision::detail::digits2_2_10(std::numeric_limits<V>::digits);
1181
1182 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
7c673cae 1183 {
1e59de90
TL
1184 BOOST_IF_CONSTEXPR(std::is_floating_point<V>::value)
1185 {
1186 if (std::numeric_limits<V>::digits > mpfr_get_prec(this->data()))
1187 mpfr_set_prec(this->data(), std::numeric_limits<V>::digits);
1188 }
7c673cae 1189 else
1e59de90
TL
1190 {
1191 if(precision() < d10)
1192 this->precision(d10);
1193 }
7c673cae 1194 }
1e59de90 1195
7c673cae
FG
1196 *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v;
1197 return *this;
1198 }
1199 mpfr_float_backend& operator=(const mpfr_t val)
1200 {
92f5a8d4 1201 if (this->m_data[0]._mpfr_d == 0)
1e59de90
TL
1202 mpfr_init2(this->m_data, preserve_all_precision() ? mpfr_get_prec(val) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
1203 else if(preserve_all_precision())
7c673cae
FG
1204 mpfr_set_prec(this->m_data, mpfr_get_prec(val));
1205 mpfr_set(this->m_data, val, GMP_RNDN);
1206 return *this;
1207 }
1208 mpfr_float_backend& operator=(const mpf_t val)
1209 {
92f5a8d4 1210 if (this->m_data[0]._mpfr_d == 0)
1e59de90
TL
1211 mpfr_init2(this->m_data, preserve_all_precision() ? (mpfr_prec_t)mpf_get_prec(val) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
1212 else if(preserve_all_precision())
92f5a8d4 1213 mpfr_set_prec(this->m_data, (unsigned)mpf_get_prec(val));
7c673cae
FG
1214 mpfr_set_f(this->m_data, val, GMP_RNDN);
1215 return *this;
1216 }
1217 mpfr_float_backend& operator=(const mpz_t val)
1218 {
92f5a8d4 1219 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1220 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
1221 mpfr_set_z(this->m_data, val, GMP_RNDN);
1222 return *this;
1223 }
1224 mpfr_float_backend& operator=(const mpq_t val)
1225 {
92f5a8d4 1226 if (this->m_data[0]._mpfr_d == 0)
7c673cae
FG
1227 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
1228 mpfr_set_q(this->m_data, val, GMP_RNDN);
1229 return *this;
1230 }
1231 template <unsigned D>
1232 mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
1233 {
92f5a8d4 1234 if (this->m_data[0]._mpfr_d == 0)
1e59de90
TL
1235 mpfr_init2(this->m_data, preserve_related_precision() ? (mpfr_prec_t)mpfr_get_prec(val.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
1236 else if (preserve_related_precision())
7c673cae
FG
1237 mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
1238 mpfr_set(this->m_data, val.data(), GMP_RNDN);
1239 return *this;
1240 }
1241 template <unsigned D>
1242 mpfr_float_backend& operator=(const gmp_float<D>& val)
1243 {
92f5a8d4 1244 if (this->m_data[0]._mpfr_d == 0)
1e59de90
TL
1245 mpfr_init2(this->m_data, preserve_all_precision() ? (mpfr_prec_t)mpf_get_prec(val.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
1246 else if (preserve_all_precision())
1247 mpfr_set_prec(this->m_data, (mpfr_prec_t)mpf_get_prec(val.data()));
7c673cae
FG
1248 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
1249 return *this;
1250 }
1251 mpfr_float_backend& operator=(const gmp_int& val)
1252 {
92f5a8d4 1253 if (this->m_data[0]._mpfr_d == 0)
1e59de90
TL
1254 {
1255 unsigned requested_precision = this->thread_default_precision();
1256 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1257 {
1258 unsigned d2 = used_gmp_int_bits(val);
1259 unsigned d10 = 1 + multiprecision::detail::digits2_2_10(d2);
1260 if (d10 > requested_precision)
1261 requested_precision = d10;
1262 }
1263 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
1264 }
1265 else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1266 {
1267 unsigned requested_precision = this->thread_default_precision();
1268 unsigned d2 = used_gmp_int_bits(val);
1269 unsigned d10 = 1 + multiprecision::detail::digits2_2_10(d2);
1270 if (d10 > requested_precision)
1271 this->precision(d10);
1272 }
7c673cae
FG
1273 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
1274 return *this;
1275 }
1276 mpfr_float_backend& operator=(const gmp_rational& val)
1277 {
92f5a8d4 1278 if (this->m_data[0]._mpfr_d == 0)
1e59de90
TL
1279 {
1280 unsigned requested_precision = this->get_default_precision();
1281 if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1282 {
1283 unsigned d10 = 1 + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val));
1284 if (d10 > requested_precision)
1285 requested_precision = d10;
1286 }
1287 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
1288 }
1289 else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
1290 {
1291 unsigned requested_precision = this->get_default_precision();
1292 unsigned d10 = 1 + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(val));
1293 if (d10 > requested_precision)
1294 this->precision(d10);
1295 }
7c673cae
FG
1296 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
1297 return *this;
1298 }
1e59de90
TL
1299 static unsigned default_precision() noexcept
1300 {
1301 return get_global_default_precision();
1302 }
1303 static void default_precision(unsigned v) noexcept
1304 {
1305 get_global_default_precision() = v;
1306 }
1307 static unsigned thread_default_precision() noexcept
7c673cae
FG
1308 {
1309 return get_default_precision();
1310 }
1e59de90 1311 static void thread_default_precision(unsigned v) noexcept
7c673cae
FG
1312 {
1313 get_default_precision() = v;
1314 }
1e59de90 1315 unsigned precision() const noexcept
7c673cae
FG
1316 {
1317 return multiprecision::detail::digits2_2_10(mpfr_get_prec(this->m_data));
1318 }
1e59de90 1319 void precision(unsigned digits10) noexcept
7c673cae
FG
1320 {
1321 mpfr_prec_round(this->m_data, multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
1322 }
1e59de90
TL
1323 //
1324 // Variable precision options:
1325 //
1326 static variable_precision_options default_variable_precision_options()noexcept
1327 {
1328 return get_global_default_options();
1329 }
1330 static variable_precision_options thread_default_variable_precision_options()noexcept
1331 {
1332 return get_default_options();
1333 }
1334 static void default_variable_precision_options(variable_precision_options opts)
1335 {
1336 get_global_default_options() = opts;
1337 }
1338 static void thread_default_variable_precision_options(variable_precision_options opts)
1339 {
1340 get_default_options() = opts;
1341 }
1342 static bool preserve_source_precision()
1343 {
1344 return get_default_options() >= variable_precision_options::preserve_source_precision;
1345 }
1346 static bool preserve_related_precision()
1347 {
1348 return get_default_options() >= variable_precision_options::preserve_related_precision;
1349 }
1350 static bool preserve_all_precision()
1351 {
1352 return get_default_options() >= variable_precision_options::preserve_all_precision;
1353 }
1354};
1355
1356template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1357inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const T& b)
1358{
7c673cae
FG
1359 return a.compare(b) == 0;
1360}
1361template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1e59de90 1362inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b)
7c673cae
FG
1363{
1364 return a.compare(b) < 0;
1365}
1366template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
1e59de90 1367inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b)
7c673cae
FG
1368{
1369 return a.compare(b) > 0;
1370}
1371
1e59de90
TL
1372template <unsigned digits10, mpfr_allocation_type AllocationType>
1373inline bool eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b)noexcept
1374{
1375 return mpfr_equal_p(a.data(), b.data());
1376}
1377template <unsigned digits10, mpfr_allocation_type AllocationType>
1378inline bool eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
1379{
1380 return mpfr_less_p(a.data(), b.data());
1381}
1382template <unsigned digits10, mpfr_allocation_type AllocationType>
1383inline bool eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const mpfr_float_backend<digits10, AllocationType>& b) noexcept
1384{
1385 return mpfr_greater_p(a.data(), b.data());
1386}
1387
7c673cae
FG
1388template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1389inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1390{
1391 mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
1392}
1393template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1394inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1395{
1396 mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
1397}
1398template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1399inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1400{
92f5a8d4 1401 if ((void*)&o == (void*)&result)
7c673cae
FG
1402 mpfr_sqr(result.data(), o.data(), GMP_RNDN);
1403 else
1404 mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
1405}
1406template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1407inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
1408{
1409 mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
1410}
1411template <unsigned digits10, mpfr_allocation_type AllocationType>
1412inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1413{
1414 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
1415}
1416template <unsigned digits10, mpfr_allocation_type AllocationType>
1417inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1418{
1419 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
1420}
1421template <unsigned digits10, mpfr_allocation_type AllocationType>
1422inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1423{
1424 mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
1425}
1426template <unsigned digits10, mpfr_allocation_type AllocationType>
1427inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1428{
1429 mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
1430}
1431template <unsigned digits10, mpfr_allocation_type AllocationType>
1432inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i)
1433{
92f5a8d4 1434 if (i > 0)
7c673cae
FG
1435 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
1436 else
1437 mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1438}
1439template <unsigned digits10, mpfr_allocation_type AllocationType>
1440inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i)
1441{
92f5a8d4 1442 if (i > 0)
7c673cae
FG
1443 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
1444 else
1445 mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1446}
1447template <unsigned digits10, mpfr_allocation_type AllocationType>
1448inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i)
1449{
1450 mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
92f5a8d4 1451 if (i < 0)
7c673cae
FG
1452 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1453}
1454template <unsigned digits10, mpfr_allocation_type AllocationType>
1455inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i)
1456{
1457 mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
92f5a8d4 1458 if (i < 0)
7c673cae
FG
1459 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1460}
1461//
1462// Specialised 3 arg versions of the basic operators:
1463//
1e59de90
TL
1464template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1465inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
7c673cae
FG
1466{
1467 mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
1468}
1469template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1470inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1471{
1472 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1473}
1474template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1475inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1476{
92f5a8d4 1477 if (y < 0)
7c673cae
FG
1478 mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1479 else
1480 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1481}
1482template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1483inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1484{
1485 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1486}
1487template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1488inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1489{
92f5a8d4 1490 if (x < 0)
7c673cae
FG
1491 {
1492 mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1493 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1494 }
1495 else
1496 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1497}
1e59de90
TL
1498template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1499inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
7c673cae
FG
1500{
1501 mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
1502}
1503template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1504inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1505{
1506 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1507}
1508template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1509inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1510{
92f5a8d4 1511 if (y < 0)
7c673cae
FG
1512 mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1513 else
1514 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1515}
1516template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1517inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1518{
1519 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1520}
1521template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1522inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1523{
92f5a8d4 1524 if (x < 0)
7c673cae
FG
1525 {
1526 mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1527 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1528 }
1529 else
1530 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1531}
1532
1e59de90
TL
1533template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1534inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
7c673cae 1535{
92f5a8d4 1536 if ((void*)&x == (void*)&y)
7c673cae
FG
1537 mpfr_sqr(a.data(), x.data(), GMP_RNDN);
1538 else
1539 mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
1540}
1541template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1542inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1543{
1544 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1545}
1546template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1547inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1548{
92f5a8d4 1549 if (y < 0)
7c673cae
FG
1550 {
1551 mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1552 a.negate();
1553 }
1554 else
1555 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1556}
1557template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1558inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1559{
1560 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1561}
1562template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1563inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1564{
92f5a8d4 1565 if (x < 0)
7c673cae
FG
1566 {
1567 mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1568 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1569 }
1570 else
1571 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1572}
1573
1e59de90
TL
1574template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3, mpfr_allocation_type A3>
1575inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3, A3>& y)
7c673cae
FG
1576{
1577 mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
1578}
1579template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1580inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1581{
1582 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1583}
1584template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1585inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1586{
92f5a8d4 1587 if (y < 0)
7c673cae
FG
1588 {
1589 mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1590 a.negate();
1591 }
1592 else
1593 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1594}
1595template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1596inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1597{
1598 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1599}
1600template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1601inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1602{
92f5a8d4 1603 if (x < 0)
7c673cae
FG
1604 {
1605 mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1606 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1607 }
1608 else
1609 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1610}
1611
1612template <unsigned digits10, mpfr_allocation_type AllocationType>
1e59de90 1613inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
7c673cae
FG
1614{
1615 return 0 != mpfr_zero_p(val.data());
1616}
1617template <unsigned digits10, mpfr_allocation_type AllocationType>
1e59de90 1618inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) noexcept
7c673cae
FG
1619{
1620 return mpfr_sgn(val.data());
1621}
1622
1623template <unsigned digits10, mpfr_allocation_type AllocationType>
1624inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1625{
92f5a8d4 1626 if (mpfr_nan_p(val.data()))
7c673cae 1627 {
1e59de90 1628 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
7c673cae
FG
1629 }
1630 *result = mpfr_get_ui(val.data(), GMP_RNDZ);
1631}
1632template <unsigned digits10, mpfr_allocation_type AllocationType>
1633inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1634{
92f5a8d4 1635 if (mpfr_nan_p(val.data()))
7c673cae 1636 {
1e59de90 1637 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
7c673cae
FG
1638 }
1639 *result = mpfr_get_si(val.data(), GMP_RNDZ);
1640}
1641#ifdef _MPFR_H_HAVE_INTMAX_T
1642template <unsigned digits10, mpfr_allocation_type AllocationType>
1e59de90 1643inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
7c673cae 1644{
92f5a8d4 1645 if (mpfr_nan_p(val.data()))
7c673cae 1646 {
1e59de90 1647 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
7c673cae
FG
1648 }
1649 *result = mpfr_get_uj(val.data(), GMP_RNDZ);
1650}
1651template <unsigned digits10, mpfr_allocation_type AllocationType>
1e59de90 1652inline void eval_convert_to(long long* result, const mpfr_float_backend<digits10, AllocationType>& val)
7c673cae 1653{
92f5a8d4 1654 if (mpfr_nan_p(val.data()))
7c673cae 1655 {
1e59de90 1656 BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
7c673cae
FG
1657 }
1658 *result = mpfr_get_sj(val.data(), GMP_RNDZ);
1659}
1660#endif
1661template <unsigned digits10, mpfr_allocation_type AllocationType>
1e59de90 1662inline void eval_convert_to(float* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
7c673cae
FG
1663{
1664 *result = mpfr_get_flt(val.data(), GMP_RNDN);
1665}
1666template <unsigned digits10, mpfr_allocation_type AllocationType>
1e59de90 1667inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
7c673cae
FG
1668{
1669 *result = mpfr_get_d(val.data(), GMP_RNDN);
1670}
1671template <unsigned digits10, mpfr_allocation_type AllocationType>
1e59de90 1672inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
7c673cae
FG
1673{
1674 *result = mpfr_get_ld(val.data(), GMP_RNDN);
1675}
1676
1e59de90
TL
1677#ifdef BOOST_HAS_INT128
1678template <unsigned digits10, mpfr_allocation_type AllocationType>
1679inline void eval_convert_to(int128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1680{
1681 gmp_int i;
1682 mpfr_get_z(i.data(), val.data(), GMP_RNDN);
1683 eval_convert_to(result, i);
1684}
1685template <unsigned digits10, mpfr_allocation_type AllocationType>
1686inline void eval_convert_to(uint128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1687{
1688 gmp_int i;
1689 mpfr_get_z(i.data(), val.data(), GMP_RNDN);
1690 eval_convert_to(result, i);
1691}
1692#endif
1693#if defined(BOOST_HAS_FLOAT128)
1694template <unsigned digits10, mpfr_allocation_type AllocationType>
1695inline void eval_convert_to(float128_type* result, const mpfr_float_backend<digits10, AllocationType>& val) noexcept
1696{
1697 *result = float128_procs::strtoflt128(val.str(0, std::ios_base::scientific).c_str(), nullptr);
1698}
1699#endif
1700
7c673cae
FG
1701//
1702// Native non-member operations:
1703//
1704template <unsigned Digits10, mpfr_allocation_type AllocateType>
1705inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1706{
1707 mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
1708}
1709
1710template <unsigned Digits10, mpfr_allocation_type AllocateType>
1711inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1712{
1713 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1714}
1715
1716template <unsigned Digits10, mpfr_allocation_type AllocateType>
1717inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1718{
1719 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1720}
1721template <unsigned Digits10, mpfr_allocation_type AllocateType>
1722inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1723{
1724 mpfr_ceil(result.data(), val.data());
1725}
1726template <unsigned Digits10, mpfr_allocation_type AllocateType>
1727inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1728{
1729 mpfr_floor(result.data(), val.data());
1730}
1731template <unsigned Digits10, mpfr_allocation_type AllocateType>
1732inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1733{
7c673cae
FG
1734 mpfr_trunc(result.data(), val.data());
1735}
1736template <unsigned Digits10, mpfr_allocation_type AllocateType>
1737inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e)
1738{
92f5a8d4 1739 if (e > 0)
7c673cae 1740 mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN);
92f5a8d4 1741 else if (e < 0)
7c673cae
FG
1742 mpfr_div_2exp(result.data(), val.data(), -e, GMP_RNDN);
1743 else
1744 result = val;
1745}
1746template <unsigned Digits10, mpfr_allocation_type AllocateType>
1747inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
1748{
20effc67
TL
1749 if (mpfr_zero_p(val.data()))
1750 {
1751 *e = 0;
1752 result = val;
1753 return;
1754 }
1755 mp_exp_t v = mpfr_get_exp(val.data());
7c673cae 1756 *e = v;
20effc67
TL
1757 if (v)
1758 eval_ldexp(result, val, -v);
1759 else
1760 result = val;
7c673cae
FG
1761}
1762template <unsigned Digits10, mpfr_allocation_type AllocateType>
1763inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
1764{
20effc67
TL
1765 if (mpfr_zero_p(val.data()))
1766 {
1767 *e = 0;
1768 result = val;
1769 return;
1770 }
1771 mp_exp_t v = mpfr_get_exp(val.data());
1772 *e = v;
1773 if(v)
1774 eval_ldexp(result, val, -v);
1775 else
1776 result = val;
7c673cae
FG
1777}
1778
1779template <unsigned Digits10, mpfr_allocation_type AllocateType>
1e59de90 1780inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) noexcept
7c673cae
FG
1781{
1782 return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
1783}
1784
1785template <unsigned Digits10, mpfr_allocation_type AllocateType>
1786inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e)
1787{
92f5a8d4 1788 if (mpfr_zero_p(b.data()) && mpfr_integer_p(e.data()) && (mpfr_signbit(e.data()) == 0) && mpfr_fits_ulong_p(e.data(), GMP_RNDN) && (mpfr_get_ui(e.data(), GMP_RNDN) & 1))
b32b8144
FG
1789 {
1790 mpfr_set(result.data(), b.data(), GMP_RNDN);
1791 }
1792 else
1793 mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
7c673cae
FG
1794}
1795
1796#ifdef BOOST_MSVC
1797//
1798// The enable_if usage below doesn't work with msvc - but only when
1799// certain other enable_if usages are defined first. It's a capricious
1800// and rather annoying compiler bug in other words....
1801//
92f5a8d4 1802#define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10)&&
7c673cae
FG
1803#else
1804#define BOOST_MP_ENABLE_IF_WORKAROUND
1805#endif
1806
1807template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1e59de90 1808inline typename std::enable_if<boost::multiprecision::detail::is_signed<Integer>::value && boost::multiprecision::detail::is_integral<Integer>::value && (BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long)))>::type
92f5a8d4 1809eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
7c673cae
FG
1810{
1811 mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
1812}
1813
1814template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1e59de90 1815inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer>::value && (BOOST_MP_ENABLE_IF_WORKAROUND(sizeof(Integer) <= sizeof(long)))>::type
92f5a8d4 1816eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
7c673cae
FG
1817{
1818 mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
1819}
1820
1821#undef BOOST_MP_ENABLE_IF_WORKAROUND
1822
1823template <unsigned Digits10, mpfr_allocation_type AllocateType>
1824inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1825{
1826 mpfr_exp(result.data(), arg.data(), GMP_RNDN);
1827}
1828
1829template <unsigned Digits10, mpfr_allocation_type AllocateType>
1830inline void eval_exp2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1831{
1832 mpfr_exp2(result.data(), arg.data(), GMP_RNDN);
1833}
1834
1835template <unsigned Digits10, mpfr_allocation_type AllocateType>
1836inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1837{
1838 mpfr_log(result.data(), arg.data(), GMP_RNDN);
1839}
1840
1841template <unsigned Digits10, mpfr_allocation_type AllocateType>
1842inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1843{
1844 mpfr_log10(result.data(), arg.data(), GMP_RNDN);
1845}
1846
1847template <unsigned Digits10, mpfr_allocation_type AllocateType>
1848inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1849{
1850 mpfr_sin(result.data(), arg.data(), GMP_RNDN);
1851}
1852
1853template <unsigned Digits10, mpfr_allocation_type AllocateType>
1854inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1855{
1856 mpfr_cos(result.data(), arg.data(), GMP_RNDN);
1857}
1858
1859template <unsigned Digits10, mpfr_allocation_type AllocateType>
1860inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1861{
1862 mpfr_tan(result.data(), arg.data(), GMP_RNDN);
1863}
1864
1865template <unsigned Digits10, mpfr_allocation_type AllocateType>
1866inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1867{
1868 mpfr_asin(result.data(), arg.data(), GMP_RNDN);
1869}
1870
1871template <unsigned Digits10, mpfr_allocation_type AllocateType>
1872inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1873{
1874 mpfr_acos(result.data(), arg.data(), GMP_RNDN);
1875}
1876
1877template <unsigned Digits10, mpfr_allocation_type AllocateType>
1878inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1879{
1880 mpfr_atan(result.data(), arg.data(), GMP_RNDN);
1881}
1882
1883template <unsigned Digits10, mpfr_allocation_type AllocateType>
1884inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2)
1885{
1886 mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN);
1887}
1888
1889template <unsigned Digits10, mpfr_allocation_type AllocateType>
1890inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1891{
1892 mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
1893}
1894
1895template <unsigned Digits10, mpfr_allocation_type AllocateType>
1896inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1897{
1898 mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
1899}
1900
1901template <unsigned Digits10, mpfr_allocation_type AllocateType>
1902inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1903{
1904 mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
1905}
1906
1907template <unsigned Digits10, mpfr_allocation_type AllocateType>
1908inline void eval_log2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1909{
1910 mpfr_log2(result.data(), arg.data(), GMP_RNDN);
1911}
1912
1913template <unsigned Digits10, mpfr_allocation_type AllocateType>
1914inline void eval_modf(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg, mpfr_float_backend<Digits10, AllocateType>* pipart)
1915{
92f5a8d4 1916 if (0 == pipart)
7c673cae
FG
1917 {
1918 mpfr_float_backend<Digits10, AllocateType> ipart;
1919 mpfr_modf(ipart.data(), result.data(), arg.data(), GMP_RNDN);
1920 }
1921 else
1922 {
1923 mpfr_modf(pipart->data(), result.data(), arg.data(), GMP_RNDN);
1924 }
1925}
1926template <unsigned Digits10, mpfr_allocation_type AllocateType>
1927inline void eval_remainder(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1928{
1929 mpfr_remainder(result.data(), a.data(), b.data(), GMP_RNDN);
1930}
1931template <unsigned Digits10, mpfr_allocation_type AllocateType>
1932inline void eval_remquo(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, int* pi)
1933{
1934 long l;
1935 mpfr_remquo(result.data(), &l, a.data(), b.data(), GMP_RNDN);
92f5a8d4
TL
1936 if (pi)
1937 *pi = l;
7c673cae
FG
1938}
1939
1940template <unsigned Digits10, mpfr_allocation_type AllocateType>
1941inline void eval_fmod(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1942{
1943 mpfr_fmod(result.data(), a.data(), b.data(), GMP_RNDN);
1944}
1945
1946template <unsigned Digits10, mpfr_allocation_type AllocateType>
1947inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1948{
1949 mpfr_fma(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1950}
1951
1952template <unsigned Digits10, mpfr_allocation_type AllocateType>
1953inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
1954{
1955 mpfr_fma(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1956}
1957
1958template <unsigned Digits10, mpfr_allocation_type AllocateType>
1959inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1960{
1961 mpfr_fms(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1962 result.negate();
1963}
1964
1965template <unsigned Digits10, mpfr_allocation_type AllocateType>
1966inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
1967{
1968 mpfr_fms(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1969}
1970
b32b8144
FG
1971template <unsigned Digits10, mpfr_allocation_type AllocateType>
1972inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const mpfr_float_backend<Digits10, AllocateType>& arg)
1973{
1974 return (arg.data()[0]._mpfr_sign < 0) ? 1 : 0;
1975}
1976
7c673cae
FG
1977template <unsigned Digits10, mpfr_allocation_type AllocateType>
1978inline std::size_t hash_value(const mpfr_float_backend<Digits10, AllocateType>& val)
1979{
1980 std::size_t result = 0;
92f5a8d4
TL
1981 std::size_t len = val.data()[0]._mpfr_prec / mp_bits_per_limb;
1982 if (val.data()[0]._mpfr_prec % mp_bits_per_limb)
7c673cae 1983 ++len;
92f5a8d4 1984 for (std::size_t i = 0; i < len; ++i)
1e59de90
TL
1985 boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_d[i]);
1986 boost::multiprecision::detail::hash_combine(result, val.data()[0]._mpfr_exp, val.data()[0]._mpfr_sign);
7c673cae
FG
1987 return result;
1988}
1989
1990} // namespace backends
1991
92f5a8d4
TL
1992namespace detail {
1993template <>
1e59de90 1994struct is_variable_precision<backends::mpfr_float_backend<0> > : public std::integral_constant<bool, true>
92f5a8d4
TL
1995{};
1996} // namespace detail
1997
1998template <>
1e59de90 1999struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public std::integral_constant<int, number_kind_floating_point>
92f5a8d4 2000{};
7c673cae 2001
1e59de90
TL
2002template <unsigned D, boost::multiprecision::mpfr_allocation_type A1, boost::multiprecision::mpfr_allocation_type A2>
2003struct is_equivalent_number_type<backends::mpfr_float_backend<D, A1>, backends::mpfr_float_backend<D, A2> > : public std::integral_constant<bool, true> {};
2004
7c673cae
FG
2005using boost::multiprecision::backends::mpfr_float_backend;
2006
1e59de90
TL
2007using mpfr_float_50 = number<mpfr_float_backend<50> > ;
2008using mpfr_float_100 = number<mpfr_float_backend<100> > ;
2009using mpfr_float_500 = number<mpfr_float_backend<500> > ;
2010using mpfr_float_1000 = number<mpfr_float_backend<1000> >;
2011using mpfr_float = number<mpfr_float_backend<0> > ;
7c673cae 2012
1e59de90
TL
2013using static_mpfr_float_50 = number<mpfr_float_backend<50, allocate_stack> > ;
2014using static_mpfr_float_100 = number<mpfr_float_backend<100, allocate_stack> >;
7c673cae 2015
92f5a8d4 2016template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
7c673cae
FG
2017inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& b)
2018{
2019 return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(-a) : a;
2020}
2021
92f5a8d4 2022template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
7c673cae
FG
2023inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& b)
2024{
2025 return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>(-a) : a;
2026}
2027
2028} // namespace multiprecision
2029
92f5a8d4 2030namespace math {
7c673cae 2031
92f5a8d4
TL
2032using boost::multiprecision::copysign;
2033using boost::multiprecision::signbit;
7c673cae 2034
92f5a8d4 2035namespace tools {
7c673cae 2036
1e59de90
TL
2037#ifndef BOOST_MP_MATH_AVAILABLE
2038
2039template <typename T>
2040inline int digits();
2041
2042template <typename T>
2043inline T max_value();
2044
2045template <typename T>
2046inline T min_value();
2047
2048#endif
2049
20effc67
TL
2050inline void set_output_precision(const boost::multiprecision::mpfr_float& val, std::ostream& os)
2051{
2052 os << std::setprecision(val.precision());
2053}
2054
7c673cae
FG
2055template <>
2056inline int digits<boost::multiprecision::mpfr_float>()
2057#ifdef BOOST_MATH_NOEXCEPT
1e59de90 2058 noexcept
7c673cae
FG
2059#endif
2060{
1e59de90 2061 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision());
7c673cae
FG
2062}
2063template <>
2064inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
2065#ifdef BOOST_MATH_NOEXCEPT
1e59de90 2066 noexcept
7c673cae
FG
2067#endif
2068{
1e59de90 2069 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::thread_default_precision());
7c673cae
FG
2070}
2071
2072template <>
2073inline boost::multiprecision::mpfr_float
92f5a8d4 2074max_value<boost::multiprecision::mpfr_float>()
7c673cae
FG
2075{
2076 boost::multiprecision::mpfr_float result(0.5);
2077 mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
1e59de90 2078 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
7c673cae
FG
2079 return result;
2080}
2081
2082template <>
2083inline boost::multiprecision::mpfr_float
92f5a8d4 2084min_value<boost::multiprecision::mpfr_float>()
7c673cae
FG
2085{
2086 boost::multiprecision::mpfr_float result(0.5);
2087 mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
1e59de90 2088 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
7c673cae
FG
2089 return result;
2090}
2091
2092template <>
92f5a8d4
TL
2093inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
2094max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
7c673cae
FG
2095{
2096 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
2097 mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
1e59de90 2098 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
7c673cae
FG
2099 return result;
2100}
2101
2102template <>
2103inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
92f5a8d4 2104min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
7c673cae
FG
2105{
2106 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
2107 mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
1e59de90 2108 BOOST_MP_ASSERT(mpfr_number_p(result.backend().data()));
7c673cae
FG
2109 return result;
2110}
1e59de90
TL
2111//
2112// Over again with debug_adaptor:
2113//
7c673cae
FG
2114template <>
2115inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2116#ifdef BOOST_MATH_NOEXCEPT
1e59de90 2117 noexcept
7c673cae
FG
2118#endif
2119{
1e59de90 2120 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::thread_default_precision());
7c673cae
FG
2121}
2122template <>
2123inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2124#ifdef BOOST_MATH_NOEXCEPT
1e59de90 2125 noexcept
7c673cae
FG
2126#endif
2127{
1e59de90 2128 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::thread_default_precision());
7c673cae
FG
2129}
2130
2131template <>
2132inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2133max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2134{
2135 return max_value<boost::multiprecision::mpfr_float>().backend();
2136}
2137
2138template <>
2139inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2140min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2141{
2142 return min_value<boost::multiprecision::mpfr_float>().backend();
2143}
2144
2145template <>
2146inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2147max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2148{
2149 return max_value<boost::multiprecision::mpfr_float>().backend();
2150}
2151
2152template <>
2153inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2154min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2155{
2156 return min_value<boost::multiprecision::mpfr_float>().backend();
2157}
2158
1e59de90
TL
2159//
2160// Over again with logged_adaptor:
2161//
2162template <>
2163inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2164#ifdef BOOST_MATH_NOEXCEPT
2165 noexcept
2166#endif
2167{
2168 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision());
2169}
2170template <>
2171inline int digits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2172#ifdef BOOST_MATH_NOEXCEPT
2173 noexcept
2174#endif
2175{
2176 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision());
2177}
2178
2179template <>
2180inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2181max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2182{
2183 return max_value<boost::multiprecision::mpfr_float>().backend();
2184}
2185
2186template <>
2187inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> >
2188min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
2189{
2190 return min_value<boost::multiprecision::mpfr_float>().backend();
2191}
2192
2193template <>
2194inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2195max_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2196{
2197 return max_value<boost::multiprecision::mpfr_float>().backend();
2198}
2199
2200template <>
2201inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
2202min_value<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
2203{
2204 return min_value<boost::multiprecision::mpfr_float>().backend();
2205}
2206
7c673cae
FG
2207} // namespace tools
2208
92f5a8d4 2209namespace constants { namespace detail {
7c673cae 2210
92f5a8d4
TL
2211template <class T>
2212struct constant_pi;
2213template <class T>
2214struct constant_ln_two;
2215template <class T>
2216struct constant_euler;
2217template <class T>
2218struct constant_catalan;
7c673cae 2219
92f5a8d4 2220template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
7c673cae
FG
2221struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2222{
1e59de90 2223 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
92f5a8d4 2224 template <int N>
1e59de90 2225 static inline const result_type& get(const std::integral_constant<int, N>&)
7c673cae 2226 {
1e59de90
TL
2227 // Rely on C++11 thread safe initialization:
2228 static result_type result{get(std::integral_constant<int, 0>())};
7c673cae
FG
2229 return result;
2230 }
1e59de90 2231 static inline const result_type get(const std::integral_constant<int, 0>&)
7c673cae
FG
2232 {
2233 result_type result;
2234 mpfr_const_pi(result.backend().data(), GMP_RNDN);
2235 return result;
2236 }
2237};
92f5a8d4 2238template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
7c673cae
FG
2239struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2240{
1e59de90 2241 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
92f5a8d4 2242 template <int N>
1e59de90 2243 static inline const result_type& get(const std::integral_constant<int, N>&)
7c673cae 2244 {
1e59de90
TL
2245 // Rely on C++11 thread safe initialization:
2246 static result_type result{get(std::integral_constant<int, 0>())};
7c673cae
FG
2247 return result;
2248 }
1e59de90 2249 static inline const result_type get(const std::integral_constant<int, 0>&)
7c673cae
FG
2250 {
2251 result_type result;
2252 mpfr_const_log2(result.backend().data(), GMP_RNDN);
2253 return result;
2254 }
2255};
92f5a8d4 2256template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
7c673cae
FG
2257struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2258{
1e59de90 2259 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
92f5a8d4 2260 template <int N>
1e59de90 2261 static inline const result_type& get(const std::integral_constant<int, N>&)
7c673cae 2262 {
1e59de90
TL
2263 // Rely on C++11 thread safe initialization:
2264 static result_type result{get(std::integral_constant<int, 0>())};
7c673cae
FG
2265 return result;
2266 }
1e59de90 2267 static inline const result_type get(const std::integral_constant<int, 0>&)
7c673cae
FG
2268 {
2269 result_type result;
2270 mpfr_const_euler(result.backend().data(), GMP_RNDN);
2271 return result;
2272 }
2273};
92f5a8d4 2274template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
7c673cae
FG
2275struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2276{
1e59de90 2277 using result_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
92f5a8d4 2278 template <int N>
1e59de90 2279 static inline const result_type& get(const std::integral_constant<int, N>&)
7c673cae 2280 {
1e59de90
TL
2281 // Rely on C++11 thread safe initialization:
2282 static result_type result{get(std::integral_constant<int, 0>())};
7c673cae
FG
2283 return result;
2284 }
1e59de90 2285 static inline const result_type get(const std::integral_constant<int, 0>&)
7c673cae
FG
2286 {
2287 result_type result;
2288 mpfr_const_catalan(result.backend().data(), GMP_RNDN);
2289 return result;
2290 }
2291};
1e59de90
TL
2292//
2293// Over again with debug_adaptor:
2294//
92f5a8d4 2295template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
7c673cae
FG
2296struct constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2297{
1e59de90
TL
2298 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2299 template <int N>
2300 static inline const result_type& get(const std::integral_constant<int, N>&)
2301 {
2302 // Rely on C++11 thread safe initialization:
2303 static result_type result{get(std::integral_constant<int, 0>())};
2304 return result;
2305 }
2306 static inline const result_type get(const std::integral_constant<int, 0>&)
2307 {
2308 result_type result;
2309 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
2310 result.backend().update_view();
2311 return result;
2312 }
2313};
2314template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2315struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2316{
2317 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2318 template <int N>
2319 static inline const result_type& get(const std::integral_constant<int, N>&)
2320 {
2321 // Rely on C++11 thread safe initialization:
2322 static result_type result{get(std::integral_constant<int, 0>())};
2323 return result;
2324 }
2325 static inline const result_type get(const std::integral_constant<int, 0>&)
2326 {
2327 result_type result;
2328 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
2329 result.backend().update_view();
2330 return result;
2331 }
2332};
2333template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2334struct constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2335{
2336 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2337 template <int N>
2338 static inline const result_type& get(const std::integral_constant<int, N>&)
2339 {
2340 // Rely on C++11 thread safe initialization:
2341 static result_type result{get(std::integral_constant<int, 0>())};
2342 return result;
2343 }
2344 static inline const result_type get(const std::integral_constant<int, 0>&)
2345 {
2346 result_type result;
2347 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
2348 result.backend().update_view();
2349 return result;
2350 }
2351};
2352template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2353struct constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2354{
2355 using result_type = boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
2356 template <int N>
2357 static inline const result_type& get(const std::integral_constant<int, N>&)
2358 {
2359 // Rely on C++11 thread safe initialization:
2360 static result_type result{get(std::integral_constant<int, 0>())};
2361 return result;
2362 }
2363 static inline const result_type get(const std::integral_constant<int, 0>&)
2364 {
2365 result_type result;
2366 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
2367 result.backend().update_view();
2368 return result;
2369 }
2370};
2371
2372//
2373// Over again with logged_adaptor:
2374//
2375template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2376struct constant_pi<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
2377{
2378 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
92f5a8d4 2379 template <int N>
1e59de90 2380 static inline const result_type& get(const std::integral_constant<int, N>&)
7c673cae 2381 {
7c673cae 2382 static result_type result;
92f5a8d4
TL
2383 static bool has_init = false;
2384 if (!has_init)
7c673cae
FG
2385 {
2386 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
2387 has_init = true;
2388 }
2389 return result;
2390 }
1e59de90 2391 static inline const result_type get(const std::integral_constant<int, 0>&)
7c673cae
FG
2392 {
2393 result_type result;
2394 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
2395 return result;
2396 }
2397};
92f5a8d4 2398template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 2399struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
7c673cae 2400{
1e59de90 2401 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
92f5a8d4 2402 template <int N>
1e59de90 2403 static inline const result_type& get(const std::integral_constant<int, N>&)
7c673cae 2404 {
7c673cae 2405 static result_type result;
92f5a8d4
TL
2406 static bool init = false;
2407 if (!init)
7c673cae
FG
2408 {
2409 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
2410 init = true;
2411 }
2412 return result;
2413 }
1e59de90 2414 static inline const result_type get(const std::integral_constant<int, 0>&)
7c673cae
FG
2415 {
2416 result_type result;
2417 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
2418 return result;
2419 }
2420};
92f5a8d4 2421template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 2422struct constant_euler<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
7c673cae 2423{
1e59de90 2424 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
92f5a8d4 2425 template <int N>
1e59de90 2426 static inline const result_type& get(const std::integral_constant<int, N>&)
7c673cae 2427 {
7c673cae 2428 static result_type result;
92f5a8d4
TL
2429 static bool init = false;
2430 if (!init)
7c673cae
FG
2431 {
2432 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
2433 init = true;
2434 }
2435 return result;
2436 }
1e59de90 2437 static inline const result_type get(const std::integral_constant<int, 0>&)
7c673cae
FG
2438 {
2439 result_type result;
2440 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
2441 return result;
2442 }
2443};
92f5a8d4 2444template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 2445struct constant_catalan<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
7c673cae 2446{
1e59de90 2447 using result_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>;
92f5a8d4 2448 template <int N>
1e59de90 2449 static inline const result_type& get(const std::integral_constant<int, N>&)
7c673cae 2450 {
7c673cae 2451 static result_type result;
92f5a8d4
TL
2452 static bool init = false;
2453 if (!init)
7c673cae
FG
2454 {
2455 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
2456 init = true;
2457 }
2458 return result;
2459 }
1e59de90 2460 static inline const result_type get(const std::integral_constant<int, 0>&)
7c673cae
FG
2461 {
2462 result_type result;
2463 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
2464 return result;
2465 }
2466};
2467
92f5a8d4 2468}} // namespace constants::detail
7c673cae 2469
92f5a8d4 2470} // namespace math
7c673cae
FG
2471
2472namespace multiprecision {
92f5a8d4
TL
2473//
2474// Overloaded special functions which call native mpfr routines:
2475//
2476template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2477inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2478{
2479 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2480
2481 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2482 mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2483 return result;
2484}
2485template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2486inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2487{
2488 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2489
2490 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2491 mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2492 return result;
2493}
2494template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2495inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2496{
2497 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2498
2499 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2500 mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2501 return result;
2502}
2503template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2504inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2505{
2506 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2507
2508 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2509 mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2510 return result;
2511}
2512template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2513inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2514{
2515 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2516
2517 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2518 mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
2519 return result;
2520}
2521template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2522inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2523{
2524 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2525
2526 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2527 mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
2528 return result;
2529}
2530template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2531inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2532{
2533 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2534
2535 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2536 mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
2537 return result;
2538}
2539template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2540inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2541{
2542 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2543
2544 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2545 mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2546 return result;
2547}
2548template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2549inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2550{
2551 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2552
2553 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2554 mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2555 return result;
2556}
2557template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2558inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2559{
2560 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2561
2562 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2563 mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
2564 return result;
2565}
2566
92f5a8d4 2567//
1e59de90 2568// Over again with debug_adaptor:
92f5a8d4 2569//
1e59de90
TL
2570template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2571inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
92f5a8d4 2572{
1e59de90 2573 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
92f5a8d4 2574
1e59de90
TL
2575 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2576 mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2577 result.backend().update_view();
92f5a8d4
TL
2578 return result;
2579}
2580template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 2581inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
92f5a8d4 2582{
1e59de90 2583 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
92f5a8d4 2584
1e59de90
TL
2585 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2586 mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2587 result.backend().update_view();
2588 return result;
2589}
2590template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2591inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
92f5a8d4 2592{
1e59de90 2593 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
92f5a8d4 2594
1e59de90
TL
2595 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2596 mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2597 result.backend().update_view();
92f5a8d4
TL
2598 return result;
2599}
2600template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 2601inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
92f5a8d4 2602{
1e59de90 2603 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
92f5a8d4 2604
1e59de90
TL
2605 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2606 mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2607 result.backend().update_view();
2608 return result;
2609}
2610template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2611inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
92f5a8d4 2612{
1e59de90 2613 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
92f5a8d4 2614
1e59de90
TL
2615 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2616 mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2617 result.backend().update_view();
92f5a8d4
TL
2618 return result;
2619}
2620template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 2621inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
92f5a8d4 2622{
1e59de90 2623 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
92f5a8d4 2624
1e59de90
TL
2625 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2626 mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2627 result.backend().update_view();
2628 return result;
2629}
2630template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2631inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
92f5a8d4 2632{
1e59de90 2633 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
92f5a8d4 2634
1e59de90
TL
2635 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2636 mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2637 result.backend().update_view();
92f5a8d4
TL
2638 return result;
2639}
2640template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90
TL
2641inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2642{
2643 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2644
2645 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2646 mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2647 result.backend().update_view();
2648 return result;
2649}
2650template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2651inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2652{
2653 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2654
2655 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2656 mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2657 result.backend().update_view();
2658 return result;
2659}
2660template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2661inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2662{
2663 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2664
2665 boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2666 mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2667 result.backend().update_view();
2668 return result;
2669}
2670
2671//
2672// Over again with logged_adaptor:
2673//
2674template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2675inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2676{
2677 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2678
2679 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2680 mpfr_asinh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2681 return result;
2682}
2683template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2684inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2685{
2686 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2687
2688 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2689 mpfr_acosh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2690 return result;
2691}
2692template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2693inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2694{
2695 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2696
2697 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2698 mpfr_atanh(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2699 return result;
2700}
2701template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2702inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2703{
2704 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2705
2706 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2707 mpfr_cbrt(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2708 return result;
2709}
2710template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2711inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2712{
2713 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2714
2715 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2716 mpfr_erf(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2717 return result;
2718}
2719template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2720inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2721{
2722 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2723
2724 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2725 mpfr_erfc(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2726 return result;
2727}
2728template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2729inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2730{
2731 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2732
2733 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2734 mpfr_expm1(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2735 return result;
2736}
2737template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2738inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2739{
2740 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2741
2742 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2743 mpfr_lngamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2744 return result;
2745}
2746template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2747inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2748{
2749 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2750
2751 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2752 mpfr_gamma(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2753 return result;
2754}
2755template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2756inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
2757{
2758 boost::multiprecision::detail::scoped_default_precision<number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> > precision_guard(arg);
2759
2760 boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result;
2761 mpfr_log1p(result.backend().value().data(), arg.backend().value().data(), GMP_RNDN);
2762 return result;
2763}
2764
2765} // namespace multiprecision
2766
2767namespace math {
2768//
2769// Overloaded special functions which call native mpfr routines:
2770//
2771template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2772inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
2773{
2774 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2775
2776 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2777 mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2778 if (mpfr_inf_p(result.backend().data()))
2779 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("asinh<%1%>(%1%)", 0, Policy());
2780 if (mpfr_nan_p(result.backend().data()))
2781 return policies::raise_evaluation_error("asinh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2782 return result;
2783}
2784template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2785inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2786{
2787 return asinh(arg, policies::policy<>());
2788}
2789
2790template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2791inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
2792{
2793 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2794
2795 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2796 mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2797 if (mpfr_inf_p(result.backend().data()))
2798 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("acosh<%1%>(%1%)", 0, Policy());
2799 if (mpfr_nan_p(result.backend().data()))
2800 return policies::raise_evaluation_error("acosh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2801 return result;
2802}
2803template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2804inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2805{
2806 return acosh(arg, policies::policy<>());
2807}
2808
2809template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2810inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& )
2811{
2812 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2813
2814 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2815 mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
2816 if (mpfr_inf_p(result.backend().data()))
2817 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("atanh<%1%>(%1%)", 0, Policy());
2818 if (mpfr_nan_p(result.backend().data()))
2819 return policies::raise_evaluation_error("atanh<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2820 return result;
2821}
2822template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2823inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2824{
2825 return atanh(arg, policies::policy<>());
2826}
2827
2828template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2829inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy&)
2830{
2831 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2832
2833 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2834 mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
2835 if (mpfr_inf_p(result.backend().data()))
2836 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("cbrt<%1%>(%1%)", 0, Policy());
2837 if (mpfr_nan_p(result.backend().data()))
2838 return policies::raise_evaluation_error("cbrt<%1%>(%1%)", "Unknown error, result is a NaN", result, Policy());
2839 return result;
2840}
2841template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2842inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
92f5a8d4
TL
2843{
2844 return cbrt(arg, policies::policy<>());
2845}
2846
2847template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2848inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2849{
2850 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2851
2852 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2853 mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
2854 if (mpfr_inf_p(result.backend().data()))
2855 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erf<%1%>(%1%)", 0, pol);
2856 if (mpfr_nan_p(result.backend().data()))
2857 return policies::raise_evaluation_error("erf<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2858 return result;
2859}
2860template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2861inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2862{
2863 return erf(arg, policies::policy<>());
2864}
2865
2866template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2867inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2868{
2869 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2870
2871 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2872 mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
2873 if (mpfr_inf_p(result.backend().data()))
2874 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("erfc<%1%>(%1%)", 0, pol);
2875 if (mpfr_nan_p(result.backend().data()))
2876 return policies::raise_evaluation_error("erfc<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2877 return result;
2878}
2879template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2880inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2881{
2882 return erfc(arg, policies::policy<>());
2883}
2884
2885template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2886inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2887{
2888 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2889
2890 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2891 mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
2892 if (mpfr_inf_p(result.backend().data()))
2893 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("expm1<%1%>(%1%)", 0, pol);
2894 if (mpfr_nan_p(result.backend().data()))
2895 return policies::raise_evaluation_error("expm1<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2896 return result;
2897}
2898template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2899inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2900{
2901 return expm1(arg, policies::policy<>());
2902}
2903
1e59de90 2904#ifdef BOOST_MP_MATH_AVAILABLE
92f5a8d4
TL
2905template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2906inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> arg, int* sign, const Policy& pol)
2907{
2908 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2909 (void)precision_guard; // warning suppression
2910
2911 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2912 if (arg > 0)
7c673cae 2913 {
7c673cae 2914 mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
92f5a8d4
TL
2915 if (sign)
2916 *sign = 1;
7c673cae 2917 }
92f5a8d4 2918 else
7c673cae 2919 {
92f5a8d4
TL
2920 if (floor(arg) == arg)
2921 return policies::raise_pole_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >(
2922 "lgamma<%1%>", "Evaluation of lgamma at a negative integer %1%.", arg, pol);
2923
2924 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> t = detail::sinpx(arg);
2925 arg = -arg;
2926 if (t < 0)
2927 {
2928 t = -t;
2929 }
f67539c2 2930 result = boost::multiprecision::log(boost::math::constants::pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >()) - lgamma(arg, 0, pol) - boost::multiprecision::log(t);
92f5a8d4
TL
2931 if (sign)
2932 {
2933 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> phase = 1 - arg;
2934 phase = floor(phase) / 2;
2935 if (floor(phase) == phase)
2936 *sign = -1;
2937 else
2938 *sign = 1;
2939 }
7c673cae 2940 }
92f5a8d4
TL
2941 if (mpfr_inf_p(result.backend().data()))
2942 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("lgamma<%1%>(%1%)", 0, pol);
2943 if (mpfr_nan_p(result.backend().data()))
2944 return policies::raise_evaluation_error("lgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2945 return result;
2946}
2947template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2948inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, int* sign)
2949{
2950 return lgamma(arg, sign, policies::policy<>());
2951}
2952template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2953inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2954{
2955 return lgamma(arg, 0, pol);
2956}
2957template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2958inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2959{
2960 return lgamma(arg, 0, policies::policy<>());
2961}
1e59de90 2962#endif // BOOST_MP_MATH_AVAILABLE
7c673cae 2963
92f5a8d4 2964template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
1e59de90 2965inline typename std::enable_if<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
92f5a8d4
TL
2966{
2967 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
2968
2969 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2970 mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
2971 if (mpfr_inf_p(result.backend().data()))
2972 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("tgamma<%1%>(%1%)", 0, pol);
2973 if (mpfr_nan_p(result.backend().data()))
2974 return policies::raise_evaluation_error("tgamma<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2975 return result;
2976}
2977template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2978inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2979{
2980 return tgamma(arg, policies::policy<>());
7c673cae
FG
2981}
2982
92f5a8d4
TL
2983template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
2984inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
2985{
2986 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
7c673cae 2987
92f5a8d4
TL
2988 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
2989 mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
2990 if (mpfr_inf_p(result.backend().data()))
20effc67 2991 return (arg == -1 ? -1 : 1) * policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("log1p<%1%>(%1%)", 0, pol);
92f5a8d4
TL
2992 if (mpfr_nan_p(result.backend().data()))
2993 return policies::raise_evaluation_error("log1p<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
2994 return result;
2995}
2996template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2997inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
2998{
2999 return log1p(arg, policies::policy<>());
3000}
3001
20effc67
TL
3002template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3003inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
3004{
3005 boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
3006
3007 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
3008 mpfr_rec_sqrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
3009 if (mpfr_inf_p(result.backend().data()))
3010 return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("rsqrt<%1%>(%1%)", 0, pol);
3011 if (mpfr_nan_p(result.backend().data()))
3012 return policies::raise_evaluation_error("rsqrt<%1%>(%1%)", "Negative argument, result is a NaN", result, pol);
3013 return result;
3014}
3015template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3016inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
3017{
3018 return rsqrt(arg, policies::policy<>());
3019}
3020
1e59de90
TL
3021//
3022// Over again with debug_adaptor:
3023//
3024template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3025inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3026{
3027 return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3028}
3029template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3030inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3031{
3032 return asinh(arg, policies::policy<>());
3033}
3034
3035template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3036inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3037{
3038 return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3039}
3040template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3041inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3042{
3043 return acosh(arg, policies::policy<>());
3044}
3045
3046template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3047inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3048{
3049 return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3050}
3051template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3052inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3053{
3054 return atanh(arg, policies::policy<>());
3055}
3056
3057template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3058inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3059{
3060 return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3061}
3062template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3063inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3064{
3065 return cbrt(arg, policies::policy<>());
3066}
3067
3068template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3069inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3070{
3071 return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3072}
3073template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3074inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3075{
3076 return erf(arg, policies::policy<>());
3077}
3078
3079template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3080inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3081{
3082 return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3083}
3084template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3085inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3086{
3087 return erfc(arg, policies::policy<>());
3088}
3089
3090template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3091inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3092{
3093 return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3094}
3095template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3096inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3097{
3098 return expm1(arg, policies::policy<>());
3099}
3100
3101template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3102inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> arg, int* sign, const Policy& pol)
3103{
3104 return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
3105}
3106template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3107inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, int* sign)
3108{
3109 return lgamma(arg, sign, policies::policy<>());
3110}
3111template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3112inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3113{
3114 return lgamma(arg, 0, pol);
3115}
3116template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3117inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3118{
3119 return lgamma(arg, 0, policies::policy<>());
3120}
3121
3122template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3123inline typename std::enable_if<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3124{
3125 return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3126}
3127template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3128inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3129{
3130 return tgamma(arg, policies::policy<>());
3131}
3132
3133template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3134inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3135{
3136 return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3137}
3138template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3139inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3140{
3141 return log1p(arg, policies::policy<>());
3142}
3143
3144template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3145inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3146{
3147 return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3148}
3149template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3150inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3151{
3152 return rsqrt(arg, policies::policy<>());
3153}
3154
3155//
3156// Over again with logged_adaptor:
3157//
3158template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3159inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3160{
3161 return asinh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3162}
3163template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3164inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3165{
3166 return asinh(arg, policies::policy<>());
3167}
3168
3169template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3170inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3171{
3172 return acosh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3173}
3174template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3175inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3176{
3177 return acosh(arg, policies::policy<>());
3178}
3179
3180template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3181inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3182{
3183 return atanh(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3184}
3185template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3186inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3187{
3188 return atanh(arg, policies::policy<>());
3189}
3190
3191template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3192inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3193{
3194 return cbrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3195}
3196template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3197inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3198{
3199 return cbrt(arg, policies::policy<>());
3200}
3201
3202template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3203inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3204{
3205 return erf(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3206}
3207template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3208inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3209{
3210 return erf(arg, policies::policy<>());
3211}
3212
3213template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3214inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3215{
3216 return erfc(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3217}
3218template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3219inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3220{
3221 return erfc(arg, policies::policy<>());
3222}
3223
3224template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3225inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3226{
3227 return expm1(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3228}
3229template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3230inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> exm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3231{
3232 return expm1(arg, policies::policy<>());
3233}
3234
3235template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3236inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> arg, int* sign, const Policy& pol)
3237{
3238 return lgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), sign, pol).backend();
3239}
3240template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3241inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, int* sign)
3242{
3243 return lgamma(arg, sign, policies::policy<>());
3244}
3245template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3246inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3247{
3248 return lgamma(arg, 0, pol);
3249}
3250template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3251inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3252{
3253 return lgamma(arg, 0, policies::policy<>());
3254}
3255
3256template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3257inline typename std::enable_if<boost::math::policies::is_policy<Policy>::value, boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3258{
3259 return tgamma(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3260}
3261template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3262inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3263{
3264 return tgamma(arg, policies::policy<>());
3265}
3266
3267template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3268inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3269{
3270 return log1p(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3271}
3272template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3273inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3274{
3275 return log1p(arg, policies::policy<>());
3276}
3277
3278template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
3279inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg, const Policy& pol)
3280{
3281 return rsqrt(boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(arg.backend().value()), pol).backend();
3282}
3283template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3284inline boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
3285{
3286 return rsqrt(arg, policies::policy<>());
3287}
3288
92f5a8d4
TL
3289} // namespace math
3290
3291} // namespace boost
3292
1e59de90
TL
3293namespace Eigen
3294{
3295
3296 template <class B1, class B2>
3297 struct NumTraitsImp;
3298
3299 template <boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
3300 struct NumTraitsImp<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>, boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>
3301 {
3302 using self_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>;
3303 using Real = typename boost::multiprecision::scalar_result_from_possible_complex<self_type>::type;
3304 using NonInteger = self_type; // Not correct but we can't do much better??
3305 using Literal = double;
3306 using Nested = self_type;
3307 enum
3308 {
3309 IsComplex = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_complex,
3310 IsInteger = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer,
3311 ReadCost = 1,
3312 AddCost = 4,
3313 MulCost = 8,
3314 IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
3315 RequireInitialization = 1,
3316 };
3317 static Real epsilon()
3318 {
3319 #ifdef BOOST_MP_MATH_AVAILABLE
3320 return boost::math::tools::epsilon< boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
3321 #else
3322 self_type result{1};
3323 mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<self_type>::digits - 1, GMP_RNDN);
3324 return result;
3325 #endif
3326 }
3327 static Real dummy_precision()
3328 {
3329 return 1000 * epsilon();
3330 }
3331 static Real highest()
3332 {
3333 #ifdef BOOST_MP_MATH_AVAILABLE
3334 return boost::math::tools::max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
3335 #else
3336 self_type value(0.5);
3337 mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
3338 return value;
3339 #endif
3340 }
3341 static Real lowest()
3342 {
3343 #ifdef BOOST_MP_MATH_AVAILABLE
3344 return boost::math::tools::min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0, AllocateType>, ExpressionTemplates>>();
3345 #else
3346 return -(highest)();
3347 #endif
3348 }
3349 static int digits10()
3350 {
3351 return Real::thread_default_precision();
3352 }
3353 static int digits()
3354 {
3355 return boost::math::tools::digits<Real>();
3356 }
3357 static int min_exponent()
3358 {
3359 return mpfr_get_emin();
3360 }
3361 static int max_exponent()
3362 {
3363 return mpfr_get_emax();
3364 }
3365 static Real infinity()
3366 {
3367 return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::infinity();
3368 }
3369 static Real quiet_NaN()
3370 {
3371 return std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<50, AllocateType>, ExpressionTemplates>>::quiet_NaN();
3372 }
3373 };
3374
3375}
3376
92f5a8d4 3377namespace std {
7c673cae
FG
3378
3379//
3380// numeric_limits [partial] specializations for the types declared in this header:
3381//
92f5a8d4 3382template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
7c673cae
FG
3383class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
3384{
1e59de90
TL
3385 using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>;
3386
3387 static number_type get_min()
3388 {
3389 number_type result{0.5};
3390 mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
3391 return result;
3392 }
3393 static number_type get_max()
3394 {
3395 number_type result{0.5};
3396 mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
3397 return result;
3398 }
3399 static number_type get_eps()
3400 {
3401 number_type result{1};
3402 mpfr_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
3403 return result;
3404 }
92f5a8d4
TL
3405
3406 public:
1e59de90 3407 static constexpr bool is_specialized = true;
92f5a8d4 3408 static number_type(min)()
7c673cae 3409 {
1e59de90
TL
3410 static number_type value{get_min()};
3411 return value;
7c673cae 3412 }
92f5a8d4 3413 static number_type(max)()
7c673cae 3414 {
1e59de90
TL
3415 static number_type value{get_max()};
3416 return value;
7c673cae 3417 }
1e59de90 3418 static constexpr number_type lowest()
7c673cae
FG
3419 {
3420 return -(max)();
3421 }
1e59de90
TL
3422 static constexpr int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
3423 static constexpr int digits10 = Digits10;
7c673cae 3424 // Is this really correct???
1e59de90
TL
3425 static constexpr int max_digits10 = boost::multiprecision::detail::calc_max_digits10<digits>::value;
3426 static constexpr bool is_signed = true;
3427 static constexpr bool is_integer = false;
3428 static constexpr bool is_exact = false;
3429 static constexpr int radix = 2;
92f5a8d4 3430 static number_type epsilon()
7c673cae 3431 {
1e59de90
TL
3432 static number_type value{get_eps()};
3433 return value;
7c673cae
FG
3434 }
3435 // What value should this be????
3436 static number_type round_error()
3437 {
3438 // returns epsilon/2
1e59de90
TL
3439 return 0.5;
3440 }
3441 static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
3442 static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
3443 static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
3444 static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
3445 static constexpr bool has_infinity = true;
3446 static constexpr bool has_quiet_NaN = true;
3447 static constexpr bool has_signaling_NaN = false;
3448 static constexpr float_denorm_style has_denorm = denorm_absent;
3449 static constexpr bool has_denorm_loss = false;
92f5a8d4 3450 static number_type infinity()
7c673cae 3451 {
1e59de90
TL
3452 number_type value;
3453 mpfr_set_inf(value.backend().data(), 1);
3454 return value;
7c673cae
FG
3455 }
3456 static number_type quiet_NaN()
3457 {
1e59de90
TL
3458 number_type value;
3459 mpfr_set_nan(value.backend().data());
3460 return value;
7c673cae 3461 }
1e59de90 3462 static constexpr number_type signaling_NaN()
7c673cae
FG
3463 {
3464 return number_type(0);
3465 }
1e59de90
TL
3466 static constexpr number_type denorm_min() { return number_type(0); }
3467 static constexpr bool is_iec559 = false;
3468 static constexpr bool is_bounded = true;
3469 static constexpr bool is_modulo = false;
3470 static constexpr bool traps = true;
3471 static constexpr bool tinyness_before = false;
3472 static constexpr float_round_style round_style = round_to_nearest;
7c673cae
FG
3473};
3474
92f5a8d4 3475template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3476constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits;
7c673cae 3477template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3478constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10;
7c673cae 3479template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3480constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10;
7c673cae 3481template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3482constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed;
7c673cae 3483template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3484constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer;
7c673cae 3485template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3486constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact;
7c673cae 3487template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3488constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix;
7c673cae 3489template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3490constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent;
7c673cae 3491template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3492constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10;
7c673cae 3493template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3494constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent;
7c673cae 3495template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3496constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10;
7c673cae 3497template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3498constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity;
7c673cae 3499template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3500constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN;
7c673cae 3501template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3502constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN;
7c673cae 3503template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3504constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm;
7c673cae 3505template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3506constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss;
7c673cae 3507template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3508constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559;
7c673cae 3509template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3510constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded;
7c673cae 3511template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3512constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo;
7c673cae 3513template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3514constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps;
7c673cae 3515template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3516constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before;
7c673cae 3517template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3518constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style;
7c673cae 3519
92f5a8d4 3520template <boost::multiprecision::expression_template_option ExpressionTemplates>
7c673cae
FG
3521class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >
3522{
1e59de90 3523 using number_type = boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates>;
92f5a8d4
TL
3524
3525 public:
1e59de90 3526 static constexpr bool is_specialized = false;
92f5a8d4
TL
3527 static number_type(min)()
3528 {
3529 number_type value(0.5);
3530 mpfr_div_2exp(value.backend().data(), value.backend().data(), -mpfr_get_emin(), GMP_RNDN);
3531 return value;
3532 }
3533 static number_type(max)()
3534 {
3535 number_type value(0.5);
3536 mpfr_mul_2exp(value.backend().data(), value.backend().data(), mpfr_get_emax(), GMP_RNDN);
3537 return value;
3538 }
3539 static number_type lowest()
3540 {
3541 return -(max)();
3542 }
1e59de90
TL
3543 static constexpr int digits = INT_MAX;
3544 static constexpr int digits10 = INT_MAX;
3545 static constexpr int max_digits10 = INT_MAX;
3546 static constexpr bool is_signed = true;
3547 static constexpr bool is_integer = false;
3548 static constexpr bool is_exact = false;
3549 static constexpr int radix = 2;
92f5a8d4
TL
3550 static number_type epsilon()
3551 {
3552 number_type value(1);
1e59de90 3553 mpfr_div_2exp(value.backend().data(), value.backend().data(), boost::multiprecision::detail::digits10_2_2(number_type::thread_default_precision()) - 1, GMP_RNDN);
92f5a8d4
TL
3554 return value;
3555 }
3556 static number_type round_error()
3557 {
1e59de90
TL
3558 return 0.5;
3559 }
3560 static constexpr long min_exponent = MPFR_EMIN_DEFAULT;
3561 static constexpr long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
3562 static constexpr long max_exponent = MPFR_EMAX_DEFAULT;
3563 static constexpr long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
3564 static constexpr bool has_infinity = true;
3565 static constexpr bool has_quiet_NaN = true;
3566 static constexpr bool has_signaling_NaN = false;
3567 static constexpr float_denorm_style has_denorm = denorm_absent;
3568 static constexpr bool has_denorm_loss = false;
92f5a8d4
TL
3569 static number_type infinity()
3570 {
3571 number_type value;
3572 mpfr_set_inf(value.backend().data(), 1);
3573 return value;
3574 }
3575 static number_type quiet_NaN()
3576 {
3577 number_type value;
3578 mpfr_set_nan(value.backend().data());
3579 return value;
3580 }
3581 static number_type signaling_NaN() { return number_type(0); }
3582 static number_type denorm_min() { return number_type(0); }
1e59de90
TL
3583 static constexpr bool is_iec559 = false;
3584 static constexpr bool is_bounded = true;
3585 static constexpr bool is_modulo = false;
3586 static constexpr bool traps = false;
3587 static constexpr bool tinyness_before = false;
3588 static constexpr float_round_style round_style = round_toward_zero;
7c673cae
FG
3589};
3590
7c673cae 3591template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3592constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits;
7c673cae 3593template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3594constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10;
7c673cae 3595template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3596constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10;
7c673cae 3597template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3598constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed;
7c673cae 3599template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3600constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer;
7c673cae 3601template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3602constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact;
7c673cae 3603template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3604constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix;
7c673cae 3605template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3606constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent;
7c673cae 3607template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3608constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10;
7c673cae 3609template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3610constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent;
7c673cae 3611template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3612constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10;
7c673cae 3613template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3614constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity;
7c673cae 3615template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3616constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
7c673cae 3617template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3618constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
7c673cae 3619template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3620constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm;
7c673cae 3621template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3622constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
7c673cae 3623template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3624constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559;
7c673cae 3625template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3626constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded;
7c673cae 3627template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3628constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo;
7c673cae 3629template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3630constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps;
7c673cae 3631template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3632constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before;
7c673cae 3633template <boost::multiprecision::expression_template_option ExpressionTemplates>
1e59de90 3634constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style;
7c673cae 3635
7c673cae
FG
3636} // namespace std
3637#endif