Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:48:47

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