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> |
16 | inline void log_postfix_event(const Backend&, const char* /*event_description*/) |
17 | { |
18 | } |
19 | template <class Backend, class T> |
20 | inline void log_postfix_event(const Backend&, const T&, const char* /*event_description*/) |
21 | { |
22 | } |
23 | template <class Backend> |
24 | inline void log_prefix_event(const Backend&, const char* /*event_description*/) |
25 | { |
26 | } |
27 | template <class Backend, class T> |
28 | inline void log_prefix_event(const Backend&, const T&, const char* /*event_description*/) |
29 | { |
30 | } |
31 | template <class Backend, class T, class U> |
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> |
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: |
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 | }; |
143 | |
144 | template <class T> |
145 | inline const T& unwrap_logged_type(const T& a) { return a; } |
146 | template <class Backend> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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> |
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: |
511 | static number_type (min)() BOOST_NOEXCEPT { return (base_type::min)(); } |
512 | static number_type (max)() BOOST_NOEXCEPT { return (base_type::max)(); } |
513 | static number_type lowest() BOOST_NOEXCEPT { return -(max)(); } |
514 | static number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); } |
515 | static number_type round_error() BOOST_NOEXCEPT { return epsilon() / 2; } |
516 | static number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); } |
517 | static number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); } |
518 | static number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); } |
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 | |