]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/multiprecision/logged_adaptor.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / multiprecision / logged_adaptor.hpp
CommitLineData
7c673cae
FG
1///////////////////////////////////////////////////////////////
2// Copyright 2012 John Maddock. Distributed under the Boost
3// Software License, Version 1.0. (See accompanying file
92f5a8d4 4// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
7c673cae
FG
5
6#ifndef BOOST_MATH_LOGGED_ADAPTER_HPP
7#define BOOST_MATH_LOGGED_ADAPTER_HPP
8
1e59de90 9#include <boost/multiprecision/detail/standalone_config.hpp>
7c673cae
FG
10#include <boost/multiprecision/traits/extract_exponent_type.hpp>
11#include <boost/multiprecision/detail/integer_ops.hpp>
12
92f5a8d4
TL
13namespace boost {
14namespace multiprecision {
7c673cae
FG
15
16template <class Backend>
17inline void log_postfix_event(const Backend&, const char* /*event_description*/)
18{
19}
20template <class Backend, class T>
21inline void log_postfix_event(const Backend&, const T&, const char* /*event_description*/)
22{
23}
24template <class Backend>
25inline void log_prefix_event(const Backend&, const char* /*event_description*/)
26{
27}
28template <class Backend, class T>
29inline void log_prefix_event(const Backend&, const T&, const char* /*event_description*/)
30{
31}
32template <class Backend, class T, class U>
33inline void log_prefix_event(const Backend&, const T&, const U&, const char* /*event_description*/)
34{
35}
36template <class Backend, class T, class U, class V>
37inline void log_prefix_event(const Backend&, const T&, const U&, const V&, const char* /*event_description*/)
38{
39}
40
92f5a8d4 41namespace backends {
7c673cae
FG
42
43template <class Backend>
44struct logged_adaptor
45{
1e59de90
TL
46 using signed_types = typename Backend::signed_types ;
47 using unsigned_types = typename Backend::unsigned_types;
48 using float_types = typename Backend::float_types ;
49 using exponent_type = typename extract_exponent_type<Backend, number_category<Backend>::value>::type;
7c673cae 50
92f5a8d4 51 private:
7c673cae 52 Backend m_value;
92f5a8d4
TL
53
54 public:
7c673cae
FG
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 }
1e59de90 65 // rvalue copy
92f5a8d4
TL
66 logged_adaptor(logged_adaptor&& o)
67 {
68 log_prefix_event(m_value, o.value(), "Move construct");
69 m_value = static_cast<Backend&&>(o.m_value);
70 log_postfix_event(m_value, "Move construct");
71 }
72 logged_adaptor& operator=(logged_adaptor&& o)
73 {
74 log_prefix_event(m_value, o.value(), "Move Assignment");
75 m_value = static_cast<Backend&&>(o.m_value);
76 log_postfix_event(m_value, "Move construct");
77 return *this;
78 }
92f5a8d4 79 logged_adaptor& operator=(const logged_adaptor& o)
7c673cae
FG
80 {
81 log_prefix_event(m_value, o.value(), "Assignment");
82 m_value = o.m_value;
83 log_postfix_event(m_value, "Copy construct");
84 return *this;
85 }
86 template <class T>
1e59de90 87 logged_adaptor(const T& i, const typename std::enable_if<std::is_convertible<T, Backend>::value>::type* = 0)
92f5a8d4
TL
88 : m_value(i)
89 {
90 log_postfix_event(m_value, "construct from arithmetic type");
91 }
92 template <class T>
1e59de90 93 logged_adaptor(const logged_adaptor<T>& i, const typename std::enable_if<std::is_convertible<T, Backend>::value>::type* = 0)
92f5a8d4 94 : m_value(i.value())
7c673cae
FG
95 {
96 log_postfix_event(m_value, "construct from arithmetic type");
97 }
1e59de90
TL
98 template <class T, class U>
99 logged_adaptor(const T& i, const U& j, typename std::enable_if<std::is_constructible<Backend, const T&, const U&>::value>::type* = nullptr)
100 : m_value(i, j)
101 {
102 log_postfix_event(m_value, "construct from a pair of arithmetic types");
103 }
104 template <class D = Backend>
105 logged_adaptor(const Backend& i, unsigned digits10, typename std::enable_if<std::is_constructible<D, Backend const&, unsigned>::value>::type const* = nullptr)
106 : m_value(i, digits10)
107 {
108 log_postfix_event(m_value, "construct from arithmetic type and precision");
109 }
110 template <class D = Backend>
111 logged_adaptor(const logged_adaptor<Backend>& i, unsigned digits10, typename std::enable_if<std::is_constructible<D, Backend const&, unsigned>::value>::type const* = nullptr)
112 : m_value(i.value(), digits10)
113 {
114 log_postfix_event(m_value, "construct from arithmetic type and precision");
115 }
7c673cae 116 template <class T>
1e59de90 117 typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value || std::is_assignable<Backend, T>::value, logged_adaptor&>::type operator=(const T& i)
7c673cae
FG
118 {
119 log_prefix_event(m_value, i, "Assignment from arithmetic type");
120 m_value = i;
121 log_postfix_event(m_value, "Assignment from arithmetic type");
122 return *this;
123 }
92f5a8d4 124 logged_adaptor& operator=(const char* s)
7c673cae
FG
125 {
126 log_prefix_event(m_value, s, "Assignment from string type");
127 m_value = s;
128 log_postfix_event(m_value, "Assignment from string type");
129 return *this;
130 }
131 void swap(logged_adaptor& o)
132 {
133 log_prefix_event(m_value, o.value(), "swap");
134 std::swap(m_value, o.value());
135 log_postfix_event(m_value, "swap");
136 }
92f5a8d4 137 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
7c673cae
FG
138 {
139 log_prefix_event(m_value, "Conversion to string");
140 std::string s = m_value.str(digits, f);
141 log_postfix_event(m_value, s, "Conversion to string");
142 return s;
143 }
144 void negate()
145 {
146 log_prefix_event(m_value, "negate");
147 m_value.negate();
148 log_postfix_event(m_value, "negate");
149 }
92f5a8d4 150 int compare(const logged_adaptor& o) const
7c673cae
FG
151 {
152 log_prefix_event(m_value, o.value(), "compare");
153 int r = m_value.compare(o.value());
154 log_postfix_event(m_value, r, "compare");
155 return r;
156 }
157 template <class T>
92f5a8d4 158 int compare(const T& i) const
7c673cae
FG
159 {
160 log_prefix_event(m_value, i, "compare");
161 int r = m_value.compare(i);
162 log_postfix_event(m_value, r, "compare");
163 return r;
164 }
165 Backend& value()
166 {
167 return m_value;
168 }
92f5a8d4 169 const Backend& value() const
7c673cae
FG
170 {
171 return m_value;
172 }
1e59de90
TL
173
174 #ifndef BOOST_MP_STANDALONE
7c673cae
FG
175 template <class Archive>
176 void serialize(Archive& ar, const unsigned int /*version*/)
177 {
178 log_prefix_event(m_value, "serialize");
92f5a8d4 179 ar& boost::make_nvp("value", m_value);
7c673cae
FG
180 log_postfix_event(m_value, "serialize");
181 }
1e59de90
TL
182 #endif
183
184 static unsigned default_precision() noexcept
7c673cae
FG
185 {
186 return Backend::default_precision();
187 }
1e59de90 188 static void default_precision(unsigned v) noexcept
7c673cae
FG
189 {
190 Backend::default_precision(v);
191 }
1e59de90
TL
192 static unsigned thread_default_precision() noexcept
193 {
194 return Backend::thread_default_precision();
195 }
196 static void thread_default_precision(unsigned v) noexcept
197 {
198 Backend::thread_default_precision(v);
199 }
200 unsigned precision() const noexcept
7c673cae
FG
201 {
202 return value().precision();
203 }
1e59de90 204 void precision(unsigned digits10) noexcept
7c673cae
FG
205 {
206 value().precision(digits10);
207 }
1e59de90
TL
208 //
209 // Variable precision options:
210 //
211 static constexpr variable_precision_options default_variable_precision_options()noexcept
212 {
213 return Backend::default_variable_precision_options();
214 }
215 static constexpr variable_precision_options thread_default_variable_precision_options()noexcept
216 {
217 return Backend::thread_default_variable_precision_options();
218 }
219 static BOOST_MP_CXX14_CONSTEXPR void default_variable_precision_options(variable_precision_options opts)
220 {
221 Backend::default_variable_precision_options(opts);
222 }
223 static BOOST_MP_CXX14_CONSTEXPR void thread_default_variable_precision_options(variable_precision_options opts)
224 {
225 Backend::thread_default_variable_precision_options(opts);
226 }
7c673cae
FG
227};
228
229template <class T>
230inline const T& unwrap_logged_type(const T& a) { return a; }
231template <class Backend>
232inline const Backend& unwrap_logged_type(const logged_adaptor<Backend>& a) { return a.value(); }
233
92f5a8d4
TL
234#define NON_MEMBER_OP1(name, str) \
235 template <class Backend> \
236 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result) \
237 { \
238 using default_ops::BOOST_JOIN(eval_, name); \
239 log_prefix_event(result.value(), str); \
240 BOOST_JOIN(eval_, name) \
241 (result.value()); \
242 log_postfix_event(result.value(), str); \
7c673cae
FG
243 }
244
92f5a8d4
TL
245#define NON_MEMBER_OP2(name, str) \
246 template <class Backend, class T> \
247 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a) \
248 { \
249 using default_ops::BOOST_JOIN(eval_, name); \
250 log_prefix_event(result.value(), unwrap_logged_type(a), str); \
251 BOOST_JOIN(eval_, name) \
252 (result.value(), unwrap_logged_type(a)); \
253 log_postfix_event(result.value(), str); \
254 } \
255 template <class Backend> \
256 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a) \
257 { \
258 using default_ops::BOOST_JOIN(eval_, name); \
259 log_prefix_event(result.value(), unwrap_logged_type(a), str); \
260 BOOST_JOIN(eval_, name) \
261 (result.value(), unwrap_logged_type(a)); \
262 log_postfix_event(result.value(), str); \
7c673cae
FG
263 }
264
92f5a8d4
TL
265#define NON_MEMBER_OP3(name, str) \
266 template <class Backend, class T, class U> \
267 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a, const U& b) \
268 { \
269 using default_ops::BOOST_JOIN(eval_, name); \
270 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str); \
271 BOOST_JOIN(eval_, name) \
272 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b)); \
273 log_postfix_event(result.value(), str); \
274 } \
275 template <class Backend, class T> \
276 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const T& b) \
277 { \
278 using default_ops::BOOST_JOIN(eval_, name); \
279 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str); \
280 BOOST_JOIN(eval_, name) \
281 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b)); \
282 log_postfix_event(result.value(), str); \
283 } \
284 template <class Backend, class T> \
285 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a, const logged_adaptor<Backend>& b) \
286 { \
287 using default_ops::BOOST_JOIN(eval_, name); \
288 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str); \
289 BOOST_JOIN(eval_, name) \
290 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b)); \
291 log_postfix_event(result.value(), str); \
292 } \
293 template <class Backend> \
294 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b) \
295 { \
296 using default_ops::BOOST_JOIN(eval_, name); \
297 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), str); \
298 BOOST_JOIN(eval_, name) \
299 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b)); \
300 log_postfix_event(result.value(), str); \
7c673cae
FG
301 }
302
92f5a8d4
TL
303#define NON_MEMBER_OP4(name, str) \
304 template <class Backend, class T, class U, class V> \
305 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a, const U& b, const V& c) \
306 { \
307 using default_ops::BOOST_JOIN(eval_, name); \
308 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
309 BOOST_JOIN(eval_, name) \
310 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
311 log_postfix_event(result.value(), str); \
312 } \
313 template <class Backend, class T> \
314 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const logged_adaptor<Backend>& b, const T& c) \
315 { \
316 using default_ops::BOOST_JOIN(eval_, name); \
317 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
318 BOOST_JOIN(eval_, name) \
319 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
320 log_postfix_event(result.value(), str); \
321 } \
322 template <class Backend, class T> \
323 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const T& b, const logged_adaptor<Backend>& c) \
324 { \
325 using default_ops::BOOST_JOIN(eval_, name); \
326 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
327 BOOST_JOIN(eval_, name) \
328 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
329 log_postfix_event(result.value(), str); \
330 } \
331 template <class Backend, class T> \
332 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const T& a, const logged_adaptor<Backend>& b, const logged_adaptor<Backend>& c) \
333 { \
334 using default_ops::BOOST_JOIN(eval_, name); \
335 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
336 BOOST_JOIN(eval_, name) \
337 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
338 log_postfix_event(result.value(), str); \
339 } \
340 template <class Backend> \
341 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) \
342 { \
343 using default_ops::BOOST_JOIN(eval_, name); \
344 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
345 BOOST_JOIN(eval_, name) \
346 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
347 log_postfix_event(result.value(), str); \
348 } \
349 template <class Backend, class T, class U> \
350 inline void BOOST_JOIN(eval_, name)(logged_adaptor<Backend> & result, const logged_adaptor<Backend>& a, const T& b, const U& c) \
351 { \
352 using default_ops::BOOST_JOIN(eval_, name); \
353 log_prefix_event(result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c), str); \
354 BOOST_JOIN(eval_, name) \
355 (result.value(), unwrap_logged_type(a), unwrap_logged_type(b), unwrap_logged_type(c)); \
356 log_postfix_event(result.value(), str); \
357 }
7c673cae 358
11fdf7f2
TL
359NON_MEMBER_OP2(add, "+=")
360NON_MEMBER_OP2(subtract, "-=")
361NON_MEMBER_OP2(multiply, "*=")
362NON_MEMBER_OP2(divide, "/=")
7c673cae
FG
363
364template <class Backend, class R>
365inline void eval_convert_to(R* result, const logged_adaptor<Backend>& val)
366{
367 using default_ops::eval_convert_to;
368 log_prefix_event(val.value(), "convert_to");
369 eval_convert_to(result, val.value());
370 log_postfix_event(val.value(), *result, "convert_to");
371}
372
1e59de90
TL
373template <class Backend, class R>
374inline void eval_convert_to(logged_adaptor<R>* result, const logged_adaptor<Backend>& val)
375{
376 using default_ops::eval_convert_to;
377 log_prefix_event(val.value(), "convert_to");
378 eval_convert_to(&result->value(), val.value());
379 log_postfix_event(val.value(), &result->value(), "convert_to");
380}
381template <class Backend, class R>
382inline void eval_convert_to(logged_adaptor<R>* result, const Backend& val)
383{
384 using default_ops::eval_convert_to;
385 log_prefix_event(val, "convert_to");
386 eval_convert_to(&result->value(), val);
387 log_postfix_event(val, &result->value(), "convert_to");
388}
389
390template <class Backend>
391inline void eval_convert_to(std::complex<float>* result, const logged_adaptor<Backend>& val)
392{
393 using default_ops::eval_convert_to;
394 log_prefix_event(val.value(), "convert_to");
395 eval_convert_to(result, val.value());
396 log_postfix_event(val.value(), *result, "convert_to");
397}
398template <class Backend>
399inline void eval_convert_to(std::complex<double>* result, const logged_adaptor<Backend>& val)
400{
401 using default_ops::eval_convert_to;
402 log_prefix_event(val.value(), "convert_to");
403 eval_convert_to(result, val.value());
404 log_postfix_event(val.value(), *result, "convert_to");
405}
406template <class Backend>
407inline void eval_convert_to(std::complex<long double>* result, const logged_adaptor<Backend>& val)
408{
409 using default_ops::eval_convert_to;
410 log_prefix_event(val.value(), "convert_to");
411 eval_convert_to(result, val.value());
412 log_postfix_event(val.value(), *result, "convert_to");
413}
414
415
7c673cae
FG
416template <class Backend, class Exp>
417inline void eval_frexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp* exp)
418{
419 log_prefix_event(arg.value(), "frexp");
420 eval_frexp(result.value(), arg.value(), exp);
421 log_postfix_event(result.value(), *exp, "frexp");
422}
423
424template <class Backend, class Exp>
425inline void eval_ldexp(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp)
426{
427 log_prefix_event(arg.value(), "ldexp");
428 eval_ldexp(result.value(), arg.value(), exp);
429 log_postfix_event(result.value(), exp, "ldexp");
430}
431
432template <class Backend, class Exp>
433inline void eval_scalbn(logged_adaptor<Backend>& result, const logged_adaptor<Backend>& arg, Exp exp)
434{
1e59de90 435 using default_ops::eval_scalbn;
7c673cae
FG
436 log_prefix_event(arg.value(), "scalbn");
437 eval_scalbn(result.value(), arg.value(), exp);
438 log_postfix_event(result.value(), exp, "scalbn");
439}
440
441template <class Backend>
442inline typename Backend::exponent_type eval_ilogb(const logged_adaptor<Backend>& arg)
443{
1e59de90 444 using default_ops::eval_ilogb;
7c673cae
FG
445 log_prefix_event(arg.value(), "ilogb");
446 typename Backend::exponent_type r = eval_ilogb(arg.value());
447 log_postfix_event(arg.value(), "ilogb");
448 return r;
449}
450
11fdf7f2
TL
451NON_MEMBER_OP2(floor, "floor")
452NON_MEMBER_OP2(ceil, "ceil")
453NON_MEMBER_OP2(sqrt, "sqrt")
7c673cae
FG
454
455template <class Backend>
456inline int eval_fpclassify(const logged_adaptor<Backend>& arg)
457{
458 using default_ops::eval_fpclassify;
459 log_prefix_event(arg.value(), "fpclassify");
460 int r = eval_fpclassify(arg.value());
461 log_postfix_event(arg.value(), r, "fpclassify");
462 return r;
463}
464
465/*********************************************************************
466*
467* Optional arithmetic operations come next:
468*
469*********************************************************************/
470
11fdf7f2
TL
471NON_MEMBER_OP3(add, "+")
472NON_MEMBER_OP3(subtract, "-")
473NON_MEMBER_OP3(multiply, "*")
474NON_MEMBER_OP3(divide, "/")
475NON_MEMBER_OP3(multiply_add, "fused-multiply-add")
476NON_MEMBER_OP3(multiply_subtract, "fused-multiply-subtract")
477NON_MEMBER_OP4(multiply_add, "fused-multiply-add")
478NON_MEMBER_OP4(multiply_subtract, "fused-multiply-subtract")
7c673cae 479
11fdf7f2
TL
480NON_MEMBER_OP1(increment, "increment")
481NON_MEMBER_OP1(decrement, "decrement")
7c673cae
FG
482
483/*********************************************************************
484*
485* Optional integer operations come next:
486*
487*********************************************************************/
488
11fdf7f2
TL
489NON_MEMBER_OP2(modulus, "%=")
490NON_MEMBER_OP3(modulus, "%")
491NON_MEMBER_OP2(bitwise_or, "|=")
492NON_MEMBER_OP3(bitwise_or, "|")
493NON_MEMBER_OP2(bitwise_and, "&=")
494NON_MEMBER_OP3(bitwise_and, "&")
495NON_MEMBER_OP2(bitwise_xor, "^=")
496NON_MEMBER_OP3(bitwise_xor, "^")
497NON_MEMBER_OP4(qr, "quotient-and-remainder")
498NON_MEMBER_OP2(complement, "~")
7c673cae
FG
499
500template <class Backend>
11fdf7f2 501inline void eval_left_shift(logged_adaptor<Backend>& arg, std::size_t a)
7c673cae
FG
502{
503 using default_ops::eval_left_shift;
504 log_prefix_event(arg.value(), a, "<<=");
505 eval_left_shift(arg.value(), a);
506 log_postfix_event(arg.value(), "<<=");
507}
508template <class Backend>
11fdf7f2 509inline void eval_left_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, std::size_t b)
7c673cae
FG
510{
511 using default_ops::eval_left_shift;
512 log_prefix_event(arg.value(), a, b, "<<");
513 eval_left_shift(arg.value(), a.value(), b);
514 log_postfix_event(arg.value(), "<<");
515}
516template <class Backend>
11fdf7f2 517inline void eval_right_shift(logged_adaptor<Backend>& arg, std::size_t a)
7c673cae
FG
518{
519 using default_ops::eval_right_shift;
520 log_prefix_event(arg.value(), a, ">>=");
521 eval_right_shift(arg.value(), a);
522 log_postfix_event(arg.value(), ">>=");
523}
524template <class Backend>
11fdf7f2 525inline void eval_right_shift(logged_adaptor<Backend>& arg, const logged_adaptor<Backend>& a, std::size_t b)
7c673cae
FG
526{
527 using default_ops::eval_right_shift;
528 log_prefix_event(arg.value(), a, b, ">>");
529 eval_right_shift(arg.value(), a.value(), b);
530 log_postfix_event(arg.value(), ">>");
531}
532
533template <class Backend, class T>
1e59de90 534inline T eval_integer_modulus(const logged_adaptor<Backend>& arg, const T& a)
7c673cae
FG
535{
536 using default_ops::eval_integer_modulus;
537 log_prefix_event(arg.value(), a, "integer-modulus");
1e59de90 538 T r = eval_integer_modulus(arg.value(), a);
7c673cae
FG
539 log_postfix_event(arg.value(), r, "integer-modulus");
540 return r;
541}
542
543template <class Backend>
1e59de90 544inline std::size_t eval_lsb(const logged_adaptor<Backend>& arg)
7c673cae
FG
545{
546 using default_ops::eval_lsb;
547 log_prefix_event(arg.value(), "least-significant-bit");
1e59de90 548 std::size_t r = eval_lsb(arg.value());
7c673cae
FG
549 log_postfix_event(arg.value(), r, "least-significant-bit");
550 return r;
551}
552
553template <class Backend>
1e59de90 554inline std::size_t eval_msb(const logged_adaptor<Backend>& arg)
7c673cae
FG
555{
556 using default_ops::eval_msb;
557 log_prefix_event(arg.value(), "most-significant-bit");
1e59de90 558 std::size_t r = eval_msb(arg.value());
7c673cae
FG
559 log_postfix_event(arg.value(), r, "most-significant-bit");
560 return r;
561}
562
563template <class Backend>
1e59de90 564inline bool eval_bit_test(const logged_adaptor<Backend>& arg, std::size_t a)
7c673cae
FG
565{
566 using default_ops::eval_bit_test;
567 log_prefix_event(arg.value(), a, "bit-test");
568 bool r = eval_bit_test(arg.value(), a);
569 log_postfix_event(arg.value(), r, "bit-test");
570 return r;
571}
572
573template <class Backend>
1e59de90 574inline void eval_bit_set(const logged_adaptor<Backend>& arg, std::size_t a)
7c673cae
FG
575{
576 using default_ops::eval_bit_set;
577 log_prefix_event(arg.value(), a, "bit-set");
578 eval_bit_set(arg.value(), a);
579 log_postfix_event(arg.value(), arg, "bit-set");
580}
581template <class Backend>
1e59de90 582inline void eval_bit_unset(const logged_adaptor<Backend>& arg, std::size_t a)
7c673cae
FG
583{
584 using default_ops::eval_bit_unset;
585 log_prefix_event(arg.value(), a, "bit-unset");
586 eval_bit_unset(arg.value(), a);
587 log_postfix_event(arg.value(), arg, "bit-unset");
588}
589template <class Backend>
1e59de90 590inline void eval_bit_flip(const logged_adaptor<Backend>& arg, std::size_t a)
7c673cae
FG
591{
592 using default_ops::eval_bit_flip;
593 log_prefix_event(arg.value(), a, "bit-flip");
594 eval_bit_flip(arg.value(), a);
595 log_postfix_event(arg.value(), arg, "bit-flip");
596}
597
11fdf7f2
TL
598NON_MEMBER_OP3(gcd, "gcd")
599NON_MEMBER_OP3(lcm, "lcm")
600NON_MEMBER_OP4(powm, "powm")
7c673cae
FG
601
602/*********************************************************************
603*
604* abs/fabs:
605*
606*********************************************************************/
607
11fdf7f2
TL
608NON_MEMBER_OP2(abs, "abs")
609NON_MEMBER_OP2(fabs, "fabs")
7c673cae
FG
610
611/*********************************************************************
612*
613* Floating point functions:
614*
615*********************************************************************/
616
11fdf7f2
TL
617NON_MEMBER_OP2(trunc, "trunc")
618NON_MEMBER_OP2(round, "round")
619NON_MEMBER_OP2(exp, "exp")
620NON_MEMBER_OP2(log, "log")
621NON_MEMBER_OP2(log10, "log10")
622NON_MEMBER_OP2(sin, "sin")
623NON_MEMBER_OP2(cos, "cos")
624NON_MEMBER_OP2(tan, "tan")
625NON_MEMBER_OP2(asin, "asin")
626NON_MEMBER_OP2(acos, "acos")
627NON_MEMBER_OP2(atan, "atan")
628NON_MEMBER_OP2(sinh, "sinh")
629NON_MEMBER_OP2(cosh, "cosh")
630NON_MEMBER_OP2(tanh, "tanh")
631NON_MEMBER_OP2(logb, "logb")
632NON_MEMBER_OP3(fmod, "fmod")
633NON_MEMBER_OP3(pow, "pow")
634NON_MEMBER_OP3(atan2, "atan2")
1e59de90
TL
635NON_MEMBER_OP2(asinh, "asinh")
636NON_MEMBER_OP2(acosh, "acosh")
637NON_MEMBER_OP2(atanh, "atanh")
638NON_MEMBER_OP2(conj, "conj")
7c673cae 639
b32b8144
FG
640template <class Backend>
641int eval_signbit(const logged_adaptor<Backend>& val)
642{
643 using default_ops::eval_signbit;
644 return eval_signbit(val.value());
645}
646
7c673cae
FG
647template <class Backend>
648std::size_t hash_value(const logged_adaptor<Backend>& val)
649{
650 return hash_value(val.value());
651}
652
1e59de90
TL
653template <class Backend, expression_template_option ExpressionTemplates>
654inline typename std::enable_if<number_category<Backend>::value == number_kind_rational, typename number<logged_adaptor<Backend>, ExpressionTemplates>::value_type>::type
655numerator(const number<logged_adaptor<Backend>, ExpressionTemplates>& arg)
656{
657 number<Backend, ExpressionTemplates> t(arg.backend().value());
658 return numerator(t).backend();
659}
660template <class Backend, expression_template_option ExpressionTemplates>
661inline typename std::enable_if<number_category<Backend>::value == number_kind_rational, typename number<logged_adaptor<Backend>, ExpressionTemplates>::value_type>::type
662denominator(const number<logged_adaptor<Backend>, ExpressionTemplates>& arg)
663{
664 number<Backend, ExpressionTemplates> t(arg.backend().value());
665 return denominator(t).backend();
666}
667
668template <class To, class From>
669inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(To& to, const logged_adaptor<From>& from)
670{
671 using default_ops::eval_set_real;
672 log_prefix_event(to, from.value(), "Set real part");
673 eval_set_real(to, from.value());
674 log_postfix_event(to, from.value(), "Set real part");
675}
676template <class To, class From>
677inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(logged_adaptor<To>& to, const logged_adaptor<From>& from)
678{
679 using default_ops::eval_set_real;
680 log_prefix_event(to.value(), from.value(), "Set real part");
681 eval_set_real(to.value(), from.value());
682 log_postfix_event(to.value(), from.value(), "Set real part");
683}
684template <class To, class From>
685inline BOOST_MP_CXX14_CONSTEXPR void eval_set_real(logged_adaptor<To>& to, const From& from)
686{
687 using default_ops::eval_set_real;
688 log_prefix_event(to.value(), from, "Set real part");
689 eval_set_real(to.value(), from);
690 log_postfix_event(to.value(), from, "Set real part");
691}
692
693template <class To, class From>
694inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(To& to, const logged_adaptor<From>& from)
695{
696 using default_ops::eval_set_imag;
697 log_prefix_event(to, from.value(), "Set imag part");
698 eval_set_imag(to, from.value());
699 log_postfix_event(to, from.value(), "Set imag part");
700}
701template <class To, class From>
702inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(logged_adaptor<To>& to, const logged_adaptor<From>& from)
703{
704 using default_ops::eval_set_imag;
705 log_prefix_event(to.value(), from.value(), "Set imag part");
706 eval_set_imag(to.value(), from.value());
707 log_postfix_event(to.value(), from.value(), "Set imag part");
708}
709template <class To, class From>
710inline BOOST_MP_CXX14_CONSTEXPR void eval_set_imag(logged_adaptor<To>& to, const From& from)
711{
712 using default_ops::eval_set_imag;
713 log_prefix_event(to.value(), from, "Set imag part");
714 eval_set_imag(to.value(), from);
715 log_postfix_event(to.value(), from, "Set imag part");
716}
717
718
92f5a8d4
TL
719#define NON_MEMBER_COMPLEX_TO_REAL(name, str) \
720 template <class B1, class B2> \
721 inline void BOOST_JOIN(eval_, name)(logged_adaptor<B1> & result, const logged_adaptor<B2>& a) \
722 { \
723 using default_ops::BOOST_JOIN(eval_, name); \
724 log_prefix_event(a.value(), a.value(), str); \
725 BOOST_JOIN(eval_, name) \
726 (result.value(), a.value()); \
727 log_postfix_event(result.value(), str); \
728 } \
729 template <class B1, class B2> \
730 inline void BOOST_JOIN(eval_, name)(B1 & result, const logged_adaptor<B2>& a) \
731 { \
732 using default_ops::BOOST_JOIN(eval_, name); \
733 log_prefix_event(a.value(), a.value(), str); \
734 BOOST_JOIN(eval_, name) \
735 (result, a.value()); \
736 log_postfix_event(result, str); \
737 }
738
739NON_MEMBER_COMPLEX_TO_REAL(real, "real")
740NON_MEMBER_COMPLEX_TO_REAL(imag, "imag")
741
742template <class T, class V, class U>
743inline void assign_components(logged_adaptor<T>& result, const V& v1, const U& v2)
744{
1e59de90
TL
745 using default_ops::assign_components;
746 assign_components(result.value(), unwrap_logged_type(v1), unwrap_logged_type(v2));
92f5a8d4
TL
747}
748
7c673cae
FG
749} // namespace backends
750
751using backends::logged_adaptor;
752
1e59de90
TL
753namespace detail {
754 template <class Backend>
755 struct is_variable_precision<logged_adaptor<Backend> > : public is_variable_precision<Backend>
756 {};
757#ifdef BOOST_HAS_INT128
758 template <class Backend>
759 struct is_convertible_arithmetic<int128_type, logged_adaptor<Backend> > : public is_convertible_arithmetic<int128_type, Backend>
760 {};
761 template <class Backend>
762 struct is_convertible_arithmetic<uint128_type, logged_adaptor<Backend> > : public is_convertible_arithmetic<uint128_type, Backend>
763 {};
764#endif
765#ifdef BOOST_HAS_FLOAT128
766 template <class Backend>
767 struct is_convertible_arithmetic<float128_type, logged_adaptor<Backend> > : public is_convertible_arithmetic<float128_type, Backend>
768 {};
769#endif
770 } // namespace detail
771
92f5a8d4
TL
772template <class Backend>
773struct number_category<backends::logged_adaptor<Backend> > : public number_category<Backend>
774{};
7c673cae 775
1e59de90
TL
776template <class Number>
777using logged_adaptor_t = number<logged_adaptor<typename Number::backend_type>, Number::et>;
778
779template <class Backend, expression_template_option ExpressionTemplates>
780struct component_type<number<logged_adaptor<Backend>, ExpressionTemplates>>
781{
782 //
783 // We'll make the component_type also a logged_adaptor:
784 //
785 using base_component_type = typename component_type<number<Backend, ExpressionTemplates>>::type;
786 using base_component_backend = typename base_component_type::backend_type;
787 using type = number<logged_adaptor<base_component_backend>, ExpressionTemplates>;
788};
789
790template <class Backend>
791struct is_interval_number<backends::logged_adaptor<Backend> > : public is_interval_number<Backend> {};
792
92f5a8d4 793}} // namespace boost::multiprecision
7c673cae 794
92f5a8d4 795namespace std {
7c673cae
FG
796
797template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
798class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates> >
92f5a8d4 799 : public std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> >
7c673cae 800{
1e59de90
TL
801 using base_type = std::numeric_limits<boost::multiprecision::number<Backend, ExpressionTemplates> > ;
802 using number_type = boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<Backend>, ExpressionTemplates>;
92f5a8d4
TL
803
804 public:
1e59de90
TL
805 static number_type(min)() noexcept { return (base_type::min)(); }
806 static number_type(max)() noexcept { return (base_type::max)(); }
807 static number_type lowest() noexcept { return -(max)(); }
808 static number_type epsilon() noexcept { return base_type::epsilon(); }
809 static number_type round_error() noexcept { return epsilon() / 2; }
810 static number_type infinity() noexcept { return base_type::infinity(); }
811 static number_type quiet_NaN() noexcept { return base_type::quiet_NaN(); }
812 static number_type signaling_NaN() noexcept { return base_type::signaling_NaN(); }
813 static number_type denorm_min() noexcept { return base_type::denorm_min(); }
7c673cae
FG
814};
815
816} // namespace std
817
1e59de90 818#ifdef BOOST_MP_MATH_AVAILABLE
92f5a8d4
TL
819namespace boost {
820namespace math {
7c673cae 821
92f5a8d4 822namespace policies {
7c673cae
FG
823
824template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
92f5a8d4
TL
825struct precision<boost::multiprecision::number<boost::multiprecision::logged_adaptor<Backend>, ExpressionTemplates>, Policy>
826 : public precision<boost::multiprecision::number<Backend, ExpressionTemplates>, Policy>
7c673cae
FG
827{};
828
92f5a8d4 829}
7c673cae 830
92f5a8d4 831}} // namespace boost::math::policies
1e59de90 832#endif // BOOST_MP_MATH_AVAILABLE
7c673cae
FG
833
834#undef NON_MEMBER_OP1
835#undef NON_MEMBER_OP2
836#undef NON_MEMBER_OP3
837#undef NON_MEMBER_OP4
838
839#endif