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
12 namespace boost{
13 namespace multiprecision{
14
15 template <class Backend>
log_postfix_event(const Backend &,const char *)16 inline void log_postfix_event(const Backend&, const char* /*event_description*/)
17 {
18 }
19 template <class Backend, class T>
log_postfix_event(const Backend &,const T &,const char *)20 inline void log_postfix_event(const Backend&, const T&, const char* /*event_description*/)
21 {
22 }
23 template <class Backend>
log_prefix_event(const Backend &,const char *)24 inline void log_prefix_event(const Backend&, const char* /*event_description*/)
25 {
26 }
27 template <class Backend, class T>
log_prefix_event(const Backend &,const T &,const char *)28 inline void log_prefix_event(const Backend&, const T&, const char* /*event_description*/)
29 {
30 }
31 template <class Backend, class T, class U>
log_prefix_event(const Backend &,const T &,const U &,const char *)32 inline void log_prefix_event(const Backend&, const T&, const U&, const char* /*event_description*/)
33 {
34 }
35 template <class Backend, class T, class U, class V>
log_prefix_event(const Backend &,const T &,const U &,const V &,const char *)36 inline void log_prefix_event(const Backend&, const T&, const U&, const V&, const char* /*event_description*/)
37 {
38 }
39
40 namespace backends{
41
42 template <class Backend>
43 struct 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
51 private:
52
53 Backend m_value;
54 public:
logged_adaptorboost::multiprecision::backends::logged_adaptor55 logged_adaptor()
56 {
57 log_postfix_event(m_value, "Default construct");
58 }
logged_adaptorboost::multiprecision::backends::logged_adaptor59 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 }
operator =boost::multiprecision::backends::logged_adaptor65 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>
logged_adaptorboost::multiprecision::backends::logged_adaptor73 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>
operator =boost::multiprecision::backends::logged_adaptor79 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 }
operator =boost::multiprecision::backends::logged_adaptor86 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 }
swapboost::multiprecision::backends::logged_adaptor93 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 }
strboost::multiprecision::backends::logged_adaptor99 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 }
negateboost::multiprecision::backends::logged_adaptor106 void negate()
107 {
108 log_prefix_event(m_value, "negate");
109 m_value.negate();
110 log_postfix_event(m_value, "negate");
111 }
compareboost::multiprecision::backends::logged_adaptor112 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>
compareboost::multiprecision::backends::logged_adaptor120 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 }
valueboost::multiprecision::backends::logged_adaptor127 Backend& value()
128 {
129 return m_value;
130 }
valueboost::multiprecision::backends::logged_adaptor131 const Backend& value()const
132 {
133 return m_value;
134 }
135 template <class Archive>
serializeboost::multiprecision::backends::logged_adaptor136 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 };
143
144 template <class T>
unwrap_logged_type(const T & a)145 inline const T& unwrap_logged_type(const T& a) { return a; }
146 template <class Backend>
unwrap_logged_type(const logged_adaptor<Backend> & a)147 inline const Backend& unwrap_logged_type(const logged_adaptor<Backend>& a) { return a.value(); }
148
149 #define NON_MEMBER_OP1(name, str) \
150 template <class Backend>\
151 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result)\
152 {\
153 using default_ops::BOOST_JOIN(eval_, name);\
154 log_prefix_event(result.value(), str);\
155 BOOST_JOIN(eval_, name)(result.value());\
156 log_postfix_event(result.value(), str);\
157 }
158
159 #define NON_MEMBER_OP2(name, str) \
160 template <class Backend, class T>\
161 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a)\
162 {\
163 using default_ops::BOOST_JOIN(eval_, name);\
164 log_prefix_event(result.value(), unwrap_logged_type(a), str);\
165 BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a));\
166 log_postfix_event(result.value(), str);\
167 }\
168 template <class Backend>\
169 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a)\
170 {\
171 using default_ops::BOOST_JOIN(eval_, name);\
172 log_prefix_event(result.value(), unwrap_logged_type(a), str);\
173 BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a));\
174 log_postfix_event(result.value(), str);\
175 }
176
177 #define NON_MEMBER_OP3(name, str) \
178 template <class Backend, class T, class U>\
179 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const U& b)\
180 {\
181 using default_ops::BOOST_JOIN(eval_, name);\
182 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\
183 BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\
184 log_postfix_event(result.value(), str);\
185 }\
186 template <class Backend, class T>\
187 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const T& b)\
188 {\
189 using default_ops::BOOST_JOIN(eval_, name);\
190 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str);\
191 BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b));\
192 log_postfix_event(result.value(), str);\
193 }\
194 template <class Backend, class T>\
195 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const logged_adaptor<Backend>& 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>\
203 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& 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
211 #define NON_MEMBER_OP4(name, str) \
212 template <class Backend, class T, class U, class V>\
213 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const T& a, const U& b, const V& c)\
214 {\
215 using default_ops::BOOST_JOIN(eval_, name);\
216 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\
217 BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\
218 log_postfix_event(result.value(), str);\
219 }\
220 template <class Backend, class T>\
221 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b, const T& c)\
222 {\
223 using default_ops::BOOST_JOIN(eval_, name);\
224 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str);\
225 BOOST_JOIN(eval_, name)(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c));\
226 log_postfix_event(result.value(), str);\
227 }\
228 template <class Backend, class T>\
229 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const T& b, const logged_adaptor<Backend>& 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 T& a, const logged_adaptor<Backend>& b, const logged_adaptor<Backend>& 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>\
245 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)\
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, class U>\
253 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& a, const T& b, const U& 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
261 NON_MEMBER_OP2(add, "+=");
262 NON_MEMBER_OP2(subtract, "-=");
263 NON_MEMBER_OP2(multiply, "*=");
264 NON_MEMBER_OP2(divide, "/=");
265
266 template <class Backend, class R>
eval_convert_to(R * result,const logged_adaptor<Backend> & val)267 inline void eval_convert_to(R* result, const logged_adaptor<Backend>& val)
268 {
269 using default_ops::eval_convert_to;
270 log_prefix_event(val.value(), "convert_to");
271 eval_convert_to(result, val.value());
272 log_postfix_event(val.value(), *result, "convert_to");
273 }
274
275 template <class Backend, class Exp>
eval_frexp(logged_adaptor<Backend> & result,const logged_adaptor<Backend> & arg,Exp * exp)276 inline void eval_frexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp* exp)
277 {
278 log_prefix_event(arg.value(), "frexp");
279 eval_frexp(result.value(), arg.value(), exp);
280 log_postfix_event(result.value(), *exp, "frexp");
281 }
282
283 template <class Backend, class Exp>
eval_ldexp(logged_adaptor<Backend> & result,const logged_adaptor<Backend> & arg,Exp exp)284 inline void eval_ldexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp)
285 {
286 log_prefix_event(arg.value(), "ldexp");
287 eval_ldexp(result.value(), arg.value(), exp);
288 log_postfix_event(result.value(), exp, "ldexp");
289 }
290
291 template <class Backend, class Exp>
eval_scalbn(logged_adaptor<Backend> & result,const logged_adaptor<Backend> & arg,Exp exp)292 inline void eval_scalbn(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp)
293 {
294 log_prefix_event(arg.value(), "scalbn");
295 eval_scalbn(result.value(), arg.value(), exp);
296 log_postfix_event(result.value(), exp, "scalbn");
297 }
298
299 template <class Backend>
eval_ilogb(const logged_adaptor<Backend> & arg)300 inline typename Backend::exponent_type eval_ilogb(const logged_adaptor<Backend>& arg)
301 {
302 log_prefix_event(arg.value(), "ilogb");
303 typename Backend::exponent_type r = eval_ilogb(arg.value());
304 log_postfix_event(arg.value(), "ilogb");
305 return r;
306 }
307
308 NON_MEMBER_OP2(floor, "floor");
309 NON_MEMBER_OP2(ceil, "ceil");
310 NON_MEMBER_OP2(sqrt, "sqrt");
311
312 template <class Backend>
eval_fpclassify(const logged_adaptor<Backend> & arg)313 inline int eval_fpclassify(const logged_adaptor<Backend>& arg)
314 {
315 using default_ops::eval_fpclassify;
316 log_prefix_event(arg.value(), "fpclassify");
317 int r = eval_fpclassify(arg.value());
318 log_postfix_event(arg.value(), r, "fpclassify");
319 return r;
320 }
321
322 /*********************************************************************
323 *
324 * Optional arithmetic operations come next:
325 *
326 *********************************************************************/
327
328 NON_MEMBER_OP3(add, "+");
329 NON_MEMBER_OP3(subtract, "-");
330 NON_MEMBER_OP3(multiply, "*");
331 NON_MEMBER_OP3(divide, "/");
332 NON_MEMBER_OP3(multiply_add, "fused-multiply-add");
333 NON_MEMBER_OP3(multiply_subtract, "fused-multiply-subtract");
334 NON_MEMBER_OP4(multiply_add, "fused-multiply-add");
335 NON_MEMBER_OP4(multiply_subtract, "fused-multiply-subtract");
336
337 NON_MEMBER_OP1(increment, "increment");
338 NON_MEMBER_OP1(decrement, "decrement");
339
340 /*********************************************************************
341 *
342 * Optional integer operations come next:
343 *
344 *********************************************************************/
345
346 NON_MEMBER_OP2(modulus, "%=");
347 NON_MEMBER_OP3(modulus, "%");
348 NON_MEMBER_OP2(bitwise_or, "|=");
349 NON_MEMBER_OP3(bitwise_or, "|");
350 NON_MEMBER_OP2(bitwise_and, "&=");
351 NON_MEMBER_OP3(bitwise_and, "&");
352 NON_MEMBER_OP2(bitwise_xor, "^=");
353 NON_MEMBER_OP3(bitwise_xor, "^");
354 NON_MEMBER_OP4(qr, "quotient-and-remainder");
355 NON_MEMBER_OP2(complement, "~");
356
357 template <class Backend>
eval_left_shift(logged_adaptor<Backend> & arg,unsigned a)358 inline void eval_left_shift(logged_adaptor<Backend>& arg, unsigned a)
359 {
360 using default_ops::eval_left_shift;
361 log_prefix_event(arg.value(), a, "<<=");
362 eval_left_shift(arg.value(), a);
363 log_postfix_event(arg.value(), "<<=");
364 }
365 template <class Backend>
eval_left_shift(logged_adaptor<Backend> & arg,const logged_adaptor<Backend> & a,unsigned b)366 inline void eval_left_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, unsigned b)
367 {
368 using default_ops::eval_left_shift;
369 log_prefix_event(arg.value(), a, b, "<<");
370 eval_left_shift(arg.value(), a.value(), b);
371 log_postfix_event(arg.value(), "<<");
372 }
373 template <class Backend>
eval_right_shift(logged_adaptor<Backend> & arg,unsigned a)374 inline void eval_right_shift(logged_adaptor<Backend>& arg, unsigned a)
375 {
376 using default_ops::eval_right_shift;
377 log_prefix_event(arg.value(), a, ">>=");
378 eval_right_shift(arg.value(), a);
379 log_postfix_event(arg.value(), ">>=");
380 }
381 template <class Backend>
eval_right_shift(logged_adaptor<Backend> & arg,const logged_adaptor<Backend> & a,unsigned b)382 inline void eval_right_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, unsigned b)
383 {
384 using default_ops::eval_right_shift;
385 log_prefix_event(arg.value(), a, b, ">>");
386 eval_right_shift(arg.value(), a.value(), b);
387 log_postfix_event(arg.value(), ">>");
388 }
389
390 template <class Backend, class T>
eval_integer_modulus(const logged_adaptor<Backend> & arg,const T & a)391 inline unsigned eval_integer_modulus(const logged_adaptor<Backend>& arg, const T& a)
392 {
393 using default_ops::eval_integer_modulus;
394 log_prefix_event(arg.value(), a, "integer-modulus");
395 unsigned r = eval_integer_modulus(arg.value(), a);
396 log_postfix_event(arg.value(), r, "integer-modulus");
397 return r;
398 }
399
400 template <class Backend>
eval_lsb(const logged_adaptor<Backend> & arg)401 inline unsigned eval_lsb(const logged_adaptor<Backend>& arg)
402 {
403 using default_ops::eval_lsb;
404 log_prefix_event(arg.value(), "least-significant-bit");
405 unsigned r = eval_lsb(arg.value());
406 log_postfix_event(arg.value(), r, "least-significant-bit");
407 return r;
408 }
409
410 template <class Backend>
eval_msb(const logged_adaptor<Backend> & arg)411 inline unsigned eval_msb(const logged_adaptor<Backend>& arg)
412 {
413 using default_ops::eval_msb;
414 log_prefix_event(arg.value(), "most-significant-bit");
415 unsigned r = eval_msb(arg.value());
416 log_postfix_event(arg.value(), r, "most-significant-bit");
417 return r;
418 }
419
420 template <class Backend>
eval_bit_test(const logged_adaptor<Backend> & arg,unsigned a)421 inline bool eval_bit_test(const logged_adaptor<Backend>& arg, unsigned a)
422 {
423 using default_ops::eval_bit_test;
424 log_prefix_event(arg.value(), a, "bit-test");
425 bool r = eval_bit_test(arg.value(), a);
426 log_postfix_event(arg.value(), r, "bit-test");
427 return r;
428 }
429
430 template <class Backend>
eval_bit_set(const logged_adaptor<Backend> & arg,unsigned a)431 inline void eval_bit_set(const logged_adaptor<Backend>& arg, unsigned a)
432 {
433 using default_ops::eval_bit_set;
434 log_prefix_event(arg.value(), a, "bit-set");
435 eval_bit_set(arg.value(), a);
436 log_postfix_event(arg.value(), arg, "bit-set");
437 }
438 template <class Backend>
eval_bit_unset(const logged_adaptor<Backend> & arg,unsigned a)439 inline void eval_bit_unset(const logged_adaptor<Backend>& arg, unsigned a)
440 {
441 using default_ops::eval_bit_unset;
442 log_prefix_event(arg.value(), a, "bit-unset");
443 eval_bit_unset(arg.value(), a);
444 log_postfix_event(arg.value(), arg, "bit-unset");
445 }
446 template <class Backend>
eval_bit_flip(const logged_adaptor<Backend> & arg,unsigned a)447 inline void eval_bit_flip(const logged_adaptor<Backend>& arg, unsigned a)
448 {
449 using default_ops::eval_bit_flip;
450 log_prefix_event(arg.value(), a, "bit-flip");
451 eval_bit_flip(arg.value(), a);
452 log_postfix_event(arg.value(), arg, "bit-flip");
453 }
454
455 NON_MEMBER_OP3(gcd, "gcd");
456 NON_MEMBER_OP3(lcm, "lcm");
457 NON_MEMBER_OP4(powm, "powm");
458
459 /*********************************************************************
460 *
461 * abs/fabs:
462 *
463 *********************************************************************/
464
465 NON_MEMBER_OP2(abs, "abs");
466 NON_MEMBER_OP2(fabs, "fabs");
467
468 /*********************************************************************
469 *
470 * Floating point functions:
471 *
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
493 } // namespace backends
494
495 using backends::logged_adaptor;
496
497 template<class Backend>
498 struct number_category<backends::logged_adaptor<Backend> > : public number_category<Backend> {};
499
500 }} // namespaces
501
502 namespace std{
503
504 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
505 class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates> >
506 : public std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> >
507 {
508 typedef std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> > base_type;
509 typedef boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates> number_type;
510 public:
number_type(min)511 static number_type (min)() BOOST_NOEXCEPT { return (base_type::min)(); }
number_type(max)512 static number_type (max)() BOOST_NOEXCEPT { return (base_type::max)(); }
lowest()513 static number_type lowest() BOOST_NOEXCEPT { return -(max)(); }
epsilon()514 static number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); }
round_error()515 static number_type round_error() BOOST_NOEXCEPT { return epsilon() / 2; }
infinity()516 static number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); }
quiet_NaN()517 static number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); }
signaling_NaN()518 static number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); }
denorm_min()519 static number_type denorm_min() BOOST_NOEXCEPT { return base_type::denorm_min(); }
520 };
521
522 } // namespace std
523
524 namespace boost{ namespace math{
525
526 namespace policies{
527
528 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
529 struct precision< boost::multiprecision::number<boost::multiprecision::logged_adaptor<Backend>, ExpressionTemplates>, Policy>
530 : public precision<boost::multiprecision::number<Backend, ExpressionTemplates>, Policy>
531 {};
532
533 } // namespace policies
534
535 }} // namespaces boost::math
536
537 #undef NON_MEMBER_OP1
538 #undef NON_MEMBER_OP2
539 #undef NON_MEMBER_OP3
540 #undef NON_MEMBER_OP4
541
542 #endif
543