summaryrefslogtreecommitdiff
path: root/boost/math/policies/error_handling.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/math/policies/error_handling.hpp')
-rw-r--r--boost/math/policies/error_handling.hpp88
1 files changed, 55 insertions, 33 deletions
diff --git a/boost/math/policies/error_handling.hpp b/boost/math/policies/error_handling.hpp
index 285fbea7c4..124337ee87 100644
--- a/boost/math/policies/error_handling.hpp
+++ b/boost/math/policies/error_handling.hpp
@@ -11,6 +11,8 @@
#include <stdexcept>
#include <iomanip>
#include <string>
+#include <cstring>
+#include <typeinfo>
#include <cerrno>
#include <boost/config/no_tr1/complex.hpp>
#include <boost/config/no_tr1/cmath.hpp>
@@ -18,17 +20,19 @@
#include <boost/math/tools/config.hpp>
#include <boost/math/policies/policy.hpp>
#include <boost/math/tools/precision.hpp>
+#include <boost/throw_exception.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.
+# pragma warning(disable: 4127) // conditional expression is constant
// 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>
+#include <sstream>
namespace boost{ namespace math{
@@ -68,14 +72,31 @@ T user_indeterminate_result_error(const char* function, const char* message, con
namespace detail
{
-//
-// Helper function to avoid binding rvalue to non-const-reference,
-// 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>
+std::string prec_format(const T& val)
{
- return (f % g).str();
+ typedef typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type prec_type;
+ std::stringstream ss;
+ if(prec_type::value)
+ {
+ int prec = 2 + (prec_type::value * 30103UL) / 100000UL;
+ ss << std::setprecision(prec);
+ }
+ ss << val;
+ return ss.str();
+}
+
+inline void replace_all_in_string(std::string& result, const char* what, const char* with)
+{
+ std::string::size_type pos = 0;
+ std::string::size_type slen = std::strlen(what);
+ std::string::size_type rlen = std::strlen(with);
+ while((pos = result.find(what, pos)) != std::string::npos)
+ {
+ result.replace(pos, slen, with);
+ pos += rlen;
+ }
}
template <class T>
@@ -100,19 +121,21 @@ inline const char* name_of<BOOST_MATH_FLOAT128_TYPE>()
#endif
template <class E, class T>
-void raise_error(const char* function, const char* message)
+void raise_error(const char* pfunction, const char* message)
{
- if(function == 0)
- function = "Unknown function operating on type %1%";
+ if(pfunction == 0)
+ pfunction = "Unknown function operating on type %1%";
if(message == 0)
- message = "Cause unknown";
+ message = "Cause unknown";
+ std::string function(pfunction);
std::string msg("Error in function ");
#ifndef BOOST_NO_RTTI
- msg += (boost::format(function) % boost::math::policies::detail::name_of<T>()).str();
+ replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());
#else
- msg += function;
+ replace_all_in_string(function, "%1%", "Unknown");
#endif
+ msg += function;
msg += ": ";
msg += message;
@@ -121,24 +144,27 @@ void raise_error(const char* function, const char* message)
}
template <class E, class T>
-void raise_error(const char* function, const char* message, const T& val)
+void raise_error(const char* pfunction, const char* pmessage, 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%";
+ if(pfunction == 0)
+ pfunction = "Unknown function operating on type %1%";
+ if(pmessage == 0)
+ pmessage = "Cause unknown: error caused by bad argument with value %1%";
+ std::string function(pfunction);
+ std::string message(pmessage);
std::string msg("Error in function ");
#ifndef BOOST_NO_RTTI
- msg += (boost::format(function) % boost::math::policies::detail::name_of<T>()).str();
+ replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());
#else
- msg += function;
+ replace_all_in_string(function, "%1%", "Unknown");
#endif
+ msg += function;
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));
+ std::string sval = prec_format(val);
+ replace_all_in_string(message, "%1%", sval.c_str());
+ msg += message;
E e(msg);
boost::throw_exception(e);
@@ -319,15 +345,11 @@ inline T raise_overflow_error(
const T& val,
const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
{
- std::string fmsg("Error in function ");
-#ifndef BOOST_NO_RTTI
- fmsg += (boost::format(function) % boost::math::policies::detail::name_of<T>()).str();
-#else
- fmsg += function;
-#endif
- int prec = 2 + (boost::math::policies::digits<T, boost::math::policies::policy<> >() * 30103UL) / 100000UL;
- std::string msg = do_format(boost::format(message), boost::io::group(std::setprecision(prec), val));
- return user_overflow_error(fmsg.c_str(), msg.c_str(), std::numeric_limits<T>::infinity());
+ std::string m(message ? message : "");
+ std::string sval = prec_format(val);
+ replace_all_in_string(m, "%1%", sval.c_str());
+
+ return user_overflow_error(function, m.c_str(), std::numeric_limits<T>::infinity());
}
template <class T>