$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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