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