]> git.donarmstrong.com Git - rsem.git/blobdiff - boost/math/policies/error_handling.hpp
Updated boost to v1.55.0
[rsem.git] / boost / math / policies / error_handling.hpp
index 6285e1e9f2b8c64d90d6f2df1d6b46de8b9ed241..96333d342b4f95f7f1f4a9116276af0fe71f8a73 100644 (file)
@@ -12,6 +12,7 @@
 #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>
@@ -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 <class T>
@@ -60,8 +61,8 @@ 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);
 
@@ -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 <class Formatter, class Group>
 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 <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);
@@ -128,9 +129,9 @@ inline T raise_domain_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::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 <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;
@@ -153,9 +154,9 @@ inline T raise_domain_error(
 
 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);
@@ -163,9 +164,9 @@ inline T raise_domain_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::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 <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>());
@@ -183,9 +184,9 @@ inline T raise_pole_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>());
@@ -193,29 +194,42 @@ inline T raise_pole_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
@@ -225,8 +239,8 @@ inline T raise_overflow_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;
@@ -237,28 +251,29 @@ inline T raise_overflow_error(
 
 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
@@ -268,8 +283,8 @@ inline T raise_underflow_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;
@@ -280,8 +295,8 @@ inline T raise_underflow_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::user_error>&)
 {
    return user_underflow_error(function, message, T(0));
@@ -289,8 +304,8 @@ inline T raise_underflow_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::throw_on_error>&)
 {
@@ -301,8 +316,8 @@ inline T raise_denorm_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>&)
 {
@@ -313,8 +328,8 @@ inline T raise_denorm_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>&)
 {
@@ -326,8 +341,8 @@ inline T raise_denorm_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>&)
 {
@@ -336,9 +351,9 @@ inline T raise_denorm_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);
@@ -348,9 +363,9 @@ inline T raise_evaluation_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::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 <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;
@@ -373,66 +388,72 @@ inline T raise_evaluation_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::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>&)
 {
@@ -443,10 +464,10 @@ inline T raise_indeterminate_result_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
@@ -456,10 +477,10 @@ inline T raise_indeterminate_result_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;
@@ -470,10 +491,10 @@ inline T raise_indeterminate_result_error(
 
 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);
@@ -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<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());
 }
 
@@ -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<T>(
-      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 <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>
@@ -572,6 +602,16 @@ inline bool check_overflow(T val, R* result, const char* function, const 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))
@@ -582,6 +622,16 @@ inline bool check_underflow(T val, R* result, const char* function, const Policy
    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
@@ -592,14 +642,30 @@ inline bool check_denorm(T val, R* result, const char* function, const Policy& p
    }
    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
 
@@ -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<R>(val, &result, function, overflow_type()))
       return result;
    if(detail::check_underflow<R>(val, &result, function, underflow_type()))
@@ -623,22 +689,22 @@ inline R checked_narrowing_cast(T val, const char* function)
    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