brintos

brintos / llvm-project-archived public Read only

0
0
Text · 39.5 KiB · d7ba694 Raw
1059 lines · plain
1//  Copyright John Maddock 2007.2//  Copyright Paul A. Bristow 2007.3//  Copyright Matt Borland 2024.4//  Use, modification and distribution are subject to the5//  Boost Software License, Version 1.0. (See accompanying file6//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)7 8#ifndef BOOST_MATH_POLICY_ERROR_HANDLING_HPP9#define BOOST_MATH_POLICY_ERROR_HANDLING_HPP10 11#include <boost/math/policies/policy.hpp>12#include <boost/math/tools/config.hpp>13#include <boost/math/tools/numeric_limits.hpp>14#include <boost/math/tools/precision.hpp>15#include <boost/math/tools/tuple.hpp>16#include <boost/math/tools/type_traits.hpp>17 18#ifndef BOOST_MATH_HAS_NVRTC19 20#ifndef BOOST_MATH_NO_EXCEPTIONS21#include <boost/math/tools/throw_exception.hpp>22#endif23 24#include <cerrno>25#include <cmath>26#include <complex>27#include <cstdint>28#include <cstring>29#include <iomanip>30#include <sstream>31#ifndef BOOST_MATH_NO_EXCEPTIONS32#include <stdexcept>33#endif34#include <string>35#ifndef BOOST_MATH_NO_RTTI36#include <typeinfo>37#endif38 39#ifdef _MSC_VER40#  pragma warning(push) // Quiet warnings in boost/format.hpp41#  pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE42#  pragma warning(disable: 4512) // assignment operator could not be generated.43#  pragma warning(disable: 4127) // conditional expression is constant44// And warnings in error handling:45#  pragma warning(disable: 4702) // unreachable code.46// Note that this only occurs when the compiler can deduce code is unreachable,47// for example when policy macros are used to ignore errors rather than throw.48#endif49 50namespace boost{ namespace math{51 52#ifndef BOOST_MATH_NO_EXCEPTIONS53 54class evaluation_error : public std::runtime_error55{56public:57   explicit evaluation_error(const std::string& s) : std::runtime_error(s){}58};59 60class rounding_error : public std::runtime_error61{62public:63   explicit rounding_error(const std::string& s) : std::runtime_error(s){}64};65 66#else67 68class evaluation_error {};69class rounding_error {};70 71#endif72 73namespace policies{74//75// Forward declarations of user error handlers,76// it's up to the user to provide the definition of these:77//78template <class T>79T user_domain_error(const char* function, const char* message, const T& val);80template <class T>81T user_pole_error(const char* function, const char* message, const T& val);82template <class T>83T user_overflow_error(const char* function, const char* message, const T& val);84template <class T>85T user_underflow_error(const char* function, const char* message, const T& val);86template <class T>87T user_denorm_error(const char* function, const char* message, const T& val);88template <class T>89T user_evaluation_error(const char* function, const char* message, const T& val);90template <class T, class TargetType>91TargetType user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t);92template <class T>93T user_indeterminate_result_error(const char* function, const char* message, const T& val);94 95namespace detail96{97 98template <class T>99inline std::string prec_format(const T& val)100{101   using prec_type = typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type;102 103   std::stringstream strm { };104 105   if(prec_type::value)106   {107      const std::streamsize prec { static_cast<std::streamsize>(2UL + (prec_type::value * 30103UL) / 100000UL) };108 109      strm << std::setprecision(prec);110   }111 112   strm << val;113 114   return strm.str();115}116 117#ifdef BOOST_MATH_USE_CHARCONV_FOR_CONVERSION118 119template <>120inline std::string prec_format<std::float128_t>(const std::float128_t& val)121{122   char buffer[128] {};123   const auto r = std::to_chars(buffer, buffer + sizeof(buffer), val);124   return std::string(buffer, r.ptr);125}126 127#endif128 129inline void replace_all_in_string(std::string& result, const char* what, const char* with)130{131   std::string::size_type pos = 0;132   std::string::size_type slen = std::strlen(what);133   std::string::size_type rlen = std::strlen(with);134   while((pos = result.find(what, pos)) != std::string::npos)135   {136      result.replace(pos, slen, with);137      pos += rlen;138   }139}140 141template <class T>142inline const char* name_of()143{144#ifndef BOOST_MATH_NO_RTTI145   return typeid(T).name();146#else147   return "unknown";148#endif149}150template <> inline const char* name_of<float>(){ return "float"; }151template <> inline const char* name_of<double>(){ return "double"; }152template <> inline const char* name_of<long double>(){ return "long double"; }153 154#ifdef BOOST_MATH_USE_FLOAT128155template <>156inline const char* name_of<BOOST_MATH_FLOAT128_TYPE>()157{158   return "__float128";159}160#endif161 162#ifndef BOOST_MATH_NO_EXCEPTIONS163template <class E, class T>164void raise_error(const char* pfunction, const char* message)165{166  if(pfunction == nullptr)167  {168     pfunction = "Unknown function operating on type %1%";169  }170  if(message == nullptr)171  {172     message = "Cause unknown";173  }174 175  std::string function(pfunction);176  std::string msg("Error in function ");177#ifndef BOOST_MATH_NO_RTTI178  replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());179#else180  replace_all_in_string(function, "%1%", "Unknown");181#endif182  msg += function;183  msg += ": ";184  msg += message;185 186  BOOST_MATH_THROW_EXCEPTION(E(msg))187}188 189template <class E, class T>190void raise_error(const char* pfunction, const char* pmessage, const T& val)191{192  if(pfunction == nullptr)193  {194     pfunction = "Unknown function operating on type %1%";195  }196  if(pmessage == nullptr)197  {198     pmessage = "Cause unknown: error caused by bad argument with value %1%";199  }200 201  std::string function(pfunction);202  std::string message(pmessage);203  std::string msg("Error in function ");204#ifndef BOOST_MATH_NO_RTTI205  replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());206#else207  replace_all_in_string(function, "%1%", "Unknown");208#endif209  msg += function;210  msg += ": ";211 212  std::string sval = prec_format(val);213  replace_all_in_string(message, "%1%", sval.c_str());214  msg += message;215 216  BOOST_MATH_THROW_EXCEPTION(E(msg))217}218#endif219 220template <class T>221BOOST_MATH_GPU_ENABLED inline T raise_domain_error(222           const char* function,223           const char* message,224           const T& val,225           const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&)226{227#ifdef BOOST_MATH_NO_EXCEPTIONS228   static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");229#else230   raise_error<std::domain_error, T>(function, message, val);231   // we never get here:232   return boost::math::numeric_limits<T>::quiet_NaN();233#endif234}235 236template <class T>237BOOST_MATH_GPU_ENABLED constexpr T raise_domain_error(238           const char* ,239           const char* ,240           const T& ,241           const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)242{243   // This may or may not do the right thing, but the user asked for the error244   // to be ignored so here we go anyway:245   return boost::math::numeric_limits<T>::quiet_NaN();246}247 248template <class T>249BOOST_MATH_GPU_ENABLED inline T raise_domain_error(250           const char* ,251           const char* ,252           const T& ,253           const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)254{255   errno = EDOM;256   // This may or may not do the right thing, but the user asked for the error257   // to be silent so here we go anyway:258   return boost::math::numeric_limits<T>::quiet_NaN();259}260 261template <class T>262BOOST_MATH_GPU_ENABLED inline T raise_domain_error(263           const char* function,264           const char* message,265           const T& val,266           const  ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&)267{268   return user_domain_error(function, message, val);269}270 271template <class T>272BOOST_MATH_GPU_ENABLED inline T raise_pole_error(273           const char* function,274           const char* message,275           const T& val,276           const  ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&)277{278#ifdef BOOST_MATH_NO_EXCEPTIONS279   static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");280#else281   return boost::math::policies::detail::raise_domain_error(function, message, val,  ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>());282#endif283}284 285template <class T>286BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error(287           const char* function,288           const char* message,289           const T& val,290           const  ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)291{292   return  ::boost::math::policies::detail::raise_domain_error(function, message, val,  ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>());293}294 295template <class T>296BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error(297           const char* function,298           const char* message,299           const T& val,300           const  ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)301{302   return  ::boost::math::policies::detail::raise_domain_error(function, message, val,  ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>());303}304 305template <class T>306BOOST_MATH_GPU_ENABLED inline T raise_pole_error(307           const char* function,308           const char* message,309           const T& val,310           const  ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&)311{312   return user_pole_error(function, message, val);313}314 315template <class T>316BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(317           const char* function,318           const char* message,319           const  ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)320{321#ifdef BOOST_MATH_NO_EXCEPTIONS322   static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");323#else324   raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow");325   // We should never get here:326   return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();327#endif328}329 330template <class T>331BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(332           const char* function,333           const char* message,334           const T& val,335           const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)336{337#ifdef BOOST_MATH_NO_EXCEPTIONS338   static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");339#else340   raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow", val);341   // We should never get here:342   return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();343#endif344}345 346template <class T>347BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(348           const char* ,349           const char* ,350           const  ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)351{352   // This may or may not do the right thing, but the user asked for the error353   // to be ignored so here we go anyway:354   return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();355}356 357template <class T>358BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(359           const char* ,360           const char* ,361           const T&,362           const  ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)363{364   // This may or may not do the right thing, but the user asked for the error365   // to be ignored so here we go anyway:366   return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();367}368 369template <class T>370BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(371           const char* ,372           const char* ,373           const  ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)374{375   errno = ERANGE;376   // This may or may not do the right thing, but the user asked for the error377   // to be silent so here we go anyway:378   return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();379}380 381template <class T>382BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(383           const char* ,384           const char* ,385           const T&,386           const  ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)387{388   errno = ERANGE;389   // This may or may not do the right thing, but the user asked for the error390   // to be silent so here we go anyway:391   return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();392}393 394template <class T>395BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(396           const char* function,397           const char* message,398           const  ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)399{400   return user_overflow_error(function, message, boost::math::numeric_limits<T>::infinity());401}402 403template <class T>404BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(405           const char* function,406           const char* message,407           const T& val,408           const  ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)409{410   std::string m(message ? message : "");411   std::string sval = prec_format(val);412   replace_all_in_string(m, "%1%", sval.c_str());413 414   return user_overflow_error(function, m.c_str(), boost::math::numeric_limits<T>::infinity());415}416 417template <class T>418BOOST_MATH_GPU_ENABLED inline T raise_underflow_error(419           const char* function,420           const char* message,421           const  ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&)422{423#ifdef BOOST_MATH_NO_EXCEPTIONS424   static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");425#else426   raise_error<std::underflow_error, T>(function, message ? message : "numeric underflow");427   // We should never get here:428   return 0;429#endif430}431 432template <class T>433BOOST_MATH_GPU_ENABLED constexpr T raise_underflow_error(434           const char* ,435           const char* ,436           const  ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)437{438   // This may or may not do the right thing, but the user asked for the error439   // to be ignored so here we go anyway:440   return T(0);441}442 443template <class T>444BOOST_MATH_GPU_ENABLED inline T raise_underflow_error(445           const char* /* function */,446           const char* /* message */,447           const  ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)448{449   errno = ERANGE;450   // This may or may not do the right thing, but the user asked for the error451   // to be silent so here we go anyway:452   return T(0);453}454 455template <class T>456BOOST_MATH_GPU_ENABLED inline T raise_underflow_error(457           const char* function,458           const char* message,459           const  ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&)460{461   return user_underflow_error(function, message, T(0));462}463 464template <class T>465BOOST_MATH_GPU_ENABLED inline T raise_denorm_error(466           const char* function,467           const char* message,468           const T& /* val */,469           const  ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&)470{471#ifdef BOOST_MATH_NO_EXCEPTIONS472   static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");473#else474   raise_error<std::underflow_error, T>(function, message ? message : "denormalised result");475   // we never get here:476   return T(0);477#endif478}479 480template <class T>481BOOST_MATH_GPU_ENABLED inline constexpr T raise_denorm_error(482           const char* ,483           const char* ,484           const T&  val,485           const  ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)486{487   // This may or may not do the right thing, but the user asked for the error488   // to be ignored so here we go anyway:489   return val;490}491 492template <class T>493BOOST_MATH_GPU_ENABLED inline T raise_denorm_error(494           const char* ,495           const char* ,496           const T& val,497           const  ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)498{499   errno = ERANGE;500   // This may or may not do the right thing, but the user asked for the error501   // to be silent so here we go anyway:502   return val;503}504 505template <class T>506BOOST_MATH_GPU_ENABLED inline T raise_denorm_error(507           const char* function,508           const char* message,509           const T& val,510           const  ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&)511{512   return user_denorm_error(function, message, val);513}514 515template <class T>516BOOST_MATH_GPU_ENABLED inline T raise_evaluation_error(517           const char* function,518           const char* message,519           const T& val,520           const  ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&)521{522#ifdef BOOST_MATH_NO_EXCEPTIONS523   static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");524#else525   raise_error<boost::math::evaluation_error, T>(function, message, val);526   // we never get here:527   return T(0);528#endif529}530 531template <class T>532BOOST_MATH_GPU_ENABLED constexpr T raise_evaluation_error(533           const char* ,534           const char* ,535           const T& val,536           const  ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)537{538   // This may or may not do the right thing, but the user asked for the error539   // to be ignored so here we go anyway:540   return val;541}542 543template <class T>544BOOST_MATH_GPU_ENABLED inline T raise_evaluation_error(545           const char* ,546           const char* ,547           const T& val,548           const  ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)549{550   errno = EDOM;551   // This may or may not do the right thing, but the user asked for the error552   // to be silent so here we go anyway:553   return val;554}555 556template <class T>557BOOST_MATH_GPU_ENABLED inline T raise_evaluation_error(558           const char* function,559           const char* message,560           const T& val,561           const  ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&)562{563   return user_evaluation_error(function, message, val);564}565 566template <class T, class TargetType>567BOOST_MATH_GPU_ENABLED inline TargetType raise_rounding_error(568           const char* function,569           const char* message,570           const T& val,571           const TargetType&,572           const  ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&)573{574#ifdef BOOST_MATH_NO_EXCEPTIONS575   static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");576#else577   raise_error<boost::math::rounding_error, T>(function, message, val);578   // we never get here:579   return TargetType(0);580#endif581}582 583template <class T, class TargetType>584BOOST_MATH_GPU_ENABLED constexpr TargetType raise_rounding_error(585           const char* ,586           const char* ,587           const T& val,588           const TargetType&,589           const  ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)590{591   // This may or may not do the right thing, but the user asked for the error592   // to be ignored so here we go anyway:593   static_assert(boost::math::numeric_limits<TargetType>::is_specialized, "The target type must have std::numeric_limits specialized.");594   return  val > 0 ? (boost::math::numeric_limits<TargetType>::max)() : (boost::math::numeric_limits<TargetType>::is_integer ? (boost::math::numeric_limits<TargetType>::min)() : -(boost::math::numeric_limits<TargetType>::max)());595}596 597template <class T, class TargetType>598BOOST_MATH_GPU_ENABLED inline TargetType raise_rounding_error(599           const char* ,600           const char* ,601           const T& val,602           const TargetType&,603           const  ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)604{605   errno = ERANGE;606   // This may or may not do the right thing, but the user asked for the error607   // to be silent so here we go anyway:608   static_assert(boost::math::numeric_limits<TargetType>::is_specialized, "The target type must have std::numeric_limits specialized.");609   return  val > 0 ? (boost::math::numeric_limits<TargetType>::max)() : (boost::math::numeric_limits<TargetType>::is_integer ? (boost::math::numeric_limits<TargetType>::min)() : -(boost::math::numeric_limits<TargetType>::max)());610}611template <class T, class TargetType>612BOOST_MATH_GPU_ENABLED inline TargetType raise_rounding_error(613           const char* function,614           const char* message,615           const T& val,616           const TargetType& t,617           const  ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&)618{619   return user_rounding_error(function, message, val, t);620}621 622template <class T, class R>623BOOST_MATH_GPU_ENABLED inline T raise_indeterminate_result_error(624           const char* function,625           const char* message,626           const T& val,627           const R& ,628           const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&)629{630#ifdef BOOST_MATH_NO_EXCEPTIONS631   static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");632#else633   raise_error<std::domain_error, T>(function, message, val);634   // we never get here:635   return boost::math::numeric_limits<T>::quiet_NaN();636#endif637}638 639template <class T, class R>640BOOST_MATH_GPU_ENABLED inline constexpr T raise_indeterminate_result_error(641           const char* ,642           const char* ,643           const T& ,644           const R& result,645           const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)646{647   // This may or may not do the right thing, but the user asked for the error648   // to be ignored so here we go anyway:649   return result;650}651 652template <class T, class R>653BOOST_MATH_GPU_ENABLED inline T raise_indeterminate_result_error(654           const char* ,655           const char* ,656           const T& ,657           const R& result,658           const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&)659{660   errno = EDOM;661   // This may or may not do the right thing, but the user asked for the error662   // to be silent so here we go anyway:663   return result;664}665 666template <class T, class R>667BOOST_MATH_GPU_ENABLED inline T raise_indeterminate_result_error(668           const char* function,669           const char* message,670           const T& val,671           const R& ,672           const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&)673{674   return user_indeterminate_result_error(function, message, val);675}676 677}  // namespace detail678 679template <class T, class Policy>680BOOST_MATH_GPU_ENABLED constexpr T raise_domain_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))681{682   typedef typename Policy::domain_error_type policy_type;683   return detail::raise_domain_error(684      function, message ? message : "Domain Error evaluating function at %1%",685      val, policy_type());686}687 688template <class T, class Policy>689BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))690{691   typedef typename Policy::pole_error_type policy_type;692   return detail::raise_pole_error(693      function, message ? message : "Evaluation of function at pole %1%",694      val, policy_type());695}696 697template <class T, class Policy>698BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(const char* function, const char* message, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))699{700   typedef typename Policy::overflow_error_type policy_type;701   return detail::raise_overflow_error<T>(702      function, message ? message : "Overflow Error",703      policy_type());704}705 706template <class T, class Policy>707BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))708{709   typedef typename Policy::overflow_error_type policy_type;710   return detail::raise_overflow_error(711      function, message ? message : "Overflow evaluating function at %1%",712      val, policy_type());713}714 715template <class T, class Policy>716BOOST_MATH_GPU_ENABLED constexpr T raise_underflow_error(const char* function, const char* message, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))717{718   typedef typename Policy::underflow_error_type policy_type;719   return detail::raise_underflow_error<T>(720      function, message ? message : "Underflow Error",721      policy_type());722}723 724template <class T, class Policy>725BOOST_MATH_GPU_ENABLED constexpr T raise_denorm_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))726{727   typedef typename Policy::denorm_error_type policy_type;728   return detail::raise_denorm_error<T>(729      function, message ? message : "Denorm Error",730      val,731      policy_type());732}733 734template <class T, class Policy>735BOOST_MATH_GPU_ENABLED constexpr T raise_evaluation_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))736{737   typedef typename Policy::evaluation_error_type policy_type;738   return detail::raise_evaluation_error(739      function, message ? message : "Internal Evaluation Error, best value so far was %1%",740      val, policy_type());741}742 743template <class T, class TargetType, class Policy>744BOOST_MATH_GPU_ENABLED constexpr TargetType raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))745{746   typedef typename Policy::rounding_error_type policy_type;747   return detail::raise_rounding_error(748      function, message ? message : "Value %1% can not be represented in the target integer type.",749      val, t, policy_type());750}751 752template <class T, class R, class Policy>753BOOST_MATH_GPU_ENABLED constexpr T raise_indeterminate_result_error(const char* function, const char* message, const T& val, const R& result, const Policy&) noexcept(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))754{755   typedef typename Policy::indeterminate_result_error_type policy_type;756   return detail::raise_indeterminate_result_error(757      function, message ? message : "Indeterminate result with value %1%",758      val, result, policy_type());759}760 761//762// checked_narrowing_cast:763//764namespace detail765{766 767template <class R, class T, class Policy>768BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_overflow(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))769{770   BOOST_MATH_STD_USING771   if(fabs(val) > tools::max_value<R>())772   {773      boost::math::policies::detail::raise_overflow_error<R>(function, nullptr, pol);774      *result = static_cast<R>(val);775      return true;776   }777   return false;778}779template <class R, class T, class Policy>780BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_overflow(std::complex<T> val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))781{782   typedef typename R::value_type r_type;783   r_type re, im;784   bool r = check_overflow<r_type>(val.real(), &re, function, pol);785   r = check_overflow<r_type>(val.imag(), &im, function, pol) || r;786   *result = R(re, im);787   return r;788}789template <class R, class T, class Policy>790BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_underflow(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))791{792   if((val != 0) && (static_cast<R>(val) == 0))793   {794      *result = static_cast<R>(boost::math::policies::detail::raise_underflow_error<R>(function, nullptr, pol));795      return true;796   }797   return false;798}799template <class R, class T, class Policy>800BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_underflow(std::complex<T> val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))801{802   typedef typename R::value_type r_type;803   r_type re, im;804   bool r = check_underflow<r_type>(val.real(), &re, function, pol);805   r = check_underflow<r_type>(val.imag(), &im, function, pol) || r;806   *result = R(re, im);807   return r;808}809template <class R, class T, class Policy>810BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_denorm(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))811{812   BOOST_MATH_STD_USING813   if((fabs(val) < static_cast<T>(tools::min_value<R>())) && (static_cast<R>(val) != 0))814   {815      *result = static_cast<R>(boost::math::policies::detail::raise_denorm_error<R>(function, 0, static_cast<R>(val), pol));816      return true;817   }818   return false;819}820template <class R, class T, class Policy>821BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE bool check_denorm(std::complex<T> val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))822{823   typedef typename R::value_type r_type;824   r_type re, im;825   bool r = check_denorm<r_type>(val.real(), &re, function, pol);826   r = check_denorm<r_type>(val.imag(), &im, function, pol) || r;827   *result = R(re, im);828   return r;829}830 831// Default instantiations with ignore_error policy.832template <class R, class T>833BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))834{ return false; }835template <class R, class T>836BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_overflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))837{ return false; }838template <class R, class T>839BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))840{ return false; }841template <class R, class T>842BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_underflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))843{ return false; }844template <class R, class T>845BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))846{ return false; }847template <class R, class T>848BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_denorm(std::complex<T> /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))849{ return false; }850 851} // namespace detail852 853template <class R, class Policy, class T>854BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE R checked_narrowing_cast(T val, const char* function) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value)855{856   typedef typename Policy::overflow_error_type overflow_type;857   typedef typename Policy::underflow_error_type underflow_type;858   typedef typename Policy::denorm_error_type denorm_type;859   //860   // Most of what follows will evaluate to a no-op:861   //862   R result = 0;863   if(detail::check_overflow<R>(val, &result, function, overflow_type()))864      return result;865   if(detail::check_underflow<R>(val, &result, function, underflow_type()))866      return result;867   if(detail::check_denorm<R>(val, &result, function, denorm_type()))868      return result;869 870   return static_cast<R>(val);871}872 873template <class T, class Policy>874BOOST_MATH_GPU_ENABLED inline void check_series_iterations(const char* function, std::uintmax_t max_iter, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value)875{876   if(max_iter >= policies::get_max_series_iterations<Policy>())877      raise_evaluation_error<T>(878         function,879         "Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);880}881 882template <class T, class Policy>883BOOST_MATH_GPU_ENABLED inline void check_root_iterations(const char* function, std::uintmax_t max_iter, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value)884{885   if(max_iter >= policies::get_max_root_iterations<Policy>())886      raise_evaluation_error<T>(887         function,888         "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);889}890 891} //namespace policies892 893#ifdef _MSC_VER894#  pragma warning(pop)895#endif896 897}} // namespaces boost/math898 899#else // Special values for NVRTC900 901namespace boost {902namespace math {903namespace policies {904 905template <class T, class Policy>906BOOST_MATH_GPU_ENABLED constexpr T raise_domain_error(907           const char* ,908           const char* ,909           const T& ,910           const Policy&) BOOST_MATH_NOEXCEPT(T)911{912   // This may or may not do the right thing, but the user asked for the error913   // to be ignored so here we go anyway:914   return boost::math::numeric_limits<T>::quiet_NaN();915}916 917template <class T, class Policy>918BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error(919           const char* function,920           const char* message,921           const T& val,922           const  Policy&) BOOST_MATH_NOEXCEPT(T)923{924   return boost::math::numeric_limits<T>::quiet_NaN();925}926 927template <class T, class Policy>928BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(929           const char* ,930           const char* ,931           const Policy&) BOOST_MATH_NOEXCEPT(T)932{933   // This may or may not do the right thing, but the user asked for the error934   // to be ignored so here we go anyway:935   return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : (boost::math::numeric_limits<T>::max)();936}937 938template <class T, class Policy>939BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(940           const char* ,941           const char* ,942           const T&,943           const Policy&) BOOST_MATH_NOEXCEPT(T)944{945   // This may or may not do the right thing, but the user asked for the error946   // to be ignored so here we go anyway:947   return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : (boost::math::numeric_limits<T>::max)();948}949 950template <class T, class Policy>951BOOST_MATH_GPU_ENABLED constexpr T raise_underflow_error(952           const char* ,953           const char* ,954           const Policy&) BOOST_MATH_NOEXCEPT(T)955{956   // This may or may not do the right thing, but the user asked for the error957   // to be ignored so here we go anyway:958   return static_cast<T>(0);959}960 961template <class T, class Policy>962BOOST_MATH_GPU_ENABLED inline constexpr T raise_denorm_error(963           const char* ,964           const char* ,965           const T& val,966           const Policy&) BOOST_MATH_NOEXCEPT(T)967{968   // This may or may not do the right thing, but the user asked for the error969   // to be ignored so here we go anyway:970   return val;971}972 973template <class T, class Policy>974BOOST_MATH_GPU_ENABLED constexpr T raise_evaluation_error(975           const char* ,976           const char* ,977           const T& val,978           const Policy&) BOOST_MATH_NOEXCEPT(T)979{980   // This may or may not do the right thing, but the user asked for the error981   // to be ignored so here we go anyway:982   return val;983}984 985template <class T, class TargetType, class Policy>986BOOST_MATH_GPU_ENABLED constexpr TargetType raise_rounding_error(987           const char* ,988           const char* ,989           const T& val,990           const TargetType&,991           const Policy&) BOOST_MATH_NOEXCEPT(T)992{993   // This may or may not do the right thing, but the user asked for the error994   // to be ignored so here we go anyway:995   static_assert(boost::math::numeric_limits<TargetType>::is_specialized, "The target type must have std::numeric_limits specialized.");996   return  val > 0 ? (boost::math::numeric_limits<TargetType>::max)() : (boost::math::numeric_limits<TargetType>::is_integer ? (boost::math::numeric_limits<TargetType>::min)() : -(boost::math::numeric_limits<TargetType>::max)());997}998 999template <class T, class R, class Policy>1000BOOST_MATH_GPU_ENABLED inline constexpr T raise_indeterminate_result_error(1001           const char* ,1002           const char* ,1003           const T& ,1004           const R& result,1005           const Policy&) BOOST_MATH_NOEXCEPT(T)1006{1007   // This may or may not do the right thing, but the user asked for the error1008   // to be ignored so here we go anyway:1009   return result;1010}1011 1012template <class R, class Policy, class T>1013BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE R checked_narrowing_cast(T val, const char* function) noexcept(boost::math::is_floating_point_v<R> && boost::math::is_floating_point_v<T>)1014{1015   // We only have ignore error policy so no reason to check1016   return static_cast<R>(val);1017}1018 1019template <class T, class Policy>1020BOOST_MATH_GPU_ENABLED inline void check_series_iterations(const char* function, boost::math::uintmax_t max_iter, const Policy& pol) noexcept(boost::math::is_floating_point_v<T>)1021{1022   if(max_iter >= policies::get_max_series_iterations<Policy>())1023      raise_evaluation_error<T>(1024         function,1025         "Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);1026}1027 1028template <class T, class Policy>1029BOOST_MATH_GPU_ENABLED inline void check_root_iterations(const char* function, boost::math::uintmax_t max_iter, const Policy& pol) noexcept(boost::math::is_floating_point_v<T>)1030{1031   if(max_iter >= policies::get_max_root_iterations<Policy>())1032      raise_evaluation_error<T>(1033         function,1034         "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);1035}1036 1037} // namespace policies1038} // namespace math1039} // namespace boost1040 1041#endif // BOOST_MATH_HAS_NVRTC1042 1043namespace boost { namespace math { namespace detail {1044 1045//1046// Simple helper function to assist in returning a pair from a single value,1047// that value usually comes from one of the error handlers above:1048//1049template <class T>1050BOOST_MATH_GPU_ENABLED boost::math::pair<T, T> pair_from_single(const T& val) BOOST_MATH_NOEXCEPT(T)1051{1052   return boost::math::make_pair(val, val);1053}1054 1055}}} // boost::math::detail1056 1057#endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP1058 1059