Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:48

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