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