|
Boost-Commit : |
From: johnmaddock_at_[hidden]
Date: 2007-06-17 12:29:46
Author: johnmaddock
Date: 2007-06-17 12:29:46 EDT (Sun, 17 Jun 2007)
New Revision: 7086
URL: http://svn.boost.org/trac/boost/changeset/7086
Log:
Added initial policy based code.
Added:
sandbox/math_toolkit/policy/
sandbox/math_toolkit/policy/boost/
- copied from r7023, /sandbox/math_toolkit/boost/
sandbox/math_toolkit/policy/boost/math/distributions/binomial.hpp
- copied unchanged from r7084, /sandbox/math_toolkit/boost/math/distributions/binomial.hpp
sandbox/math_toolkit/policy/boost/math/distributions/extreme_value.hpp
- copied unchanged from r7084, /sandbox/math_toolkit/boost/math/distributions/extreme_value.hpp
sandbox/math_toolkit/policy/boost/math/distributions/lognormal.hpp
- copied unchanged from r7084, /sandbox/math_toolkit/boost/math/distributions/lognormal.hpp
sandbox/math_toolkit/policy/boost/math/distributions/poisson.hpp
- copied unchanged from r7084, /sandbox/math_toolkit/boost/math/distributions/poisson.hpp
sandbox/math_toolkit/policy/boost/math/policy/
sandbox/math_toolkit/policy/boost/math/policy/error_handling.hpp
sandbox/math_toolkit/policy/boost/math/policy/policy.hpp
Added: sandbox/math_toolkit/policy/boost/math/policy/error_handling.hpp
==============================================================================
--- (empty file)
+++ sandbox/math_toolkit/policy/boost/math/policy/error_handling.hpp 2007-06-17 12:29:46 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,482 @@
+
+#ifndef BOOST_MATH_POLICY_ERROR_HANDLING_HPP
+#define BOOST_MATH_POLICY_ERROR_HANDLING_HPP
+
+#include <stdexcept>
+#include <iomanip>
+#include <string>
+#include <cerrno>
+#include <cmath>
+#include <boost/math/policy/policy.hpp>
+#include <boost/math/tools/precision.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.
+#endif
+#include <boost/format.hpp>
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+namespace boost{ namespace math{
+
+class evaluation_error : public std::runtime_error
+{
+public:
+ evaluation_error(const std::string& s) : std::runtime_error(s){}
+};
+
+namespace policy{
+//
+// 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);
+
+namespace detail{
+
+template <class E, class T>
+void raise_error(const char* function, const char* message)
+{
+ if(function == 0)
+ function = "Unknown function";
+ 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";
+ if(message == 0)
+ message = "Cause unknown";
+
+ std::string msg("Error in function ");
+ msg += (boost::format(function) % typeid(T).name()).str();
+ msg += ": ";
+ msg += message;
+
+ int prec = 2 + (tools::digits<T>() * 30103UL) / 100000UL;
+ msg = (boost::format(msg) % boost::io::group(std::setprecision(prec), val)).str();
+
+ 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::policy::domain_error< ::boost::math::policy::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::policy::domain_error< ::boost::math::policy::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::policy::domain_error< ::boost::math::policy::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::policy::domain_error< ::boost::math::policy::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::policy::pole_error< ::boost::math::policy::throw_on_error>&)
+{
+ return boost::math::policy::detail::raise_domain_error(function, message, val, ::boost::math::policy::domain_error< ::boost::math::policy::throw_on_error>());
+}
+
+template <class T>
+inline T raise_pole_error(
+ const char* function,
+ const char* message,
+ const T& val,
+ const ::boost::math::policy::pole_error< ::boost::math::policy::ignore_error>&)
+{
+ return ::boost::math::policy::detail::raise_domain_error(function, message, val, ::boost::math::policy::domain_error< ::boost::math::policy::ignore_error>());
+}
+
+template <class T>
+inline T raise_pole_error(
+ const char* function,
+ const char* message,
+ const T& val,
+ const ::boost::math::policy::pole_error< ::boost::math::policy::errno_on_error>&)
+{
+ return ::boost::math::policy::detail::raise_domain_error(function, message, val, ::boost::math::policy::domain_error< ::boost::math::policy::errno_on_error>());
+}
+
+template <class T>
+inline T raise_pole_error(
+ const char* function,
+ const char* message,
+ const T& val,
+ const ::boost::math::policy::pole_error< ::boost::math::policy::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::policy::overflow_error< ::boost::math::policy::throw_on_error>&)
+{
+ raise_error<std::overflow_error, T>(function, message);
+ // 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::policy::overflow_error< ::boost::math::policy::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::policy::overflow_error< ::boost::math::policy::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::policy::overflow_error< ::boost::math::policy::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::policy::underflow_error< ::boost::math::policy::throw_on_error>&)
+{
+ raise_error<std::underflow_error, T>(function, message);
+ // we never get here:
+ return 0;
+}
+
+template <class T>
+inline T raise_underflow_error(
+ const char* ,
+ const char* ,
+ const ::boost::math::policy::underflow_error< ::boost::math::policy::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 0;
+}
+
+template <class T>
+inline T raise_underflow_error(
+ const char* ,
+ const char* ,
+ const ::boost::math::policy::underflow_error< ::boost::math::policy::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 0;
+}
+
+template <class T>
+inline T raise_underflow_error(
+ const char* function,
+ const char* message,
+ const ::boost::math::policy::underflow_error< ::boost::math::policy::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::policy::denorm_error< ::boost::math::policy::throw_on_error>&)
+{
+ raise_error<std::underflow_error, T>(function, message);
+ // we never get here:
+ return 0;
+}
+
+template <class T>
+inline T raise_denorm_error(
+ const char* ,
+ const char* ,
+ const T& val,
+ const ::boost::math::policy::denorm_error< ::boost::math::policy::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::policy::denorm_error< ::boost::math::policy::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;
+}
+
+template <class T>
+inline T raise_denorm_error(
+ const char* function,
+ const char* message,
+ const T& val,
+ const ::boost::math::policy::denorm_error< ::boost::math::policy::user_error>&)
+{
+ return user_denorm_error(function, message, val);
+}
+
+template <class T>
+inline T raise_evaluation_error(
+ const char* function,
+ const char* message,
+ const T& val,
+ const ::boost::math::policy::evaluation_error< ::boost::math::policy::throw_on_error>&)
+{
+ raise_error<boost::math::evaluation_error, T>(function, message, val);
+ // we never get here:
+ return 0;
+}
+
+template <class T>
+inline T raise_evaluation_error(
+ const char* ,
+ const char* ,
+ const T& val,
+ const ::boost::math::policy::evaluation_error< ::boost::math::policy::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_evaluation_error(
+ const char* ,
+ const char* ,
+ const T& val,
+ const ::boost::math::policy::evaluation_error< ::boost::math::policy::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 val;
+}
+
+template <class T>
+inline T raise_evaluation_error(
+ const char* function,
+ const char* message,
+ const T& val,
+ const ::boost::math::policy::evaluation_error< ::boost::math::policy::user_error>&)
+{
+ return user_evaluation_error(function, message, val);
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline T raise_domain_error(const char* function, const char* message, const T& val, const Policy&)
+{
+ typedef typename Policy::domain_error_type policy_type;
+ return detail::raise_domain_error(
+ function, message ? message : "Domain Error evaluating function at %1%",
+ val, policy_type());
+}
+
+template <class T, class Policy>
+inline T raise_pole_error(const char* function, const char* message, const T& val, const Policy&)
+{
+ typedef typename Policy::pole_error_type policy_type;
+ return detail::raise_pole_error(
+ function, message ? message : "Evaluation of function at pole %1%",
+ val, policy_type());
+}
+
+template <class T, class Policy>
+inline T raise_overflow_error(const char* function, const char* message, const Policy&)
+{
+ typedef typename Policy::overflow_error_type policy_type;
+ return detail::raise_overflow_error<T>(
+ function, message ? message : "Overflow Error",
+ 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",
+ policy_type());
+}
+
+template <class T, class Policy>
+inline T raise_denorm_error(const char* function, const char* message, const T& val, const Policy&)
+{
+ typedef typename Policy::denorm_error_type policy_type;
+ return detail::raise_denorm_error<T>(
+ function, message ? message : "Denorm Error",
+ val,
+ policy_type());
+}
+
+template <class T, class Policy>
+inline T raise_evaluation_error(const char* function, const char* message, const T& val, const Policy&)
+{
+ 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%",
+ val, policy_type());
+}
+
+//
+// checked_narrowing_cast:
+//
+namespace detail{
+
+template <class R, class T, class Policy>
+inline bool check_overflow(T val, R* result, const char* function, const Policy& pol)
+{
+ using namespace std;
+ if(fabs(val) > tools::max_value<R>())
+ {
+ *result = raise_overflow_error<R>(function, 0, pol);
+ return true;
+ }
+ return false;
+}
+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))
+ {
+ *result = raise_underflow_error<R>(function, 0, pol);
+ return true;
+ }
+ return false;
+}
+template <class R, class T, class Policy>
+inline bool check_denorm(T val, R* result, const char* function, const Policy& pol)
+{
+ using namespace std;
+ if((fabs(val) < static_cast<T>(tools::min_value<R>())) && (static_cast<R>(val) != 0))
+ {
+ *result = raise_denorm_error<R>(function, 0, val, pol);
+ return true;
+ }
+ return false;
+}
+
+template <class R, class T>
+inline bool check_overflow(T val, R* result, const overflow_error<ignore_error>&){ return false; }
+template <class R, class T>
+inline bool check_underflow(T val, R* result, const overflow_error<ignore_error>&){ return false; }
+template <class R, class T>
+inline bool check_denormflow(T val, R* result, const overflow_error<ignore_error>&){ return false; }
+
+}
+
+template <class R, class Policy, class T>
+inline R checked_narrowing_cast(T val, const char* function)
+{
+ typedef typename Policy::overflow_error_type overflow_type;
+ typedef typename Policy::underflow_error_type underflow_type;
+ typedef typename Policy::denorm_error_type denorm_type;
+ //
+ // Most of what follows will evaluate to a no-op:
+ //
+ R result;
+ if(detail::check_overflow<R>(val, &result, function, overflow_type()))
+ return result;
+ if(detail::check_underflow<R>(val, &result, function, underflow_type()))
+ return result;
+ if(detail::check_denorm<R>(val, &result, function, denorm_type()))
+ return result;
+
+ return static_cast<R>(val);
+}
+
+} //namespace policy
+
+}} // namespaces boost/math
+
+#endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP
Added: sandbox/math_toolkit/policy/boost/math/policy/policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/math_toolkit/policy/boost/math/policy/policy.hpp 2007-06-17 12:29:46 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,608 @@
+
+#ifndef BOOST_MATH_POLICY_HPP
+#define BOOST_MATH_POLICY_HPP
+
+#define BOOST_PARAMETER_MAX_ARITY 15
+
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/contains.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/remove_if.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost{ namespace math{ namespace policy{
+
+//
+// Define macros for our default policies, if they're not defined already:
+//
+#ifndef BOOST_MATH_DOMAIN_ERROR_POLICY
+#define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error
+#endif
+#ifndef BOOST_MATH_POLE_ERROR_POLICY
+#define BOOST_MATH_POLE_ERROR_POLICY throw_on_error
+#endif
+#ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY
+#define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error
+#endif
+#ifndef BOOST_MATH_EVALUATION_ERROR_POLICY
+#define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error
+#endif
+#ifndef BOOST_MATH_UNDERFLOW_ERROR_POLICY
+#define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error
+#endif
+#ifndef BOOST_MATH_DENORM_ERROR_POLICY
+#define BOOST_MATH_DENORM_ERROR_POLICY ignore_error
+#endif
+#ifndef BOOST_MATH_DIGITS10_POLICY
+#define BOOST_MATH_DIGITS10_POLICY 0
+#endif
+#ifndef BOOST_MATH_PROMOTE_FLOAT_POLICY
+#define BOOST_MATH_PROMOTE_FLOAT_POLICY true
+#endif
+#ifndef BOOST_MATH_PROMOTE_DOUBLE_POLICY
+#define BOOST_MATH_PROMOTE_DOUBLE_POLICY true
+#endif
+#ifndef BOOST_MATH_DISCRETE_QUANTILE_POLICY
+#define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_outside
+#endif
+
+#if !defined(__BORLANDC__)
+#define BOOST_MATH_META_INT(type, name, Default)\
+ template <type N = Default> struct name : public boost::mpl::int_<N>{};\
+ namespace detail{\
+ template <type N>\
+ char test_is_valid_arg(const name<N>*);\
+ char test_is_default_arg(const name<Default>*);\
+ template <class T> struct is_##name##_imp\
+ {\
+ template <type N> static char test(const name<N>*);\
+ static double test(...);\
+ BOOST_STATIC_CONSTANT(bool, value = sizeof(test(static_cast<T*>(0))) == 1);\
+ };\
+ }\
+ template <class T> struct is_##name : public boost::mpl::bool_<detail::is_##name##_imp<T>::value>{};
+
+#define BOOST_MATH_META_BOOL(name, Default)\
+ template <bool N = Default> struct name : public boost::mpl::bool_<N>{};\
+ namespace detail{\
+ template <bool N>\
+ char test_is_valid_arg(const name<N>*);\
+ char test_is_default_arg(const name<Default>*);\
+ template <class T> struct is_##name##_imp\
+ {\
+ template <bool N> static char test(const name<N>*);\
+ static double test(...);\
+ BOOST_STATIC_CONSTANT(bool, value = sizeof(test(static_cast<T*>(0))) == 1);\
+ };\
+ }\
+ template <class T> struct is_##name : public boost::mpl::bool_<detail::is_##name##_imp<T>::value>{};
+#else
+#define BOOST_MATH_META_INT(Type, name, Default)\
+ template <Type N = Default> struct name : public boost::mpl::int_<N>{};\
+ namespace detail{\
+ template <Type N>\
+ char test_is_valid_arg(const name<N>*);\
+ char test_is_default_arg(const name<Default>*);\
+ template <class T> struct is_##name##_tester\
+ {\
+ template <Type N> static char test(const name<N>&);\
+ static double test(...);\
+ };\
+ template <class T> struct is_##name##_imp\
+ {\
+ static T inst;\
+ BOOST_STATIC_CONSTANT(bool, value = sizeof(detail::is_##name##_tester<T>::test(inst)) == 1);\
+ };\
+ }\
+ template <class T> struct is_##name : public boost::mpl::bool_<detail::is_##name##_imp<T>::value>\
+ {\
+ template <class U> struct apply{ typedef is_##name<U> type; };\
+ };
+
+#define BOOST_MATH_META_BOOL(name, Default)\
+ template <bool N = Default> struct name : public boost::mpl::bool_<N>{};\
+ namespace detail{\
+ template <bool N>\
+ char test_is_valid_arg(const name<N>*);\
+ char test_is_default_arg(const name<Default>*);\
+ template <class T> struct is_##name##_tester\
+ {\
+ template <bool N> static char test(const name<N>&);\
+ static double test(...);\
+ };\
+ template <class T> struct is_##name##_imp\
+ {\
+ static T inst;\
+ BOOST_STATIC_CONSTANT(bool, value = sizeof(detail::is_##name##_tester<T>::test(inst)) == 1);\
+ };\
+ }\
+ template <class T> struct is_##name : public boost::mpl::bool_<detail::is_##name##_imp<T>::value>\
+ {\
+ template <class U> struct apply{ typedef is_##name<U> type; };\
+ };
+#endif
+//
+// Begin by defining policy types for error handling:
+//
+enum error_policy_type
+{
+ throw_on_error = 0,
+ errno_on_error = 1,
+ ignore_error = 2,
+ user_error = 3
+};
+
+BOOST_MATH_META_INT(error_policy_type, domain_error, BOOST_MATH_DOMAIN_ERROR_POLICY)
+BOOST_MATH_META_INT(error_policy_type, pole_error, BOOST_MATH_POLE_ERROR_POLICY)
+BOOST_MATH_META_INT(error_policy_type, overflow_error, BOOST_MATH_OVERFLOW_ERROR_POLICY)
+BOOST_MATH_META_INT(error_policy_type, underflow_error, BOOST_MATH_UNDERFLOW_ERROR_POLICY)
+BOOST_MATH_META_INT(error_policy_type, denorm_error, BOOST_MATH_DENORM_ERROR_POLICY)
+BOOST_MATH_META_INT(error_policy_type, evaluation_error, BOOST_MATH_EVALUATION_ERROR_POLICY)
+
+//
+// Policy types for internal promotion:
+//
+BOOST_MATH_META_BOOL(promote_float, BOOST_MATH_PROMOTE_FLOAT_POLICY);
+BOOST_MATH_META_BOOL(promote_double, BOOST_MATH_PROMOTE_DOUBLE_POLICY);
+//
+// Policy types for discrete quantiles:
+//
+enum discrete_quantile_policy_type
+{
+ real,
+ integer_outside,
+ integer_inside,
+ integer_below,
+ integer_above
+};
+
+BOOST_MATH_META_INT(discrete_quantile_policy_type, discrete_quantile, BOOST_MATH_DISCRETE_QUANTILE_POLICY);
+//
+// Precision:
+//
+BOOST_MATH_META_INT(int, digits10, BOOST_MATH_DIGITS10_POLICY);
+BOOST_MATH_META_INT(int, digits2, 0);
+//
+// Define the names for each possible policy:
+//
+#define BOOST_MATH_PARAMETER(name)\
+ BOOST_PARAMETER_TEMPLATE_KEYWORD(name##_name)\
+ BOOST_PARAMETER_NAME(name##_name)
+
+struct default_policy{};
+
+namespace detail{
+//
+// Trait to work out bits precision from digits10 and digits2:
+//
+template <class Digits10, class Digits2>
+struct precision
+{
+ //
+ // Now work out the precision:
+ //
+ typedef typename mpl::if_c<
+ (Digits10::value == 0),
+ digits2<0>,
+ digits2<((Digits10::value + 1) * 1000L) / 301L>
+ >::type digits2_type;
+public:
+#ifdef __BORLANDC__
+ typedef typename mpl::if_c<
+ (Digits2::value > ::boost::math::policy::detail::precision<Digits10,Digits2>::digits2_type::value),
+ Digits2, digits2_type>::type type;
+#else
+ typedef typename mpl::if_c<
+ (Digits2::value > digits2_type::value),
+ Digits2, digits2_type>::type type;
+#endif
+};
+
+template <class A, class B, bool b>
+struct select_result
+{
+ typedef A type;
+};
+template <class A, class B>
+struct select_result<A, B, false>
+{
+ typedef typename mpl::deref<B>::type type;
+};
+
+template <class Seq, class Pred, class DefaultType>
+struct find_arg
+{
+private:
+ typedef typename mpl::find_if<Seq, Pred>::type iter;
+ typedef typename mpl::end<Seq>::type end_type;
+public:
+ typedef typename select_result<
+ DefaultType, iter,
+ ::boost::is_same<iter, end_type>::value>::type type;
+};
+
+double test_is_valid_arg(...);
+double test_is_default_arg(...);
+char test_is_valid_arg(const default_policy*);
+char test_is_default_arg(const default_policy*);
+
+template <class T>
+struct is_valid_policy_imp
+{
+ BOOST_STATIC_CONSTANT(bool, value = sizeof(test_is_valid_arg(static_cast<T*>(0))) == 1);
+};
+
+template <class T>
+struct is_default_policy_imp
+{
+ BOOST_STATIC_CONSTANT(bool, value = sizeof(test_is_default_arg(static_cast<T*>(0))) == 1);
+};
+
+template <class T> struct is_valid_policy
+: public mpl::bool_<
+ ::boost::math::policy::detail::is_valid_policy_imp<T>::value>
+{};
+
+template <class T> struct is_default_policy
+: public mpl::bool_<
+ ::boost::math::policy::detail::is_default_policy_imp<T>::value>
+{
+ template <class U>
+ struct apply
+ {
+ typedef is_default_policy<U> type;
+ };
+};
+
+template <class Seq, class T, int N>
+struct append_N
+{
+ typedef typename mpl::push_back<Seq, T>::type new_seq;
+ typedef typename append_N<new_seq, T, N-1>::type type;
+};
+
+template <class Seq, class T>
+struct append_N<Seq, T, 0>
+{
+ typedef Seq type;
+};
+
+//
+// Traits class to work out what template parameters our default
+// policy<> class will have when modified for forwarding:
+//
+template <bool f, bool d>
+struct default_args
+{
+ typedef promote_float<false> arg1;
+ typedef promote_double<false> arg2;
+};
+
+template <>
+struct default_args<false, false>
+{
+ typedef default_policy arg1;
+ typedef default_policy arg2;
+};
+
+template <>
+struct default_args<true, false>
+{
+ typedef promote_float<false> arg1;
+ typedef default_policy arg2;
+};
+
+template <>
+struct default_args<false, true>
+{
+ typedef promote_double<false> arg1;
+ typedef default_policy arg2;
+};
+
+typedef default_args<BOOST_MATH_PROMOTE_FLOAT_POLICY, BOOST_MATH_PROMOTE_DOUBLE_POLICY>::arg1 forwarding_arg1;
+typedef default_args<BOOST_MATH_PROMOTE_FLOAT_POLICY, BOOST_MATH_PROMOTE_DOUBLE_POLICY>::arg2 forwarding_arg2;
+
+} // detail
+//
+// Now define the policy type with enough arguments to handle all
+// the policies:
+//
+template <class A1 = default_policy,
+ class A2 = default_policy,
+ class A3 = default_policy,
+ class A4 = default_policy,
+ class A5 = default_policy,
+ class A6 = default_policy,
+ class A7 = default_policy,
+ class A8 = default_policy,
+ class A9 = default_policy,
+ class A10 = default_policy,
+ class A11 = default_policy>
+struct policy
+{
+private:
+ //
+ // Validate all our arguments:
+ //
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A1>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A2>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A3>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A4>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A5>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A6>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A7>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A8>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A9>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A10>::value);
+ BOOST_STATIC_ASSERT(::boost::math::policy::detail::is_valid_policy<A11>::value);
+ //
+ // Typelist of the arguments:
+ //
+ typedef mpl::list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11> arg_list;
+
+public:
+ typedef typename detail::find_arg<arg_list, is_domain_error<mpl::_1>, domain_error<> >::type domain_error_type;
+ typedef typename detail::find_arg<arg_list, is_pole_error<mpl::_1>, pole_error<> >::type pole_error_type;
+ typedef typename detail::find_arg<arg_list, is_overflow_error<mpl::_1>, overflow_error<> >::type overflow_error_type;
+ typedef typename detail::find_arg<arg_list, is_underflow_error<mpl::_1>, underflow_error<> >::type underflow_error_type;
+ typedef typename detail::find_arg<arg_list, is_denorm_error<mpl::_1>, denorm_error<> >::type denorm_error_type;
+ typedef typename detail::find_arg<arg_list, is_evaluation_error<mpl::_1>, evaluation_error<> >::type evaluation_error_type;
+private:
+ //
+ // Now work out the precision:
+ //
+ typedef typename detail::find_arg<arg_list, is_digits10<mpl::_1>, digits10<> >::type digits10_type;
+ typedef typename detail::find_arg<arg_list, is_digits2<mpl::_1>, digits2<> >::type bits_precision_type;
+public:
+ typedef typename detail::precision<digits10_type, bits_precision_type>::type precision_type;
+ //
+ // Internal promotion:
+ //
+ typedef typename detail::find_arg<arg_list, is_promote_float<mpl::_1>, promote_float<> >::type float_promote_type;
+ typedef typename detail::find_arg<arg_list, is_promote_double<mpl::_1>, promote_double<> >::type double_promote_type;
+ //
+ // Discrete quantiles:
+ //
+ typedef typename detail::find_arg<arg_list, is_discrete_quantile<mpl::_1>, discrete_quantile<> >::type discrete_quantile_type;
+};
+//
+// These full specializations are defined to reduce the amount of
+// template instantiations that have to take place when using the default
+// policies, they have quite a large impact on compile times:
+//
+template <>
+struct policy<default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy>
+{
+public:
+ typedef domain_error<> domain_error_type;
+ typedef pole_error<> pole_error_type;
+ typedef overflow_error<> overflow_error_type;
+ typedef underflow_error<> underflow_error_type;
+ typedef denorm_error<> denorm_error_type;
+ typedef evaluation_error<> evaluation_error_type;
+#if BOOST_MATH_DIGITS10_POLICY == 0
+ typedef digits2<> precision_type;
+#else
+ typedef typename detail::precision<digits10<>, digits2<> >::type precision_type;
+#endif
+ typedef promote_float<> float_promote_type;
+ typedef promote_double<> double_promote_type;
+ typedef discrete_quantile<> discrete_quantile_type;
+};
+
+template <>
+struct policy<detail::forwarding_arg1, detail::forwarding_arg2, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy>
+{
+public:
+ typedef domain_error<> domain_error_type;
+ typedef pole_error<> pole_error_type;
+ typedef overflow_error<> overflow_error_type;
+ typedef underflow_error<> underflow_error_type;
+ typedef denorm_error<> denorm_error_type;
+ typedef evaluation_error<> evaluation_error_type;
+#if BOOST_MATH_DIGITS10_POLICY == 0
+ typedef digits2<> precision_type;
+#else
+ typedef typename detail::precision<digits10<>, digits2<> >::type precision_type;
+#endif
+ typedef promote_float<false> float_promote_type;
+ typedef promote_double<false> double_promote_type;
+ typedef discrete_quantile<> discrete_quantile_type;
+};
+
+template <class Policy,
+ class A1 = default_policy,
+ class A2 = default_policy,
+ class A3 = default_policy,
+ class A4 = default_policy,
+ class A5 = default_policy,
+ class A6 = default_policy,
+ class A7 = default_policy,
+ class A8 = default_policy,
+ class A9 = default_policy,
+ class A10 = default_policy,
+ class A11 = default_policy>
+struct normalise
+{
+private:
+ typedef mpl::list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11> arg_list;
+ typedef typename detail::find_arg<arg_list, is_domain_error<mpl::_1>, typename Policy::domain_error_type >::type domain_error_type;
+ typedef typename detail::find_arg<arg_list, is_pole_error<mpl::_1>, typename Policy::pole_error_type >::type pole_error_type;
+ typedef typename detail::find_arg<arg_list, is_overflow_error<mpl::_1>, typename Policy::overflow_error_type >::type overflow_error_type;
+ typedef typename detail::find_arg<arg_list, is_underflow_error<mpl::_1>, typename Policy::underflow_error_type >::type underflow_error_type;
+ typedef typename detail::find_arg<arg_list, is_denorm_error<mpl::_1>, typename Policy::denorm_error_type >::type denorm_error_type;
+ typedef typename detail::find_arg<arg_list, is_evaluation_error<mpl::_1>, typename Policy::evaluation_error_type >::type evaluation_error_type;
+ //
+ // Now work out the precision:
+ //
+ typedef typename detail::find_arg<arg_list, is_digits10<mpl::_1>, digits10<> >::type digits10_type;
+ typedef typename detail::find_arg<arg_list, is_digits2<mpl::_1>, typename Policy::precision_type >::type bits_precision_type;
+ typedef typename detail::precision<digits10_type, bits_precision_type>::type precision_type;
+ //
+ // Internal promotion:
+ //
+ typedef typename detail::find_arg<arg_list, is_promote_float<mpl::_1>, typename Policy::float_promote_type >::type float_promote_type;
+ typedef typename detail::find_arg<arg_list, is_promote_double<mpl::_1>, typename Policy::double_promote_type >::type double_promote_type;
+ //
+ // Discrete quantiles:
+ //
+ typedef typename detail::find_arg<arg_list, is_discrete_quantile<mpl::_1>, typename Policy::discrete_quantile_type >::type discrete_quantile_type;
+ //
+ // Define a typelist of the policies:
+ //
+ typedef mpl::vector<
+ domain_error_type,
+ pole_error_type,
+ overflow_error_type,
+ underflow_error_type,
+ denorm_error_type,
+ evaluation_error_type,
+ precision_type,
+ float_promote_type,
+ double_promote_type,
+ discrete_quantile_type > result_list;
+ //
+ // Remove all the policies that are the same as the default:
+ //
+ typedef typename mpl::remove_if<result_list, detail::is_default_policy<mpl::_> >::type reduced_list;
+ //
+ // Pad out the list with defaults:
+ //
+ typedef typename detail::append_N<reduced_list, default_policy, (12 - ::boost::mpl::size<reduced_list>::value)>::type result_type;
+public:
+ typedef policy<
+ typename mpl::at<result_type, mpl::int_<0> >::type,
+ typename mpl::at<result_type, mpl::int_<1> >::type,
+ typename mpl::at<result_type, mpl::int_<2> >::type,
+ typename mpl::at<result_type, mpl::int_<3> >::type,
+ typename mpl::at<result_type, mpl::int_<4> >::type,
+ typename mpl::at<result_type, mpl::int_<5> >::type,
+ typename mpl::at<result_type, mpl::int_<6> >::type,
+ typename mpl::at<result_type, mpl::int_<7> >::type,
+ typename mpl::at<result_type, mpl::int_<8> >::type,
+ typename mpl::at<result_type, mpl::int_<9> >::type,
+ typename mpl::at<result_type, mpl::int_<10> >::type > type;
+};
+//
+// Full specialisation to speed up compilation of the common case:
+//
+template <>
+struct normalise<policy<>,
+ promote_float<false>,
+ promote_double<false>,
+ discrete_quantile<>,
+ default_policy,
+ default_policy,
+ default_policy,
+ default_policy,
+ default_policy,
+ default_policy,
+ default_policy,
+ default_policy>
+{
+ typedef policy<detail::forwarding_arg1, detail::forwarding_arg2> type;
+};
+
+inline policy<> make_policy()
+{ return policy<>(); }
+
+template <class A1>
+inline typename normalise<policy<>, A1>::type make_policy(const A1&)
+{
+ typedef typename normalise<policy<>, A1>::type result_type;
+ return result_type();
+}
+
+template <class A1, class A2>
+inline typename normalise<policy<>, A1, A2>::type make_policy(const A1&, const A2&)
+{
+ typedef typename normalise<policy<>, A1, A2>::type result_type;
+ return result_type();
+}
+
+template <class A1, class A2, class A3>
+inline typename normalise<policy<>, A1, A2, A3>::type make_policy(const A1&, const A2&, const A3&)
+{
+ typedef typename normalise<policy<>, A1, A2, A3>::type result_type;
+ return result_type();
+}
+
+template <class A1, class A2, class A3, class A4>
+inline typename normalise<policy<>, A1, A2, A3, A4>::type make_policy(const A1&, const A2&, const A3&, const A4&)
+{
+ typedef typename normalise<policy<>, A1, A2, A3, A4>::type result_type;
+ return result_type();
+}
+
+template <class A1, class A2, class A3, class A4, class A5>
+inline typename normalise<policy<>, A1, A2, A3, A4, A5>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&)
+{
+ typedef typename normalise<policy<>, A1, A2, A3, A4, A5>::type result_type;
+ return result_type();
+}
+
+template <class A1, class A2, class A3, class A4, class A5, class A6>
+inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&)
+{
+ typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type result_type;
+ return result_type();
+}
+
+template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&)
+{
+ typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7>::type result_type;
+ return result_type();
+}
+
+template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&)
+{
+ typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8>::type result_type;
+ return result_type();
+}
+
+template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&)
+{
+ typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type result_type;
+ return result_type();
+}
+
+template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
+inline typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&)
+{
+ typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type result_type;
+ return result_type();
+}
+
+//
+// Traits class to handle internal promotion:
+//
+template <class Real, class Policy>
+struct evaluation
+{
+ typedef Real type;
+};
+
+template <class Policy>
+struct evaluation<float, Policy>
+{
+ typedef typename mpl::if_<typename Policy::float_promote_type, double, float>::type type;
+};
+
+template <class Policy>
+struct evaluation<double, Policy>
+{
+ typedef typename mpl::if_<typename Policy::double_promote_type, long double, double>::type type;
+};
+
+}}} // namespaces
+
+#endif // BOOST_MATH_POLICY_HPP
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk