File indexing completed on 2025-01-18 09:42:28
0001
0002
0003
0004
0005
0006 #ifndef BOOST_MP_DEBUG_ADAPTOR_HPP
0007 #define BOOST_MP_DEBUG_ADAPTOR_HPP
0008
0009 #include <boost/multiprecision/detail/standalone_config.hpp>
0010 #include <boost/multiprecision/traits/extract_exponent_type.hpp>
0011 #include <boost/multiprecision/detail/integer_ops.hpp>
0012
0013 namespace boost {
0014 namespace multiprecision {
0015 namespace backends {
0016
0017 template <class Backend>
0018 struct debug_adaptor
0019 {
0020 using signed_types = typename Backend::signed_types ;
0021 using unsigned_types = typename Backend::unsigned_types;
0022 using float_types = typename Backend::float_types ;
0023 using exponent_type = typename extract_exponent_type<Backend, number_category<Backend>::value>::type;
0024
0025 private:
0026 std::string debug_value;
0027 Backend m_value;
0028
0029 public:
0030 void update_view()
0031 {
0032 #ifndef BOOST_NO_EXCEPTIONS
0033 try
0034 {
0035 #endif
0036 debug_value = m_value.str(0, static_cast<std::ios_base::fmtflags>(0));
0037 #ifndef BOOST_NO_EXCEPTIONS
0038 }
0039 catch (const std::exception& e)
0040 {
0041 debug_value = "String conversion failed with message: \"";
0042 debug_value += e.what();
0043 debug_value += "\"";
0044 }
0045 #endif
0046 }
0047 debug_adaptor()
0048 {
0049 update_view();
0050 }
0051 debug_adaptor(const debug_adaptor& o) : debug_value(o.debug_value), m_value(o.m_value)
0052 {
0053 }
0054 debug_adaptor& operator=(const debug_adaptor& o)
0055 {
0056 debug_value = o.debug_value;
0057 m_value = o.m_value;
0058 return *this;
0059 }
0060 template <class T>
0061 debug_adaptor(const T& i, const typename std::enable_if<std::is_convertible<T, Backend>::value>::type* = nullptr)
0062 : m_value(i)
0063 {
0064 update_view();
0065 }
0066 template <class T>
0067 debug_adaptor(const debug_adaptor<T>& i, const typename std::enable_if<std::is_convertible<T, Backend>::value>::type* = nullptr)
0068 : m_value(i.value())
0069 {
0070 update_view();
0071 }
0072 template <class T, class U>
0073 debug_adaptor(const T& i, const U& j, typename std::enable_if<std::is_constructible<Backend, const T&, const U&>::value>::type* = nullptr)
0074 : m_value(i, j)
0075 {
0076 update_view();
0077 }
0078 template <class B2>
0079 debug_adaptor(const B2& i, unsigned digits10, typename std::enable_if<std::is_same<B2, Backend>::value && std::is_constructible<Backend, const Backend&, unsigned>::value>::type* = nullptr)
0080 : m_value(i, digits10)
0081 {
0082 update_view();
0083 }
0084 template <class T>
0085 typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value || std::is_assignable<Backend, T>::value, debug_adaptor&>::type operator=(const T& i)
0086 {
0087 m_value = i;
0088 update_view();
0089 return *this;
0090 }
0091 debug_adaptor& operator=(const char* s)
0092 {
0093 m_value = s;
0094 update_view();
0095 return *this;
0096 }
0097 void swap(debug_adaptor& o)
0098 {
0099 std::swap(m_value, o.value());
0100 std::swap(debug_value, o.debug_value);
0101 }
0102 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
0103 {
0104 return m_value.str(digits, f);
0105 }
0106 void negate()
0107 {
0108 m_value.negate();
0109 update_view();
0110 }
0111 int compare(const debug_adaptor& o) const
0112 {
0113 return m_value.compare(o.value());
0114 }
0115 template <class T>
0116 int compare(const T& i) const
0117 {
0118 return m_value.compare(i);
0119 }
0120 Backend& value()
0121 {
0122 return m_value;
0123 }
0124 const Backend& value() const
0125 {
0126 return m_value;
0127 }
0128
0129 #ifndef BOOST_MP_STANDALONE
0130 template <class Archive>
0131 void serialize(Archive& ar, const unsigned int )
0132 {
0133 ar & boost::make_nvp("value", m_value);
0134 using tag = typename Archive::is_loading;
0135 if (tag::value)
0136 update_view();
0137 }
0138 #endif
0139
0140 static unsigned default_precision() noexcept
0141 {
0142 return Backend::default_precision();
0143 }
0144 static void default_precision(unsigned v) noexcept
0145 {
0146 Backend::default_precision(v);
0147 }
0148 static unsigned thread_default_precision() noexcept
0149 {
0150 return Backend::thread_default_precision();
0151 }
0152 static void thread_default_precision(unsigned v) noexcept
0153 {
0154 Backend::thread_default_precision(v);
0155 }
0156 unsigned precision() const noexcept
0157 {
0158 return value().precision();
0159 }
0160 void precision(unsigned digits10) noexcept
0161 {
0162 value().precision(digits10);
0163 }
0164
0165
0166
0167 static constexpr variable_precision_options default_variable_precision_options()noexcept
0168 {
0169 return Backend::default_variable_precision_options();
0170 }
0171 static constexpr variable_precision_options thread_default_variable_precision_options()noexcept
0172 {
0173 return Backend::thread_default_variable_precision_options();
0174 }
0175 static BOOST_MP_CXX14_CONSTEXPR void default_variable_precision_options(variable_precision_options opts)
0176 {
0177 Backend::default_variable_precision_options(opts);
0178 }
0179 static BOOST_MP_CXX14_CONSTEXPR void thread_default_variable_precision_options(variable_precision_options opts)
0180 {
0181 Backend::thread_default_variable_precision_options(opts);
0182 }
0183 };
0184
0185 template <class Backend>
0186 inline Backend const& unwrap_debug_type(debug_adaptor<Backend> const& val)
0187 {
0188 return val.value();
0189 }
0190 template <class T>
0191 inline const T& unwrap_debug_type(const T& val)
0192 {
0193 return val;
0194 }
0195
0196 template <class Backend, class V, class U>
0197 inline BOOST_MP_CXX14_CONSTEXPR void assign_components(debug_adaptor<Backend>& result, const V& v1, const U& v2)
0198 {
0199 using default_ops::assign_components;
0200 assign_components(result.value(), unwrap_debug_type(v1), unwrap_debug_type(v2));
0201 result.update_view();
0202 }
0203
0204 #define NON_MEMBER_OP1(name, str) \
0205 template <class Backend> \
0206 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result) \
0207 { \
0208 using default_ops::BOOST_JOIN(eval_, name); \
0209 BOOST_JOIN(eval_, name) \
0210 (result.value()); \
0211 result.update_view(); \
0212 }
0213
0214 #define NON_MEMBER_OP2(name, str) \
0215 template <class Backend, class T> \
0216 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const T& a) \
0217 { \
0218 using default_ops::BOOST_JOIN(eval_, name); \
0219 BOOST_JOIN(eval_, name) \
0220 (result.value(), unwrap_debug_type(a)); \
0221 result.update_view(); \
0222 } \
0223 template <class Backend> \
0224 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const debug_adaptor<Backend>& a) \
0225 { \
0226 using default_ops::BOOST_JOIN(eval_, name); \
0227 BOOST_JOIN(eval_, name) \
0228 (result.value(), unwrap_debug_type(a)); \
0229 result.update_view(); \
0230 }
0231
0232 #define NON_MEMBER_OP3(name, str) \
0233 template <class Backend, class T, class U> \
0234 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const T& a, const U& b) \
0235 { \
0236 using default_ops::BOOST_JOIN(eval_, name); \
0237 BOOST_JOIN(eval_, name) \
0238 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b)); \
0239 result.update_view(); \
0240 } \
0241 template <class Backend, class T> \
0242 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const debug_adaptor<Backend>& a, const T& b) \
0243 { \
0244 using default_ops::BOOST_JOIN(eval_, name); \
0245 BOOST_JOIN(eval_, name) \
0246 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b)); \
0247 result.update_view(); \
0248 } \
0249 template <class Backend, class T> \
0250 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const T& a, const debug_adaptor<Backend>& b) \
0251 { \
0252 using default_ops::BOOST_JOIN(eval_, name); \
0253 BOOST_JOIN(eval_, name) \
0254 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b)); \
0255 result.update_view(); \
0256 } \
0257 template <class Backend> \
0258 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const debug_adaptor<Backend>& a, const debug_adaptor<Backend>& b) \
0259 { \
0260 using default_ops::BOOST_JOIN(eval_, name); \
0261 BOOST_JOIN(eval_, name) \
0262 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b)); \
0263 result.update_view(); \
0264 }
0265
0266 #define NON_MEMBER_OP4(name, str) \
0267 template <class Backend, class T, class U, class V> \
0268 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const T& a, const U& b, const V& c) \
0269 { \
0270 using default_ops::BOOST_JOIN(eval_, name); \
0271 BOOST_JOIN(eval_, name) \
0272 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c)); \
0273 result.update_view(); \
0274 } \
0275 template <class Backend, class T> \
0276 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const debug_adaptor<Backend>& a, const debug_adaptor<Backend>& b, const T& c) \
0277 { \
0278 using default_ops::BOOST_JOIN(eval_, name); \
0279 BOOST_JOIN(eval_, name) \
0280 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c)); \
0281 result.update_view(); \
0282 } \
0283 template <class Backend, class T> \
0284 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const debug_adaptor<Backend>& a, const T& b, const debug_adaptor<Backend>& c) \
0285 { \
0286 using default_ops::BOOST_JOIN(eval_, name); \
0287 BOOST_JOIN(eval_, name) \
0288 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c)); \
0289 result.update_view(); \
0290 } \
0291 template <class Backend, class T> \
0292 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const T& a, const debug_adaptor<Backend>& b, const debug_adaptor<Backend>& c) \
0293 { \
0294 using default_ops::BOOST_JOIN(eval_, name); \
0295 BOOST_JOIN(eval_, name) \
0296 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c)); \
0297 result.update_view(); \
0298 } \
0299 template <class Backend> \
0300 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const debug_adaptor<Backend>& a, const debug_adaptor<Backend>& b, const debug_adaptor<Backend>& c) \
0301 { \
0302 using default_ops::BOOST_JOIN(eval_, name); \
0303 BOOST_JOIN(eval_, name) \
0304 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c)); \
0305 result.update_view(); \
0306 } \
0307 template <class Backend, class T, class U> \
0308 inline void BOOST_JOIN(eval_, name)(debug_adaptor<Backend> & result, const debug_adaptor<Backend>& a, const T& b, const U& c) \
0309 { \
0310 using default_ops::BOOST_JOIN(eval_, name); \
0311 BOOST_JOIN(eval_, name) \
0312 (result.value(), unwrap_debug_type(a), unwrap_debug_type(b), unwrap_debug_type(c)); \
0313 result.update_view(); \
0314 }
0315
0316 NON_MEMBER_OP2(add, "+=")
0317 NON_MEMBER_OP2(subtract, "-=")
0318 NON_MEMBER_OP2(multiply, "*=")
0319 NON_MEMBER_OP2(divide, "/=")
0320
0321 template <class Backend, class R>
0322 inline void eval_convert_to(R* result, const debug_adaptor<Backend>& val)
0323 {
0324 using default_ops::eval_convert_to;
0325 eval_convert_to(result, val.value());
0326 }
0327 template <class Backend, class R>
0328 inline void eval_convert_to(debug_adaptor<R>* result, const debug_adaptor<Backend>& val)
0329 {
0330 using default_ops::eval_convert_to;
0331 eval_convert_to(&result->value(), val.value());
0332 }
0333 template <class Backend, class R>
0334 inline void eval_convert_to(debug_adaptor<R>* result, const Backend& val)
0335 {
0336 using default_ops::eval_convert_to;
0337 eval_convert_to(&result->value(), val);
0338 }
0339
0340 template <class Backend>
0341 inline void eval_convert_to(std::complex<float>* result, const debug_adaptor<Backend>& val)
0342 {
0343 using default_ops::eval_convert_to;
0344 eval_convert_to(result, val.value());
0345 }
0346 template <class Backend>
0347 inline void eval_convert_to(std::complex<double>* result, const debug_adaptor<Backend>& val)
0348 {
0349 using default_ops::eval_convert_to;
0350 eval_convert_to(result, val.value());
0351 }
0352 template <class Backend>
0353 inline void eval_convert_to(std::complex<long double>* result, const debug_adaptor<Backend>& val)
0354 {
0355 using default_ops::eval_convert_to;
0356 eval_convert_to(result, val.value());
0357 }
0358
0359
0360
0361 template <class Backend, class Exp>
0362 inline void eval_frexp(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& arg, Exp* exp)
0363 {
0364 eval_frexp(result.value(), arg.value(), exp);
0365 result.update_view();
0366 }
0367
0368 template <class Backend, class Exp>
0369 inline void eval_ldexp(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& arg, Exp exp)
0370 {
0371 eval_ldexp(result.value(), arg.value(), exp);
0372 result.update_view();
0373 }
0374
0375 template <class Backend, class Exp>
0376 inline void eval_scalbn(debug_adaptor<Backend>& result, const debug_adaptor<Backend>& arg, Exp exp)
0377 {
0378 using default_ops::eval_scalbn;
0379 eval_scalbn(result.value(), arg.value(), exp);
0380 result.update_view();
0381 }
0382
0383 template <class Backend>
0384 inline typename Backend::exponent_type eval_ilogb(const debug_adaptor<Backend>& arg)
0385 {
0386 using default_ops::eval_ilogb;
0387 return eval_ilogb(arg.value());
0388 }
0389
0390 NON_MEMBER_OP2(floor, "floor")
0391 NON_MEMBER_OP2(ceil, "ceil")
0392 NON_MEMBER_OP2(sqrt, "sqrt")
0393 NON_MEMBER_OP2(logb, "logb")
0394
0395 template <class Backend>
0396 inline int eval_fpclassify(const debug_adaptor<Backend>& arg)
0397 {
0398 using default_ops::eval_fpclassify;
0399 return eval_fpclassify(arg.value());
0400 }
0401
0402
0403
0404
0405
0406
0407
0408 NON_MEMBER_OP3(add, "+")
0409 NON_MEMBER_OP3(subtract, "-")
0410 NON_MEMBER_OP3(multiply, "*")
0411 NON_MEMBER_OP3(divide, "/")
0412 NON_MEMBER_OP3(multiply_add, "fused-multiply-add")
0413 NON_MEMBER_OP3(multiply_subtract, "fused-multiply-subtract")
0414 NON_MEMBER_OP4(multiply_add, "fused-multiply-add")
0415 NON_MEMBER_OP4(multiply_subtract, "fused-multiply-subtract")
0416
0417 NON_MEMBER_OP1(increment, "increment")
0418 NON_MEMBER_OP1(decrement, "decrement")
0419
0420
0421
0422
0423
0424
0425
0426 NON_MEMBER_OP2(modulus, "%=")
0427 NON_MEMBER_OP3(modulus, "%")
0428 NON_MEMBER_OP2(bitwise_or, "|=")
0429 NON_MEMBER_OP3(bitwise_or, "|")
0430 NON_MEMBER_OP2(bitwise_and, "&=")
0431 NON_MEMBER_OP3(bitwise_and, "&")
0432 NON_MEMBER_OP2(bitwise_xor, "^=")
0433 NON_MEMBER_OP3(bitwise_xor, "^")
0434 NON_MEMBER_OP4(qr, "quotient-and-remainder")
0435 NON_MEMBER_OP2(complement, "~")
0436
0437 template <class Backend>
0438 inline void eval_left_shift(debug_adaptor<Backend>& arg, std::size_t a)
0439 {
0440 using default_ops::eval_left_shift;
0441 eval_left_shift(arg.value(), a);
0442 arg.update_view();
0443 }
0444 template <class Backend>
0445 inline void eval_left_shift(debug_adaptor<Backend>& arg, const debug_adaptor<Backend>& a, std::size_t b)
0446 {
0447 using default_ops::eval_left_shift;
0448 eval_left_shift(arg.value(), a.value(), b);
0449 arg.update_view();
0450 }
0451 template <class Backend>
0452 inline void eval_right_shift(debug_adaptor<Backend>& arg, std::size_t a)
0453 {
0454 using default_ops::eval_right_shift;
0455 eval_right_shift(arg.value(), a);
0456 arg.update_view();
0457 }
0458 template <class Backend>
0459 inline void eval_right_shift(debug_adaptor<Backend>& arg, const debug_adaptor<Backend>& a, std::size_t b)
0460 {
0461 using default_ops::eval_right_shift;
0462 eval_right_shift(arg.value(), a.value(), b);
0463 arg.update_view();
0464 }
0465
0466 template <class Backend, class T>
0467 inline T eval_integer_modulus(const debug_adaptor<Backend>& arg, const T& a)
0468 {
0469 using default_ops::eval_integer_modulus;
0470 return eval_integer_modulus(arg.value(), a);
0471 }
0472
0473 template <class Backend>
0474 inline std::size_t eval_lsb(const debug_adaptor<Backend>& arg)
0475 {
0476 using default_ops::eval_lsb;
0477 return eval_lsb(arg.value());
0478 }
0479
0480 template <class Backend>
0481 inline std::size_t eval_msb(const debug_adaptor<Backend>& arg)
0482 {
0483 using default_ops::eval_msb;
0484 return eval_msb(arg.value());
0485 }
0486
0487 template <class Backend>
0488 inline bool eval_bit_test(const debug_adaptor<Backend>& arg, std::size_t a)
0489 {
0490 using default_ops::eval_bit_test;
0491 return eval_bit_test(arg.value(), a);
0492 }
0493
0494 template <class Backend>
0495 inline void eval_bit_set(const debug_adaptor<Backend>& arg, std::size_t a)
0496 {
0497 using default_ops::eval_bit_set;
0498 eval_bit_set(arg.value(), a);
0499 arg.update_view();
0500 }
0501 template <class Backend>
0502 inline void eval_bit_unset(const debug_adaptor<Backend>& arg, std::size_t a)
0503 {
0504 using default_ops::eval_bit_unset;
0505 eval_bit_unset(arg.value(), a);
0506 arg.update_view();
0507 }
0508 template <class Backend>
0509 inline void eval_bit_flip(const debug_adaptor<Backend>& arg, std::size_t a)
0510 {
0511 using default_ops::eval_bit_flip;
0512 eval_bit_flip(arg.value(), a);
0513 arg.update_view();
0514 }
0515
0516 NON_MEMBER_OP3(gcd, "gcd")
0517 NON_MEMBER_OP3(lcm, "lcm")
0518 NON_MEMBER_OP4(powm, "powm")
0519
0520
0521
0522
0523
0524
0525
0526 NON_MEMBER_OP2(abs, "abs")
0527 NON_MEMBER_OP2(fabs, "fabs")
0528
0529
0530
0531
0532
0533
0534
0535 NON_MEMBER_OP2(trunc, "trunc")
0536 NON_MEMBER_OP2(round, "round")
0537 NON_MEMBER_OP2(exp, "exp")
0538 NON_MEMBER_OP2(log, "log")
0539 NON_MEMBER_OP2(log10, "log10")
0540 NON_MEMBER_OP2(sin, "sin")
0541 NON_MEMBER_OP2(cos, "cos")
0542 NON_MEMBER_OP2(tan, "tan")
0543 NON_MEMBER_OP2(asin, "asin")
0544 NON_MEMBER_OP2(acos, "acos")
0545 NON_MEMBER_OP2(atan, "atan")
0546 NON_MEMBER_OP2(sinh, "sinh")
0547 NON_MEMBER_OP2(cosh, "cosh")
0548 NON_MEMBER_OP2(tanh, "tanh")
0549 NON_MEMBER_OP2(asinh, "asinh")
0550 NON_MEMBER_OP2(acosh, "acosh")
0551 NON_MEMBER_OP2(atanh, "atanh")
0552 NON_MEMBER_OP3(fmod, "fmod")
0553 NON_MEMBER_OP3(pow, "pow")
0554 NON_MEMBER_OP3(atan2, "atan2")
0555 NON_MEMBER_OP2(conj, "conj")
0556
0557 template <class Backend>
0558 int eval_signbit(const debug_adaptor<Backend>& val)
0559 {
0560 using default_ops::eval_signbit;
0561 return eval_signbit(val.value());
0562 }
0563
0564 template <class Backend>
0565 std::size_t hash_value(const debug_adaptor<Backend>& val)
0566 {
0567 return hash_value(val.value());
0568 }
0569
0570 template <class Backend, expression_template_option ExpressionTemplates>
0571 inline typename std::enable_if<number_category<Backend>::value == number_kind_rational, typename number<debug_adaptor<Backend>, ExpressionTemplates>::value_type>::type
0572 numerator(const number<debug_adaptor<Backend>, ExpressionTemplates>& arg)
0573 {
0574 number<Backend, ExpressionTemplates> t(arg.backend().value());
0575 return numerator(t).backend();
0576 }
0577 template <class Backend, expression_template_option ExpressionTemplates>
0578 inline typename std::enable_if<number_category<Backend>::value == number_kind_rational, typename number<debug_adaptor<Backend>, ExpressionTemplates>::value_type>::type
0579 denominator(const number<debug_adaptor<Backend>, ExpressionTemplates>& arg)
0580 {
0581 number<Backend, ExpressionTemplates> t(arg.backend().value());
0582 return denominator(t).backend();
0583 }
0584
0585 template <class To, class From>
0586 inline BOOST_MP_CXX14_CONSTEXPR void eval_real(To& to, const debug_adaptor<From>& from)
0587 {
0588 using default_ops::eval_real;
0589 eval_real(to, from.value());
0590 }
0591 template <class To, class From>
0592 inline BOOST_MP_CXX14_CONSTEXPR void eval_real(debug_adaptor<To>& to, const debug_adaptor<From>& from)
0593 {
0594 using default_ops::eval_real;
0595 eval_real(to.value(), from.value());
0596 to.update_view();
0597 }
0598 template <class To, class From>
0599 inline BOOST_MP_CXX14_CONSTEXPR void eval_real(debug_adaptor<To>& to, const From& from)
0600 {
0601 using default_ops::eval_real;
0602 eval_real(to.value(), from);
0603 to.update_view();
0604 }
0605
0606 template <class To, class From>
0607 inline BOOST_MP_CXX14_CONSTEXPR void eval_imag(To& to, const debug_adaptor<From>& from)
0608 {
0609 using default_ops::eval_imag;
0610 eval_imag(to, from.value());
0611 }
0612 template <class To, class From>
0613 inline BOOST_MP_CXX14_CONSTEXPR void eval_imag(debug_adaptor<To>& to, const debug_adaptor<From>& from)
0614 {
0615 using default_ops::eval_imag;
0616 eval_imag(to.value(), from.value());
0617 to.update_view();
0618 }
0619 template <class To, class From>
0620 inline BOOST_MP_CXX14_CONSTEXPR void eval_imag(debug_adaptor<To>& to, const From& from)
0621 {
0622 using default_ops::eval_imag;
0623 eval_imag(to.value(), from);
0624 to.update_view();
0625 }
0626
0627 template <class To, class From>
0628 inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(To& to, const debug_adaptor<From>& from)
0629 {
0630 using default_ops::eval_set_real;
0631 eval_set_real(to, from.value());
0632 }
0633 template <class To, class From>
0634 inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(debug_adaptor<To>& to, const debug_adaptor<From>& from)
0635 {
0636 using default_ops::eval_set_real;
0637 eval_set_real(to.value(), from.value());
0638 to.update_view();
0639 }
0640 template <class To, class From>
0641 inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(debug_adaptor<To>& to, const From& from)
0642 {
0643 using default_ops::eval_set_real;
0644 eval_set_real(to.value(), from);
0645 to.update_view();
0646 }
0647
0648 template <class To, class From>
0649 inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(To& to, const debug_adaptor<From>& from)
0650 {
0651 using default_ops::eval_set_imag;
0652 eval_set_imag(to, from.value());
0653 }
0654 template <class To, class From>
0655 inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(debug_adaptor<To>& to, const debug_adaptor<From>& from)
0656 {
0657 using default_ops::eval_set_imag;
0658 eval_set_imag(to.value(), from.value());
0659 to.update_view();
0660 }
0661 template <class To, class From>
0662 inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(debug_adaptor<To>& to, const From& from)
0663 {
0664 using default_ops::eval_set_imag;
0665 eval_set_imag(to.value(), from);
0666 to.update_view();
0667 }
0668
0669
0670 }
0671
0672 namespace detail {
0673 template <class Backend>
0674 struct is_variable_precision<debug_adaptor<Backend> > : public is_variable_precision<Backend>
0675 {};
0676 #ifdef BOOST_HAS_INT128
0677 template <class Backend>
0678 struct is_convertible_arithmetic<int128_type, debug_adaptor<Backend> > : public is_convertible_arithmetic<int128_type, Backend>
0679 {};
0680 template <class Backend>
0681 struct is_convertible_arithmetic<uint128_type, debug_adaptor<Backend> > : public is_convertible_arithmetic<uint128_type, Backend>
0682 {};
0683 #endif
0684 #ifdef BOOST_HAS_FLOAT128
0685 template <class Backend>
0686 struct is_convertible_arithmetic<float128_type, debug_adaptor<Backend> > : public is_convertible_arithmetic<float128_type, Backend>
0687 {};
0688 #endif
0689 }
0690
0691 template <class Backend>
0692 struct number_category<backends::debug_adaptor<Backend> > : public number_category<Backend>
0693 {};
0694
0695 template <class Backend, expression_template_option ExpressionTemplates>
0696 struct component_type<number<debug_adaptor<Backend>, ExpressionTemplates>>
0697 {
0698
0699
0700
0701 using base_component_type = typename component_type<number<Backend, ExpressionTemplates>>::type;
0702 using base_component_backend = typename base_component_type::backend_type;
0703 using type = number<debug_adaptor<base_component_backend>, ExpressionTemplates>;
0704 };
0705
0706 template <class Backend>
0707 struct is_interval_number<backends::debug_adaptor<Backend> > : public is_interval_number<Backend> {};
0708
0709 }}
0710
0711 namespace std {
0712
0713 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
0714 class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<Backend>, ExpressionTemplates> >
0715 : public std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> >
0716 {
0717 using base_type = std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> > ;
0718 using number_type = boost::multiprecision::number<boost::multiprecision::backends::debug_adaptor<Backend>, ExpressionTemplates>;
0719
0720 public:
0721 static number_type(min)() noexcept { return (base_type::min)(); }
0722 static number_type(max)() noexcept { return (base_type::max)(); }
0723 static number_type lowest() noexcept { return -(max)(); }
0724 static number_type epsilon() noexcept { return base_type::epsilon(); }
0725 static number_type round_error() noexcept { return epsilon() / 2; }
0726 static number_type infinity() noexcept { return base_type::infinity(); }
0727 static number_type quiet_NaN() noexcept { return base_type::quiet_NaN(); }
0728 static number_type signaling_NaN() noexcept { return base_type::signaling_NaN(); }
0729 static number_type denorm_min() noexcept { return base_type::denorm_min(); }
0730 };
0731
0732 }
0733
0734 #ifdef BOOST_MP_MATH_AVAILABLE
0735 namespace boost {
0736 namespace math {
0737
0738 namespace policies {
0739
0740 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
0741 struct precision<boost::multiprecision::number<boost::multiprecision::debug_adaptor<Backend>, ExpressionTemplates>, Policy>
0742 : public precision<boost::multiprecision::number<Backend, ExpressionTemplates>, Policy>
0743 {};
0744
0745 #undef NON_MEMBER_OP1
0746 #undef NON_MEMBER_OP2
0747 #undef NON_MEMBER_OP3
0748 #undef NON_MEMBER_OP4
0749
0750 }
0751
0752 }}
0753 #else
0754 #undef NON_MEMBER_OP1
0755 #undef NON_MEMBER_OP2
0756 #undef NON_MEMBER_OP3
0757 #undef NON_MEMBER_OP4
0758 #endif
0759
0760 #endif