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