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