brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.2 KiB · 43f562e Raw
428 lines · plain
1//  Copyright John Maddock 2006.2//  Use, modification and distribution are subject to the3//  Boost Software License, Version 1.0. (See accompanying file4//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)5 6// std_real_concept is an archetype for built-in Real types.7 8// The main purpose in providing this type is to verify9// that std lib functions are found via a using declaration10// bringing those functions into the current scope, and not11// just because they happen to be in global scope.12//13// If ::pow is found rather than std::pow say, then the code14// will silently compile, but truncation of long doubles to15// double will cause a significant loss of precision.16// A template instantiated with std_real_concept will *only*17// compile if it std::whatever is in scope.18 19#include <boost/math/policies/policy.hpp>20#include <boost/math/special_functions/math_fwd.hpp>21#include <limits>22#include <ostream>23#include <istream>24#include <cmath>25 26#ifndef BOOST_MATH_STD_REAL_CONCEPT_HPP27#define BOOST_MATH_STD_REAL_CONCEPT_HPP28 29namespace boost{ namespace math{30 31namespace concepts32{33 34#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS35   typedef double std_real_concept_base_type;36#else37   typedef long double std_real_concept_base_type;38#endif39 40class std_real_concept41{42public:43   // Constructors:44   std_real_concept() : m_value(0){}45   std_real_concept(char c) : m_value(c){}46#ifndef BOOST_NO_INTRINSIC_WCHAR_T47   std_real_concept(wchar_t c) : m_value(c){}48#endif49   std_real_concept(unsigned char c) : m_value(c){}50   std_real_concept(signed char c) : m_value(c){}51   std_real_concept(unsigned short c) : m_value(c){}52   std_real_concept(short c) : m_value(c){}53   std_real_concept(unsigned int c) : m_value(c){}54   std_real_concept(int c) : m_value(c){}55   std_real_concept(unsigned long c) : m_value(c){}56   std_real_concept(long c) : m_value(c){}57#if defined(__DECCXX) || defined(__SUNPRO_CC)58   std_real_concept(unsigned long long c) : m_value(static_cast<std_real_concept_base_type>(c)){}59   std_real_concept(long long c) : m_value(static_cast<std_real_concept_base_type>(c)){}60#endif61   std_real_concept(unsigned long long c) : m_value(static_cast<std_real_concept_base_type>(c)){}62   std_real_concept(long long c) : m_value(static_cast<std_real_concept_base_type>(c)){}63   std_real_concept(float c) : m_value(c){}64   std_real_concept(double c) : m_value(c){}65   std_real_concept(long double c) : m_value(c){}66#ifdef BOOST_MATH_USE_FLOAT12867   std_real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){}68#endif69 70   // Assignment:71   std_real_concept& operator=(char c) { m_value = c; return *this; }72   std_real_concept& operator=(unsigned char c) { m_value = c; return *this; }73   std_real_concept& operator=(signed char c) { m_value = c; return *this; }74#ifndef BOOST_NO_INTRINSIC_WCHAR_T75   std_real_concept& operator=(wchar_t c) { m_value = c; return *this; }76#endif77   std_real_concept& operator=(short c) { m_value = c; return *this; }78   std_real_concept& operator=(unsigned short c) { m_value = c; return *this; }79   std_real_concept& operator=(int c) { m_value = c; return *this; }80   std_real_concept& operator=(unsigned int c) { m_value = c; return *this; }81   std_real_concept& operator=(long c) { m_value = c; return *this; }82   std_real_concept& operator=(unsigned long c) { m_value = c; return *this; }83#if defined(__DECCXX) || defined(__SUNPRO_CC)84   std_real_concept& operator=(unsigned long long c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }85   std_real_concept& operator=(long long c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }86#endif87   std_real_concept& operator=(long long c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }88   std_real_concept& operator=(unsigned long long c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }89 90   std_real_concept& operator=(float c) { m_value = c; return *this; }91   std_real_concept& operator=(double c) { m_value = c; return *this; }92   std_real_concept& operator=(long double c) { m_value = c; return *this; }93#ifdef BOOST_MATH_USE_FLOAT12894   std_real_concept& operator=(BOOST_MATH_FLOAT128_TYPE c) { m_value = c; return *this; }95#endif96 97   // Access:98   std_real_concept_base_type value()const{ return m_value; }99 100   // Member arithmetic:101   std_real_concept& operator+=(const std_real_concept& other)102   { m_value += other.value(); return *this; }103   std_real_concept& operator-=(const std_real_concept& other)104   { m_value -= other.value(); return *this; }105   std_real_concept& operator*=(const std_real_concept& other)106   { m_value *= other.value(); return *this; }107   std_real_concept& operator/=(const std_real_concept& other)108   { m_value /= other.value(); return *this; }109   std_real_concept operator-()const110   { return -m_value; }111   std_real_concept const& operator+()const112   { return *this; }113 114private:115   std_real_concept_base_type m_value;116};117 118// Non-member arithmetic:119inline std_real_concept operator+(const std_real_concept& a, const std_real_concept& b)120{121   std_real_concept result(a);122   result += b;123   return result;124}125inline std_real_concept operator-(const std_real_concept& a, const std_real_concept& b)126{127   std_real_concept result(a);128   result -= b;129   return result;130}131inline std_real_concept operator*(const std_real_concept& a, const std_real_concept& b)132{133   std_real_concept result(a);134   result *= b;135   return result;136}137inline std_real_concept operator/(const std_real_concept& a, const std_real_concept& b)138{139   std_real_concept result(a);140   result /= b;141   return result;142}143 144// Comparison:145inline bool operator == (const std_real_concept& a, const std_real_concept& b)146{ return a.value() == b.value(); }147inline bool operator != (const std_real_concept& a, const std_real_concept& b)148{ return a.value() != b.value();}149inline bool operator < (const std_real_concept& a, const std_real_concept& b)150{ return a.value() < b.value(); }151inline bool operator <= (const std_real_concept& a, const std_real_concept& b)152{ return a.value() <= b.value(); }153inline bool operator > (const std_real_concept& a, const std_real_concept& b)154{ return a.value() > b.value(); }155inline bool operator >= (const std_real_concept& a, const std_real_concept& b)156{ return a.value() >= b.value(); }157 158} // namespace concepts159} // namespace math160} // namespace boost161 162namespace std{163 164// Non-member functions:165inline boost::math::concepts::std_real_concept acos(boost::math::concepts::std_real_concept a)166{ return std::acos(a.value()); }167inline boost::math::concepts::std_real_concept cos(boost::math::concepts::std_real_concept a)168{ return std::cos(a.value()); }169inline boost::math::concepts::std_real_concept asin(boost::math::concepts::std_real_concept a)170{ return std::asin(a.value()); }171inline boost::math::concepts::std_real_concept atan(boost::math::concepts::std_real_concept a)172{ return std::atan(a.value()); }173inline boost::math::concepts::std_real_concept atan2(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b)174{ return std::atan2(a.value(), b.value()); }175inline boost::math::concepts::std_real_concept ceil(boost::math::concepts::std_real_concept a)176{ return std::ceil(a.value()); }177#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS178inline boost::math::concepts::std_real_concept fmod(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b)179{ return fmodl(a.value(), b.value()); }180#else181inline boost::math::concepts::std_real_concept fmod(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b)182{ return std::fmod(a.value(), b.value()); }183#endif184inline boost::math::concepts::std_real_concept cosh(boost::math::concepts::std_real_concept a)185{ return std::cosh(a.value()); }186inline boost::math::concepts::std_real_concept exp(boost::math::concepts::std_real_concept a)187{ return std::exp(a.value()); }188inline boost::math::concepts::std_real_concept fabs(boost::math::concepts::std_real_concept a)189{ return std::fabs(a.value()); }190inline boost::math::concepts::std_real_concept abs(boost::math::concepts::std_real_concept a)191{ return std::abs(a.value()); }192inline boost::math::concepts::std_real_concept floor(boost::math::concepts::std_real_concept a)193{ return std::floor(a.value()); }194inline boost::math::concepts::std_real_concept modf(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept* ipart)195{196   boost::math::concepts::std_real_concept_base_type ip;197   boost::math::concepts::std_real_concept_base_type result = std::modf(a.value(), &ip);198   *ipart = ip;199   return result;200}201inline boost::math::concepts::std_real_concept frexp(boost::math::concepts::std_real_concept a, int* expon)202{ return std::frexp(a.value(), expon); }203inline boost::math::concepts::std_real_concept ldexp(boost::math::concepts::std_real_concept a, int expon)204{ return std::ldexp(a.value(), expon); }205inline boost::math::concepts::std_real_concept log(boost::math::concepts::std_real_concept a)206{ return std::log(a.value()); }207inline boost::math::concepts::std_real_concept log10(boost::math::concepts::std_real_concept a)208{ return std::log10(a.value()); }209inline boost::math::concepts::std_real_concept tan(boost::math::concepts::std_real_concept a)210{ return std::tan(a.value()); }211inline boost::math::concepts::std_real_concept pow(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b)212{ return std::pow(a.value(), b.value()); }213#if !defined(__SUNPRO_CC)214inline boost::math::concepts::std_real_concept pow(boost::math::concepts::std_real_concept a, int b)215{ return std::pow(a.value(), b); }216#else217inline boost::math::concepts::std_real_concept pow(boost::math::concepts::std_real_concept a, int b)218{ return std::pow(a.value(), static_cast<long double>(b)); }219#endif220inline boost::math::concepts::std_real_concept sin(boost::math::concepts::std_real_concept a)221{ return std::sin(a.value()); }222inline boost::math::concepts::std_real_concept sinh(boost::math::concepts::std_real_concept a)223{ return std::sinh(a.value()); }224inline boost::math::concepts::std_real_concept sqrt(boost::math::concepts::std_real_concept a)225{ return std::sqrt(a.value()); }226inline boost::math::concepts::std_real_concept tanh(boost::math::concepts::std_real_concept a)227{ return std::tanh(a.value()); }228inline boost::math::concepts::std_real_concept (nextafter)(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b)229{ return (boost::math::nextafter)(a, b); }230//231// C++11 ism's232// Now that we only support C++11 and later, we can allow use of these:233//234inline boost::math::concepts::std_real_concept asinh(boost::math::concepts::std_real_concept a)235{ return std::asinh(a.value()); }236inline boost::math::concepts::std_real_concept acosh(boost::math::concepts::std_real_concept a)237{ return std::acosh(a.value()); }238inline boost::math::concepts::std_real_concept atanh(boost::math::concepts::std_real_concept a)239{ return std::atanh(a.value()); }240inline bool (isfinite)(boost::math::concepts::std_real_concept a)241{242   return (boost::math::isfinite)(a.value());243}244inline boost::math::concepts::std_real_concept log2(boost::math::concepts::std_real_concept a)245{ return std::log2(a.value()); }246inline int ilogb(boost::math::concepts::std_real_concept a)247{ return std::ilogb(a.value()); }248 249 250} // namespace std251 252#include <boost/math/special_functions/round.hpp>253#include <boost/math/special_functions/trunc.hpp>254#include <boost/math/special_functions/modf.hpp>255#include <boost/math/tools/precision.hpp>256 257namespace boost{ namespace math{ namespace concepts{258 259//260// Conversion and truncation routines:261//262template <class Policy>263inline int iround(const concepts::std_real_concept& v, const Policy& pol)264{265   return boost::math::iround(v.value(), pol);266}267inline int iround(const concepts::std_real_concept& v)268{269   return boost::math::iround(v.value(), policies::policy<>());270}271 272template <class Policy>273inline long lround(const concepts::std_real_concept& v, const Policy& pol)274{275   return boost::math::lround(v.value(), pol);276}277inline long lround(const concepts::std_real_concept& v)278{279   return boost::math::lround(v.value(), policies::policy<>());280}281 282template <class Policy>283inline long long llround(const concepts::std_real_concept& v, const Policy& pol)284{285   return boost::math::llround(v.value(), pol);286}287inline long long llround(const concepts::std_real_concept& v)288{289   return boost::math::llround(v.value(), policies::policy<>());290}291 292template <class Policy>293inline int itrunc(const concepts::std_real_concept& v, const Policy& pol)294{295   return boost::math::itrunc(v.value(), pol);296}297inline int itrunc(const concepts::std_real_concept& v)298{299   return boost::math::itrunc(v.value(), policies::policy<>());300}301 302template <class Policy>303inline long ltrunc(const concepts::std_real_concept& v, const Policy& pol)304{305   return boost::math::ltrunc(v.value(), pol);306}307inline long ltrunc(const concepts::std_real_concept& v)308{309   return boost::math::ltrunc(v.value(), policies::policy<>());310}311 312template <class Policy>313inline long long lltrunc(const concepts::std_real_concept& v, const Policy& pol)314{315   return boost::math::lltrunc(v.value(), pol);316}317inline long long lltrunc(const concepts::std_real_concept& v)318{319   return boost::math::lltrunc(v.value(), policies::policy<>());320}321 322// Streaming:323template <class charT, class traits>324inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const std_real_concept& a)325{326   return os << a.value();327}328template <class charT, class traits>329inline std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& is, std_real_concept& a)330{331#if defined(__SGI_STL_PORT) || defined(_RWSTD_VER) || defined(__LIBCOMO__) || defined(_LIBCPP_VERSION)332   std::string s;333   std_real_concept_base_type d;334   is >> s;335   std::sscanf(s.c_str(), "%Lf", &d);336   a = d;337   return is;338#else339   std_real_concept_base_type v;340   is >> v;341   a = v;342   return is;343#endif344}345 346} // namespace concepts347}}348 349#include <boost/math/tools/big_constant.hpp>350 351namespace boost{ namespace math{352namespace tools353{354 355template <>356inline concepts::std_real_concept make_big_value<concepts::std_real_concept>(boost::math::tools::largest_float val, const char*, std::false_type const&, std::false_type const&)357{358   return val;  // Can't use lexical_cast here, sometimes it fails....359}360 361template <>362inline concepts::std_real_concept max_value<concepts::std_real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))363{364   return max_value<concepts::std_real_concept_base_type>();365}366 367template <>368inline concepts::std_real_concept min_value<concepts::std_real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))369{370   return min_value<concepts::std_real_concept_base_type>();371}372 373template <>374inline concepts::std_real_concept log_max_value<concepts::std_real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))375{376   return log_max_value<concepts::std_real_concept_base_type>();377}378 379template <>380inline concepts::std_real_concept log_min_value<concepts::std_real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))381{382   return log_min_value<concepts::std_real_concept_base_type>();383}384 385template <>386inline concepts::std_real_concept epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))387{388   return tools::epsilon<concepts::std_real_concept_base_type>();389}390 391template <>392inline constexpr int digits<concepts::std_real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) noexcept393{ // Assume number of significand bits is same as std_real_concept_base_type,394  // unless std::numeric_limits<T>::is_specialized to provide digits.395   return digits<concepts::std_real_concept_base_type>();396}397 398template <>399inline double real_cast<double, concepts::std_real_concept>(concepts::std_real_concept r)400{401   return static_cast<double>(r.value());402}403 404 405} // namespace tools406 407#if defined(_MSC_VER) && (_MSC_VER <= 1310)408using concepts::itrunc;409using concepts::ltrunc;410using concepts::lltrunc;411using concepts::iround;412using concepts::lround;413using concepts::llround;414#endif415 416} // namespace math417} // namespace boost418 419//420// These must go at the end, as they include stuff that won't compile until421// after std_real_concept has been defined:422//423#include <boost/math/special_functions/acosh.hpp>424#include <boost/math/special_functions/asinh.hpp>425#include <boost/math/special_functions/atanh.hpp>426 427#endif // BOOST_MATH_STD_REAL_CONCEPT_HPP428