File indexing completed on 2025-09-17 08:35:40
0001
0002
0003
0004
0005
0006
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)
0038 # pragma warning(disable: 4996)
0039 # pragma warning(disable: 4512)
0040 # pragma warning(disable: 4127)
0041
0042 # pragma warning(disable: 4702)
0043
0044
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
0069
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
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
0232
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
0245
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
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
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
0341
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
0353
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
0365
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
0378
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
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
0427
0428 return T(0);
0429 }
0430
0431 template <class T>
0432 BOOST_MATH_GPU_ENABLED inline T raise_underflow_error(
0433 const char* ,
0434 const char* ,
0435 const ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
0436 {
0437 errno = ERANGE;
0438
0439
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& ,
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
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
0476
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
0489
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
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
0527
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
0540
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
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
0580
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
0595
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
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
0636
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
0650
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 }
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
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
0820 template <class R, class T>
0821 BOOST_MATH_GPU_ENABLED BOOST_MATH_FORCEINLINE constexpr bool check_overflow(T , R* , const char* , 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> , R* , const char* , 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 , R* , const char* , 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> , R* , const char* , 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 , R* , const char* , 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> , R* , const char* , const denorm_error<ignore_error>&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))
0837 { return false; }
0838
0839 }
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
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 }
0880
0881 #ifdef _MSC_VER
0882 # pragma warning(pop)
0883 #endif
0884
0885 }}
0886
0887 #else
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
0901
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
0922
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
0934
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
0945
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
0957
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
0969
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
0982
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
0996
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
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 }
1026 }
1027 }
1028
1029 #endif
1030
1031 namespace boost { namespace math { namespace detail {
1032
1033
1034
1035
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 }}}
1044
1045 #endif
1046