1 // Copyright John Maddock 2007.
2 // Copyright Paul A. Bristow 2007.
4 // Use, modification and distribution are subject to the
5 // Boost Software License, Version 1.0. (See accompanying file
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_MATH_POLICY_ERROR_HANDLING_HPP
9 #define BOOST_MATH_POLICY_ERROR_HANDLING_HPP
17 #include <boost/config/no_tr1/complex.hpp>
18 #include <boost/config/no_tr1/cmath.hpp>
20 #include <boost/math/tools/config.hpp>
21 #include <boost/math/policies/policy.hpp>
22 #include <boost/math/tools/precision.hpp>
23 #include <boost/throw_exception.hpp>
24 #include <boost/cstdint.hpp>
26 # pragma warning(push) // Quiet warnings in boost/format.hpp
27 # pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE
28 # pragma warning(disable: 4512) // assignment operator could not be generated.
29 # pragma warning(disable: 4127) // conditional expression is constant
30 // And warnings in error handling:
31 # pragma warning(disable: 4702) // unreachable code.
32 // Note that this only occurs when the compiler can deduce code is unreachable,
33 // for example when policy macros are used to ignore errors rather than throw.
37 namespace boost{ namespace math{
39 class evaluation_error : public std::runtime_error
42 evaluation_error(const std::string& s) : std::runtime_error(s){}
45 class rounding_error : public std::runtime_error
48 rounding_error(const std::string& s) : std::runtime_error(s){}
53 // Forward declarations of user error handlers,
54 // it's up to the user to provide the definition of these:
57 T user_domain_error(const char* function, const char* message, const T& val);
59 T user_pole_error(const char* function, const char* message, const T& val);
61 T user_overflow_error(const char* function, const char* message, const T& val);
63 T user_underflow_error(const char* function, const char* message, const T& val);
65 T user_denorm_error(const char* function, const char* message, const T& val);
67 T user_evaluation_error(const char* function, const char* message, const T& val);
68 template <class T, class TargetType>
69 T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t);
71 T user_indeterminate_result_error(const char* function, const char* message, const T& val);
77 std::string prec_format(const T& val)
79 typedef typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type prec_type;
83 int prec = 2 + (prec_type::value * 30103UL) / 100000UL;
84 ss << std::setprecision(prec);
90 inline void replace_all_in_string(std::string& result, const char* what, const char* with)
92 std::string::size_type pos = 0;
93 std::string::size_type slen = std::strlen(what);
94 std::string::size_type rlen = std::strlen(with);
95 while((pos = result.find(what, pos)) != std::string::npos)
97 result.replace(pos, slen, with);
103 inline const char* name_of()
105 #ifndef BOOST_NO_RTTI
106 return typeid(T).name();
111 template <> inline const char* name_of<float>(){ return "float"; }
112 template <> inline const char* name_of<double>(){ return "double"; }
113 template <> inline const char* name_of<long double>(){ return "long double"; }
115 #ifdef BOOST_MATH_USE_FLOAT128
117 inline const char* name_of<BOOST_MATH_FLOAT128_TYPE>()
123 template <class E, class T>
124 void raise_error(const char* pfunction, const char* message)
127 pfunction = "Unknown function operating on type %1%";
129 message = "Cause unknown";
131 std::string function(pfunction);
132 std::string msg("Error in function ");
133 #ifndef BOOST_NO_RTTI
134 replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());
136 replace_all_in_string(function, "%1%", "Unknown");
143 boost::throw_exception(e);
146 template <class E, class T>
147 void raise_error(const char* pfunction, const char* pmessage, const T& val)
150 pfunction = "Unknown function operating on type %1%";
152 pmessage = "Cause unknown: error caused by bad argument with value %1%";
154 std::string function(pfunction);
155 std::string message(pmessage);
156 std::string msg("Error in function ");
157 #ifndef BOOST_NO_RTTI
158 replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());
160 replace_all_in_string(function, "%1%", "Unknown");
165 std::string sval = prec_format(val);
166 replace_all_in_string(message, "%1%", sval.c_str());
170 boost::throw_exception(e);
174 inline T raise_domain_error(
175 const char* function,
178 const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&)
180 raise_error<std::domain_error, T>(function, message, val);
181 // we never get here:
182 return std::numeric_limits<T>::quiet_NaN();
186 inline BOOST_MATH_CONSTEXPR T raise_domain_error(
190 const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
192 // This may or may not do the right thing, but the user asked for the error
193 // to be ignored so here we go anyway:
194 return std::numeric_limits<T>::quiet_NaN();
198 inline T raise_domain_error(
202 const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
205 // This may or may not do the right thing, but the user asked for the error
206 // to be silent so here we go anyway:
207 return std::numeric_limits<T>::quiet_NaN();
211 inline T raise_domain_error(
212 const char* function,
215 const ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&)
217 return user_domain_error(function, message, val);
221 inline T raise_pole_error(
222 const char* function,
225 const ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&)
227 return boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>());
231 inline BOOST_MATH_CONSTEXPR T raise_pole_error(
232 const char* function,
235 const ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
237 return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>());
241 inline BOOST_MATH_CONSTEXPR T raise_pole_error(
242 const char* function,
245 const ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
247 return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>());
251 inline T raise_pole_error(
252 const char* function,
255 const ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&)
257 return user_pole_error(function, message, val);
262 inline T raise_overflow_error(
263 const char* function,
265 const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)
267 raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow");
268 // We should never get here:
269 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
273 inline T raise_overflow_error(
274 const char* function,
277 const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)
279 raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow", val);
280 // We should never get here:
281 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
285 inline BOOST_MATH_CONSTEXPR T raise_overflow_error(
288 const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
290 // This may or may not do the right thing, but the user asked for the error
291 // to be ignored so here we go anyway:
292 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
296 inline BOOST_MATH_CONSTEXPR T raise_overflow_error(
300 const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
302 // This may or may not do the right thing, but the user asked for the error
303 // to be ignored so here we go anyway:
304 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
308 inline T raise_overflow_error(
311 const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
314 // This may or may not do the right thing, but the user asked for the error
315 // to be silent so here we go anyway:
316 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
320 inline T raise_overflow_error(
324 const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
327 // This may or may not do the right thing, but the user asked for the error
328 // to be silent so here we go anyway:
329 return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
333 inline T raise_overflow_error(
334 const char* function,
336 const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
338 return user_overflow_error(function, message, std::numeric_limits<T>::infinity());
342 inline T raise_overflow_error(
343 const char* function,
346 const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
348 std::string m(message ? message : "");
349 std::string sval = prec_format(val);
350 replace_all_in_string(m, "%1%", sval.c_str());
352 return user_overflow_error(function, m.c_str(), std::numeric_limits<T>::infinity());
356 inline T raise_underflow_error(
357 const char* function,
359 const ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&)
361 raise_error<std::underflow_error, T>(function, message ? message : "numeric underflow");
362 // We should never get here:
367 inline BOOST_MATH_CONSTEXPR T raise_underflow_error(
370 const ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
372 // This may or may not do the right thing, but the user asked for the error
373 // to be ignored so here we go anyway:
378 inline T raise_underflow_error(
379 const char* /* function */,
380 const char* /* message */,
381 const ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
384 // This may or may not do the right thing, but the user asked for the error
385 // to be silent so here we go anyway:
390 inline T raise_underflow_error(
391 const char* function,
393 const ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&)
395 return user_underflow_error(function, message, T(0));
399 inline T raise_denorm_error(
400 const char* function,
403 const ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&)
405 raise_error<std::underflow_error, T>(function, message ? message : "denormalised result");
406 // we never get here:
411 inline BOOST_MATH_CONSTEXPR T raise_denorm_error(
415 const ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
417 // This may or may not do the right thing, but the user asked for the error
418 // to be ignored so here we go anyway:
423 inline T raise_denorm_error(
427 const ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
430 // This may or may not do the right thing, but the user asked for the error
431 // to be silent so here we go anyway:
436 inline T raise_denorm_error(
437 const char* function,
440 const ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&)
442 return user_denorm_error(function, message, val);
446 inline T raise_evaluation_error(
447 const char* function,
450 const ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&)
452 raise_error<boost::math::evaluation_error, T>(function, message, val);
453 // we never get here:
458 inline BOOST_MATH_CONSTEXPR T raise_evaluation_error(
462 const ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
464 // This may or may not do the right thing, but the user asked for the error
465 // to be ignored so here we go anyway:
470 inline T raise_evaluation_error(
474 const ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
477 // This may or may not do the right thing, but the user asked for the error
478 // to be silent so here we go anyway:
483 inline T raise_evaluation_error(
484 const char* function,
487 const ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&)
489 return user_evaluation_error(function, message, val);
492 template <class T, class TargetType>
493 inline TargetType raise_rounding_error(
494 const char* function,
498 const ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&)
500 raise_error<boost::math::rounding_error, T>(function, message, val);
501 // we never get here:
502 return TargetType(0);
505 template <class T, class TargetType>
506 inline BOOST_MATH_CONSTEXPR TargetType raise_rounding_error(
511 const ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
513 // This may or may not do the right thing, but the user asked for the error
514 // to be ignored so here we go anyway:
515 BOOST_STATIC_ASSERT(std::numeric_limits<TargetType>::is_specialized);
516 return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
519 template <class T, class TargetType>
520 inline TargetType raise_rounding_error(
525 const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
528 // This may or may not do the right thing, but the user asked for the error
529 // to be silent so here we go anyway:
530 BOOST_STATIC_ASSERT(std::numeric_limits<TargetType>::is_specialized);
531 return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
535 inline T raise_rounding_error(
540 const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
543 // This may or may not do the right thing, but the user asked for the error
544 // to be silent so here we go anyway:
545 return val > 0 ? boost::math::tools::max_value<T>() : -boost::math::tools::max_value<T>();
548 template <class T, class TargetType>
549 inline TargetType raise_rounding_error(
550 const char* function,
554 const ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&)
556 return user_rounding_error(function, message, val, t);
559 template <class T, class R>
560 inline T raise_indeterminate_result_error(
561 const char* function,
565 const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&)
567 raise_error<std::domain_error, T>(function, message, val);
568 // we never get here:
569 return std::numeric_limits<T>::quiet_NaN();
572 template <class T, class R>
573 inline BOOST_MATH_CONSTEXPR T raise_indeterminate_result_error(
578 const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
580 // This may or may not do the right thing, but the user asked for the error
581 // to be ignored so here we go anyway:
585 template <class T, class R>
586 inline T raise_indeterminate_result_error(
591 const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&)
594 // This may or may not do the right thing, but the user asked for the error
595 // to be silent so here we go anyway:
599 template <class T, class R>
600 inline T raise_indeterminate_result_error(
601 const char* function,
605 const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&)
607 return user_indeterminate_result_error(function, message, val);
610 } // namespace detail
612 template <class T, class Policy>
613 inline BOOST_MATH_CONSTEXPR T raise_domain_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
615 typedef typename Policy::domain_error_type policy_type;
616 return detail::raise_domain_error(
617 function, message ? message : "Domain Error evaluating function at %1%",
621 template <class T, class Policy>
622 inline BOOST_MATH_CONSTEXPR T raise_pole_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
624 typedef typename Policy::pole_error_type policy_type;
625 return detail::raise_pole_error(
626 function, message ? message : "Evaluation of function at pole %1%",
630 template <class T, class Policy>
631 inline BOOST_MATH_CONSTEXPR T raise_overflow_error(const char* function, const char* message, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
633 typedef typename Policy::overflow_error_type policy_type;
634 return detail::raise_overflow_error<T>(
635 function, message ? message : "Overflow Error",
639 template <class T, class Policy>
640 inline BOOST_MATH_CONSTEXPR T raise_overflow_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
642 typedef typename Policy::overflow_error_type policy_type;
643 return detail::raise_overflow_error(
644 function, message ? message : "Overflow evaluating function at %1%",
648 template <class T, class Policy>
649 inline BOOST_MATH_CONSTEXPR T raise_underflow_error(const char* function, const char* message, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
651 typedef typename Policy::underflow_error_type policy_type;
652 return detail::raise_underflow_error<T>(
653 function, message ? message : "Underflow Error",
657 template <class T, class Policy>
658 inline BOOST_MATH_CONSTEXPR T raise_denorm_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
660 typedef typename Policy::denorm_error_type policy_type;
661 return detail::raise_denorm_error<T>(
662 function, message ? message : "Denorm Error",
667 template <class T, class Policy>
668 inline BOOST_MATH_CONSTEXPR T raise_evaluation_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
670 typedef typename Policy::evaluation_error_type policy_type;
671 return detail::raise_evaluation_error(
672 function, message ? message : "Internal Evaluation Error, best value so far was %1%",
676 template <class T, class TargetType, class Policy>
677 inline BOOST_MATH_CONSTEXPR TargetType raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
679 typedef typename Policy::rounding_error_type policy_type;
680 return detail::raise_rounding_error(
681 function, message ? message : "Value %1% can not be represented in the target integer type.",
682 val, t, policy_type());
685 template <class T, class R, class Policy>
686 inline BOOST_MATH_CONSTEXPR T raise_indeterminate_result_error(const char* function, const char* message, const T& val, const R& result, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
688 typedef typename Policy::indeterminate_result_error_type policy_type;
689 return detail::raise_indeterminate_result_error(
690 function, message ? message : "Indeterminate result with value %1%",
691 val, result, policy_type());
695 // checked_narrowing_cast:
700 template <class R, class T, class Policy>
701 inline bool check_overflow(T val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
704 if(fabs(val) > tools::max_value<R>())
706 boost::math::policies::detail::raise_overflow_error<R>(function, 0, pol);
707 *result = static_cast<R>(val);
712 template <class R, class T, class Policy>
713 inline bool check_overflow(std::complex<T> val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
715 typedef typename R::value_type r_type;
717 bool r = check_overflow<r_type>(val.real(), &re, function, pol);
718 r = check_overflow<r_type>(val.imag(), &im, function, pol) || r;
722 template <class R, class T, class Policy>
723 inline bool check_underflow(T val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
725 if((val != 0) && (static_cast<R>(val) == 0))
727 *result = static_cast<R>(boost::math::policies::detail::raise_underflow_error<R>(function, 0, pol));
732 template <class R, class T, class Policy>
733 inline bool check_underflow(std::complex<T> val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
735 typedef typename R::value_type r_type;
737 bool r = check_underflow<r_type>(val.real(), &re, function, pol);
738 r = check_underflow<r_type>(val.imag(), &im, function, pol) || r;
742 template <class R, class T, class Policy>
743 inline bool check_denorm(T val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
746 if((fabs(val) < static_cast<T>(tools::min_value<R>())) && (static_cast<R>(val) != 0))
748 *result = static_cast<R>(boost::math::policies::detail::raise_denorm_error<R>(function, 0, static_cast<R>(val), pol));
753 template <class R, class T, class Policy>
754 inline bool check_denorm(std::complex<T> val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
756 typedef typename R::value_type r_type;
758 bool r = check_denorm<r_type>(val.real(), &re, function, pol);
759 r = check_denorm<r_type>(val.imag(), &im, function, pol) || r;
764 // Default instantiations with ignore_error policy.
765 template <class R, class T>
766 inline BOOST_MATH_CONSTEXPR bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))
768 template <class R, class T>
769 inline BOOST_MATH_CONSTEXPR bool check_overflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))
771 template <class R, class T>
772 inline BOOST_MATH_CONSTEXPR bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))
774 template <class R, class T>
775 inline BOOST_MATH_CONSTEXPR bool check_underflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))
777 template <class R, class T>
778 inline BOOST_MATH_CONSTEXPR bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))
780 template <class R, class T>
781 inline BOOST_MATH_CONSTEXPR bool check_denorm(std::complex<T> /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T))
784 } // namespace detail
786 template <class R, class Policy, class T>
787 inline R checked_narrowing_cast(T val, const char* function) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value)
789 typedef typename Policy::overflow_error_type overflow_type;
790 typedef typename Policy::underflow_error_type underflow_type;
791 typedef typename Policy::denorm_error_type denorm_type;
793 // Most of what follows will evaluate to a no-op:
796 if(detail::check_overflow<R>(val, &result, function, overflow_type()))
798 if(detail::check_underflow<R>(val, &result, function, underflow_type()))
800 if(detail::check_denorm<R>(val, &result, function, denorm_type()))
803 return static_cast<R>(val);
806 template <class T, class Policy>
807 inline void check_series_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value)
809 if(max_iter >= policies::get_max_series_iterations<Policy>())
810 raise_evaluation_error<T>(
812 "Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
815 template <class T, class Policy>
816 inline void check_root_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value)
818 if(max_iter >= policies::get_max_root_iterations<Policy>())
819 raise_evaluation_error<T>(
821 "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
824 } //namespace policies
829 // Simple helper function to assist in returning a pair from a single value,
830 // that value usually comes from one of the error handlers above:
833 std::pair<T, T> pair_from_single(const T& val) BOOST_MATH_NOEXCEPT(T)
835 return std::make_pair(val, val);
841 # pragma warning(pop)
844 }} // namespaces boost/math
846 #endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP