]>
Commit | Line | Data |
---|---|---|
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 | ||
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 | 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 | ||
160 | template <class T> | |
161 | inline const T& unwrap_logged_type(const T& a) { return a; } | |
162 | template <class Backend> | |
163 | inline 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 | ||
277 | NON_MEMBER_OP2(add, "+="); | |
278 | NON_MEMBER_OP2(subtract, "-="); | |
279 | NON_MEMBER_OP2(multiply, "*="); | |
280 | NON_MEMBER_OP2(divide, "/="); | |
281 | ||
282 | template <class Backend, class R> | |
283 | inline 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 | ||
291 | template <class Backend, class Exp> | |
292 | inline 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 | ||
299 | template <class Backend, class Exp> | |
300 | inline 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 | ||
307 | template <class Backend, class Exp> | |
308 | inline 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 | ||
315 | template <class Backend> | |
316 | inline 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 | ||
324 | NON_MEMBER_OP2(floor, "floor"); | |
325 | NON_MEMBER_OP2(ceil, "ceil"); | |
326 | NON_MEMBER_OP2(sqrt, "sqrt"); | |
327 | ||
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 | * | |
340 | * Optional arithmetic operations come next: | |
341 | * | |
342 | *********************************************************************/ | |
343 | ||
344 | NON_MEMBER_OP3(add, "+"); | |
345 | NON_MEMBER_OP3(subtract, "-"); | |
346 | NON_MEMBER_OP3(multiply, "*"); | |
347 | NON_MEMBER_OP3(divide, "/"); | |
348 | NON_MEMBER_OP3(multiply_add, "fused-multiply-add"); | |
349 | NON_MEMBER_OP3(multiply_subtract, "fused-multiply-subtract"); | |
350 | NON_MEMBER_OP4(multiply_add, "fused-multiply-add"); | |
351 | NON_MEMBER_OP4(multiply_subtract, "fused-multiply-subtract"); | |
352 | ||
353 | NON_MEMBER_OP1(increment, "increment"); | |
354 | NON_MEMBER_OP1(decrement, "decrement"); | |
355 | ||
356 | /********************************************************************* | |
357 | * | |
358 | * Optional integer operations come next: | |
359 | * | |
360 | *********************************************************************/ | |
361 | ||
362 | NON_MEMBER_OP2(modulus, "%="); | |
363 | NON_MEMBER_OP3(modulus, "%"); | |
364 | NON_MEMBER_OP2(bitwise_or, "|="); | |
365 | NON_MEMBER_OP3(bitwise_or, "|"); | |
366 | NON_MEMBER_OP2(bitwise_and, "&="); | |
367 | NON_MEMBER_OP3(bitwise_and, "&"); | |
368 | NON_MEMBER_OP2(bitwise_xor, "^="); | |
369 | NON_MEMBER_OP3(bitwise_xor, "^"); | |
370 | NON_MEMBER_OP4(qr, "quotient-and-remainder"); | |
371 | NON_MEMBER_OP2(complement, "~"); | |
372 | ||
373 | template <class Backend> | |
374 | inline 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 | } | |
381 | template <class Backend> | |
382 | inline 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 | } | |
389 | template <class Backend> | |
390 | inline 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 | } | |
397 | template <class Backend> | |
398 | inline 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 | ||
406 | template <class Backend, class T> | |
407 | inline 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 | ||
416 | template <class Backend> | |
417 | inline 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 | ||
426 | template <class Backend> | |
427 | inline 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 | ||
436 | template <class Backend> | |
437 | inline 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 | ||
446 | template <class Backend> | |
447 | inline 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 | } | |
454 | template <class Backend> | |
455 | inline 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 | } | |
462 | template <class Backend> | |
463 | inline 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 | ||
471 | NON_MEMBER_OP3(gcd, "gcd"); | |
472 | NON_MEMBER_OP3(lcm, "lcm"); | |
473 | NON_MEMBER_OP4(powm, "powm"); | |
474 | ||
475 | /********************************************************************* | |
476 | * | |
477 | * abs/fabs: | |
478 | * | |
479 | *********************************************************************/ | |
480 | ||
481 | NON_MEMBER_OP2(abs, "abs"); | |
482 | NON_MEMBER_OP2(fabs, "fabs"); | |
483 | ||
484 | /********************************************************************* | |
485 | * | |
486 | * Floating point functions: | |
487 | * | |
488 | *********************************************************************/ | |
489 | ||
490 | NON_MEMBER_OP2(trunc, "trunc"); | |
491 | NON_MEMBER_OP2(round, "round"); | |
492 | NON_MEMBER_OP2(exp, "exp"); | |
493 | NON_MEMBER_OP2(log, "log"); | |
494 | NON_MEMBER_OP2(log10, "log10"); | |
495 | NON_MEMBER_OP2(sin, "sin"); | |
496 | NON_MEMBER_OP2(cos, "cos"); | |
497 | NON_MEMBER_OP2(tan, "tan"); | |
498 | NON_MEMBER_OP2(asin, "asin"); | |
499 | NON_MEMBER_OP2(acos, "acos"); | |
500 | NON_MEMBER_OP2(atan, "atan"); | |
501 | NON_MEMBER_OP2(sinh, "sinh"); | |
502 | NON_MEMBER_OP2(cosh, "cosh"); | |
503 | NON_MEMBER_OP2(tanh, "tanh"); | |
504 | NON_MEMBER_OP2(logb, "logb"); | |
505 | NON_MEMBER_OP3(fmod, "fmod"); | |
506 | NON_MEMBER_OP3(pow, "pow"); | |
507 | NON_MEMBER_OP3(atan2, "atan2"); | |
508 | ||
509 | template <class Backend> | |
510 | std::size_t hash_value(const logged_adaptor<Backend>& val) | |
511 | { | |
512 | return hash_value(val.value()); | |
513 | } | |
514 | ||
515 | } // namespace backends | |
516 | ||
517 | using backends::logged_adaptor; | |
518 | ||
519 | template<class Backend> | |
520 | struct number_category<backends::logged_adaptor<Backend> > : public number_category<Backend> {}; | |
521 | ||
522 | }} // namespaces | |
523 | ||
524 | namespace std{ | |
525 | ||
526 | template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates> | |
527 | class 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; | |
532 | public: | |
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 | ||
546 | namespace boost{ namespace math{ | |
547 | ||
548 | namespace policies{ | |
549 | ||
550 | template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy> | |
551 | struct 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 |