Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:35:40

0001 //  Copyright John Maddock 2007.
0002 //  Copyright Paul A. Bristow 2007.
0003 //  Copyright Matt Borland 2024.
0004 //  Use, modification and distribution are subject to the
0005 //  Boost Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_MATH_POLICY_ERROR_HANDLING_HPP
0009 #define BOOST_MATH_POLICY_ERROR_HANDLING_HPP
0010 
0011 #include <boost/math/tools/config.hpp>
0012 #include <boost/math/tools/numeric_limits.hpp>
0013 #include <boost/math/tools/type_traits.hpp>
0014 #include <boost/math/tools/cstdint.hpp>
0015 #include <boost/math/tools/tuple.hpp>
0016 #include <boost/math/policies/policy.hpp>
0017 #include <boost/math/tools/precision.hpp>
0018 
0019 #ifndef BOOST_MATH_HAS_NVRTC
0020 
0021 #include <iomanip>
0022 #include <string>
0023 #include <cstring>
0024 #ifndef BOOST_MATH_NO_RTTI
0025 #include <typeinfo>
0026 #endif
0027 #include <cerrno>
0028 #include <complex>
0029 #include <cmath>
0030 #include <cstdint>
0031 #ifndef BOOST_MATH_NO_EXCEPTIONS
0032 #include <stdexcept>
0033 #include <boost/math/tools/throw_exception.hpp>
0034 #endif
0035 
0036 #ifdef _MSC_VER
0037 #  pragma warning(push) // Quiet warnings in boost/format.hpp
0038 #  pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE
0039 #  pragma warning(disable: 4512) // assignment operator could not be generated.
0040 #  pragma warning(disable: 4127) // conditional expression is constant
0041 // And warnings in error handling:
0042 #  pragma warning(disable: 4702) // unreachable code.
0043 // Note that this only occurs when the compiler can deduce code is unreachable,
0044 // for example when policy macros are used to ignore errors rather than throw.
0045 #endif
0046 #include <sstream>
0047 
0048 namespace boost{ namespace math{
0049 
0050 #ifndef BOOST_MATH_NO_EXCEPTIONS
0051 
0052 class evaluation_error : public std::runtime_error
0053 {
0054 public:
0055    explicit evaluation_error(const std::string& s) : std::runtime_error(s){}
0056 };
0057 
0058 class rounding_error : public std::runtime_error
0059 {
0060 public:
0061    explicit rounding_error(const std::string& s) : std::runtime_error(s){}
0062 };
0063 
0064 #endif
0065 
0066 namespace policies{
0067 //
0068 // Forward declarations of user error handlers,
0069 // it's up to the user to provide the definition of these:
0070 //
0071 template <class T>
0072 T user_domain_error(const char* function, const char* message, const T& val);
0073 template <class T>
0074 T user_pole_error(const char* function, const char* message, const T& val);
0075 template <class T>
0076 T user_overflow_error(const char* function, const char* message, const T& val);
0077 template <class T>
0078 T user_underflow_error(const char* function, const char* message, const T& val);
0079 template <class T>
0080 T user_denorm_error(const char* function, const char* message, const T& val);
0081 template <class T>
0082 T user_evaluation_error(const char* function, const char* message, const T& val);
0083 template <class T, class TargetType>
0084 TargetType user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t);
0085 template <class T>
0086 T user_indeterminate_result_error(const char* function, const char* message, const T& val);
0087 
0088 namespace detail
0089 {
0090 
0091 template <class T>
0092 inline std::string prec_format(const T& val)
0093 {
0094    typedef typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type prec_type;
0095    std::stringstream ss;
0096    if(prec_type::value)
0097    {
0098       int prec = 2 + (prec_type::value * 30103UL) / 100000UL;
0099       ss << std::setprecision(prec);
0100    }
0101    ss << val;
0102    return ss.str();
0103 }
0104 
0105 #ifdef BOOST_MATH_USE_CHARCONV_FOR_CONVERSION
0106 
0107 template <>
0108 inline std::string prec_format<std::float128_t>(const std::float128_t& val)
0109 {
0110    char buffer[128] {};
0111    const auto r = std::to_chars(buffer, buffer + sizeof(buffer), val);
0112    return std::string(buffer, r.ptr);
0113 }
0114 
0115 #endif
0116 
0117 inline void replace_all_in_string(std::string& result, const char* what, const char* with)
0118 {
0119    std::string::size_type pos = 0;
0120    std::string::size_type slen = std::strlen(what);
0121    std::string::size_type rlen = std::strlen(with);
0122    while((pos = result.find(what, pos)) != std::string::npos)
0123    {
0124       result.replace(pos, slen, with);
0125       pos += rlen;
0126    }
0127 }
0128 
0129 template <class T>
0130 inline const char* name_of()
0131 {
0132 #ifndef BOOST_MATH_NO_RTTI
0133    return typeid(T).name();
0134 #else
0135    return "unknown";
0136 #endif
0137 }
0138 template <> inline const char* name_of<float>(){ return "float"; }
0139 template <> inline const char* name_of<double>(){ return "double"; }
0140 template <> inline const char* name_of<long double>(){ return "long double"; }
0141 
0142 #ifdef BOOST_MATH_USE_FLOAT128
0143 template <>
0144 inline const char* name_of<BOOST_MATH_FLOAT128_TYPE>()
0145 {
0146    return "__float128";
0147 }
0148 #endif
0149 
0150 #ifndef BOOST_MATH_NO_EXCEPTIONS
0151 template <class E, class T>
0152 void raise_error(const char* pfunction, const char* message)
0153 {
0154   if(pfunction == nullptr)
0155   {
0156      pfunction = "Unknown function operating on type %1%";
0157   }
0158   if(message == nullptr)
0159   {
0160      message = "Cause unknown";
0161   }
0162 
0163   std::string function(pfunction);
0164   std::string msg("Error in function ");
0165 #ifndef BOOST_MATH_NO_RTTI
0166   replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());
0167 #else
0168   replace_all_in_string(function, "%1%", "Unknown");
0169 #endif
0170   msg += function;
0171   msg += ": ";
0172   msg += message;
0173 
0174   BOOST_MATH_THROW_EXCEPTION(E(msg))
0175 }
0176 
0177 template <class E, class T>
0178 void raise_error(const char* pfunction, const char* pmessage, const T& val)
0179 {
0180   if(pfunction == nullptr)
0181   {
0182      pfunction = "Unknown function operating on type %1%";
0183   }
0184   if(pmessage == nullptr)
0185   {
0186      pmessage = "Cause unknown: error caused by bad argument with value %1%";
0187   }
0188 
0189   std::string function(pfunction);
0190   std::string message(pmessage);
0191   std::string msg("Error in function ");
0192 #ifndef BOOST_MATH_NO_RTTI
0193   replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());
0194 #else
0195   replace_all_in_string(function, "%1%", "Unknown");
0196 #endif
0197   msg += function;
0198   msg += ": ";
0199 
0200   std::string sval = prec_format(val);
0201   replace_all_in_string(message, "%1%", sval.c_str());
0202   msg += message;
0203 
0204   BOOST_MATH_THROW_EXCEPTION(E(msg))
0205 }
0206 #endif
0207 
0208 template <class T>
0209 BOOST_MATH_GPU_ENABLED inline T raise_domain_error(
0210            const char* function,
0211            const char* message,
0212            const T& val,
0213            const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&)
0214 {
0215 #ifdef BOOST_MATH_NO_EXCEPTIONS
0216    static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");
0217 #else
0218    raise_error<std::domain_error, T>(function, message, val);
0219    // we never get here:
0220    return boost::math::numeric_limits<T>::quiet_NaN();
0221 #endif
0222 }
0223 
0224 template <class T>
0225 BOOST_MATH_GPU_ENABLED constexpr T raise_domain_error(
0226            const char* ,
0227            const char* ,
0228            const T& ,
0229            const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
0230 {
0231    // This may or may not do the right thing, but the user asked for the error
0232    // to be ignored so here we go anyway:
0233    return boost::math::numeric_limits<T>::quiet_NaN();
0234 }
0235 
0236 template <class T>
0237 BOOST_MATH_GPU_ENABLED inline T raise_domain_error(
0238            const char* ,
0239            const char* ,
0240            const T& ,
0241            const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
0242 {
0243    errno = EDOM;
0244    // This may or may not do the right thing, but the user asked for the error
0245    // to be silent so here we go anyway:
0246    return boost::math::numeric_limits<T>::quiet_NaN();
0247 }
0248 
0249 template <class T>
0250 BOOST_MATH_GPU_ENABLED inline T raise_domain_error(
0251            const char* function,
0252            const char* message,
0253            const T& val,
0254            const  ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&)
0255 {
0256    return user_domain_error(function, message, val);
0257 }
0258 
0259 template <class T>
0260 BOOST_MATH_GPU_ENABLED inline T raise_pole_error(
0261            const char* function,
0262            const char* message,
0263            const T& val,
0264            const  ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&)
0265 {
0266 #ifdef BOOST_MATH_NO_EXCEPTIONS
0267    static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");
0268 #else
0269    return boost::math::policies::detail::raise_domain_error(function, message, val,  ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>());
0270 #endif
0271 }
0272 
0273 template <class T>
0274 BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error(
0275            const char* function,
0276            const char* message,
0277            const T& val,
0278            const  ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
0279 {
0280    return  ::boost::math::policies::detail::raise_domain_error(function, message, val,  ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>());
0281 }
0282 
0283 template <class T>
0284 BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error(
0285            const char* function,
0286            const char* message,
0287            const T& val,
0288            const  ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
0289 {
0290    return  ::boost::math::policies::detail::raise_domain_error(function, message, val,  ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>());
0291 }
0292 
0293 template <class T>
0294 BOOST_MATH_GPU_ENABLED inline T raise_pole_error(
0295            const char* function,
0296            const char* message,
0297            const T& val,
0298            const  ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&)
0299 {
0300    return user_pole_error(function, message, val);
0301 }
0302 
0303 template <class T>
0304 BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(
0305            const char* function,
0306            const char* message,
0307            const  ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)
0308 {
0309 #ifdef BOOST_MATH_NO_EXCEPTIONS
0310    static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");
0311 #else
0312    raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow");
0313    // We should never get here:
0314    return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
0315 #endif
0316 }
0317 
0318 template <class T>
0319 BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(
0320            const char* function,
0321            const char* message,
0322            const T& val,
0323            const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)
0324 {
0325 #ifdef BOOST_MATH_NO_EXCEPTIONS
0326    static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");
0327 #else
0328    raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow", val);
0329    // We should never get here:
0330    return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
0331 #endif
0332 }
0333 
0334 template <class T>
0335 BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(
0336            const char* ,
0337            const char* ,
0338            const  ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
0339 {
0340    // This may or may not do the right thing, but the user asked for the error
0341    // to be ignored so here we go anyway:
0342    return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
0343 }
0344 
0345 template <class T>
0346 BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(
0347            const char* ,
0348            const char* ,
0349            const T&,
0350            const  ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
0351 {
0352    // This may or may not do the right thing, but the user asked for the error
0353    // to be ignored so here we go anyway:
0354    return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
0355 }
0356 
0357 template <class T>
0358 BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(
0359            const char* ,
0360            const char* ,
0361            const  ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
0362 {
0363    errno = ERANGE;
0364    // This may or may not do the right thing, but the user asked for the error
0365    // to be silent so here we go anyway:
0366    return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
0367 }
0368 
0369 template <class T>
0370 BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(
0371            const char* ,
0372            const char* ,
0373            const T&,
0374            const  ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
0375 {
0376    errno = ERANGE;
0377    // This may or may not do the right thing, but the user asked for the error
0378    // to be silent so here we go anyway:
0379    return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
0380 }
0381 
0382 template <class T>
0383 BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(
0384            const char* function,
0385            const char* message,
0386            const  ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
0387 {
0388    return user_overflow_error(function, message, boost::math::numeric_limits<T>::infinity());
0389 }
0390 
0391 template <class T>
0392 BOOST_MATH_GPU_ENABLED inline T raise_overflow_error(
0393            const char* function,
0394            const char* message,
0395            const T& val,
0396            const  ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
0397 {
0398    std::string m(message ? message : "");
0399    std::string sval = prec_format(val);
0400    replace_all_in_string(m, "%1%", sval.c_str());
0401 
0402    return user_overflow_error(function, m.c_str(), boost::math::numeric_limits<T>::infinity());
0403 }
0404 
0405 template <class T>
0406 BOOST_MATH_GPU_ENABLED inline T raise_underflow_error(
0407            const char* function,
0408            const char* message,
0409            const  ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&)
0410 {
0411 #ifdef BOOST_MATH_NO_EXCEPTIONS
0412    static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");
0413 #else
0414    raise_error<std::underflow_error, T>(function, message ? message : "numeric underflow");
0415    // We should never get here:
0416    return 0;
0417 #endif
0418 }
0419 
0420 template <class T>
0421 BOOST_MATH_GPU_ENABLED constexpr T raise_underflow_error(
0422            const char* ,
0423            const char* ,
0424            const  ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
0425 {
0426    // This may or may not do the right thing, but the user asked for the error
0427    // to be ignored so here we go anyway:
0428    return T(0);
0429 }
0430 
0431 template <class T>
0432 BOOST_MATH_GPU_ENABLED inline T raise_underflow_error(
0433            const char* /* function */,
0434            const char* /* message */,
0435            const  ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
0436 {
0437    errno = ERANGE;
0438    // This may or may not do the right thing, but the user asked for the error
0439    // to be silent so here we go anyway:
0440    return T(0);
0441 }
0442 
0443 template <class T>
0444 BOOST_MATH_GPU_ENABLED inline T raise_underflow_error(
0445            const char* function,
0446            const char* message,
0447            const  ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&)
0448 {
0449    return user_underflow_error(function, message, T(0));
0450 }
0451 
0452 template <class T>
0453 BOOST_MATH_GPU_ENABLED inline T raise_denorm_error(
0454            const char* function,
0455            const char* message,
0456            const T& /* val */,
0457            const  ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&)
0458 {
0459 #ifdef BOOST_MATH_NO_EXCEPTIONS
0460    static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");
0461 #else
0462    raise_error<std::underflow_error, T>(function, message ? message : "denormalised result");
0463    // we never get here:
0464    return T(0);
0465 #endif
0466 }
0467 
0468 template <class T>
0469 BOOST_MATH_GPU_ENABLED inline constexpr T raise_denorm_error(
0470            const char* ,
0471            const char* ,
0472            const T&  val,
0473            const  ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
0474 {
0475    // This may or may not do the right thing, but the user asked for the error
0476    // to be ignored so here we go anyway:
0477    return val;
0478 }
0479 
0480 template <class T>
0481 BOOST_MATH_GPU_ENABLED inline T raise_denorm_error(
0482            const char* ,
0483            const char* ,
0484            const T& val,
0485            const  ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
0486 {
0487    errno = ERANGE;
0488    // This may or may not do the right thing, but the user asked for the error
0489    // to be silent so here we go anyway:
0490    return val;
0491 }
0492 
0493 template <class T>
0494 BOOST_MATH_GPU_ENABLED inline T raise_denorm_error(
0495            const char* function,
0496            const char* message,
0497            const T& val,
0498            const  ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&)
0499 {
0500    return user_denorm_error(function, message, val);
0501 }
0502 
0503 template <class T>
0504 BOOST_MATH_GPU_ENABLED inline T raise_evaluation_error(
0505            const char* function,
0506            const char* message,
0507            const T& val,
0508            const  ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&)
0509 {
0510 #ifdef BOOST_MATH_NO_EXCEPTIONS
0511    static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");
0512 #else
0513    raise_error<boost::math::evaluation_error, T>(function, message, val);
0514    // we never get here:
0515    return T(0);
0516 #endif
0517 }
0518 
0519 template <class T>
0520 BOOST_MATH_GPU_ENABLED constexpr T raise_evaluation_error(
0521            const char* ,
0522            const char* ,
0523            const T& val,
0524            const  ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
0525 {
0526    // This may or may not do the right thing, but the user asked for the error
0527    // to be ignored so here we go anyway:
0528    return val;
0529 }
0530 
0531 template <class T>
0532 BOOST_MATH_GPU_ENABLED inline T raise_evaluation_error(
0533            const char* ,
0534            const char* ,
0535            const T& val,
0536            const  ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
0537 {
0538    errno = EDOM;
0539    // This may or may not do the right thing, but the user asked for the error
0540    // to be silent so here we go anyway:
0541    return val;
0542 }
0543 
0544 template <class T>
0545 BOOST_MATH_GPU_ENABLED inline T raise_evaluation_error(
0546            const char* function,
0547            const char* message,
0548            const T& val,
0549            const  ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&)
0550 {
0551    return user_evaluation_error(function, message, val);
0552 }
0553 
0554 template <class T, class TargetType>
0555 BOOST_MATH_GPU_ENABLED inline TargetType raise_rounding_error(
0556            const char* function,
0557            const char* message,
0558            const T& val,
0559            const TargetType&,
0560            const  ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&)
0561 {
0562 #ifdef BOOST_MATH_NO_EXCEPTIONS
0563    static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");
0564 #else
0565    raise_error<boost::math::rounding_error, T>(function, message, val);
0566    // we never get here:
0567    return TargetType(0);
0568 #endif
0569 }
0570 
0571 template <class T, class TargetType>
0572 BOOST_MATH_GPU_ENABLED constexpr TargetType raise_rounding_error(
0573            const char* ,
0574            const char* ,
0575            const T& val,
0576            const TargetType&,
0577            const  ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
0578 {
0579    // This may or may not do the right thing, but the user asked for the error
0580    // to be ignored so here we go anyway:
0581    static_assert(boost::math::numeric_limits<TargetType>::is_specialized, "The target type must have std::numeric_limits specialized.");
0582    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)());
0583 }
0584 
0585 template <class T, class TargetType>
0586 BOOST_MATH_GPU_ENABLED inline TargetType raise_rounding_error(
0587            const char* ,
0588            const char* ,
0589            const T& val,
0590            const TargetType&,
0591            const  ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
0592 {
0593    errno = ERANGE;
0594    // This may or may not do the right thing, but the user asked for the error
0595    // to be silent so here we go anyway:
0596    static_assert(boost::math::numeric_limits<TargetType>::is_specialized, "The target type must have std::numeric_limits specialized.");
0597    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)());
0598 }
0599 template <class T, class TargetType>
0600 BOOST_MATH_GPU_ENABLED inline TargetType raise_rounding_error(
0601            const char* function,
0602            const char* message,
0603            const T& val,
0604            const TargetType& t,
0605            const  ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&)
0606 {
0607    return user_rounding_error(function, message, val, t);
0608 }
0609 
0610 template <class T, class R>
0611 BOOST_MATH_GPU_ENABLED inline T raise_indeterminate_result_error(
0612            const char* function,
0613            const char* message,
0614            const T& val,
0615            const R& ,
0616            const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&)
0617 {
0618 #ifdef BOOST_MATH_NO_EXCEPTIONS
0619    static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_MATH_NO_EXCEPTIONS set.");
0620 #else
0621    raise_error<std::domain_error, T>(function, message, val);
0622    // we never get here:
0623    return boost::math::numeric_limits<T>::quiet_NaN();
0624 #endif
0625 }
0626 
0627 template <class T, class R>
0628 BOOST_MATH_GPU_ENABLED inline constexpr T raise_indeterminate_result_error(
0629            const char* ,
0630            const char* ,
0631            const T& ,
0632            const R& result,
0633            const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
0634 {
0635    // This may or may not do the right thing, but the user asked for the error
0636    // to be ignored so here we go anyway:
0637    return result;
0638 }
0639 
0640 template <class T, class R>
0641 BOOST_MATH_GPU_ENABLED inline T raise_indeterminate_result_error(
0642            const char* ,
0643            const char* ,
0644            const T& ,
0645            const R& result,
0646            const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&)
0647 {
0648    errno = EDOM;
0649    // This may or may not do the right thing, but the user asked for the error
0650    // to be silent so here we go anyway:
0651    return result;
0652 }
0653 
0654 template <class T, class R>
0655 BOOST_MATH_GPU_ENABLED inline T raise_indeterminate_result_error(
0656            const char* function,
0657            const char* message,
0658            const T& val,
0659            const R& ,
0660            const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&)
0661 {
0662    return user_indeterminate_result_error(function, message, val);
0663 }
0664 
0665 }  // namespace detail
0666 
0667 template <class T, class Policy>
0668 BOOST_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))
0669 {
0670    typedef typename Policy::domain_error_type policy_type;
0671    return detail::raise_domain_error(
0672       function, message ? message : "Domain Error evaluating function at %1%",
0673       val, policy_type());
0674 }
0675 
0676 template <class T, class Policy>
0677 BOOST_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))
0678 {
0679    typedef typename Policy::pole_error_type policy_type;
0680    return detail::raise_pole_error(
0681       function, message ? message : "Evaluation of function at pole %1%",
0682       val, policy_type());
0683 }
0684 
0685 template <class T, class Policy>
0686 BOOST_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))
0687 {
0688    typedef typename Policy::overflow_error_type policy_type;
0689    return detail::raise_overflow_error<T>(
0690       function, message ? message : "Overflow Error",
0691       policy_type());
0692 }
0693 
0694 template <class T, class Policy>
0695 BOOST_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))
0696 {
0697    typedef typename Policy::overflow_error_type policy_type;
0698    return detail::raise_overflow_error(
0699       function, message ? message : "Overflow evaluating function at %1%",
0700       val, policy_type());
0701 }
0702 
0703 template <class T, class Policy>
0704 BOOST_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))
0705 {
0706    typedef typename Policy::underflow_error_type policy_type;
0707    return detail::raise_underflow_error<T>(
0708       function, message ? message : "Underflow Error",
0709       policy_type());
0710 }
0711 
0712 template <class T, class Policy>
0713 BOOST_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))
0714 {
0715    typedef typename Policy::denorm_error_type policy_type;
0716    return detail::raise_denorm_error<T>(
0717       function, message ? message : "Denorm Error",
0718       val,
0719       policy_type());
0720 }
0721 
0722 template <class T, class Policy>
0723 BOOST_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))
0724 {
0725    typedef typename Policy::evaluation_error_type policy_type;
0726    return detail::raise_evaluation_error(
0727       function, message ? message : "Internal Evaluation Error, best value so far was %1%",
0728       val, policy_type());
0729 }
0730 
0731 template <class T, class TargetType, class Policy>
0732 BOOST_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))
0733 {
0734    typedef typename Policy::rounding_error_type policy_type;
0735    return detail::raise_rounding_error(
0736       function, message ? message : "Value %1% can not be represented in the target integer type.",
0737       val, t, policy_type());
0738 }
0739 
0740 template <class T, class R, class Policy>
0741 BOOST_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))
0742 {
0743    typedef typename Policy::indeterminate_result_error_type policy_type;
0744    return detail::raise_indeterminate_result_error(
0745       function, message ? message : "Indeterminate result with value %1%",
0746       val, result, policy_type());
0747 }
0748 
0749 //
0750 // checked_narrowing_cast:
0751 //
0752 namespace detail
0753 {
0754 
0755 template <class R, class T, class Policy>
0756 BOOST_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))
0757 {
0758    BOOST_MATH_STD_USING
0759    if(fabs(val) > tools::max_value<R>())
0760    {
0761       boost::math::policies::detail::raise_overflow_error<R>(function, nullptr, pol);
0762       *result = static_cast<R>(val);
0763       return true;
0764    }
0765    return false;
0766 }
0767 template <class R, class T, class Policy>
0768 BOOST_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))
0769 {
0770    typedef typename R::value_type r_type;
0771    r_type re, im;
0772    bool r = check_overflow<r_type>(val.real(), &re, function, pol);
0773    r = check_overflow<r_type>(val.imag(), &im, function, pol) || r;
0774    *result = R(re, im);
0775    return r;
0776 }
0777 template <class R, class T, class Policy>
0778 BOOST_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))
0779 {
0780    if((val != 0) && (static_cast<R>(val) == 0))
0781    {
0782       *result = static_cast<R>(boost::math::policies::detail::raise_underflow_error<R>(function, nullptr, pol));
0783       return true;
0784    }
0785    return false;
0786 }
0787 template <class R, class T, class Policy>
0788 BOOST_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))
0789 {
0790    typedef typename R::value_type r_type;
0791    r_type re, im;
0792    bool r = check_underflow<r_type>(val.real(), &re, function, pol);
0793    r = check_underflow<r_type>(val.imag(), &im, function, pol) || r;
0794    *result = R(re, im);
0795    return r;
0796 }
0797 template <class R, class T, class Policy>
0798 BOOST_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))
0799 {
0800    BOOST_MATH_STD_USING
0801    if((fabs(val) < static_cast<T>(tools::min_value<R>())) && (static_cast<R>(val) != 0))
0802    {
0803       *result = static_cast<R>(boost::math::policies::detail::raise_denorm_error<R>(function, 0, static_cast<R>(val), pol));
0804       return true;
0805    }
0806    return false;
0807 }
0808 template <class R, class T, class Policy>
0809 BOOST_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))
0810 {
0811    typedef typename R::value_type r_type;
0812    r_type re, im;
0813    bool r = check_denorm<r_type>(val.real(), &re, function, pol);
0814    r = check_denorm<r_type>(val.imag(), &im, function, pol) || r;
0815    *result = R(re, im);
0816    return r;
0817 }
0818 
0819 // Default instantiations with ignore_error policy.
0820 template <class R, class T>
0821 BOOST_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))
0822 { return false; }
0823 template <class R, class T>
0824 BOOST_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))
0825 { return false; }
0826 template <class R, class T>
0827 BOOST_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))
0828 { return false; }
0829 template <class R, class T>
0830 BOOST_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))
0831 { return false; }
0832 template <class R, class T>
0833 BOOST_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))
0834 { return false; }
0835 template <class R, class T>
0836 BOOST_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))
0837 { return false; }
0838 
0839 } // namespace detail
0840 
0841 template <class R, class Policy, class T>
0842 BOOST_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)
0843 {
0844    typedef typename Policy::overflow_error_type overflow_type;
0845    typedef typename Policy::underflow_error_type underflow_type;
0846    typedef typename Policy::denorm_error_type denorm_type;
0847    //
0848    // Most of what follows will evaluate to a no-op:
0849    //
0850    R result = 0;
0851    if(detail::check_overflow<R>(val, &result, function, overflow_type()))
0852       return result;
0853    if(detail::check_underflow<R>(val, &result, function, underflow_type()))
0854       return result;
0855    if(detail::check_denorm<R>(val, &result, function, denorm_type()))
0856       return result;
0857 
0858    return static_cast<R>(val);
0859 }
0860 
0861 template <class T, class Policy>
0862 BOOST_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)
0863 {
0864    if(max_iter >= policies::get_max_series_iterations<Policy>())
0865       raise_evaluation_error<T>(
0866          function,
0867          "Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
0868 }
0869 
0870 template <class T, class Policy>
0871 BOOST_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)
0872 {
0873    if(max_iter >= policies::get_max_root_iterations<Policy>())
0874       raise_evaluation_error<T>(
0875          function,
0876          "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
0877 }
0878 
0879 } //namespace policies
0880 
0881 #ifdef _MSC_VER
0882 #  pragma warning(pop)
0883 #endif
0884 
0885 }} // namespaces boost/math
0886 
0887 #else // Special values for NVRTC
0888 
0889 namespace boost {
0890 namespace math {
0891 namespace policies {
0892 
0893 template <class T, class Policy>
0894 BOOST_MATH_GPU_ENABLED constexpr T raise_domain_error(
0895            const char* ,
0896            const char* ,
0897            const T& ,
0898            const Policy&) BOOST_MATH_NOEXCEPT(T)
0899 {
0900    // This may or may not do the right thing, but the user asked for the error
0901    // to be ignored so here we go anyway:
0902    return boost::math::numeric_limits<T>::quiet_NaN();
0903 }
0904 
0905 template <class T, class Policy>
0906 BOOST_MATH_GPU_ENABLED constexpr T raise_pole_error(
0907            const char* function,
0908            const char* message,
0909            const T& val,
0910            const  Policy&) BOOST_MATH_NOEXCEPT(T)
0911 {
0912    return boost::math::numeric_limits<T>::quiet_NaN();
0913 }
0914 
0915 template <class T, class Policy>
0916 BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(
0917            const char* ,
0918            const char* ,
0919            const Policy&) BOOST_MATH_NOEXCEPT(T)
0920 {
0921    // This may or may not do the right thing, but the user asked for the error
0922    // to be ignored so here we go anyway:
0923    return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : (boost::math::numeric_limits<T>::max)();
0924 }
0925 
0926 template <class T, class Policy>
0927 BOOST_MATH_GPU_ENABLED constexpr T raise_overflow_error(
0928            const char* ,
0929            const char* ,
0930            const T&,
0931            const Policy&) BOOST_MATH_NOEXCEPT(T)
0932 {
0933    // This may or may not do the right thing, but the user asked for the error
0934    // to be ignored so here we go anyway:
0935    return boost::math::numeric_limits<T>::has_infinity ? boost::math::numeric_limits<T>::infinity() : (boost::math::numeric_limits<T>::max)();
0936 }
0937 
0938 template <class T, class Policy>
0939 BOOST_MATH_GPU_ENABLED constexpr T raise_underflow_error(
0940            const char* ,
0941            const char* ,
0942            const Policy&) BOOST_MATH_NOEXCEPT(T)
0943 {
0944    // This may or may not do the right thing, but the user asked for the error
0945    // to be ignored so here we go anyway:
0946    return static_cast<T>(0);
0947 }
0948 
0949 template <class T, class Policy>
0950 BOOST_MATH_GPU_ENABLED inline constexpr T raise_denorm_error(
0951            const char* ,
0952            const char* ,
0953            const T& val,
0954            const Policy&) BOOST_MATH_NOEXCEPT(T)
0955 {
0956    // This may or may not do the right thing, but the user asked for the error
0957    // to be ignored so here we go anyway:
0958    return val;
0959 }
0960 
0961 template <class T, class Policy>
0962 BOOST_MATH_GPU_ENABLED constexpr T raise_evaluation_error(
0963            const char* ,
0964            const char* ,
0965            const T& val,
0966            const Policy&) BOOST_MATH_NOEXCEPT(T)
0967 {
0968    // This may or may not do the right thing, but the user asked for the error
0969    // to be ignored so here we go anyway:
0970    return val;
0971 }
0972 
0973 template <class T, class TargetType, class Policy>
0974 BOOST_MATH_GPU_ENABLED constexpr TargetType raise_rounding_error(
0975            const char* ,
0976            const char* ,
0977            const T& val,
0978            const TargetType&,
0979            const Policy&) BOOST_MATH_NOEXCEPT(T)
0980 {
0981    // This may or may not do the right thing, but the user asked for the error
0982    // to be ignored so here we go anyway:
0983    static_assert(boost::math::numeric_limits<TargetType>::is_specialized, "The target type must have std::numeric_limits specialized.");
0984    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)());
0985 }
0986 
0987 template <class T, class R, class Policy>
0988 BOOST_MATH_GPU_ENABLED inline constexpr T raise_indeterminate_result_error(
0989            const char* ,
0990            const char* ,
0991            const T& ,
0992            const R& result,
0993            const Policy&) BOOST_MATH_NOEXCEPT(T)
0994 {
0995    // This may or may not do the right thing, but the user asked for the error
0996    // to be ignored so here we go anyway:
0997    return result;
0998 }
0999 
1000 template <class R, class Policy, class T>
1001 BOOST_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>)
1002 {
1003    // We only have ignore error policy so no reason to check
1004    return static_cast<R>(val);
1005 }
1006 
1007 template <class T, class Policy>
1008 BOOST_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>)
1009 {
1010    if(max_iter >= policies::get_max_series_iterations<Policy>())
1011       raise_evaluation_error<T>(
1012          function,
1013          "Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
1014 }
1015 
1016 template <class T, class Policy>
1017 BOOST_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>)
1018 {
1019    if(max_iter >= policies::get_max_root_iterations<Policy>())
1020       raise_evaluation_error<T>(
1021          function,
1022          "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
1023 }
1024 
1025 } // namespace policies
1026 } // namespace math
1027 } // namespace boost
1028 
1029 #endif // BOOST_MATH_HAS_NVRTC
1030 
1031 namespace boost { namespace math { namespace detail {
1032 
1033 //
1034 // Simple helper function to assist in returning a pair from a single value,
1035 // that value usually comes from one of the error handlers above:
1036 //
1037 template <class T>
1038 BOOST_MATH_GPU_ENABLED boost::math::pair<T, T> pair_from_single(const T& val) BOOST_MATH_NOEXCEPT(T)
1039 {
1040    return boost::math::make_pair(val, val);
1041 }
1042 
1043 }}} // boost::math::detail
1044 
1045 #endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP
1046