]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/math/concepts/real_concept.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / math / concepts / real_concept.hpp
CommitLineData
7c673cae
FG
1// Copyright John Maddock 2006.
2// Use, modification and distribution are subject to the
3// Boost Software License, Version 1.0. (See accompanying file
4// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6// Test real concept.
7
8// real_concept is an archetype for User defined Real types.
9
10// This file defines the features, constructors, operators, functions...
11// that are essential to use mathematical and statistical functions.
12// The template typename "RealType" is used where this type
13// (as well as the normal built-in types, float, double & long double)
14// can be used.
15// That this is the minimum set is confirmed by use as a type
16// in tests of all functions & distributions, for example:
17// test_spots(0.F); & test_spots(0.); for float and double, but also
18// test_spots(boost::math::concepts::real_concept(0.));
19// NTL quad_float type is an example of a type meeting the requirements,
20// but note minor additions are needed - see ntl.diff and documentation
21// "Using With NTL - a High-Precision Floating-Point Library".
22
23#ifndef BOOST_MATH_REAL_CONCEPT_HPP
24#define BOOST_MATH_REAL_CONCEPT_HPP
25
26#include <boost/config.hpp>
27#include <boost/limits.hpp>
28#include <boost/math/special_functions/round.hpp>
29#include <boost/math/special_functions/trunc.hpp>
30#include <boost/math/special_functions/modf.hpp>
31#include <boost/math/tools/big_constant.hpp>
32#include <boost/math/tools/precision.hpp>
33#include <boost/math/policies/policy.hpp>
b32b8144
FG
34#include <boost/math/special_functions/asinh.hpp>
35#include <boost/math/special_functions/atanh.hpp>
7c673cae
FG
36#if defined(__SGI_STL_PORT)
37# include <boost/math/tools/real_cast.hpp>
38#endif
39#include <ostream>
40#include <istream>
41#include <boost/config/no_tr1/cmath.hpp>
42#include <math.h> // fmodl
43
44#if defined(__SGI_STL_PORT) || defined(_RWSTD_VER) || defined(__LIBCOMO__)
45# include <cstdio>
46#endif
47
48namespace boost{ namespace math{
49
50namespace concepts
51{
52
53#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
54 typedef double real_concept_base_type;
55#else
56 typedef long double real_concept_base_type;
57#endif
58
59class real_concept
60{
61public:
62 // Constructors:
63 real_concept() : m_value(0){}
64 real_concept(char c) : m_value(c){}
65#ifndef BOOST_NO_INTRINSIC_WCHAR_T
66 real_concept(wchar_t c) : m_value(c){}
67#endif
68 real_concept(unsigned char c) : m_value(c){}
69 real_concept(signed char c) : m_value(c){}
70 real_concept(unsigned short c) : m_value(c){}
71 real_concept(short c) : m_value(c){}
72 real_concept(unsigned int c) : m_value(c){}
73 real_concept(int c) : m_value(c){}
74 real_concept(unsigned long c) : m_value(c){}
75 real_concept(long c) : m_value(c){}
76#if defined(__DECCXX) || defined(__SUNPRO_CC)
77 real_concept(unsigned long long c) : m_value(static_cast<real_concept_base_type>(c)){}
78 real_concept(long long c) : m_value(static_cast<real_concept_base_type>(c)){}
79#elif defined(BOOST_HAS_LONG_LONG)
80 real_concept(boost::ulong_long_type c) : m_value(static_cast<real_concept_base_type>(c)){}
81 real_concept(boost::long_long_type c) : m_value(static_cast<real_concept_base_type>(c)){}
82#elif defined(BOOST_HAS_MS_INT64)
83 real_concept(unsigned __int64 c) : m_value(static_cast<real_concept_base_type>(c)){}
84 real_concept(__int64 c) : m_value(static_cast<real_concept_base_type>(c)){}
85#endif
86 real_concept(float c) : m_value(c){}
87 real_concept(double c) : m_value(c){}
88 real_concept(long double c) : m_value(c){}
89#ifdef BOOST_MATH_USE_FLOAT128
90 real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){}
91#endif
92
93 // Assignment:
94 real_concept& operator=(char c) { m_value = c; return *this; }
95 real_concept& operator=(unsigned char c) { m_value = c; return *this; }
96 real_concept& operator=(signed char c) { m_value = c; return *this; }
97#ifndef BOOST_NO_INTRINSIC_WCHAR_T
98 real_concept& operator=(wchar_t c) { m_value = c; return *this; }
99#endif
100 real_concept& operator=(short c) { m_value = c; return *this; }
101 real_concept& operator=(unsigned short c) { m_value = c; return *this; }
102 real_concept& operator=(int c) { m_value = c; return *this; }
103 real_concept& operator=(unsigned int c) { m_value = c; return *this; }
104 real_concept& operator=(long c) { m_value = c; return *this; }
105 real_concept& operator=(unsigned long c) { m_value = c; return *this; }
106#ifdef BOOST_HAS_LONG_LONG
107 real_concept& operator=(boost::long_long_type c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
108 real_concept& operator=(boost::ulong_long_type c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
109#endif
110 real_concept& operator=(float c) { m_value = c; return *this; }
111 real_concept& operator=(double c) { m_value = c; return *this; }
112 real_concept& operator=(long double c) { m_value = c; return *this; }
113
114 // Access:
115 real_concept_base_type value()const{ return m_value; }
116
117 // Member arithmetic:
118 real_concept& operator+=(const real_concept& other)
119 { m_value += other.value(); return *this; }
120 real_concept& operator-=(const real_concept& other)
121 { m_value -= other.value(); return *this; }
122 real_concept& operator*=(const real_concept& other)
123 { m_value *= other.value(); return *this; }
124 real_concept& operator/=(const real_concept& other)
125 { m_value /= other.value(); return *this; }
126 real_concept operator-()const
127 { return -m_value; }
128 real_concept const& operator+()const
129 { return *this; }
130 real_concept& operator++()
131 { ++m_value; return *this; }
132 real_concept& operator--()
133 { --m_value; return *this; }
134
135private:
136 real_concept_base_type m_value;
137};
138
139// Non-member arithmetic:
140inline real_concept operator+(const real_concept& a, const real_concept& b)
141{
142 real_concept result(a);
143 result += b;
144 return result;
145}
146inline real_concept operator-(const real_concept& a, const real_concept& b)
147{
148 real_concept result(a);
149 result -= b;
150 return result;
151}
152inline real_concept operator*(const real_concept& a, const real_concept& b)
153{
154 real_concept result(a);
155 result *= b;
156 return result;
157}
158inline real_concept operator/(const real_concept& a, const real_concept& b)
159{
160 real_concept result(a);
161 result /= b;
162 return result;
163}
164
165// Comparison:
166inline bool operator == (const real_concept& a, const real_concept& b)
167{ return a.value() == b.value(); }
168inline bool operator != (const real_concept& a, const real_concept& b)
169{ return a.value() != b.value();}
170inline bool operator < (const real_concept& a, const real_concept& b)
171{ return a.value() < b.value(); }
172inline bool operator <= (const real_concept& a, const real_concept& b)
173{ return a.value() <= b.value(); }
174inline bool operator > (const real_concept& a, const real_concept& b)
175{ return a.value() > b.value(); }
176inline bool operator >= (const real_concept& a, const real_concept& b)
177{ return a.value() >= b.value(); }
178
179// Non-member functions:
180inline real_concept acos(real_concept a)
181{ return std::acos(a.value()); }
182inline real_concept cos(real_concept a)
183{ return std::cos(a.value()); }
184inline real_concept asin(real_concept a)
185{ return std::asin(a.value()); }
186inline real_concept atan(real_concept a)
187{ return std::atan(a.value()); }
188inline real_concept atan2(real_concept a, real_concept b)
189{ return std::atan2(a.value(), b.value()); }
190inline real_concept ceil(real_concept a)
191{ return std::ceil(a.value()); }
192#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
193// I've seen std::fmod(long double) crash on some platforms
194// so use fmodl instead:
195#ifdef _WIN32_WCE
196//
197// Ugly workaround for macro fmodl:
198//
199inline long double call_fmodl(long double a, long double b)
200{ return fmodl(a, b); }
201inline real_concept fmod(real_concept a, real_concept b)
202{ return call_fmodl(a.value(), b.value()); }
203#else
204inline real_concept fmod(real_concept a, real_concept b)
205{ return fmodl(a.value(), b.value()); }
206#endif
207#endif
208inline real_concept cosh(real_concept a)
209{ return std::cosh(a.value()); }
210inline real_concept exp(real_concept a)
211{ return std::exp(a.value()); }
212inline real_concept fabs(real_concept a)
213{ return std::fabs(a.value()); }
214inline real_concept abs(real_concept a)
215{ return std::abs(a.value()); }
216inline real_concept floor(real_concept a)
217{ return std::floor(a.value()); }
218inline real_concept modf(real_concept a, real_concept* ipart)
219{
220#ifdef __MINGW32__
221 real_concept_base_type ip;
222 real_concept_base_type result = boost::math::modf(a.value(), &ip);
223 *ipart = ip;
224 return result;
225#else
226 real_concept_base_type ip;
227 real_concept_base_type result = std::modf(a.value(), &ip);
228 *ipart = ip;
229 return result;
230#endif
231}
232inline real_concept frexp(real_concept a, int* expon)
233{ return std::frexp(a.value(), expon); }
234inline real_concept ldexp(real_concept a, int expon)
235{ return std::ldexp(a.value(), expon); }
236inline real_concept log(real_concept a)
237{ return std::log(a.value()); }
238inline real_concept log10(real_concept a)
239{ return std::log10(a.value()); }
240inline real_concept tan(real_concept a)
241{ return std::tan(a.value()); }
242inline real_concept pow(real_concept a, real_concept b)
243{ return std::pow(a.value(), b.value()); }
244#if !defined(__SUNPRO_CC)
245inline real_concept pow(real_concept a, int b)
246{ return std::pow(a.value(), b); }
247#else
248inline real_concept pow(real_concept a, int b)
249{ return std::pow(a.value(), static_cast<real_concept_base_type>(b)); }
250#endif
251inline real_concept sin(real_concept a)
252{ return std::sin(a.value()); }
253inline real_concept sinh(real_concept a)
254{ return std::sinh(a.value()); }
255inline real_concept sqrt(real_concept a)
256{ return std::sqrt(a.value()); }
257inline real_concept tanh(real_concept a)
258{ return std::tanh(a.value()); }
259
260//
b32b8144
FG
261// C++11 ism's
262// Note that these must not actually call the std:: versions as that precludes using this
263// header to test in C++03 mode, call the Boost versions instead:
264//
265inline boost::math::concepts::real_concept asinh(boost::math::concepts::real_concept a)
266{
267 return boost::math::asinh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error<boost::math::policies::ignore_error>()));
268}
269inline boost::math::concepts::real_concept acosh(boost::math::concepts::real_concept a)
270{
271 return boost::math::acosh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error<boost::math::policies::ignore_error>()));
272}
273inline boost::math::concepts::real_concept atanh(boost::math::concepts::real_concept a)
274{
275 return boost::math::atanh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error<boost::math::policies::ignore_error>()));
276}
277
278//
7c673cae
FG
279// Conversion and truncation routines:
280//
281template <class Policy>
282inline int iround(const concepts::real_concept& v, const Policy& pol)
283{ return boost::math::iround(v.value(), pol); }
284inline int iround(const concepts::real_concept& v)
285{ return boost::math::iround(v.value(), policies::policy<>()); }
286template <class Policy>
287inline long lround(const concepts::real_concept& v, const Policy& pol)
288{ return boost::math::lround(v.value(), pol); }
289inline long lround(const concepts::real_concept& v)
290{ return boost::math::lround(v.value(), policies::policy<>()); }
291
292#ifdef BOOST_HAS_LONG_LONG
293template <class Policy>
294inline boost::long_long_type llround(const concepts::real_concept& v, const Policy& pol)
295{ return boost::math::llround(v.value(), pol); }
296inline boost::long_long_type llround(const concepts::real_concept& v)
297{ return boost::math::llround(v.value(), policies::policy<>()); }
298#endif
299
300template <class Policy>
301inline int itrunc(const concepts::real_concept& v, const Policy& pol)
302{ return boost::math::itrunc(v.value(), pol); }
303inline int itrunc(const concepts::real_concept& v)
304{ return boost::math::itrunc(v.value(), policies::policy<>()); }
305template <class Policy>
306inline long ltrunc(const concepts::real_concept& v, const Policy& pol)
307{ return boost::math::ltrunc(v.value(), pol); }
308inline long ltrunc(const concepts::real_concept& v)
309{ return boost::math::ltrunc(v.value(), policies::policy<>()); }
310
311#ifdef BOOST_HAS_LONG_LONG
312template <class Policy>
313inline boost::long_long_type lltrunc(const concepts::real_concept& v, const Policy& pol)
314{ return boost::math::lltrunc(v.value(), pol); }
315inline boost::long_long_type lltrunc(const concepts::real_concept& v)
316{ return boost::math::lltrunc(v.value(), policies::policy<>()); }
317#endif
318
319// Streaming:
320template <class charT, class traits>
321inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const real_concept& a)
322{
323 return os << a.value();
324}
325template <class charT, class traits>
326inline std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& is, real_concept& a)
327{
7c673cae
FG
328 real_concept_base_type v;
329 is >> v;
330 a = v;
331 return is;
7c673cae
FG
332}
333
334} // namespace concepts
335
336namespace tools
337{
338
339template <>
f67539c2 340inline concepts::real_concept make_big_value<concepts::real_concept>(boost::math::tools::largest_float val, const char* , boost::false_type const&, boost::false_type const&)
7c673cae
FG
341{
342 return val; // Can't use lexical_cast here, sometimes it fails....
343}
344
345template <>
346inline concepts::real_concept max_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
347{
348 return max_value<concepts::real_concept_base_type>();
349}
350
351template <>
352inline concepts::real_concept min_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
353{
354 return min_value<concepts::real_concept_base_type>();
355}
356
357template <>
358inline concepts::real_concept log_max_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
359{
360 return log_max_value<concepts::real_concept_base_type>();
361}
362
363template <>
364inline concepts::real_concept log_min_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
365{
366 return log_min_value<concepts::real_concept_base_type>();
367}
368
369template <>
370inline concepts::real_concept epsilon<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
371{
372#ifdef __SUNPRO_CC
373 return std::numeric_limits<concepts::real_concept_base_type>::epsilon();
374#else
375 return tools::epsilon<concepts::real_concept_base_type>();
376#endif
377}
378
379template <>
380inline BOOST_MATH_CONSTEXPR int digits<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) BOOST_NOEXCEPT
381{
382 // Assume number of significand bits is same as real_concept_base_type,
383 // unless std::numeric_limits<T>::is_specialized to provide digits.
384 return tools::digits<concepts::real_concept_base_type>();
385 // Note that if numeric_limits real concept is NOT specialized to provide digits10
386 // (or max_digits10) then the default precision of 6 decimal digits will be used
387 // by Boost test (giving misleading error messages like
388 // "difference between {9.79796} and {9.79796} exceeds 5.42101e-19%"
389 // and by Boost lexical cast and serialization causing loss of accuracy.
390}
391
392} // namespace tools
7c673cae
FG
393} // namespace math
394} // namespace boost
395
396#endif // BOOST_MATH_REAL_CONCEPT_HPP
397
398