]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/multiprecision/performance/arithmetic_backend.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / multiprecision / performance / arithmetic_backend.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_FLOAT_BACKEND_HPP
7#define BOOST_MATH_FLOAT_BACKEND_HPP
8
9#include <iostream>
10#include <iomanip>
11#include <sstream>
12#include <boost/cstdint.hpp>
13#include <boost/lexical_cast.hpp>
14#include <boost/math/concepts/real_concept.hpp>
15#include <boost/multiprecision/number.hpp>
92f5a8d4 16#include <boost/integer/common_factor_rt.hpp>
11fdf7f2 17#include <boost/type_traits/common_type.hpp>
92f5a8d4 18#include <boost/container_hash/hash.hpp>
7c673cae 19
92f5a8d4
TL
20namespace boost {
21namespace multiprecision {
22namespace backends {
7c673cae
FG
23
24#ifdef BOOST_MSVC
92f5a8d4
TL
25#pragma warning(push)
26#pragma warning(disable : 4389 4244 4018 4244 4127)
7c673cae
FG
27#endif
28
29template <class Arithmetic>
30struct arithmetic_backend
31{
92f5a8d4
TL
32 typedef mpl::list<short, int, long, long long> signed_types;
33 typedef mpl::list<unsigned short, unsigned, unsigned long, unsigned long long> unsigned_types;
34 typedef mpl::list<float, double, long double> float_types;
35 typedef int exponent_type;
7c673cae 36
92f5a8d4
TL
37 BOOST_MP_CXX14_CONSTEXPR arithmetic_backend() : m_value(0) {}
38 BOOST_MP_CXX14_CONSTEXPR arithmetic_backend(const arithmetic_backend& o) : m_value(o.m_value) {}
7c673cae 39 template <class A>
92f5a8d4 40 BOOST_MP_CXX14_CONSTEXPR arithmetic_backend(const A& o, const typename enable_if<is_arithmetic<A> >::type* = 0) : m_value(o) {}
7c673cae 41 template <class A>
92f5a8d4
TL
42 BOOST_MP_CXX14_CONSTEXPR arithmetic_backend(const arithmetic_backend<A>& o) : m_value(o.data()) {}
43 BOOST_MP_CXX14_CONSTEXPR arithmetic_backend& operator=(const arithmetic_backend& o)
7c673cae
FG
44 {
45 m_value = o.m_value;
46 return *this;
47 }
48 template <class A>
92f5a8d4 49 BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A>, arithmetic_backend&>::type operator=(A i)
7c673cae
FG
50 {
51 m_value = i;
52 return *this;
53 }
54 template <class A>
92f5a8d4 55 BOOST_MP_CXX14_CONSTEXPR arithmetic_backend& operator=(const arithmetic_backend<A>& i)
7c673cae
FG
56 {
57 m_value = i.data();
58 return *this;
59 }
92f5a8d4 60 arithmetic_backend& operator=(const char* s)
7c673cae
FG
61 {
62#ifndef BOOST_NO_EXCEPTIONS
63 try
64 {
65#endif
66 m_value = boost::lexical_cast<Arithmetic>(s);
67#ifndef BOOST_NO_EXCEPTIONS
68 }
92f5a8d4 69 catch (const bad_lexical_cast&)
7c673cae
FG
70 {
71 throw std::runtime_error(std::string("Unable to interpret the string provided: \"") + s + std::string("\" as a compatible number type."));
72 }
73#endif
74 return *this;
75 }
92f5a8d4 76 BOOST_MP_CXX14_CONSTEXPR void swap(arithmetic_backend& o)
7c673cae
FG
77 {
78 std::swap(m_value, o.m_value);
79 }
92f5a8d4 80 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
7c673cae
FG
81 {
82 std::stringstream ss;
83 ss.flags(f);
84 ss << std::setprecision(digits ? digits : std::numeric_limits<Arithmetic>::digits10 + 4) << m_value;
85 return ss.str();
86 }
92f5a8d4 87 BOOST_MP_CXX14_CONSTEXPR void do_negate(const mpl::true_&)
7c673cae
FG
88 {
89 m_value = 1 + ~m_value;
90 }
92f5a8d4 91 BOOST_MP_CXX14_CONSTEXPR void do_negate(const mpl::false_&)
7c673cae
FG
92 {
93 m_value = -m_value;
94 }
92f5a8d4 95 BOOST_MP_CXX14_CONSTEXPR void negate()
7c673cae 96 {
92f5a8d4 97 do_negate(mpl::bool_<is_unsigned<Arithmetic>::value>());
7c673cae 98 }
92f5a8d4 99 BOOST_MP_CXX14_CONSTEXPR int compare(const arithmetic_backend& o) const
7c673cae
FG
100 {
101 return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0);
102 }
103 template <class A>
92f5a8d4 104 BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A>, int>::type compare(A i) const
7c673cae
FG
105 {
106 return m_value > static_cast<Arithmetic>(i) ? 1 : (m_value < static_cast<Arithmetic>(i) ? -1 : 0);
107 }
92f5a8d4
TL
108 BOOST_MP_CXX14_CONSTEXPR Arithmetic& data() { return m_value; }
109 BOOST_MP_CXX14_CONSTEXPR const Arithmetic& data() const { return m_value; }
110
111 private:
7c673cae
FG
112 Arithmetic m_value;
113};
114
115template <class R, class Arithmetic>
92f5a8d4 116inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<boost::is_integral<R>::value>::type eval_convert_to(R* result, const arithmetic_backend<Arithmetic>& backend)
11fdf7f2
TL
117{
118 typedef typename boost::common_type<R, Arithmetic>::type c_type;
92f5a8d4
TL
119 BOOST_CONSTEXPR const c_type max = static_cast<c_type>((std::numeric_limits<R>::max)());
120 BOOST_CONSTEXPR const c_type min = static_cast<c_type>((std::numeric_limits<R>::min)());
121 c_type ct = static_cast<c_type>(backend.data());
11fdf7f2
TL
122 if ((backend.data() < 0) && !std::numeric_limits<R>::is_signed)
123 BOOST_THROW_EXCEPTION(std::range_error("Attempt to convert negative number to unsigned type."));
124 if (ct > max)
92f5a8d4 125 *result = boost::is_signed<R>::value ? (std::numeric_limits<R>::max)() : backend.data();
11fdf7f2
TL
126 else if (std::numeric_limits<Arithmetic>::is_signed && (ct < min))
127 *result = (std::numeric_limits<R>::min)();
128 else
129 *result = backend.data();
130}
131
132template <class R, class Arithmetic>
92f5a8d4 133inline BOOST_MP_CXX14_CONSTEXPR typename disable_if_c<boost::is_integral<R>::value>::type eval_convert_to(R* result, const arithmetic_backend<Arithmetic>& backend)
7c673cae
FG
134{
135 *result = backend.data();
136}
137
138template <class Arithmetic>
92f5a8d4 139inline BOOST_MP_CXX14_CONSTEXPR bool eval_eq(const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
140{
141 return a.data() == b.data();
142}
143template <class Arithmetic, class A2>
92f5a8d4 144inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A2>, bool>::type eval_eq(const arithmetic_backend<Arithmetic>& a, const A2& b)
7c673cae
FG
145{
146 return a.data() == static_cast<Arithmetic>(b);
147}
148template <class Arithmetic>
92f5a8d4 149inline BOOST_MP_CXX14_CONSTEXPR bool eval_lt(const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
150{
151 return a.data() < b.data();
152}
153template <class Arithmetic, class A2>
92f5a8d4 154inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A2>, bool>::type eval_lt(const arithmetic_backend<Arithmetic>& a, const A2& b)
7c673cae
FG
155{
156 return a.data() < static_cast<Arithmetic>(b);
157}
158template <class Arithmetic>
92f5a8d4 159inline BOOST_MP_CXX14_CONSTEXPR bool eval_gt(const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
160{
161 return a.data() > b.data();
162}
163template <class Arithmetic, class A2>
92f5a8d4 164inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A2>, bool>::type eval_gt(const arithmetic_backend<Arithmetic>& a, const A2& b)
7c673cae
FG
165{
166 return a.data() > static_cast<Arithmetic>(b);
167}
168
169template <class Arithmetic>
92f5a8d4 170inline BOOST_MP_CXX14_CONSTEXPR void eval_add(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
171{
172 result.data() += o.data();
173}
174template <class Arithmetic>
92f5a8d4 175inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
176{
177 result.data() -= o.data();
178}
179template <class Arithmetic>
92f5a8d4 180inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
181{
182 result.data() *= o.data();
183}
184template <class Arithmetic>
92f5a8d4 185inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<std::numeric_limits<Arithmetic>::has_infinity>::type eval_divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
186{
187 result.data() /= o.data();
188}
189template <class Arithmetic>
92f5a8d4 190inline BOOST_MP_CXX14_CONSTEXPR typename disable_if_c<std::numeric_limits<Arithmetic>::has_infinity>::type eval_divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae 191{
92f5a8d4 192 if (!o.data())
7c673cae
FG
193 BOOST_THROW_EXCEPTION(std::overflow_error("Divide by zero"));
194 result.data() /= o.data();
195}
196
197template <class Arithmetic, class A2>
92f5a8d4 198inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A2> >::type eval_add(arithmetic_backend<Arithmetic>& result, const A2& o)
7c673cae
FG
199{
200 result.data() += o;
201}
202template <class Arithmetic, class A2>
92f5a8d4 203inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A2> >::type eval_subtract(arithmetic_backend<Arithmetic>& result, const A2& o)
7c673cae
FG
204{
205 result.data() -= o;
206}
207template <class Arithmetic, class A2>
92f5a8d4 208inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A2> >::type eval_multiply(arithmetic_backend<Arithmetic>& result, const A2& o)
7c673cae
FG
209{
210 result.data() *= o;
211}
212template <class Arithmetic, class A2>
92f5a8d4
TL
213inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<(is_arithmetic<A2>::value && !std::numeric_limits<Arithmetic>::has_infinity)>::type
214eval_divide(arithmetic_backend<Arithmetic>& result, const A2& o)
7c673cae 215{
92f5a8d4 216 if (!o)
7c673cae
FG
217 BOOST_THROW_EXCEPTION(std::overflow_error("Divide by zero"));
218 result.data() /= o;
219}
220template <class Arithmetic, class A2>
92f5a8d4
TL
221inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<(is_arithmetic<A2>::value && std::numeric_limits<Arithmetic>::has_infinity)>::type
222eval_divide(arithmetic_backend<Arithmetic>& result, const A2& o)
7c673cae
FG
223{
224 result.data() /= o;
225}
226
227template <class Arithmetic>
92f5a8d4 228inline BOOST_MP_CXX14_CONSTEXPR void eval_add(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
229{
230 result.data() = a.data() + b.data();
231}
232template <class Arithmetic>
92f5a8d4 233inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
234{
235 result.data() = a.data() - b.data();
236}
237template <class Arithmetic>
92f5a8d4 238inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
239{
240 result.data() = a.data() * b.data();
241}
242template <class Arithmetic>
92f5a8d4 243inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<std::numeric_limits<Arithmetic>::has_infinity>::type eval_divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
244{
245 result.data() = a.data() / b.data();
246}
247template <class Arithmetic>
92f5a8d4 248inline BOOST_MP_CXX14_CONSTEXPR typename disable_if_c<std::numeric_limits<Arithmetic>::has_infinity>::type eval_divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae 249{
92f5a8d4 250 if (!b.data())
7c673cae
FG
251 BOOST_THROW_EXCEPTION(std::overflow_error("Divide by zero"));
252 result.data() = a.data() / b.data();
253}
254
255template <class Arithmetic, class A2>
92f5a8d4 256inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A2> >::type eval_add(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const A2& b)
7c673cae
FG
257{
258 result.data() = a.data() + b;
259}
260template <class Arithmetic, class A2>
92f5a8d4 261inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A2> >::type eval_subtract(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const A2& b)
7c673cae
FG
262{
263 result.data() = a.data() - b;
264}
265template <class Arithmetic, class A2>
92f5a8d4 266inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_arithmetic<A2> >::type eval_multiply(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const A2& b)
7c673cae
FG
267{
268 result.data() = a.data() * b;
269}
270template <class Arithmetic, class A2>
92f5a8d4
TL
271inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<(is_arithmetic<A2>::value && !std::numeric_limits<Arithmetic>::has_infinity)>::type
272eval_divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const A2& b)
7c673cae 273{
92f5a8d4 274 if (!b)
7c673cae
FG
275 BOOST_THROW_EXCEPTION(std::overflow_error("Divide by zero"));
276 result.data() = a.data() / b;
277}
278template <class Arithmetic, class A2>
92f5a8d4
TL
279inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<(is_arithmetic<A2>::value && std::numeric_limits<Arithmetic>::has_infinity)>::type
280eval_divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const A2& b)
7c673cae
FG
281{
282 result.data() = a.data() / b;
283}
284
285template <class Arithmetic>
92f5a8d4 286inline BOOST_MP_CXX14_CONSTEXPR bool eval_is_zero(const arithmetic_backend<Arithmetic>& val)
7c673cae
FG
287{
288 return val.data() == 0;
289}
290
291template <class Arithmetic>
92f5a8d4
TL
292inline BOOST_MP_CXX14_CONSTEXPR typename enable_if_c<
293 (!std::numeric_limits<Arithmetic>::is_specialized || std::numeric_limits<Arithmetic>::is_signed), int>::type
294eval_get_sign(const arithmetic_backend<Arithmetic>& val)
7c673cae
FG
295{
296 return val.data() == 0 ? 0 : val.data() < 0 ? -1 : 1;
297}
298template <class Arithmetic>
92f5a8d4
TL
299inline BOOST_MP_CXX14_CONSTEXPR typename disable_if_c<
300 (std::numeric_limits<Arithmetic>::is_specialized || std::numeric_limits<Arithmetic>::is_signed), int>::type
301eval_get_sign(const arithmetic_backend<Arithmetic>& val)
7c673cae
FG
302{
303 return val.data() == 0 ? 0 : 1;
304}
305
306template <class T>
92f5a8d4 307inline BOOST_MP_CXX14_CONSTEXPR typename enable_if<is_unsigned<T>, T>::type abs(T v) { return v; }
7c673cae
FG
308
309template <class Arithmetic>
92f5a8d4 310inline BOOST_MP_CXX14_CONSTEXPR void eval_abs(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae 311{
7c673cae 312 using boost::multiprecision::backends::abs;
92f5a8d4 313 using std::abs;
7c673cae
FG
314 result.data() = abs(o.data());
315}
316
317template <class Arithmetic>
92f5a8d4 318inline BOOST_MP_CXX14_CONSTEXPR void eval_fabs(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
319{
320 result.data() = std::abs(o.data());
321}
322
323template <class Arithmetic>
92f5a8d4 324inline BOOST_MP_CXX14_CONSTEXPR void eval_floor(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
325{
326 BOOST_MATH_STD_USING
327 result.data() = floor(o.data());
328}
329
330template <class Arithmetic>
92f5a8d4 331inline BOOST_MP_CXX14_CONSTEXPR void eval_ceil(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
332{
333 BOOST_MATH_STD_USING
334 result.data() = ceil(o.data());
335}
336
337template <class Arithmetic>
92f5a8d4 338inline BOOST_MP_CXX14_CONSTEXPR void eval_sqrt(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
339{
340 BOOST_MATH_STD_USING
341 result.data() = sqrt(o.data());
342}
343
344template <class Arithmetic>
92f5a8d4 345inline BOOST_MP_CXX14_CONSTEXPR int eval_fpclassify(const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
346{
347 return (boost::math::fpclassify)(o.data());
348}
349
350template <class Arithmetic>
92f5a8d4 351inline BOOST_MP_CXX14_CONSTEXPR void eval_trunc(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
352{
353 BOOST_MATH_STD_USING
354 result.data() = trunc(o.data());
355}
356
357template <class Arithmetic>
92f5a8d4 358inline BOOST_MP_CXX14_CONSTEXPR void eval_round(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
359{
360 BOOST_MATH_STD_USING
361 result.data() = round(o.data());
362}
363
364template <class Arithmetic>
92f5a8d4 365inline BOOST_MP_CXX14_CONSTEXPR void eval_frexp(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, int* v)
7c673cae
FG
366{
367 BOOST_MATH_STD_USING
368 result.data() = frexp(a.data(), v);
369}
370
371template <class Arithmetic>
92f5a8d4 372inline BOOST_MP_CXX14_CONSTEXPR void eval_ldexp(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, int v)
7c673cae
FG
373{
374 BOOST_MATH_STD_USING
375 result.data() = ldexp(a.data(), v);
376}
377
378template <class Arithmetic>
92f5a8d4 379inline BOOST_MP_CXX14_CONSTEXPR void eval_exp(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
380{
381 BOOST_MATH_STD_USING
382 result.data() = exp(o.data());
383}
384
385template <class Arithmetic>
92f5a8d4 386inline BOOST_MP_CXX14_CONSTEXPR void eval_log(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
387{
388 BOOST_MATH_STD_USING
389 result.data() = log(o.data());
390}
391
392template <class Arithmetic>
92f5a8d4 393inline BOOST_MP_CXX14_CONSTEXPR void eval_log10(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
394{
395 BOOST_MATH_STD_USING
396 result.data() = log10(o.data());
397}
398
399template <class Arithmetic>
92f5a8d4 400inline BOOST_MP_CXX14_CONSTEXPR void eval_sin(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
401{
402 BOOST_MATH_STD_USING
403 result.data() = sin(o.data());
404}
405
406template <class Arithmetic>
92f5a8d4 407inline BOOST_MP_CXX14_CONSTEXPR void eval_cos(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
408{
409 BOOST_MATH_STD_USING
410 result.data() = cos(o.data());
411}
412
413template <class Arithmetic>
92f5a8d4 414inline BOOST_MP_CXX14_CONSTEXPR void eval_tan(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
415{
416 BOOST_MATH_STD_USING
417 result.data() = tan(o.data());
418}
419
420template <class Arithmetic>
92f5a8d4 421inline BOOST_MP_CXX14_CONSTEXPR void eval_acos(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
422{
423 BOOST_MATH_STD_USING
424 result.data() = acos(o.data());
425}
426
427template <class Arithmetic>
92f5a8d4 428inline BOOST_MP_CXX14_CONSTEXPR void eval_asin(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
429{
430 BOOST_MATH_STD_USING
431 result.data() = asin(o.data());
432}
433
434template <class Arithmetic>
92f5a8d4 435inline BOOST_MP_CXX14_CONSTEXPR void eval_atan(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
436{
437 BOOST_MATH_STD_USING
438 result.data() = atan(o.data());
439}
440
441template <class Arithmetic>
92f5a8d4 442inline BOOST_MP_CXX14_CONSTEXPR void eval_sinh(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
443{
444 BOOST_MATH_STD_USING
445 result.data() = sinh(o.data());
446}
447
448template <class Arithmetic>
92f5a8d4 449inline BOOST_MP_CXX14_CONSTEXPR void eval_cosh(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
450{
451 BOOST_MATH_STD_USING
452 result.data() = cosh(o.data());
453}
454
455template <class Arithmetic>
92f5a8d4 456inline BOOST_MP_CXX14_CONSTEXPR void eval_tanh(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
7c673cae
FG
457{
458 BOOST_MATH_STD_USING
459 result.data() = tanh(o.data());
460}
461
462template <class Arithmetic>
92f5a8d4 463inline BOOST_MP_CXX14_CONSTEXPR void eval_fmod(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
464{
465 BOOST_MATH_STD_USING
466 result.data() = fmod(a.data(), b.data());
467}
468
469template <class Arithmetic>
92f5a8d4 470inline BOOST_MP_CXX14_CONSTEXPR void eval_pow(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
471{
472 BOOST_MATH_STD_USING
473 result.data() = pow(a.data(), b.data());
474}
475
476template <class Arithmetic>
92f5a8d4 477inline BOOST_MP_CXX14_CONSTEXPR void eval_atan2(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae
FG
478{
479 BOOST_MATH_STD_USING
480 result.data() = atan2(a.data(), b.data());
481}
482
483template <class Arithmetic, class I>
92f5a8d4 484inline BOOST_MP_CXX14_CONSTEXPR void eval_left_shift(arithmetic_backend<Arithmetic>& result, I val)
7c673cae
FG
485{
486 result.data() <<= val;
487}
488
489template <class Arithmetic, class I>
92f5a8d4 490inline BOOST_MP_CXX14_CONSTEXPR void eval_right_shift(arithmetic_backend<Arithmetic>& result, I val)
7c673cae
FG
491{
492 result.data() >>= val;
493}
494
495template <class Arithmetic>
92f5a8d4 496inline BOOST_MP_CXX14_CONSTEXPR void eval_modulus(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
7c673cae
FG
497{
498 result.data() %= a.data();
499}
500
501template <class Arithmetic>
92f5a8d4 502inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_and(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
7c673cae
FG
503{
504 result.data() &= a.data();
505}
506
507template <class Arithmetic>
92f5a8d4 508inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_or(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
7c673cae
FG
509{
510 result.data() |= a.data();
511}
512
513template <class Arithmetic>
92f5a8d4 514inline BOOST_MP_CXX14_CONSTEXPR void eval_bitwise_xor(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
7c673cae
FG
515{
516 result.data() ^= a.data();
517}
518
519template <class Arithmetic>
92f5a8d4 520inline BOOST_MP_CXX14_CONSTEXPR void eval_complement(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
7c673cae
FG
521{
522 result.data() = ~a.data();
523}
524
525template <class Arithmetic>
92f5a8d4
TL
526inline BOOST_MP_CXX14_CONSTEXPR void eval_gcd(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
527{
528 result.data() = boost::integer::gcd(a.data(), b.data());
529}
530
531template <class Arithmetic>
532inline BOOST_MP_CXX14_CONSTEXPR void eval_lcm(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
7c673cae 533{
92f5a8d4 534 result.data() = boost::integer::lcm(a.data(), b.data());
7c673cae
FG
535}
536
537template <class Arithmetic>
92f5a8d4 538inline BOOST_MP_CXX14_CONSTEXPR std::size_t hash_value(const arithmetic_backend<Arithmetic>& a)
7c673cae 539{
92f5a8d4
TL
540 boost::hash<Arithmetic> hasher;
541 return hasher(a.data());
7c673cae
FG
542}
543
544#ifdef BOOST_MSVC
92f5a8d4 545#pragma warning(pop)
7c673cae
FG
546#endif
547
548} // namespace backends
549
550using boost::multiprecision::backends::arithmetic_backend;
551
552template <class Arithmetic>
92f5a8d4
TL
553struct number_category<arithmetic_backend<Arithmetic> > : public mpl::int_<is_integral<Arithmetic>::value ? number_kind_integer : number_kind_floating_point>
554{};
7c673cae 555
92f5a8d4 556namespace detail {
7c673cae
FG
557
558template <class Backend>
559struct double_precision_type;
560
92f5a8d4 561template <class Arithmetic, boost::multiprecision::expression_template_option ET>
7c673cae
FG
562struct double_precision_type<number<arithmetic_backend<Arithmetic>, ET> >
563{
564 typedef number<arithmetic_backend<typename double_precision_type<Arithmetic>::type>, ET> type;
565};
92f5a8d4 566template <>
7c673cae
FG
567struct double_precision_type<arithmetic_backend<boost::int32_t> >
568{
569 typedef arithmetic_backend<boost::int64_t> type;
570};
571
92f5a8d4 572} // namespace detail
7c673cae 573
92f5a8d4 574}} // namespace boost::multiprecision
7c673cae
FG
575#if !(defined(__SGI_STL_PORT) || defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS))
576//
577// We shouldn't need these to get code to compile, however for the sake of
578// "level playing field" performance comparisons they avoid the very slow
579// lexical_cast's that would otherwise take place. Definition has to be guarded
580// by the inverse of pp-logic in real_concept.hpp which defines these as a workaround
581// for STLPort plus some other old/broken standartd libraries.
582//
92f5a8d4 583namespace boost { namespace math { namespace tools {
7c673cae 584
92f5a8d4
TL
585template <>
586inline unsigned int real_cast<unsigned int, concepts::real_concept>(concepts::real_concept r)
587{
588 return static_cast<unsigned int>(r.value());
589}
7c673cae 590
92f5a8d4
TL
591template <>
592inline int real_cast<int, concepts::real_concept>(concepts::real_concept r)
593{
594 return static_cast<int>(r.value());
595}
7c673cae 596
92f5a8d4
TL
597template <>
598inline long real_cast<long, concepts::real_concept>(concepts::real_concept r)
599{
600 return static_cast<long>(r.value());
601}
7c673cae 602
92f5a8d4 603// Converts from T to narrower floating-point types, float, double & long double.
7c673cae 604
92f5a8d4
TL
605template <>
606inline float real_cast<float, concepts::real_concept>(concepts::real_concept r)
607{
608 return static_cast<float>(r.value());
609}
610template <>
611inline double real_cast<double, concepts::real_concept>(concepts::real_concept r)
612{
613 return static_cast<double>(r.value());
614}
615template <>
616inline long double real_cast<long double, concepts::real_concept>(concepts::real_concept r)
617{
618 return r.value();
619}
7c673cae 620
92f5a8d4 621}}} // namespace boost::math::tools
7c673cae
FG
622#endif
623
92f5a8d4 624namespace std {
7c673cae
FG
625
626template <class Arithmetic, boost::multiprecision::expression_template_option ExpressionTemplates>
92f5a8d4 627class numeric_limits<boost::multiprecision::number<boost::multiprecision::arithmetic_backend<Arithmetic>, ExpressionTemplates> > : public std::numeric_limits<Arithmetic>
7c673cae 628{
92f5a8d4 629 typedef std::numeric_limits<Arithmetic> base_type;
7c673cae 630 typedef boost::multiprecision::number<boost::multiprecision::arithmetic_backend<Arithmetic>, ExpressionTemplates> number_type;
92f5a8d4
TL
631
632 public:
633 BOOST_STATIC_CONSTEXPR number_type(min)() BOOST_NOEXCEPT { return (base_type::min)(); }
634 BOOST_STATIC_CONSTEXPR number_type(max)() BOOST_NOEXCEPT { return (base_type::max)(); }
7c673cae
FG
635 BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_NOEXCEPT { return -(max)(); }
636 BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); }
637 BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_NOEXCEPT { return epsilon() / 2; }
638 BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); }
639 BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); }
640 BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); }
641 BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_NOEXCEPT { return base_type::denorm_min(); }
642};
643
92f5a8d4 644template <>
7c673cae
FG
645class numeric_limits<boost::math::concepts::real_concept> : public std::numeric_limits<long double>
646{
92f5a8d4 647 typedef std::numeric_limits<long double> base_type;
7c673cae 648 typedef boost::math::concepts::real_concept number_type;
92f5a8d4
TL
649
650 public:
651 static const number_type(min)() BOOST_NOEXCEPT { return (base_type::min)(); }
652 static const number_type(max)() BOOST_NOEXCEPT { return (base_type::max)(); }
7c673cae
FG
653 static const number_type lowest() BOOST_NOEXCEPT { return -(max)(); }
654 static const number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); }
655 static const number_type round_error() BOOST_NOEXCEPT { return epsilon() / 2; }
656 static const number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); }
657 static const number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); }
658 static const number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); }
659 static const number_type denorm_min() BOOST_NOEXCEPT { return base_type::denorm_min(); }
660};
661
92f5a8d4 662} // namespace std
7c673cae
FG
663
664#include <boost/multiprecision/detail/integer_ops.hpp>
665
666#endif