logged_adaptor.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. ///////////////////////////////////////////////////////////////
  2. // Copyright 2012 John Maddock. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
  5. #ifndef BOOST_MATH_LOGGED_ADAPTER_HPP
  6. #define BOOST_MATH_LOGGED_ADAPTER_HPP
  7. #include <boost/multiprecision/traits/extract_exponent_type.hpp>
  8. #include <boost/multiprecision/detail/integer_ops.hpp>
  9. namespace boost{
  10. namespace multiprecision{
  11. template <class Backend>
  12. inline void log_postfix_event(const Backend&, const char* /*event_description*/)
  13. {
  14. }
  15. template <class Backend, class T>
  16. inline void log_postfix_event(const Backend&, const T&, const char* /*event_description*/)
  17. {
  18. }
  19. template <class Backend>
  20. inline void log_prefix_event(const Backend&, const char* /*event_description*/)
  21. {
  22. }
  23. template <class Backend, class T>
  24. inline void log_prefix_event(const Backend&, const T&, const char* /*event_description*/)
  25. {
  26. }
  27. template <class Backend, class T, class U>
  28. inline void log_prefix_event(const Backend&, const T&, const U&, const char* /*event_description*/)
  29. {
  30. }
  31. template <class Backend, class T, class U, class V>
  32. inline void log_prefix_event(const Backend&, const T&, const U&, const V&, const char* /*event_description*/)
  33. {
  34. }
  35. namespace backends{
  36. template <class Backend>
  37. struct logged_adaptor
  38. {
  39. typedef typename Backend::signed_types signed_types;
  40. typedef typename Backend::unsigned_types unsigned_types;
  41. typedef typename Backend::float_types float_types;
  42. typedef typename extract_exponent_type<
  43. Backend, number_category<Backend>::value>::type exponent_type;
  44. private:
  45. Backend m_value;
  46. public:
  47. logged_adaptor()
  48. {
  49. log_postfix_event(m_value, "Default construct");
  50. }
  51. logged_adaptor(const logged_adaptor& o)
  52. {
  53. log_prefix_event(m_value, o.value(), "Copy construct");
  54. m_value = o.m_value;
  55. log_postfix_event(m_value, "Copy construct");
  56. }
  57. #ifndef BOOST_NO_RVALUE_REFERENCES
  58. logged_adaptor(logged_adaptor&& o)
  59. {
  60. log_prefix_event(m_value, o.value(), "Move construct");
  61. m_value = static_cast<Backend&&>(o.m_value);
  62. log_postfix_event(m_value, "Move construct");
  63. }
  64. logged_adaptor& operator = (logged_adaptor&& o)
  65. {
  66. log_prefix_event(m_value, o.value(), "Move Assignment");
  67. m_value = static_cast<Backend&&>(o.m_value);
  68. log_postfix_event(m_value, "Move construct");
  69. return *this;
  70. }
  71. #endif
  72. logged_adaptor& operator = (const logged_adaptor& o)
  73. {
  74. log_prefix_event(m_value, o.value(), "Assignment");
  75. m_value = o.m_value;
  76. log_postfix_event(m_value, "Copy construct");
  77. return *this;
  78. }
  79. template <class T>
  80. logged_adaptor(const T& i, const typename enable_if_c<is_convertible<T, Backend>::value>::type* = 0)
  81. : m_value(i)
  82. {
  83. log_postfix_event(m_value, "construct from arithmetic type");
  84. }
  85. template <class T>
  86. logged_adaptor(const logged_adaptor<T>& i, const typename enable_if_c<is_convertible<T, Backend>::value>::type* = 0)
  87. : m_value(i.value())
  88. {
  89. log_postfix_event(m_value, "construct from arithmetic type");
  90. }
  91. template <class T>
  92. typename enable_if_c<is_arithmetic<T>::value || is_convertible<T, Backend>::value, logged_adaptor&>::type operator = (const T& i)
  93. {
  94. log_prefix_event(m_value, i, "Assignment from arithmetic type");
  95. m_value = i;
  96. log_postfix_event(m_value, "Assignment from arithmetic type");
  97. return *this;
  98. }
  99. logged_adaptor& operator = (const char* s)
  100. {
  101. log_prefix_event(m_value, s, "Assignment from string type");
  102. m_value = s;
  103. log_postfix_event(m_value, "Assignment from string type");
  104. return *this;
  105. }
  106. void swap(logged_adaptor& o)
  107. {
  108. log_prefix_event(m_value, o.value(), "swap");
  109. std::swap(m_value, o.value());
  110. log_postfix_event(m_value, "swap");
  111. }
  112. std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
  113. {
  114. log_prefix_event(m_value, "Conversion to string");
  115. std::string s = m_value.str(digits, f);
  116. log_postfix_event(m_value, s, "Conversion to string");
  117. return s;
  118. }
  119. void negate()
  120. {
  121. log_prefix_event(m_value, "negate");
  122. m_value.negate();
  123. log_postfix_event(m_value, "negate");
  124. }
  125. int compare(const logged_adaptor& o)const
  126. {
  127. log_prefix_event(m_value, o.value(), "compare");
  128. int r = m_value.compare(o.value());
  129. log_postfix_event(m_value, r, "compare");
  130. return r;
  131. }
  132. template <class T>
  133. int compare(const T& i)const
  134. {
  135. log_prefix_event(m_value, i, "compare");
  136. int r = m_value.compare(i);
  137. log_postfix_event(m_value, r, "compare");
  138. return r;
  139. }
  140. Backend& value()
  141. {
  142. return m_value;
  143. }
  144. const Backend& value()const
  145. {
  146. return m_value;
  147. }
  148. template <class Archive>
  149. void serialize(Archive& ar, const unsigned int /*version*/)
  150. {
  151. log_prefix_event(m_value, "serialize");
  152. ar & boost::serialization::make_nvp("value", m_value);
  153. log_postfix_event(m_value, "serialize");
  154. }
  155. static unsigned default_precision() BOOST_NOEXCEPT
  156. {
  157. return Backend::default_precision();
  158. }
  159. static void default_precision(unsigned v) BOOST_NOEXCEPT
  160. {
  161. Backend::default_precision(v);
  162. }
  163. unsigned precision()const BOOST_NOEXCEPT
  164. {
  165. return value().precision();
  166. }
  167. void precision(unsigned digits10) BOOST_NOEXCEPT
  168. {
  169. value().precision(digits10);
  170. }
  171. };
  172. template <class T>
  173. inline const T& unwrap_logged_type(const T& a) { return a; }
  174. template <class Backend>
  175. inline const Backend& unwrap_logged_type(const logged_adaptor<Backend>& a) { return a.value(); }
  176. #define NON_MEMBER_OP1(name, str) \
  177. template <class Backend>\
  178. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result)\
  179. {\
  180. using default_ops::BOOST_JOIN(eval_, name);\
  181. log_prefix_event(result.value(), str);\
  182. BOOST_JOIN(eval_, name)(result.value());\
  183. log_postfix_event(result.value(), str);\
  184. }
  185. #define NON_MEMBER_OP2(name, str) \
  186. template <class Backend, class T>\
  187. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a)\
  188. {\
  189. using default_ops::BOOST_JOIN(eval_, name);\
  190. log_prefix_event(result.value(), unwrap_logged_type(a), str);\
  191. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a));\
  192. log_postfix_event(result.value(), str);\
  193. }\
  194. template <class Backend>\
  195. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a)\
  196. {\
  197. using default_ops::BOOST_JOIN(eval_, name);\
  198. log_prefix_event(result.value(), unwrap_logged_type(a), str);\
  199. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a));\
  200. log_postfix_event(result.value(), str);\
  201. }
  202. #define NON_MEMBER_OP3(name, str) \
  203. template <class Backend, class T, class U>\
  204. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const U& b)\
  205. {\
  206. using default_ops::BOOST_JOIN(eval_, name);\
  207. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\
  208. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\
  209. log_postfix_event(result.value(), str);\
  210. }\
  211. template <class Backend, class T>\
  212. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const T& b)\
  213. {\
  214. using default_ops::BOOST_JOIN(eval_, name);\
  215. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\
  216. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\
  217. log_postfix_event(result.value(), str);\
  218. }\
  219. template <class Backend, class T>\
  220. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const logged_adaptor<Backend>& b)\
  221. {\
  222. using default_ops::BOOST_JOIN(eval_, name);\
  223. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\
  224. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\
  225. log_postfix_event(result.value(), str);\
  226. }\
  227. template <class Backend>\
  228. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b)\
  229. {\
  230. using default_ops::BOOST_JOIN(eval_, name);\
  231. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\
  232. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\
  233. log_postfix_event(result.value(), str);\
  234. }
  235. #define NON_MEMBER_OP4(name, str) \
  236. template <class Backend, class T, class U, class V>\
  237. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const U& b, const V& c)\
  238. {\
  239. using default_ops::BOOST_JOIN(eval_, name);\
  240. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\
  241. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\
  242. log_postfix_event(result.value(), str);\
  243. }\
  244. template <class Backend, class T>\
  245. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b, const T& c)\
  246. {\
  247. using default_ops::BOOST_JOIN(eval_, name);\
  248. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\
  249. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\
  250. log_postfix_event(result.value(), str);\
  251. }\
  252. template <class Backend, class T>\
  253. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const T& b, const logged_adaptor<Backend>& c)\
  254. {\
  255. using default_ops::BOOST_JOIN(eval_, name);\
  256. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\
  257. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\
  258. log_postfix_event(result.value(), str);\
  259. }\
  260. template <class Backend, class T>\
  261. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const logged_adaptor<Backend>& b, const logged_adaptor<Backend>& c)\
  262. {\
  263. using default_ops::BOOST_JOIN(eval_, name);\
  264. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\
  265. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\
  266. log_postfix_event(result.value(), str);\
  267. }\
  268. template <class Backend>\
  269. 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)\
  270. {\
  271. using default_ops::BOOST_JOIN(eval_, name);\
  272. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\
  273. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\
  274. log_postfix_event(result.value(), str);\
  275. }\
  276. template <class Backend, class T, class U>\
  277. inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const T& b, const U& c)\
  278. {\
  279. using default_ops::BOOST_JOIN(eval_, name);\
  280. log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\
  281. BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\
  282. log_postfix_event(result.value(), str);\
  283. }\
  284. NON_MEMBER_OP2(add, "+=")
  285. NON_MEMBER_OP2(subtract, "-=")
  286. NON_MEMBER_OP2(multiply, "*=")
  287. NON_MEMBER_OP2(divide, "/=")
  288. template <class Backend, class R>
  289. inline void eval_convert_to(R* result, const logged_adaptor<Backend>& val)
  290. {
  291. using default_ops::eval_convert_to;
  292. log_prefix_event(val.value(), "convert_to");
  293. eval_convert_to(result, val.value());
  294. log_postfix_event(val.value(), *result, "convert_to");
  295. }
  296. template <class Backend, class Exp>
  297. inline void eval_frexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp* exp)
  298. {
  299. log_prefix_event(arg.value(), "frexp");
  300. eval_frexp(result.value(), arg.value(), exp);
  301. log_postfix_event(result.value(), *exp, "frexp");
  302. }
  303. template <class Backend, class Exp>
  304. inline void eval_ldexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp)
  305. {
  306. log_prefix_event(arg.value(), "ldexp");
  307. eval_ldexp(result.value(), arg.value(), exp);
  308. log_postfix_event(result.value(), exp, "ldexp");
  309. }
  310. template <class Backend, class Exp>
  311. inline void eval_scalbn(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp)
  312. {
  313. log_prefix_event(arg.value(), "scalbn");
  314. eval_scalbn(result.value(), arg.value(), exp);
  315. log_postfix_event(result.value(), exp, "scalbn");
  316. }
  317. template <class Backend>
  318. inline typename Backend::exponent_type eval_ilogb(const logged_adaptor<Backend>& arg)
  319. {
  320. log_prefix_event(arg.value(), "ilogb");
  321. typename Backend::exponent_type r = eval_ilogb(arg.value());
  322. log_postfix_event(arg.value(), "ilogb");
  323. return r;
  324. }
  325. NON_MEMBER_OP2(floor, "floor")
  326. NON_MEMBER_OP2(ceil, "ceil")
  327. NON_MEMBER_OP2(sqrt, "sqrt")
  328. template <class Backend>
  329. inline int eval_fpclassify(const logged_adaptor<Backend>& arg)
  330. {
  331. using default_ops::eval_fpclassify;
  332. log_prefix_event(arg.value(), "fpclassify");
  333. int r = eval_fpclassify(arg.value());
  334. log_postfix_event(arg.value(), r, "fpclassify");
  335. return r;
  336. }
  337. /*********************************************************************
  338. *
  339. * Optional arithmetic operations come next:
  340. *
  341. *********************************************************************/
  342. NON_MEMBER_OP3(add, "+")
  343. NON_MEMBER_OP3(subtract, "-")
  344. NON_MEMBER_OP3(multiply, "*")
  345. NON_MEMBER_OP3(divide, "/")
  346. NON_MEMBER_OP3(multiply_add, "fused-multiply-add")
  347. NON_MEMBER_OP3(multiply_subtract, "fused-multiply-subtract")
  348. NON_MEMBER_OP4(multiply_add, "fused-multiply-add")
  349. NON_MEMBER_OP4(multiply_subtract, "fused-multiply-subtract")
  350. NON_MEMBER_OP1(increment, "increment")
  351. NON_MEMBER_OP1(decrement, "decrement")
  352. /*********************************************************************
  353. *
  354. * Optional integer operations come next:
  355. *
  356. *********************************************************************/
  357. NON_MEMBER_OP2(modulus, "%=")
  358. NON_MEMBER_OP3(modulus, "%")
  359. NON_MEMBER_OP2(bitwise_or, "|=")
  360. NON_MEMBER_OP3(bitwise_or, "|")
  361. NON_MEMBER_OP2(bitwise_and, "&=")
  362. NON_MEMBER_OP3(bitwise_and, "&")
  363. NON_MEMBER_OP2(bitwise_xor, "^=")
  364. NON_MEMBER_OP3(bitwise_xor, "^")
  365. NON_MEMBER_OP4(qr, "quotient-and-remainder")
  366. NON_MEMBER_OP2(complement, "~")
  367. template <class Backend>
  368. inline void eval_left_shift(logged_adaptor<Backend>& arg, std::size_t a)
  369. {
  370. using default_ops::eval_left_shift;
  371. log_prefix_event(arg.value(), a, "<<=");
  372. eval_left_shift(arg.value(), a);
  373. log_postfix_event(arg.value(), "<<=");
  374. }
  375. template <class Backend>
  376. inline void eval_left_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, std::size_t b)
  377. {
  378. using default_ops::eval_left_shift;
  379. log_prefix_event(arg.value(), a, b, "<<");
  380. eval_left_shift(arg.value(), a.value(), b);
  381. log_postfix_event(arg.value(), "<<");
  382. }
  383. template <class Backend>
  384. inline void eval_right_shift(logged_adaptor<Backend>& arg, std::size_t a)
  385. {
  386. using default_ops::eval_right_shift;
  387. log_prefix_event(arg.value(), a, ">>=");
  388. eval_right_shift(arg.value(), a);
  389. log_postfix_event(arg.value(), ">>=");
  390. }
  391. template <class Backend>
  392. inline void eval_right_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, std::size_t b)
  393. {
  394. using default_ops::eval_right_shift;
  395. log_prefix_event(arg.value(), a, b, ">>");
  396. eval_right_shift(arg.value(), a.value(), b);
  397. log_postfix_event(arg.value(), ">>");
  398. }
  399. template <class Backend, class T>
  400. inline unsigned eval_integer_modulus(const logged_adaptor<Backend>& arg, const T& a)
  401. {
  402. using default_ops::eval_integer_modulus;
  403. log_prefix_event(arg.value(), a, "integer-modulus");
  404. unsigned r = eval_integer_modulus(arg.value(), a);
  405. log_postfix_event(arg.value(), r, "integer-modulus");
  406. return r;
  407. }
  408. template <class Backend>
  409. inline unsigned eval_lsb(const logged_adaptor<Backend>& arg)
  410. {
  411. using default_ops::eval_lsb;
  412. log_prefix_event(arg.value(), "least-significant-bit");
  413. unsigned r = eval_lsb(arg.value());
  414. log_postfix_event(arg.value(), r, "least-significant-bit");
  415. return r;
  416. }
  417. template <class Backend>
  418. inline unsigned eval_msb(const logged_adaptor<Backend>& arg)
  419. {
  420. using default_ops::eval_msb;
  421. log_prefix_event(arg.value(), "most-significant-bit");
  422. unsigned r = eval_msb(arg.value());
  423. log_postfix_event(arg.value(), r, "most-significant-bit");
  424. return r;
  425. }
  426. template <class Backend>
  427. inline bool eval_bit_test(const logged_adaptor<Backend>& arg, unsigned a)
  428. {
  429. using default_ops::eval_bit_test;
  430. log_prefix_event(arg.value(), a, "bit-test");
  431. bool r = eval_bit_test(arg.value(), a);
  432. log_postfix_event(arg.value(), r, "bit-test");
  433. return r;
  434. }
  435. template <class Backend>
  436. inline void eval_bit_set(const logged_adaptor<Backend>& arg, unsigned a)
  437. {
  438. using default_ops::eval_bit_set;
  439. log_prefix_event(arg.value(), a, "bit-set");
  440. eval_bit_set(arg.value(), a);
  441. log_postfix_event(arg.value(), arg, "bit-set");
  442. }
  443. template <class Backend>
  444. inline void eval_bit_unset(const logged_adaptor<Backend>& arg, unsigned a)
  445. {
  446. using default_ops::eval_bit_unset;
  447. log_prefix_event(arg.value(), a, "bit-unset");
  448. eval_bit_unset(arg.value(), a);
  449. log_postfix_event(arg.value(), arg, "bit-unset");
  450. }
  451. template <class Backend>
  452. inline void eval_bit_flip(const logged_adaptor<Backend>& arg, unsigned a)
  453. {
  454. using default_ops::eval_bit_flip;
  455. log_prefix_event(arg.value(), a, "bit-flip");
  456. eval_bit_flip(arg.value(), a);
  457. log_postfix_event(arg.value(), arg, "bit-flip");
  458. }
  459. NON_MEMBER_OP3(gcd, "gcd")
  460. NON_MEMBER_OP3(lcm, "lcm")
  461. NON_MEMBER_OP4(powm, "powm")
  462. /*********************************************************************
  463. *
  464. * abs/fabs:
  465. *
  466. *********************************************************************/
  467. NON_MEMBER_OP2(abs, "abs")
  468. NON_MEMBER_OP2(fabs, "fabs")
  469. /*********************************************************************
  470. *
  471. * Floating point functions:
  472. *
  473. *********************************************************************/
  474. NON_MEMBER_OP2(trunc, "trunc")
  475. NON_MEMBER_OP2(round, "round")
  476. NON_MEMBER_OP2(exp, "exp")
  477. NON_MEMBER_OP2(log, "log")
  478. NON_MEMBER_OP2(log10, "log10")
  479. NON_MEMBER_OP2(sin, "sin")
  480. NON_MEMBER_OP2(cos, "cos")
  481. NON_MEMBER_OP2(tan, "tan")
  482. NON_MEMBER_OP2(asin, "asin")
  483. NON_MEMBER_OP2(acos, "acos")
  484. NON_MEMBER_OP2(atan, "atan")
  485. NON_MEMBER_OP2(sinh, "sinh")
  486. NON_MEMBER_OP2(cosh, "cosh")
  487. NON_MEMBER_OP2(tanh, "tanh")
  488. NON_MEMBER_OP2(logb, "logb")
  489. NON_MEMBER_OP3(fmod, "fmod")
  490. NON_MEMBER_OP3(pow, "pow")
  491. NON_MEMBER_OP3(atan2, "atan2")
  492. template <class Backend>
  493. int eval_signbit(const logged_adaptor<Backend>& val)
  494. {
  495. using default_ops::eval_signbit;
  496. return eval_signbit(val.value());
  497. }
  498. template <class Backend>
  499. std::size_t hash_value(const logged_adaptor<Backend>& val)
  500. {
  501. return hash_value(val.value());
  502. }
  503. #define NON_MEMBER_COMPLEX_TO_REAL(name, str) \
  504. template <class B1, class B2>\
  505. inline void BOOST_JOIN(eval_, name)(logged_adaptor<B1>& result, const logged_adaptor<B2>& a)\
  506. {\
  507. using default_ops::BOOST_JOIN(eval_, name);\
  508. log_prefix_event(a.value(), a.value(), str);\
  509. BOOST_JOIN(eval_, name)(result.value(), a.value());\
  510. log_postfix_event(result.value(), str);\
  511. }\
  512. template <class B1, class B2>\
  513. inline void BOOST_JOIN(eval_, name)(B1& result, const logged_adaptor<B2>& a)\
  514. {\
  515. using default_ops::BOOST_JOIN(eval_, name);\
  516. log_prefix_event(a.value(), a.value(), str);\
  517. BOOST_JOIN(eval_, name)(result, a.value());\
  518. log_postfix_event(result, str);\
  519. }
  520. NON_MEMBER_COMPLEX_TO_REAL(real, "real")
  521. NON_MEMBER_COMPLEX_TO_REAL(imag, "imag")
  522. template <class T, class V, class U>
  523. inline void assign_components(logged_adaptor<T>& result, const V& v1, const U& v2)
  524. {
  525. assign_components(result.value(), v1, v2);
  526. }
  527. } // namespace backends
  528. using backends::logged_adaptor;
  529. template<class Backend>
  530. struct number_category<backends::logged_adaptor<Backend> > : public number_category<Backend> {};
  531. }} // namespaces
  532. namespace std{
  533. template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
  534. class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates> >
  535. : public std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> >
  536. {
  537. typedef std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> > base_type;
  538. typedef boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates> number_type;
  539. public:
  540. static number_type (min)() BOOST_NOEXCEPT { return (base_type::min)(); }
  541. static number_type (max)() BOOST_NOEXCEPT { return (base_type::max)(); }
  542. static number_type lowest() BOOST_NOEXCEPT { return -(max)(); }
  543. static number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); }
  544. static number_type round_error() BOOST_NOEXCEPT { return epsilon() / 2; }
  545. static number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); }
  546. static number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); }
  547. static number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); }
  548. static number_type denorm_min() BOOST_NOEXCEPT { return base_type::denorm_min(); }
  549. };
  550. } // namespace std
  551. namespace boost{ namespace math{
  552. namespace policies{
  553. template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
  554. struct precision< boost::multiprecision::number<boost::multiprecision::logged_adaptor<Backend>, ExpressionTemplates>, Policy>
  555. : public precision<boost::multiprecision::number<Backend, ExpressionTemplates>, Policy>
  556. {};
  557. } // namespace policies
  558. }} // namespaces boost::math
  559. #undef NON_MEMBER_OP1
  560. #undef NON_MEMBER_OP2
  561. #undef NON_MEMBER_OP3
  562. #undef NON_MEMBER_OP4
  563. #endif