error_handling.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 645 行 · 第 1/2 页

HPP
645
字号
//  Copyright John Maddock 2007.//  Copyright Paul A. Bristow 2007.//  Use, modification and distribution are subject to the//  Boost Software License, Version 1.0. (See accompanying file//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)#ifndef BOOST_MATH_POLICY_ERROR_HANDLING_HPP#define BOOST_MATH_POLICY_ERROR_HANDLING_HPP#include <stdexcept>#include <iomanip>#include <string>#include <cerrno>#include <boost/config/no_tr1/cmath.hpp>#include <stdexcept>#include <boost/math/tools/config.hpp>#include <boost/math/policies/policy.hpp>#include <boost/math/tools/precision.hpp>#include <boost/cstdint.hpp>#ifdef BOOST_MSVC#  pragma warning(push) // Quiet warnings in boost/format.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// 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#include <boost/format.hpp>namespace boost{ namespace math{class evaluation_error : public std::runtime_error{public:   evaluation_error(const std::string& s) : std::runtime_error(s){}};class rounding_error : public std::runtime_error{public:   rounding_error(const std::string& s) : std::runtime_error(s){}};namespace policies{//// Forward declarations of user error handlers, // it's up to the user to provide the definition of these://template <class T>T user_domain_error(const char* function, const char* message, const T& val);template <class T>T user_pole_error(const char* function, const char* message, const T& val);template <class T>T user_overflow_error(const char* function, const char* message, const T& val);template <class T>T user_underflow_error(const char* function, const char* message, const T& val);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>T user_indeterminate_result_error(const char* function, const char* message, const T& val);namespace detail{//// Helper function to avoid binding rvalue to non-const-reference,// in other words a warning suppression mechansim://template <class Formatter, class Group>inline std::string do_format(Formatter f, const Group& g){   return (f % g).str();}template <class E, class T>void raise_error(const char* function, const char* message){  if(function == 0)       function = "Unknown function operating on type %1%";  if(message == 0)       message = "Cause unknown";  std::string msg("Error in function ");  msg += (boost::format(function) % typeid(T).name()).str();  msg += ": ";  msg += message;  E e(msg);  boost::throw_exception(e);}template <class E, class T>void raise_error(const char* function, const char* message, const T& val){  if(function == 0)     function = "Unknown function operating on type %1%";  if(message == 0)     message = "Cause unknown: error caused by bad argument with value %1%";  std::string msg("Error in function ");  msg += (boost::format(function) % typeid(T).name()).str();  msg += ": ";  msg += message;  int prec = 2 + (boost::math::policies::digits<T, boost::math::policies::policy<> >() * 30103UL) / 100000UL;  msg = do_format(boost::format(msg), boost::io::group(std::setprecision(prec), val));  E e(msg);  boost::throw_exception(e);}template <class T>inline T raise_domain_error(           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);   // we never get here:   return std::numeric_limits<T>::quiet_NaN();}template <class T>inline T raise_domain_error(           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   // to be ignored so here we go anyway:   return std::numeric_limits<T>::quiet_NaN();}template <class T>inline T raise_domain_error(           const char* ,            const char* ,            const T& ,            const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&){   errno = EDOM;   // 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 std::numeric_limits<T>::quiet_NaN();}template <class T>inline T raise_domain_error(           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  ::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  ::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  ::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  ::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  ::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:   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   // to be ignored so here we go anyway:   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::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 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* 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  ::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:   return 0;}template <class T>inline T raise_underflow_error(           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   // to be ignored so here we go anyway:   return T(0);}template <class T>inline T raise_underflow_error(           const char* /* function */,            const char* /* message */,            const  ::boost::math::policies::underflow_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 T(0);}template <class T>inline T raise_underflow_error(           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 T& /* val */,           const  ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&){   raise_error<std::underflow_error, T>(function, message ? message : "denormalised result");   // we never get here:   return T(0);}template <class T>inline T raise_denorm_error(           const char* ,            const char* ,            const T&  val,           const  ::boost::math::policies::denorm_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;}template <class T>inline T raise_denorm_error(           const char* ,            const char* ,            const T& val,           const  ::boost::math::policies::denorm_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:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?