#include <iomanip>
#include <string>
#include <cerrno>
+#include <boost/config/no_tr1/complex.hpp>
#include <boost/config/no_tr1/cmath.hpp>
#include <stdexcept>
#include <boost/math/tools/config.hpp>
# 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
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 <class T>
T user_denorm_error(const char* function, const char* message, const T& val);
template <class T>
T user_evaluation_error(const char* function, const char* message, const T& val);
-template <class T>
-T user_rounding_error(const char* function, const char* message, const T& val);
+template <class T, class TargetType>
+T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t);
template <class T>
T user_indeterminate_result_error(const char* function, const char* message, const T& val);
{
//
// 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 <class Formatter, class Group>
inline std::string do_format(Formatter f, const Group& g)
template <class T>
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<std::domain_error, T>(function, message, val);
template <class T>
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
template <class T>
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;
template <class T>
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);
template <class T>
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>());
template <class T>
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>());
template <class T>
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>());
template <class T>
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 <class T>
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<std::overflow_error, T>(function, message ? message : "numeric overflow");
- // we never get here:
+ // We should never get here:
return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
}
template <class T>
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<std::overflow_error, T>(function, message ? message : "numeric overflow", val);
+ // We should never get here:
+ return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
+}
+
+template <class T>
+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
template <class T>
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;
template <class T>
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<T>::infinity());
}
+
template <class T>
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<std::underflow_error, T>(function, message ? message : "numeric underflow");
- // we never get here:
+ // We should never get here:
return 0;
}
template <class T>
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
template <class T>
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;
template <class T>
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));
template <class T>
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>&)
{
template <class T>
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>&)
{
template <class T>
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>&)
{
template <class T>
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>&)
{
template <class T>
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<boost::math::evaluation_error, T>(function, message, val);
template <class T>
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
template <class T>
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;
template <class T>
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 <class T>
-inline T raise_rounding_error(
- const char* function,
- const char* message,
- const T& val,
+template <class T, class TargetType>
+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<boost::math::rounding_error, T>(function, message, val);
// we never get here:
- return T(0);
+ return TargetType(0);
}
-template <class T>
-inline T raise_rounding_error(
- const char* ,
- const char* ,
- const T& val,
+template <class T, class TargetType>
+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<TargetType>::is_specialized);
+ return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
}
-template <class T>
-inline T raise_rounding_error(
- const char* ,
- const char* ,
- const T& val,
+template <class T, class TargetType>
+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<TargetType>::is_specialized);
+ return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
}
-template <class T>
-inline T raise_rounding_error(
- const char* function,
- const char* message,
- const T& val,
+template <class T, class TargetType>
+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 <class T, class R>
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>&)
{
template <class T, class R>
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
template <class T, class R>
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;
template <class T, class R>
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);
{
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());
}
{
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());
}
{
typedef typename Policy::overflow_error_type policy_type;
return detail::raise_overflow_error<T>(
- function, message ? message : "Overflow Error",
+ function, message ? message : "Overflow Error",
policy_type());
}
+template <class T, class Policy>
+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 <class T, class Policy>
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<T>(
- function, message ? message : "Underflow Error",
+ function, message ? message : "Underflow Error",
policy_type());
}
{
typedef typename Policy::denorm_error_type policy_type;
return detail::raise_denorm_error<T>(
- function, message ? message : "Denorm Error",
+ function, message ? message : "Denorm Error",
val,
policy_type());
}
{
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 <class T, class Policy>
-inline T raise_rounding_error(const char* function, const char* message, const T& val, const Policy&)
+template <class T, class TargetType, class Policy>
+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 <class T, class R, class Policy>
return false;
}
template <class R, class T, class Policy>
+inline bool check_overflow(std::complex<T> val, R* result, const char* function, const Policy& pol)
+{
+ typedef typename R::value_type r_type;
+ r_type re, im;
+ bool r = check_overflow<r_type>(val.real(), &re, function, pol);
+ r = check_overflow<r_type>(val.imag(), &im, function, pol) || r;
+ *result = R(re, im);
+ return r;
+}
+template <class R, class T, class Policy>
inline bool check_underflow(T val, R* result, const char* function, const Policy& pol)
{
if((val != 0) && (static_cast<R>(val) == 0))
return false;
}
template <class R, class T, class Policy>
+inline bool check_underflow(std::complex<T> val, R* result, const char* function, const Policy& pol)
+{
+ typedef typename R::value_type r_type;
+ r_type re, im;
+ bool r = check_underflow<r_type>(val.real(), &re, function, pol);
+ r = check_underflow<r_type>(val.imag(), &im, function, pol) || r;
+ *result = R(re, im);
+ return r;
+}
+template <class R, class T, class Policy>
inline bool check_denorm(T val, R* result, const char* function, const Policy& pol)
{
BOOST_MATH_STD_USING
}
return false;
}
+template <class R, class T, class Policy>
+inline bool check_denorm(std::complex<T> val, R* result, const char* function, const Policy& pol)
+{
+ typedef typename R::value_type r_type;
+ r_type re, im;
+ bool r = check_denorm<r_type>(val.real(), &re, function, pol);
+ r = check_denorm<r_type>(val.imag(), &im, function, pol) || r;
+ *result = R(re, im);
+ return r;
+}
// Default instantiations with ignore_error policy.
template <class R, class T>
inline bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&){ return false; }
template <class R, class T>
+inline bool check_overflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&){ return false; }
+template <class R, class T>
inline bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&){ return false; }
template <class R, class T>
+inline bool check_underflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&){ return false; }
+template <class R, class T>
inline bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&){ return false; }
+template <class R, class T>
+inline bool check_denorm(std::complex<T> /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&){ return false; }
} // namespace detail
//
// Most of what follows will evaluate to a no-op:
//
- R result;
+ R result = 0;
if(detail::check_overflow<R>(val, &result, function, overflow_type()))
return result;
if(detail::check_underflow<R>(val, &result, function, underflow_type()))
return static_cast<R>(val);
}
-template <class Policy>
+template <class T, class Policy>
inline void check_series_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol)
{
if(max_iter >= policies::get_max_series_iterations<Policy>())
- raise_evaluation_error<boost::uintmax_t>(
+ raise_evaluation_error<T>(
function,
- "Series evaluation exceeded %1% iterations, giving up now.", max_iter, pol);
+ "Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
}
-template <class Policy>
+template <class T, class Policy>
inline void check_root_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol)
{
if(max_iter >= policies::get_max_root_iterations<Policy>())
- raise_evaluation_error<boost::uintmax_t>(
+ raise_evaluation_error<T>(
function,
- "Root finding evaluation exceeded %1% iterations, giving up now.", max_iter, pol);
+ "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
}
} //namespace policies