X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=boost%2Fmath%2Fpolicies%2Ferror_handling.hpp;fp=boost%2Fmath%2Fpolicies%2Ferror_handling.hpp;h=96333d342b4f95f7f1f4a9116276af0fe71f8a73;hp=6285e1e9f2b8c64d90d6f2df1d6b46de8b9ed241;hb=2d71eb92104693ca9baa5a2e1c23eeca776d8fd3;hpb=da57529b92adbb7ae74a89861cb39fb35ac7c62d diff --git a/boost/math/policies/error_handling.hpp b/boost/math/policies/error_handling.hpp index 6285e1e..96333d3 100644 --- a/boost/math/policies/error_handling.hpp +++ b/boost/math/policies/error_handling.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,7 @@ # pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE # pragma warning(disable: 4512) // assignment operator could not be generated. // And warnings in error handling: -# pragma warning(disable: 4702) // unreachable code +# pragma warning(disable: 4702) // unreachable code. // Note that this only occurs when the compiler can deduce code is unreachable, // for example when policy macros are used to ignore errors rather than throw. #endif @@ -45,7 +46,7 @@ public: namespace policies{ // -// Forward declarations of user error handlers, +// Forward declarations of user error handlers, // it's up to the user to provide the definition of these: // template @@ -60,8 +61,8 @@ template T user_denorm_error(const char* function, const char* message, const T& val); template T user_evaluation_error(const char* function, const char* message, const T& val); -template -T user_rounding_error(const char* function, const char* message, const T& val); +template +T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t); template T user_indeterminate_result_error(const char* function, const char* message, const T& val); @@ -69,7 +70,7 @@ namespace detail { // // Helper function to avoid binding rvalue to non-const-reference, -// in other words a warning suppression mechansim: +// in other words a warning suppression mechanism: // template inline std::string do_format(Formatter f, const Group& g) @@ -116,9 +117,9 @@ void raise_error(const char* function, const char* message, const T& val) template inline T raise_domain_error( - const char* function, - const char* message, - const T& val, + const char* function, + const char* message, + const T& val, const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&) { raise_error(function, message, val); @@ -128,9 +129,9 @@ inline T raise_domain_error( template inline T raise_domain_error( - const char* , - const char* , - const T& , + const char* , + const char* , + const T& , const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&) { // This may or may not do the right thing, but the user asked for the error @@ -140,9 +141,9 @@ inline T raise_domain_error( template inline T raise_domain_error( - const char* , - const char* , - const T& , + const char* , + const char* , + const T& , const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&) { errno = EDOM; @@ -153,9 +154,9 @@ inline T raise_domain_error( template inline T raise_domain_error( - const char* function, - const char* message, - const T& val, + const char* function, + const char* message, + const T& val, const ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&) { return user_domain_error(function, message, val); @@ -163,9 +164,9 @@ inline T raise_domain_error( template inline T raise_pole_error( - const char* function, - const char* message, - const T& val, + const char* function, + const char* message, + const T& val, const ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&) { return boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>()); @@ -173,9 +174,9 @@ inline T raise_pole_error( template inline T raise_pole_error( - const char* function, - const char* message, - const T& val, + const char* function, + const char* message, + const T& val, const ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&) { return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>()); @@ -183,9 +184,9 @@ inline T raise_pole_error( template inline T raise_pole_error( - const char* function, - const char* message, - const T& val, + const char* function, + const char* message, + const T& val, const ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&) { return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>()); @@ -193,29 +194,42 @@ inline T raise_pole_error( template inline T raise_pole_error( - const char* function, - const char* message, - const T& val, + const char* function, + const char* message, + const T& val, const ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&) { return user_pole_error(function, message, val); } + template inline T raise_overflow_error( - const char* function, - const char* message, + const char* function, + const char* message, const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&) { raise_error(function, message ? message : "numeric overflow"); - // we never get here: + // We should never get here: return std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : boost::math::tools::max_value(); } template inline T raise_overflow_error( - const char* , - const char* , + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&) +{ + raise_error(function, message ? message : "numeric overflow", val); + // We should never get here: + return std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : boost::math::tools::max_value(); +} + +template +inline T raise_overflow_error( + const char* , + const char* , const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) { // This may or may not do the right thing, but the user asked for the error @@ -225,8 +239,8 @@ inline T raise_overflow_error( template inline T raise_overflow_error( - const char* , - const char* , + const char* , + const char* , const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) { errno = ERANGE; @@ -237,28 +251,29 @@ inline T raise_overflow_error( template inline T raise_overflow_error( - const char* function, - const char* message, + const char* function, + const char* message, const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&) { return user_overflow_error(function, message, std::numeric_limits::infinity()); } + template inline T raise_underflow_error( - const char* function, - const char* message, + const char* function, + const char* message, const ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&) { raise_error(function, message ? message : "numeric underflow"); - // we never get here: + // We should never get here: return 0; } template inline T raise_underflow_error( - const char* , - const char* , + const char* , + const char* , const ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&) { // This may or may not do the right thing, but the user asked for the error @@ -268,8 +283,8 @@ inline T raise_underflow_error( template inline T raise_underflow_error( - const char* /* function */, - const char* /* message */, + const char* /* function */, + const char* /* message */, const ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&) { errno = ERANGE; @@ -280,8 +295,8 @@ inline T raise_underflow_error( template inline T raise_underflow_error( - const char* function, - const char* message, + const char* function, + const char* message, const ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&) { return user_underflow_error(function, message, T(0)); @@ -289,8 +304,8 @@ inline T raise_underflow_error( template inline T raise_denorm_error( - const char* function, - const char* message, + const char* function, + const char* message, const T& /* val */, const ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&) { @@ -301,8 +316,8 @@ inline T raise_denorm_error( template inline T raise_denorm_error( - const char* , - const char* , + const char* , + const char* , const T& val, const ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&) { @@ -313,8 +328,8 @@ inline T raise_denorm_error( template inline T raise_denorm_error( - const char* , - const char* , + const char* , + const char* , const T& val, const ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&) { @@ -326,8 +341,8 @@ inline T raise_denorm_error( template inline T raise_denorm_error( - const char* function, - const char* message, + const char* function, + const char* message, const T& val, const ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&) { @@ -336,9 +351,9 @@ inline T raise_denorm_error( template inline T raise_evaluation_error( - const char* function, - const char* message, - const T& val, + const char* function, + const char* message, + const T& val, const ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&) { raise_error(function, message, val); @@ -348,9 +363,9 @@ inline T raise_evaluation_error( template inline T raise_evaluation_error( - const char* , - const char* , - const T& val, + const char* , + const char* , + const T& val, const ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&) { // This may or may not do the right thing, but the user asked for the error @@ -360,9 +375,9 @@ inline T raise_evaluation_error( template inline T raise_evaluation_error( - const char* , - const char* , - const T& val, + const char* , + const char* , + const T& val, const ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&) { errno = EDOM; @@ -373,66 +388,72 @@ inline T raise_evaluation_error( template inline T raise_evaluation_error( - const char* function, - const char* message, - const T& val, + const char* function, + const char* message, + const T& val, const ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&) { return user_evaluation_error(function, message, val); } -template -inline T raise_rounding_error( - const char* function, - const char* message, - const T& val, +template +inline TargetType raise_rounding_error( + const char* function, + const char* message, + const T& val, + const TargetType&, const ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&) { raise_error(function, message, val); // we never get here: - return T(0); + return TargetType(0); } -template -inline T raise_rounding_error( - const char* , - const char* , - const T& val, +template +inline TargetType raise_rounding_error( + const char* , + const char* , + const T& val, + const TargetType&, const ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&) { // This may or may not do the right thing, but the user asked for the error // to be ignored so here we go anyway: - return val; + BOOST_STATIC_ASSERT(std::numeric_limits::is_specialized); + return val > 0 ? (std::numeric_limits::max)() : (std::numeric_limits::is_integer ? (std::numeric_limits::min)() : -(std::numeric_limits::max)()); } -template -inline T raise_rounding_error( - const char* , - const char* , - const T& val, +template +inline TargetType raise_rounding_error( + const char* , + const char* , + const T& val, + const TargetType&, const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) { errno = ERANGE; // This may or may not do the right thing, but the user asked for the error // to be silent so here we go anyway: - return val; + BOOST_STATIC_ASSERT(std::numeric_limits::is_specialized); + return val > 0 ? (std::numeric_limits::max)() : (std::numeric_limits::is_integer ? (std::numeric_limits::min)() : -(std::numeric_limits::max)()); } -template -inline T raise_rounding_error( - const char* function, - const char* message, - const T& val, +template +inline TargetType raise_rounding_error( + const char* function, + const char* message, + const T& val, + const TargetType& t, const ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&) { - return user_rounding_error(function, message, val); + return user_rounding_error(function, message, val, t); } template inline T raise_indeterminate_result_error( - const char* function, - const char* message, - const T& val, + const char* function, + const char* message, + const T& val, const R& , const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&) { @@ -443,10 +464,10 @@ inline T raise_indeterminate_result_error( template inline T raise_indeterminate_result_error( - const char* , - const char* , - const T& , - const R& result, + const char* , + const char* , + const T& , + const R& result, const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&) { // This may or may not do the right thing, but the user asked for the error @@ -456,10 +477,10 @@ inline T raise_indeterminate_result_error( template inline T raise_indeterminate_result_error( - const char* , - const char* , - const T& , - const R& result, + const char* , + const char* , + const T& , + const R& result, const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&) { errno = EDOM; @@ -470,10 +491,10 @@ inline T raise_indeterminate_result_error( template inline T raise_indeterminate_result_error( - const char* function, - const char* message, - const T& val, - const R& , + const char* function, + const char* message, + const T& val, + const R& , const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&) { return user_indeterminate_result_error(function, message, val); @@ -486,7 +507,7 @@ inline T raise_domain_error(const char* function, const char* message, const T& { typedef typename Policy::domain_error_type policy_type; return detail::raise_domain_error( - function, message ? message : "Domain Error evaluating function at %1%", + function, message ? message : "Domain Error evaluating function at %1%", val, policy_type()); } @@ -495,7 +516,7 @@ inline T raise_pole_error(const char* function, const char* message, const T& va { typedef typename Policy::pole_error_type policy_type; return detail::raise_pole_error( - function, message ? message : "Evaluation of function at pole %1%", + function, message ? message : "Evaluation of function at pole %1%", val, policy_type()); } @@ -504,16 +525,25 @@ inline T raise_overflow_error(const char* function, const char* message, const P { typedef typename Policy::overflow_error_type policy_type; return detail::raise_overflow_error( - function, message ? message : "Overflow Error", + function, message ? message : "Overflow Error", policy_type()); } +template +inline T raise_overflow_error(const char* function, const char* message, const T& val, const Policy&) +{ + typedef typename Policy::overflow_error_type policy_type; + return detail::raise_overflow_error( + function, message ? message : "Overflow evaluating function at %1%", + val, policy_type()); +} + template inline T raise_underflow_error(const char* function, const char* message, const Policy&) { typedef typename Policy::underflow_error_type policy_type; return detail::raise_underflow_error( - function, message ? message : "Underflow Error", + function, message ? message : "Underflow Error", policy_type()); } @@ -522,7 +552,7 @@ inline T raise_denorm_error(const char* function, const char* message, const T& { typedef typename Policy::denorm_error_type policy_type; return detail::raise_denorm_error( - function, message ? message : "Denorm Error", + function, message ? message : "Denorm Error", val, policy_type()); } @@ -532,17 +562,17 @@ inline T raise_evaluation_error(const char* function, const char* message, const { typedef typename Policy::evaluation_error_type policy_type; return detail::raise_evaluation_error( - function, message ? message : "Internal Evaluation Error, best value so far was %1%", + function, message ? message : "Internal Evaluation Error, best value so far was %1%", val, policy_type()); } -template -inline T raise_rounding_error(const char* function, const char* message, const T& val, const Policy&) +template +inline TargetType raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&) { typedef typename Policy::rounding_error_type policy_type; return detail::raise_rounding_error( - function, message ? message : "Value %1% can not be represented in the target integer type.", - val, policy_type()); + function, message ? message : "Value %1% can not be represented in the target integer type.", + val, t, policy_type()); } template @@ -572,6 +602,16 @@ inline bool check_overflow(T val, R* result, const char* function, const Policy& return false; } template +inline bool check_overflow(std::complex val, R* result, const char* function, const Policy& pol) +{ + typedef typename R::value_type r_type; + r_type re, im; + bool r = check_overflow(val.real(), &re, function, pol); + r = check_overflow(val.imag(), &im, function, pol) || r; + *result = R(re, im); + return r; +} +template inline bool check_underflow(T val, R* result, const char* function, const Policy& pol) { if((val != 0) && (static_cast(val) == 0)) @@ -582,6 +622,16 @@ inline bool check_underflow(T val, R* result, const char* function, const Policy return false; } template +inline bool check_underflow(std::complex val, R* result, const char* function, const Policy& pol) +{ + typedef typename R::value_type r_type; + r_type re, im; + bool r = check_underflow(val.real(), &re, function, pol); + r = check_underflow(val.imag(), &im, function, pol) || r; + *result = R(re, im); + return r; +} +template inline bool check_denorm(T val, R* result, const char* function, const Policy& pol) { BOOST_MATH_STD_USING @@ -592,14 +642,30 @@ inline bool check_denorm(T val, R* result, const char* function, const Policy& p } return false; } +template +inline bool check_denorm(std::complex val, R* result, const char* function, const Policy& pol) +{ + typedef typename R::value_type r_type; + r_type re, im; + bool r = check_denorm(val.real(), &re, function, pol); + r = check_denorm(val.imag(), &im, function, pol) || r; + *result = R(re, im); + return r; +} // Default instantiations with ignore_error policy. template inline bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error&){ return false; } template +inline bool check_overflow(std::complex /* val */, R* /* result */, const char* /* function */, const overflow_error&){ return false; } +template inline bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error&){ return false; } template +inline bool check_underflow(std::complex /* val */, R* /* result */, const char* /* function */, const underflow_error&){ return false; } +template inline bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error&){ return false; } +template +inline bool check_denorm(std::complex /* val */, R* /* result*/, const char* /* function */, const denorm_error&){ return false; } } // namespace detail @@ -612,7 +678,7 @@ inline R checked_narrowing_cast(T val, const char* function) // // Most of what follows will evaluate to a no-op: // - R result; + R result = 0; if(detail::check_overflow(val, &result, function, overflow_type())) return result; if(detail::check_underflow(val, &result, function, underflow_type())) @@ -623,22 +689,22 @@ inline R checked_narrowing_cast(T val, const char* function) return static_cast(val); } -template +template inline void check_series_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol) { if(max_iter >= policies::get_max_series_iterations()) - raise_evaluation_error( + raise_evaluation_error( function, - "Series evaluation exceeded %1% iterations, giving up now.", max_iter, pol); + "Series evaluation exceeded %1% iterations, giving up now.", static_cast(static_cast(max_iter)), pol); } -template +template inline void check_root_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol) { if(max_iter >= policies::get_max_root_iterations()) - raise_evaluation_error( + raise_evaluation_error( function, - "Root finding evaluation exceeded %1% iterations, giving up now.", max_iter, pol); + "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast(static_cast(max_iter)), pol); } } //namespace policies