123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834 |
- ///////////////////////////////////////////////////////////////
- // Copyright 2012 John Maddock. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
- #ifndef BOOST_MP_LOGGED_ADAPTER_HPP
- #define BOOST_MP_LOGGED_ADAPTER_HPP
- #include <boost/multiprecision/detail/standalone_config.hpp>
- #include <boost/multiprecision/traits/extract_exponent_type.hpp>
- #include <boost/multiprecision/detail/integer_ops.hpp>
- namespace boost {
- namespace multiprecision {
- template <class Backend>
- inline void log_postfix_event(const Backend&, const char* /*event_description*/)
- {
- }
- template <class Backend, class T>
- inline void log_postfix_event(const Backend&, const T&, const char* /*event_description*/)
- {
- }
- template <class Backend>
- inline void log_prefix_event(const Backend&, const char* /*event_description*/)
- {
- }
- template <class Backend, class T>
- inline void log_prefix_event(const Backend&, const T&, const char* /*event_description*/)
- {
- }
- template <class Backend, class T, class U>
- inline void log_prefix_event(const Backend&, const T&, const U&, const char* /*event_description*/)
- {
- }
- template <class Backend, class T, class U, class V>
- inline void log_prefix_event(const Backend&, const T&, const U&, const V&, const char* /*event_description*/)
- {
- }
- namespace backends {
- template <class Backend>
- struct logged_adaptor
- {
- using signed_types = typename Backend::signed_types ;
- using unsigned_types = typename Backend::unsigned_types;
- using float_types = typename Backend::float_types ;
- using exponent_type = typename extract_exponent_type<Backend, number_category<Backend>::value>::type;
- private:
- Backend m_value;
- public:
- logged_adaptor()
- {
- log_postfix_event(m_value, "Default construct");
- }
- logged_adaptor(const logged_adaptor& o)
- {
- log_prefix_event(m_value, o.value(), "Copy construct");
- m_value = o.m_value;
- log_postfix_event(m_value, "Copy construct");
- }
- // rvalue copy
- logged_adaptor(logged_adaptor&& o)
- {
- log_prefix_event(m_value, o.value(), "Move construct");
- m_value = static_cast<Backend&&>(o.m_value);
- log_postfix_event(m_value, "Move construct");
- }
- logged_adaptor& operator=(logged_adaptor&& o)
- {
- log_prefix_event(m_value, o.value(), "Move Assignment");
- m_value = static_cast<Backend&&>(o.m_value);
- log_postfix_event(m_value, "Move construct");
- return *this;
- }
- logged_adaptor& operator=(const logged_adaptor& o)
- {
- log_prefix_event(m_value, o.value(), "Assignment");
- m_value = o.m_value;
- log_postfix_event(m_value, "Copy construct");
- return *this;
- }
- template <class T>
- logged_adaptor(const T& i, const typename std::enable_if<std::is_convertible<T, Backend>::value>::type* = nullptr)
- : m_value(i)
- {
- log_postfix_event(m_value, "construct from arithmetic type");
- }
- template <class T>
- logged_adaptor(const logged_adaptor<T>& i, const typename std::enable_if<std::is_convertible<T, Backend>::value>::type* = nullptr)
- : m_value(i.value())
- {
- log_postfix_event(m_value, "construct from arithmetic type");
- }
- template <class T, class U>
- logged_adaptor(const T& i, const U& j, typename std::enable_if<std::is_constructible<Backend, const T&, const U&>::value>::type* = nullptr)
- : m_value(i, j)
- {
- log_postfix_event(m_value, "construct from a pair of arithmetic types");
- }
- template <class D = Backend>
- logged_adaptor(const Backend& i, unsigned digits10, typename std::enable_if<std::is_constructible<D, Backend const&, unsigned>::value>::type const* = nullptr)
- : m_value(i, digits10)
- {
- log_postfix_event(m_value, "construct from arithmetic type and precision");
- }
- template <class D = Backend>
- logged_adaptor(const logged_adaptor<Backend>& i, unsigned digits10, typename std::enable_if<std::is_constructible<D, Backend const&, unsigned>::value>::type const* = nullptr)
- : m_value(i.value(), digits10)
- {
- log_postfix_event(m_value, "construct from arithmetic type and precision");
- }
- template <class T>
- typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value || std::is_assignable<Backend, T>::value, logged_adaptor&>::type operator=(const T& i)
- {
- log_prefix_event(m_value, i, "Assignment from arithmetic type");
- m_value = i;
- log_postfix_event(m_value, "Assignment from arithmetic type");
- return *this;
- }
- logged_adaptor& operator=(const char* s)
- {
- log_prefix_event(m_value, s, "Assignment from string type");
- m_value = s;
- log_postfix_event(m_value, "Assignment from string type");
- return *this;
- }
- void swap(logged_adaptor& o)
- {
- log_prefix_event(m_value, o.value(), "swap");
- std::swap(m_value, o.value());
- log_postfix_event(m_value, "swap");
- }
- std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
- {
- log_prefix_event(m_value, "Conversion to string");
- std::string s = m_value.str(digits, f);
- log_postfix_event(m_value, s, "Conversion to string");
- return s;
- }
- void negate()
- {
- log_prefix_event(m_value, "negate");
- m_value.negate();
- log_postfix_event(m_value, "negate");
- }
- int compare(const logged_adaptor& o) const
- {
- log_prefix_event(m_value, o.value(), "compare");
- int r = m_value.compare(o.value());
- log_postfix_event(m_value, r, "compare");
- return r;
- }
- template <class T>
- int compare(const T& i) const
- {
- log_prefix_event(m_value, i, "compare");
- int r = m_value.compare(i);
- log_postfix_event(m_value, r, "compare");
- return r;
- }
- Backend& value()
- {
- return m_value;
- }
- const Backend& value() const
- {
- return m_value;
- }
-
- #ifndef BOOST_MP_STANDALONE
- template <class Archive>
- void serialize(Archive& ar, const unsigned int /*version*/)
- {
- log_prefix_event(m_value, "serialize");
- ar& boost::make_nvp("value", m_value);
- log_postfix_event(m_value, "serialize");
- }
- #endif
- static unsigned default_precision() noexcept
- {
- return Backend::default_precision();
- }
- static void default_precision(unsigned v) noexcept
- {
- Backend::default_precision(v);
- }
- static unsigned thread_default_precision() noexcept
- {
- return Backend::thread_default_precision();
- }
- static void thread_default_precision(unsigned v) noexcept
- {
- Backend::thread_default_precision(v);
- }
- unsigned precision() const noexcept
- {
- return value().precision();
- }
- void precision(unsigned digits10) noexcept
- {
- value().precision(digits10);
- }
- //
- // Variable precision options:
- //
- static constexpr variable_precision_options default_variable_precision_options()noexcept
- {
- return Backend::default_variable_precision_options();
- }
- static constexpr variable_precision_options thread_default_variable_precision_options()noexcept
- {
- return Backend::thread_default_variable_precision_options();
- }
- static BOOST_MP_CXX14_CONSTEXPR void default_variable_precision_options(variable_precision_options opts)
- {
- Backend::default_variable_precision_options(opts);
- }
- static BOOST_MP_CXX14_CONSTEXPR void thread_default_variable_precision_options(variable_precision_options opts)
- {
- Backend::thread_default_variable_precision_options(opts);
- }
- };
- template <class T>
- inline const T& unwrap_logged_type(const T& a) { return a; }
- template <class Backend>
- inline const Backend& unwrap_logged_type(const logged_adaptor<Backend>& a) { return a.value(); }
- #define NON_MEMBER_OP1(name, str) \
- template <class Backend> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), str); \
- BOOST_JOIN(eval_, name) \
- (result.value()); \
- log_postfix_event(result.value(), str); \
- }
- #define NON_MEMBER_OP2(name, str) \
- template <class Backend, class T> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a)); \
- log_postfix_event(result.value(), str); \
- } \
- template <class Backend> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a)); \
- log_postfix_event(result.value(), str); \
- }
- #define NON_MEMBER_OP3(name, str) \
- template <class Backend, class T, class U> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a, const U& b) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b)); \
- log_postfix_event(result.value(), str); \
- } \
- template <class Backend, class T> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const T& b) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b)); \
- log_postfix_event(result.value(), str); \
- } \
- template <class Backend, class T> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a, const logged_adaptor<Backend>& b) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b)); \
- log_postfix_event(result.value(), str); \
- } \
- template <class Backend> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b)); \
- log_postfix_event(result.value(), str); \
- }
- #define NON_MEMBER_OP4(name, str) \
- template <class Backend, class T, class U, class V> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a, const U& b, const V& c) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
- log_postfix_event(result.value(), str); \
- } \
- template <class Backend, class T> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b, const T& c) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
- log_postfix_event(result.value(), str); \
- } \
- template <class Backend, class T> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const T& b, const logged_adaptor<Backend>& c) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
- log_postfix_event(result.value(), str); \
- } \
- template <class Backend, class T> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a, const logged_adaptor<Backend>& b, const logged_adaptor<Backend>& c) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
- log_postfix_event(result.value(), str); \
- } \
- template <class Backend> \
- 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) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
- log_postfix_event(result.value(), str); \
- } \
- template <class Backend, class T, class U> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const T& b, const U& c) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
- log_postfix_event(result.value(), str); \
- }
- NON_MEMBER_OP2(add, "+=")
- NON_MEMBER_OP2(subtract, "-=")
- NON_MEMBER_OP2(multiply, "*=")
- NON_MEMBER_OP2(divide, "/=")
- template <class Backend, class R>
- inline void eval_convert_to(R* result, const logged_adaptor<Backend>& val)
- {
- using default_ops::eval_convert_to;
- log_prefix_event(val.value(), "convert_to");
- eval_convert_to(result, val.value());
- log_postfix_event(val.value(), *result, "convert_to");
- }
- template <class Backend, class R>
- inline void eval_convert_to(logged_adaptor<R>* result, const logged_adaptor<Backend>& val)
- {
- using default_ops::eval_convert_to;
- log_prefix_event(val.value(), "convert_to");
- eval_convert_to(&result->value(), val.value());
- log_postfix_event(val.value(), &result->value(), "convert_to");
- }
- template <class Backend, class R>
- inline void eval_convert_to(logged_adaptor<R>* result, const Backend& val)
- {
- using default_ops::eval_convert_to;
- log_prefix_event(val, "convert_to");
- eval_convert_to(&result->value(), val);
- log_postfix_event(val, &result->value(), "convert_to");
- }
- template <class Backend>
- inline void eval_convert_to(std::complex<float>* result, const logged_adaptor<Backend>& val)
- {
- using default_ops::eval_convert_to;
- log_prefix_event(val.value(), "convert_to");
- eval_convert_to(result, val.value());
- log_postfix_event(val.value(), *result, "convert_to");
- }
- template <class Backend>
- inline void eval_convert_to(std::complex<double>* result, const logged_adaptor<Backend>& val)
- {
- using default_ops::eval_convert_to;
- log_prefix_event(val.value(), "convert_to");
- eval_convert_to(result, val.value());
- log_postfix_event(val.value(), *result, "convert_to");
- }
- template <class Backend>
- inline void eval_convert_to(std::complex<long double>* result, const logged_adaptor<Backend>& val)
- {
- using default_ops::eval_convert_to;
- log_prefix_event(val.value(), "convert_to");
- eval_convert_to(result, val.value());
- log_postfix_event(val.value(), *result, "convert_to");
- }
- template <class Backend, class Exp>
- inline void eval_frexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp* exp)
- {
- log_prefix_event(arg.value(), "frexp");
- eval_frexp(result.value(), arg.value(), exp);
- log_postfix_event(result.value(), *exp, "frexp");
- }
- template <class Backend, class Exp>
- inline void eval_ldexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp)
- {
- log_prefix_event(arg.value(), "ldexp");
- eval_ldexp(result.value(), arg.value(), exp);
- log_postfix_event(result.value(), exp, "ldexp");
- }
- template <class Backend, class Exp>
- inline void eval_scalbn(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp)
- {
- using default_ops::eval_scalbn;
- log_prefix_event(arg.value(), "scalbn");
- eval_scalbn(result.value(), arg.value(), exp);
- log_postfix_event(result.value(), exp, "scalbn");
- }
- template <class Backend>
- inline typename Backend::exponent_type eval_ilogb(const logged_adaptor<Backend>& arg)
- {
- using default_ops::eval_ilogb;
- log_prefix_event(arg.value(), "ilogb");
- typename Backend::exponent_type r = eval_ilogb(arg.value());
- log_postfix_event(arg.value(), "ilogb");
- return r;
- }
- NON_MEMBER_OP2(floor, "floor")
- NON_MEMBER_OP2(ceil, "ceil")
- NON_MEMBER_OP2(sqrt, "sqrt")
- template <class Backend>
- inline int eval_fpclassify(const logged_adaptor<Backend>& arg)
- {
- using default_ops::eval_fpclassify;
- log_prefix_event(arg.value(), "fpclassify");
- int r = eval_fpclassify(arg.value());
- log_postfix_event(arg.value(), r, "fpclassify");
- return r;
- }
- /*********************************************************************
- *
- * Optional arithmetic operations come next:
- *
- *********************************************************************/
- NON_MEMBER_OP3(add, "+")
- NON_MEMBER_OP3(subtract, "-")
- NON_MEMBER_OP3(multiply, "*")
- NON_MEMBER_OP3(divide, "/")
- NON_MEMBER_OP3(multiply_add, "fused-multiply-add")
- NON_MEMBER_OP3(multiply_subtract, "fused-multiply-subtract")
- NON_MEMBER_OP4(multiply_add, "fused-multiply-add")
- NON_MEMBER_OP4(multiply_subtract, "fused-multiply-subtract")
- NON_MEMBER_OP1(increment, "increment")
- NON_MEMBER_OP1(decrement, "decrement")
- /*********************************************************************
- *
- * Optional integer operations come next:
- *
- *********************************************************************/
- NON_MEMBER_OP2(modulus, "%=")
- NON_MEMBER_OP3(modulus, "%")
- NON_MEMBER_OP2(bitwise_or, "|=")
- NON_MEMBER_OP3(bitwise_or, "|")
- NON_MEMBER_OP2(bitwise_and, "&=")
- NON_MEMBER_OP3(bitwise_and, "&")
- NON_MEMBER_OP2(bitwise_xor, "^=")
- NON_MEMBER_OP3(bitwise_xor, "^")
- NON_MEMBER_OP4(qr, "quotient-and-remainder")
- NON_MEMBER_OP2(complement, "~")
- template <class Backend>
- inline void eval_left_shift(logged_adaptor<Backend>& arg, std::size_t a)
- {
- using default_ops::eval_left_shift;
- log_prefix_event(arg.value(), a, "<<=");
- eval_left_shift(arg.value(), a);
- log_postfix_event(arg.value(), "<<=");
- }
- template <class Backend>
- inline void eval_left_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, std::size_t b)
- {
- using default_ops::eval_left_shift;
- log_prefix_event(arg.value(), a, b, "<<");
- eval_left_shift(arg.value(), a.value(), b);
- log_postfix_event(arg.value(), "<<");
- }
- template <class Backend>
- inline void eval_right_shift(logged_adaptor<Backend>& arg, std::size_t a)
- {
- using default_ops::eval_right_shift;
- log_prefix_event(arg.value(), a, ">>=");
- eval_right_shift(arg.value(), a);
- log_postfix_event(arg.value(), ">>=");
- }
- template <class Backend>
- inline void eval_right_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, std::size_t b)
- {
- using default_ops::eval_right_shift;
- log_prefix_event(arg.value(), a, b, ">>");
- eval_right_shift(arg.value(), a.value(), b);
- log_postfix_event(arg.value(), ">>");
- }
- template <class Backend, class T>
- inline T eval_integer_modulus(const logged_adaptor<Backend>& arg, const T& a)
- {
- using default_ops::eval_integer_modulus;
- log_prefix_event(arg.value(), a, "integer-modulus");
- T r = eval_integer_modulus(arg.value(), a);
- log_postfix_event(arg.value(), r, "integer-modulus");
- return r;
- }
- template <class Backend>
- inline std::size_t eval_lsb(const logged_adaptor<Backend>& arg)
- {
- using default_ops::eval_lsb;
- log_prefix_event(arg.value(), "least-significant-bit");
- std::size_t r = eval_lsb(arg.value());
- log_postfix_event(arg.value(), r, "least-significant-bit");
- return r;
- }
- template <class Backend>
- inline std::size_t eval_msb(const logged_adaptor<Backend>& arg)
- {
- using default_ops::eval_msb;
- log_prefix_event(arg.value(), "most-significant-bit");
- std::size_t r = eval_msb(arg.value());
- log_postfix_event(arg.value(), r, "most-significant-bit");
- return r;
- }
- template <class Backend>
- inline bool eval_bit_test(const logged_adaptor<Backend>& arg, std::size_t a)
- {
- using default_ops::eval_bit_test;
- log_prefix_event(arg.value(), a, "bit-test");
- bool r = eval_bit_test(arg.value(), a);
- log_postfix_event(arg.value(), r, "bit-test");
- return r;
- }
- template <class Backend>
- inline void eval_bit_set(const logged_adaptor<Backend>& arg, std::size_t a)
- {
- using default_ops::eval_bit_set;
- log_prefix_event(arg.value(), a, "bit-set");
- eval_bit_set(arg.value(), a);
- log_postfix_event(arg.value(), arg, "bit-set");
- }
- template <class Backend>
- inline void eval_bit_unset(const logged_adaptor<Backend>& arg, std::size_t a)
- {
- using default_ops::eval_bit_unset;
- log_prefix_event(arg.value(), a, "bit-unset");
- eval_bit_unset(arg.value(), a);
- log_postfix_event(arg.value(), arg, "bit-unset");
- }
- template <class Backend>
- inline void eval_bit_flip(const logged_adaptor<Backend>& arg, std::size_t a)
- {
- using default_ops::eval_bit_flip;
- log_prefix_event(arg.value(), a, "bit-flip");
- eval_bit_flip(arg.value(), a);
- log_postfix_event(arg.value(), arg, "bit-flip");
- }
- NON_MEMBER_OP3(gcd, "gcd")
- NON_MEMBER_OP3(lcm, "lcm")
- NON_MEMBER_OP4(powm, "powm")
- /*********************************************************************
- *
- * abs/fabs:
- *
- *********************************************************************/
- NON_MEMBER_OP2(abs, "abs")
- NON_MEMBER_OP2(fabs, "fabs")
- /*********************************************************************
- *
- * Floating point functions:
- *
- *********************************************************************/
- NON_MEMBER_OP2(trunc, "trunc")
- NON_MEMBER_OP2(round, "round")
- NON_MEMBER_OP2(exp, "exp")
- NON_MEMBER_OP2(log, "log")
- NON_MEMBER_OP2(log10, "log10")
- NON_MEMBER_OP2(sin, "sin")
- NON_MEMBER_OP2(cos, "cos")
- NON_MEMBER_OP2(tan, "tan")
- NON_MEMBER_OP2(asin, "asin")
- NON_MEMBER_OP2(acos, "acos")
- NON_MEMBER_OP2(atan, "atan")
- NON_MEMBER_OP2(sinh, "sinh")
- NON_MEMBER_OP2(cosh, "cosh")
- NON_MEMBER_OP2(tanh, "tanh")
- NON_MEMBER_OP2(logb, "logb")
- NON_MEMBER_OP3(fmod, "fmod")
- NON_MEMBER_OP3(pow, "pow")
- NON_MEMBER_OP3(atan2, "atan2")
- NON_MEMBER_OP2(asinh, "asinh")
- NON_MEMBER_OP2(acosh, "acosh")
- NON_MEMBER_OP2(atanh, "atanh")
- NON_MEMBER_OP2(conj, "conj")
- template <class Backend>
- int eval_signbit(const logged_adaptor<Backend>& val)
- {
- using default_ops::eval_signbit;
- return eval_signbit(val.value());
- }
- template <class Backend>
- std::size_t hash_value(const logged_adaptor<Backend>& val)
- {
- return hash_value(val.value());
- }
- template <class Backend, expression_template_option ExpressionTemplates>
- inline typename std::enable_if<number_category<Backend>::value == number_kind_rational, typename number<logged_adaptor<Backend>, ExpressionTemplates>::value_type>::type
- numerator(const number<logged_adaptor<Backend>, ExpressionTemplates>& arg)
- {
- number<Backend, ExpressionTemplates> t(arg.backend().value());
- return numerator(t).backend();
- }
- template <class Backend, expression_template_option ExpressionTemplates>
- inline typename std::enable_if<number_category<Backend>::value == number_kind_rational, typename number<logged_adaptor<Backend>, ExpressionTemplates>::value_type>::type
- denominator(const number<logged_adaptor<Backend>, ExpressionTemplates>& arg)
- {
- number<Backend, ExpressionTemplates> t(arg.backend().value());
- return denominator(t).backend();
- }
- template <class To, class From>
- inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(To& to, const logged_adaptor<From>& from)
- {
- using default_ops::eval_set_real;
- log_prefix_event(to, from.value(), "Set real part");
- eval_set_real(to, from.value());
- log_postfix_event(to, from.value(), "Set real part");
- }
- template <class To, class From>
- inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(logged_adaptor<To>& to, const logged_adaptor<From>& from)
- {
- using default_ops::eval_set_real;
- log_prefix_event(to.value(), from.value(), "Set real part");
- eval_set_real(to.value(), from.value());
- log_postfix_event(to.value(), from.value(), "Set real part");
- }
- template <class To, class From>
- inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(logged_adaptor<To>& to, const From& from)
- {
- using default_ops::eval_set_real;
- log_prefix_event(to.value(), from, "Set real part");
- eval_set_real(to.value(), from);
- log_postfix_event(to.value(), from, "Set real part");
- }
- template <class To, class From>
- inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(To& to, const logged_adaptor<From>& from)
- {
- using default_ops::eval_set_imag;
- log_prefix_event(to, from.value(), "Set imag part");
- eval_set_imag(to, from.value());
- log_postfix_event(to, from.value(), "Set imag part");
- }
- template <class To, class From>
- inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(logged_adaptor<To>& to, const logged_adaptor<From>& from)
- {
- using default_ops::eval_set_imag;
- log_prefix_event(to.value(), from.value(), "Set imag part");
- eval_set_imag(to.value(), from.value());
- log_postfix_event(to.value(), from.value(), "Set imag part");
- }
- template <class To, class From>
- inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(logged_adaptor<To>& to, const From& from)
- {
- using default_ops::eval_set_imag;
- log_prefix_event(to.value(), from, "Set imag part");
- eval_set_imag(to.value(), from);
- log_postfix_event(to.value(), from, "Set imag part");
- }
- #define NON_MEMBER_COMPLEX_TO_REAL(name, str) \
- template <class B1, class B2> \
- inline void BOOST_JOIN(eval_, name)(logged_adaptor<B1> & result, const logged_adaptor<B2>& a) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(a.value(), a.value(), str); \
- BOOST_JOIN(eval_, name) \
- (result.value(), a.value()); \
- log_postfix_event(result.value(), str); \
- } \
- template <class B1, class B2> \
- inline void BOOST_JOIN(eval_, name)(B1 & result, const logged_adaptor<B2>& a) \
- { \
- using default_ops::BOOST_JOIN(eval_, name); \
- log_prefix_event(a.value(), a.value(), str); \
- BOOST_JOIN(eval_, name) \
- (result, a.value()); \
- log_postfix_event(result, str); \
- }
- NON_MEMBER_COMPLEX_TO_REAL(real, "real")
- NON_MEMBER_COMPLEX_TO_REAL(imag, "imag")
- template <class T, class V, class U>
- inline void assign_components(logged_adaptor<T>& result, const V& v1, const U& v2)
- {
- using default_ops::assign_components;
- assign_components(result.value(), unwrap_logged_type(v1), unwrap_logged_type(v2));
- }
- } // namespace backends
- namespace detail {
- template <class Backend>
- struct is_variable_precision<logged_adaptor<Backend> > : public is_variable_precision<Backend>
- {};
- #ifdef BOOST_HAS_INT128
- template <class Backend>
- struct is_convertible_arithmetic<int128_type, logged_adaptor<Backend> > : public is_convertible_arithmetic<int128_type, Backend>
- {};
- template <class Backend>
- struct is_convertible_arithmetic<uint128_type, logged_adaptor<Backend> > : public is_convertible_arithmetic<uint128_type, Backend>
- {};
- #endif
- #ifdef BOOST_HAS_FLOAT128
- template <class Backend>
- struct is_convertible_arithmetic<float128_type, logged_adaptor<Backend> > : public is_convertible_arithmetic<float128_type, Backend>
- {};
- #endif
- } // namespace detail
- template <class Backend>
- struct number_category<backends::logged_adaptor<Backend> > : public number_category<Backend>
- {};
- template <class Backend, expression_template_option ExpressionTemplates>
- struct component_type<number<logged_adaptor<Backend>, ExpressionTemplates>>
- {
- //
- // We'll make the component_type also a logged_adaptor:
- //
- using base_component_type = typename component_type<number<Backend, ExpressionTemplates>>::type;
- using base_component_backend = typename base_component_type::backend_type;
- using type = number<logged_adaptor<base_component_backend>, ExpressionTemplates>;
- };
- template <class Backend>
- struct is_interval_number<backends::logged_adaptor<Backend> > : public is_interval_number<Backend> {};
- }} // namespace boost::multiprecision
- namespace std {
- template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
- class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates> >
- : public std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> >
- {
- using base_type = std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> > ;
- using number_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates>;
- public:
- static number_type(min)() noexcept { return (base_type::min)(); }
- static number_type(max)() noexcept { return (base_type::max)(); }
- static number_type lowest() noexcept { return -(max)(); }
- static number_type epsilon() noexcept { return base_type::epsilon(); }
- static number_type round_error() noexcept { return epsilon() / 2; }
- static number_type infinity() noexcept { return base_type::infinity(); }
- static number_type quiet_NaN() noexcept { return base_type::quiet_NaN(); }
- static number_type signaling_NaN() noexcept { return base_type::signaling_NaN(); }
- static number_type denorm_min() noexcept { return base_type::denorm_min(); }
- };
- } // namespace std
- #ifdef BOOST_MP_MATH_AVAILABLE
- namespace boost {
- namespace math {
- namespace policies {
- template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
- struct precision<boost::multiprecision::number<boost::multiprecision::logged_adaptor<Backend>, ExpressionTemplates>, Policy>
- : public precision<boost::multiprecision::number<Backend, ExpressionTemplates>, Policy>
- {};
- }
- }} // namespace boost::math::policies
- #endif // BOOST_MP_MATH_AVAILABLE
- #undef NON_MEMBER_OP1
- #undef NON_MEMBER_OP2
- #undef NON_MEMBER_OP3
- #undef NON_MEMBER_OP4
- #endif
|