Chris@16: // Copyright John Maddock 2007. Chris@16: // Use, modification and distribution are subject to the Chris@16: // Boost Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_MATH_POLICY_HPP Chris@16: #define BOOST_MATH_POLICY_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: // Sadly we do need the .h versions of these to be sure of getting Chris@16: // FLT_MANT_DIG etc. Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost{ namespace math{ Chris@16: Chris@16: namespace tools{ Chris@16: Chris@16: template Chris@16: int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)); Chris@16: template Chris@16: T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)); Chris@16: Chris@16: } Chris@16: Chris@16: namespace policies{ Chris@16: Chris@16: // Chris@16: // Define macros for our default policies, if they're not defined already: Chris@16: // Chris@16: #ifndef BOOST_MATH_DOMAIN_ERROR_POLICY Chris@16: #define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error Chris@16: #endif Chris@16: #ifndef BOOST_MATH_POLE_ERROR_POLICY Chris@16: #define BOOST_MATH_POLE_ERROR_POLICY throw_on_error Chris@16: #endif Chris@16: #ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY Chris@16: #define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error Chris@16: #endif Chris@16: #ifndef BOOST_MATH_EVALUATION_ERROR_POLICY Chris@16: #define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error Chris@16: #endif Chris@16: #ifndef BOOST_MATH_ROUNDING_ERROR_POLICY Chris@16: #define BOOST_MATH_ROUNDING_ERROR_POLICY throw_on_error Chris@16: #endif Chris@16: #ifndef BOOST_MATH_UNDERFLOW_ERROR_POLICY Chris@16: #define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error Chris@16: #endif Chris@16: #ifndef BOOST_MATH_DENORM_ERROR_POLICY Chris@16: #define BOOST_MATH_DENORM_ERROR_POLICY ignore_error Chris@16: #endif Chris@16: #ifndef BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY Chris@16: #define BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY ignore_error Chris@16: #endif Chris@16: #ifndef BOOST_MATH_DIGITS10_POLICY Chris@16: #define BOOST_MATH_DIGITS10_POLICY 0 Chris@16: #endif Chris@16: #ifndef BOOST_MATH_PROMOTE_FLOAT_POLICY Chris@16: #define BOOST_MATH_PROMOTE_FLOAT_POLICY true Chris@16: #endif Chris@16: #ifndef BOOST_MATH_PROMOTE_DOUBLE_POLICY Chris@16: #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS Chris@16: #define BOOST_MATH_PROMOTE_DOUBLE_POLICY false Chris@16: #else Chris@16: #define BOOST_MATH_PROMOTE_DOUBLE_POLICY true Chris@16: #endif Chris@16: #endif Chris@16: #ifndef BOOST_MATH_DISCRETE_QUANTILE_POLICY Chris@16: #define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards Chris@16: #endif Chris@16: #ifndef BOOST_MATH_ASSERT_UNDEFINED_POLICY Chris@16: #define BOOST_MATH_ASSERT_UNDEFINED_POLICY true Chris@16: #endif Chris@16: #ifndef BOOST_MATH_MAX_SERIES_ITERATION_POLICY Chris@16: #define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000 Chris@16: #endif Chris@16: #ifndef BOOST_MATH_MAX_ROOT_ITERATION_POLICY Chris@16: #define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200 Chris@16: #endif Chris@16: Chris@101: #if !defined(__BORLANDC__) Chris@16: #define BOOST_MATH_META_INT(type, name, Default)\ Chris@16: template struct name : public boost::mpl::int_{};\ Chris@16: namespace detail{\ Chris@16: template \ Chris@16: char test_is_valid_arg(const name*);\ Chris@16: char test_is_default_arg(const name*);\ Chris@16: template struct is_##name##_imp\ Chris@16: {\ Chris@16: template static char test(const name*);\ Chris@16: static double test(...);\ Chris@16: BOOST_STATIC_CONSTANT(bool, value = sizeof(test(static_cast(0))) == 1);\ Chris@16: };\ Chris@16: }\ Chris@16: template struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp::value>{}; Chris@16: Chris@16: #define BOOST_MATH_META_BOOL(name, Default)\ Chris@16: template struct name : public boost::mpl::bool_{};\ Chris@16: namespace detail{\ Chris@16: template \ Chris@16: char test_is_valid_arg(const name*);\ Chris@16: char test_is_default_arg(const name*);\ Chris@16: template struct is_##name##_imp\ Chris@16: {\ Chris@16: template static char test(const name*);\ Chris@16: static double test(...);\ Chris@16: BOOST_STATIC_CONSTANT(bool, value = sizeof(test(static_cast(0))) == 1);\ Chris@16: };\ Chris@16: }\ Chris@16: template struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp::value>{}; Chris@16: #else Chris@16: #define BOOST_MATH_META_INT(Type, name, Default)\ Chris@16: template struct name : public boost::mpl::int_{};\ Chris@16: namespace detail{\ Chris@16: template \ Chris@16: char test_is_valid_arg(const name*);\ Chris@16: char test_is_default_arg(const name*);\ Chris@16: template struct is_##name##_tester\ Chris@16: {\ Chris@16: template static char test(const name&);\ Chris@16: static double test(...);\ Chris@16: };\ Chris@16: template struct is_##name##_imp\ Chris@16: {\ Chris@16: static T inst;\ Chris@16: BOOST_STATIC_CONSTANT(bool, value = sizeof( ::boost::math::policies::detail::is_##name##_tester::test(inst)) == 1);\ Chris@16: };\ Chris@16: }\ Chris@16: template struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp::value>\ Chris@16: {\ Chris@16: template struct apply{ typedef is_##name type; };\ Chris@16: }; Chris@16: Chris@16: #define BOOST_MATH_META_BOOL(name, Default)\ Chris@16: template struct name : public boost::mpl::bool_{};\ Chris@16: namespace detail{\ Chris@16: template \ Chris@16: char test_is_valid_arg(const name*);\ Chris@16: char test_is_default_arg(const name*);\ Chris@16: template struct is_##name##_tester\ Chris@16: {\ Chris@16: template static char test(const name&);\ Chris@16: static double test(...);\ Chris@16: };\ Chris@16: template struct is_##name##_imp\ Chris@16: {\ Chris@16: static T inst;\ Chris@16: BOOST_STATIC_CONSTANT(bool, value = sizeof( ::boost::math::policies::detail::is_##name##_tester::test(inst)) == 1);\ Chris@16: };\ Chris@16: }\ Chris@16: template struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp::value>\ Chris@16: {\ Chris@16: template struct apply{ typedef is_##name type; };\ Chris@16: }; Chris@16: #endif Chris@16: // Chris@16: // Begin by defining policy types for error handling: Chris@16: // Chris@16: enum error_policy_type Chris@16: { Chris@16: throw_on_error = 0, Chris@16: errno_on_error = 1, Chris@16: ignore_error = 2, Chris@16: user_error = 3 Chris@16: }; Chris@16: Chris@16: BOOST_MATH_META_INT(error_policy_type, domain_error, BOOST_MATH_DOMAIN_ERROR_POLICY) Chris@16: BOOST_MATH_META_INT(error_policy_type, pole_error, BOOST_MATH_POLE_ERROR_POLICY) Chris@16: BOOST_MATH_META_INT(error_policy_type, overflow_error, BOOST_MATH_OVERFLOW_ERROR_POLICY) Chris@16: BOOST_MATH_META_INT(error_policy_type, underflow_error, BOOST_MATH_UNDERFLOW_ERROR_POLICY) Chris@16: BOOST_MATH_META_INT(error_policy_type, denorm_error, BOOST_MATH_DENORM_ERROR_POLICY) Chris@16: BOOST_MATH_META_INT(error_policy_type, evaluation_error, BOOST_MATH_EVALUATION_ERROR_POLICY) Chris@16: BOOST_MATH_META_INT(error_policy_type, rounding_error, BOOST_MATH_ROUNDING_ERROR_POLICY) Chris@16: BOOST_MATH_META_INT(error_policy_type, indeterminate_result_error, BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY) Chris@16: Chris@16: // Chris@16: // Policy types for internal promotion: Chris@16: // Chris@16: BOOST_MATH_META_BOOL(promote_float, BOOST_MATH_PROMOTE_FLOAT_POLICY) Chris@16: BOOST_MATH_META_BOOL(promote_double, BOOST_MATH_PROMOTE_DOUBLE_POLICY) Chris@16: BOOST_MATH_META_BOOL(assert_undefined, BOOST_MATH_ASSERT_UNDEFINED_POLICY) Chris@16: // Chris@16: // Policy types for discrete quantiles: Chris@16: // Chris@16: enum discrete_quantile_policy_type Chris@16: { Chris@16: real, Chris@16: integer_round_outwards, Chris@16: integer_round_inwards, Chris@16: integer_round_down, Chris@16: integer_round_up, Chris@16: integer_round_nearest Chris@16: }; Chris@16: Chris@16: BOOST_MATH_META_INT(discrete_quantile_policy_type, discrete_quantile, BOOST_MATH_DISCRETE_QUANTILE_POLICY) Chris@16: // Chris@16: // Precision: Chris@16: // Chris@16: BOOST_MATH_META_INT(int, digits10, BOOST_MATH_DIGITS10_POLICY) Chris@16: BOOST_MATH_META_INT(int, digits2, 0) Chris@16: // Chris@16: // Iterations: Chris@16: // Chris@16: BOOST_MATH_META_INT(unsigned long, max_series_iterations, BOOST_MATH_MAX_SERIES_ITERATION_POLICY) Chris@16: BOOST_MATH_META_INT(unsigned long, max_root_iterations, BOOST_MATH_MAX_ROOT_ITERATION_POLICY) Chris@16: // Chris@16: // Define the names for each possible policy: Chris@16: // Chris@16: #define BOOST_MATH_PARAMETER(name)\ Chris@16: BOOST_PARAMETER_TEMPLATE_KEYWORD(name##_name)\ Chris@16: BOOST_PARAMETER_NAME(name##_name) Chris@16: Chris@16: struct default_policy{}; Chris@16: Chris@16: namespace detail{ Chris@16: // Chris@16: // Trait to work out bits precision from digits10 and digits2: Chris@16: // Chris@16: template Chris@16: struct precision Chris@16: { Chris@16: // Chris@16: // Now work out the precision: Chris@16: // Chris@16: typedef typename mpl::if_c< Chris@16: (Digits10::value == 0), Chris@16: digits2<0>, Chris@16: digits2<((Digits10::value + 1) * 1000L) / 301L> Chris@16: >::type digits2_type; Chris@16: public: Chris@16: #ifdef __BORLANDC__ Chris@16: typedef typename mpl::if_c< Chris@16: (Digits2::value > ::boost::math::policies::detail::precision::digits2_type::value), Chris@16: Digits2, digits2_type>::type type; Chris@16: #else Chris@16: typedef typename mpl::if_c< Chris@16: (Digits2::value > digits2_type::value), Chris@16: Digits2, digits2_type>::type type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template Chris@16: struct select_result Chris@16: { Chris@16: typedef A type; Chris@16: }; Chris@16: template Chris@16: struct select_result Chris@16: { Chris@16: typedef typename mpl::deref::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct find_arg Chris@16: { Chris@16: private: Chris@16: typedef typename mpl::find_if::type iter; Chris@16: typedef typename mpl::end::type end_type; Chris@16: public: Chris@16: typedef typename select_result< Chris@16: DefaultType, iter, Chris@16: ::boost::is_same::value>::type type; Chris@16: }; Chris@16: Chris@16: double test_is_valid_arg(...); Chris@16: double test_is_default_arg(...); Chris@16: char test_is_valid_arg(const default_policy*); Chris@16: char test_is_default_arg(const default_policy*); Chris@16: Chris@16: template Chris@16: struct is_valid_policy_imp Chris@16: { Chris@16: BOOST_STATIC_CONSTANT(bool, value = sizeof(::boost::math::policies::detail::test_is_valid_arg(static_cast(0))) == 1); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_default_policy_imp Chris@16: { Chris@16: BOOST_STATIC_CONSTANT(bool, value = sizeof(::boost::math::policies::detail::test_is_default_arg(static_cast(0))) == 1); Chris@16: }; Chris@16: Chris@16: template struct is_valid_policy Chris@16: : public mpl::bool_< Chris@16: ::boost::math::policies::detail::is_valid_policy_imp::value> Chris@16: {}; Chris@16: Chris@16: template struct is_default_policy Chris@16: : public mpl::bool_< Chris@16: ::boost::math::policies::detail::is_default_policy_imp::value> Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef is_default_policy type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct append_N Chris@16: { Chris@16: typedef typename mpl::push_back::type new_seq; Chris@16: typedef typename append_N::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct append_N Chris@16: { Chris@16: typedef Seq type; Chris@16: }; Chris@16: Chris@16: // Chris@16: // Traits class to work out what template parameters our default Chris@16: // policy<> class will have when modified for forwarding: Chris@16: // Chris@16: template Chris@16: struct default_args Chris@16: { Chris@16: typedef promote_float arg1; Chris@16: typedef promote_double arg2; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct default_args Chris@16: { Chris@16: typedef default_policy arg1; Chris@16: typedef default_policy arg2; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct default_args Chris@16: { Chris@16: typedef promote_float arg1; Chris@16: typedef default_policy arg2; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct default_args Chris@16: { Chris@16: typedef promote_double arg1; Chris@16: typedef default_policy arg2; Chris@16: }; Chris@16: Chris@16: typedef default_args::arg1 forwarding_arg1; Chris@16: typedef default_args::arg2 forwarding_arg2; Chris@16: Chris@16: } // detail Chris@16: // Chris@16: // Now define the policy type with enough arguments to handle all Chris@16: // the policies: Chris@16: // Chris@16: template Chris@16: struct policy Chris@16: { Chris@16: private: Chris@16: // Chris@16: // Validate all our arguments: Chris@16: // Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy::value); Chris@16: // Chris@16: // Typelist of the arguments: Chris@16: // Chris@16: typedef mpl::list arg_list; Chris@16: Chris@16: public: Chris@16: typedef typename detail::find_arg, domain_error<> >::type domain_error_type; Chris@16: typedef typename detail::find_arg, pole_error<> >::type pole_error_type; Chris@16: typedef typename detail::find_arg, overflow_error<> >::type overflow_error_type; Chris@16: typedef typename detail::find_arg, underflow_error<> >::type underflow_error_type; Chris@16: typedef typename detail::find_arg, denorm_error<> >::type denorm_error_type; Chris@16: typedef typename detail::find_arg, evaluation_error<> >::type evaluation_error_type; Chris@16: typedef typename detail::find_arg, rounding_error<> >::type rounding_error_type; Chris@16: typedef typename detail::find_arg, indeterminate_result_error<> >::type indeterminate_result_error_type; Chris@16: private: Chris@16: // Chris@16: // Now work out the precision: Chris@16: // Chris@16: typedef typename detail::find_arg, digits10<> >::type digits10_type; Chris@16: typedef typename detail::find_arg, digits2<> >::type bits_precision_type; Chris@16: public: Chris@16: typedef typename detail::precision::type precision_type; Chris@16: // Chris@16: // Internal promotion: Chris@16: // Chris@16: typedef typename detail::find_arg, promote_float<> >::type promote_float_type; Chris@16: typedef typename detail::find_arg, promote_double<> >::type promote_double_type; Chris@16: // Chris@16: // Discrete quantiles: Chris@16: // Chris@16: typedef typename detail::find_arg, discrete_quantile<> >::type discrete_quantile_type; Chris@16: // Chris@16: // Mathematically undefined properties: Chris@16: // Chris@16: typedef typename detail::find_arg, assert_undefined<> >::type assert_undefined_type; Chris@16: // Chris@16: // Max iterations: Chris@16: // Chris@16: typedef typename detail::find_arg, max_series_iterations<> >::type max_series_iterations_type; Chris@16: typedef typename detail::find_arg, max_root_iterations<> >::type max_root_iterations_type; Chris@16: }; Chris@16: // Chris@16: // These full specializations are defined to reduce the amount of Chris@16: // template instantiations that have to take place when using the default Chris@16: // policies, they have quite a large impact on compile times: Chris@16: // Chris@16: template <> Chris@16: struct policy Chris@16: { Chris@16: public: Chris@16: typedef domain_error<> domain_error_type; Chris@16: typedef pole_error<> pole_error_type; Chris@16: typedef overflow_error<> overflow_error_type; Chris@16: typedef underflow_error<> underflow_error_type; Chris@16: typedef denorm_error<> denorm_error_type; Chris@16: typedef evaluation_error<> evaluation_error_type; Chris@16: typedef rounding_error<> rounding_error_type; Chris@16: typedef indeterminate_result_error<> indeterminate_result_error_type; Chris@16: #if BOOST_MATH_DIGITS10_POLICY == 0 Chris@16: typedef digits2<> precision_type; Chris@16: #else Chris@16: typedef detail::precision, digits2<> >::type precision_type; Chris@16: #endif Chris@16: typedef promote_float<> promote_float_type; Chris@16: typedef promote_double<> promote_double_type; Chris@16: typedef discrete_quantile<> discrete_quantile_type; Chris@16: typedef assert_undefined<> assert_undefined_type; Chris@16: typedef max_series_iterations<> max_series_iterations_type; Chris@16: typedef max_root_iterations<> max_root_iterations_type; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct policy Chris@16: { Chris@16: public: Chris@16: typedef domain_error<> domain_error_type; Chris@16: typedef pole_error<> pole_error_type; Chris@16: typedef overflow_error<> overflow_error_type; Chris@16: typedef underflow_error<> underflow_error_type; Chris@16: typedef denorm_error<> denorm_error_type; Chris@16: typedef evaluation_error<> evaluation_error_type; Chris@16: typedef rounding_error<> rounding_error_type; Chris@16: typedef indeterminate_result_error<> indeterminate_result_error_type; Chris@16: #if BOOST_MATH_DIGITS10_POLICY == 0 Chris@16: typedef digits2<> precision_type; Chris@16: #else Chris@16: typedef detail::precision, digits2<> >::type precision_type; Chris@16: #endif Chris@16: typedef promote_float promote_float_type; Chris@16: typedef promote_double promote_double_type; Chris@16: typedef discrete_quantile<> discrete_quantile_type; Chris@16: typedef assert_undefined<> assert_undefined_type; Chris@16: typedef max_series_iterations<> max_series_iterations_type; Chris@16: typedef max_root_iterations<> max_root_iterations_type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct normalise Chris@16: { Chris@16: private: Chris@16: typedef mpl::list arg_list; Chris@16: typedef typename detail::find_arg, typename Policy::domain_error_type >::type domain_error_type; Chris@16: typedef typename detail::find_arg, typename Policy::pole_error_type >::type pole_error_type; Chris@16: typedef typename detail::find_arg, typename Policy::overflow_error_type >::type overflow_error_type; Chris@16: typedef typename detail::find_arg, typename Policy::underflow_error_type >::type underflow_error_type; Chris@16: typedef typename detail::find_arg, typename Policy::denorm_error_type >::type denorm_error_type; Chris@16: typedef typename detail::find_arg, typename Policy::evaluation_error_type >::type evaluation_error_type; Chris@16: typedef typename detail::find_arg, typename Policy::rounding_error_type >::type rounding_error_type; Chris@16: typedef typename detail::find_arg, typename Policy::indeterminate_result_error_type >::type indeterminate_result_error_type; Chris@16: // Chris@16: // Now work out the precision: Chris@16: // Chris@16: typedef typename detail::find_arg, digits10<> >::type digits10_type; Chris@16: typedef typename detail::find_arg, typename Policy::precision_type >::type bits_precision_type; Chris@16: typedef typename detail::precision::type precision_type; Chris@16: // Chris@16: // Internal promotion: Chris@16: // Chris@16: typedef typename detail::find_arg, typename Policy::promote_float_type >::type promote_float_type; Chris@16: typedef typename detail::find_arg, typename Policy::promote_double_type >::type promote_double_type; Chris@16: // Chris@16: // Discrete quantiles: Chris@16: // Chris@16: typedef typename detail::find_arg, typename Policy::discrete_quantile_type >::type discrete_quantile_type; Chris@16: // Chris@16: // Mathematically undefined properties: Chris@16: // Chris@16: typedef typename detail::find_arg, typename Policy::assert_undefined_type >::type assert_undefined_type; Chris@16: // Chris@16: // Max iterations: Chris@16: // Chris@16: typedef typename detail::find_arg, typename Policy::max_series_iterations_type>::type max_series_iterations_type; Chris@16: typedef typename detail::find_arg, typename Policy::max_root_iterations_type>::type max_root_iterations_type; Chris@16: // Chris@16: // Define a typelist of the policies: Chris@16: // Chris@16: typedef mpl::vector< Chris@16: domain_error_type, Chris@16: pole_error_type, Chris@16: overflow_error_type, Chris@16: underflow_error_type, Chris@16: denorm_error_type, Chris@16: evaluation_error_type, Chris@16: rounding_error_type, Chris@16: indeterminate_result_error_type, Chris@16: precision_type, Chris@16: promote_float_type, Chris@16: promote_double_type, Chris@16: discrete_quantile_type, Chris@16: assert_undefined_type, Chris@16: max_series_iterations_type, Chris@16: max_root_iterations_type> result_list; Chris@16: // Chris@16: // Remove all the policies that are the same as the default: Chris@16: // Chris@16: typedef typename mpl::remove_if >::type reduced_list; Chris@16: // Chris@16: // Pad out the list with defaults: Chris@16: // Chris@16: typedef typename detail::append_N::value)>::type result_type; Chris@16: public: Chris@16: typedef policy< Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type, Chris@16: typename mpl::at >::type > type; Chris@16: }; Chris@16: // Chris@16: // Full specialisation to speed up compilation of the common case: Chris@16: // Chris@16: template <> Chris@16: struct normalise, Chris@16: promote_float, Chris@16: promote_double, Chris@16: discrete_quantile<>, Chris@16: assert_undefined<>, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy> Chris@16: { Chris@16: typedef policy type; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct normalise, Chris@16: promote_float, Chris@16: promote_double, Chris@16: discrete_quantile<>, Chris@16: assert_undefined<>, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy, Chris@16: default_policy> Chris@16: { Chris@16: typedef policy type; Chris@16: }; Chris@16: Chris@16: inline policy<> make_policy() Chris@16: { return policy<>(); } Chris@16: Chris@16: template Chris@16: inline typename normalise, A1>::type make_policy(const A1&) Chris@16: { Chris@16: typedef typename normalise, A1>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, A1, A2>::type make_policy(const A1&, const A2&) Chris@16: { Chris@16: typedef typename normalise, A1, A2>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, A1, A2, A3>::type make_policy(const A1&, const A2&, const A3&) Chris@16: { Chris@16: typedef typename normalise, A1, A2, A3>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, A1, A2, A3, A4>::type make_policy(const A1&, const A2&, const A3&, const A4&) Chris@16: { Chris@16: typedef typename normalise, A1, A2, A3, A4>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, A1, A2, A3, A4, A5>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&) Chris@16: { Chris@16: typedef typename normalise, A1, A2, A3, A4, A5>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&) Chris@16: { Chris@16: typedef typename normalise, A1, A2, A3, A4, A5, A6>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, A1, A2, A3, A4, A5, A6, A7>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&) Chris@16: { Chris@16: typedef typename normalise, A1, A2, A3, A4, A5, A6, A7>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, 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&) Chris@16: { Chris@16: typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, 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&) Chris@16: { Chris@16: typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, 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&) Chris@16: { Chris@16: typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&, const A11&) Chris@16: { Chris@16: typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type result_type; Chris@16: return result_type(); Chris@16: } Chris@16: Chris@16: // Chris@16: // Traits class to handle internal promotion: Chris@16: // Chris@16: template Chris@16: struct evaluation Chris@16: { Chris@16: typedef Real type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct evaluation Chris@16: { Chris@16: typedef typename mpl::if_::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct evaluation Chris@16: { Chris@16: typedef typename mpl::if_::type type; Chris@16: }; Chris@16: Chris@16: #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS Chris@16: Chris@16: template Chris@16: struct basic_digits : public mpl::int_<0>{ }; Chris@16: template <> Chris@16: struct basic_digits : public mpl::int_{ }; Chris@16: template <> Chris@16: struct basic_digits : public mpl::int_{ }; Chris@16: template <> Chris@16: struct basic_digits : public mpl::int_{ }; Chris@16: Chris@16: template Chris@16: struct precision Chris@16: { Chris@16: BOOST_STATIC_ASSERT( ::std::numeric_limits::radix == 2); Chris@16: typedef typename Policy::precision_type precision_type; Chris@16: typedef basic_digits digits_t; Chris@16: typedef typename mpl::if_< Chris@16: mpl::equal_to >, Chris@16: // Possibly unknown precision: Chris@16: precision_type, Chris@16: typename mpl::if_< Chris@16: mpl::or_, mpl::less_equal > >, Chris@16: // Default case, full precision for RealType: Chris@16: digits2< ::std::numeric_limits::digits>, Chris@16: // User customised precision: Chris@16: precision_type Chris@16: >::type Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct precision Chris@16: { Chris@16: typedef digits2 type; Chris@16: }; Chris@16: template Chris@16: struct precision Chris@16: { Chris@16: typedef digits2 type; Chris@16: }; Chris@16: template Chris@16: struct precision Chris@16: { Chris@16: typedef digits2 type; Chris@16: }; Chris@16: Chris@16: #else Chris@16: Chris@16: template Chris@16: struct precision Chris@16: { Chris@16: BOOST_STATIC_ASSERT((::std::numeric_limits::radix == 2) || ((::std::numeric_limits::is_specialized == 0) || (::std::numeric_limits::digits == 0))); Chris@16: #ifndef __BORLANDC__ Chris@16: typedef typename Policy::precision_type precision_type; Chris@16: typedef typename mpl::if_c< Chris@16: ((::std::numeric_limits::is_specialized == 0) || (::std::numeric_limits::digits == 0)), Chris@16: // Possibly unknown precision: Chris@16: precision_type, Chris@16: typename mpl::if_c< Chris@16: ((::std::numeric_limits::digits <= precision_type::value) Chris@16: || (Policy::precision_type::value <= 0)), Chris@16: // Default case, full precision for RealType: Chris@16: digits2< ::std::numeric_limits::digits>, Chris@16: // User customised precision: Chris@16: precision_type Chris@16: >::type Chris@16: >::type type; Chris@16: #else Chris@16: typedef typename Policy::precision_type precision_type; Chris@16: typedef mpl::int_< ::std::numeric_limits::digits> digits_t; Chris@16: typedef mpl::bool_< ::std::numeric_limits::is_specialized> spec_t; Chris@16: typedef typename mpl::if_< Chris@16: mpl::or_, mpl::equal_to > >, Chris@16: // Possibly unknown precision: Chris@16: precision_type, Chris@16: typename mpl::if_< Chris@16: mpl::or_, mpl::less_equal > >, Chris@16: // Default case, full precision for RealType: Chris@16: digits2< ::std::numeric_limits::digits>, Chris@16: // User customised precision: Chris@16: precision_type Chris@16: >::type Chris@16: >::type type; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: #endif Chris@16: Chris@16: #ifdef BOOST_MATH_USE_FLOAT128 Chris@16: Chris@16: template Chris@101: struct precision Chris@16: { Chris@16: typedef mpl::int_<113> type; Chris@16: }; Chris@16: Chris@16: #endif Chris@16: Chris@16: namespace detail{ Chris@16: Chris@16: template Chris@16: inline int digits_imp(mpl::true_ const&) Chris@16: { Chris@16: #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS Chris@16: BOOST_STATIC_ASSERT( ::std::numeric_limits::is_specialized); Chris@16: #else Chris@16: BOOST_ASSERT(::std::numeric_limits::is_specialized); Chris@16: #endif Chris@16: typedef typename boost::math::policies::precision::type p_t; Chris@16: return p_t::value; Chris@16: } Chris@16: Chris@16: template Chris@16: inline int digits_imp(mpl::false_ const&) Chris@16: { Chris@16: return tools::digits(); Chris@16: } Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: template Chris@16: inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) Chris@16: { Chris@16: typedef mpl::bool_< std::numeric_limits::is_specialized > tag_type; Chris@16: return detail::digits_imp(tag_type()); Chris@16: } Chris@101: template Chris@101: inline int digits_base10(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) Chris@101: { Chris@101: return boost::math::policies::digits() * 301 / 1000L; Chris@101: } Chris@16: Chris@16: template Chris@16: inline unsigned long get_max_series_iterations() Chris@16: { Chris@16: typedef typename Policy::max_series_iterations_type iter_type; Chris@16: return iter_type::value; Chris@16: } Chris@16: Chris@16: template Chris@16: inline unsigned long get_max_root_iterations() Chris@16: { Chris@16: typedef typename Policy::max_root_iterations_type iter_type; Chris@16: return iter_type::value; Chris@16: } Chris@16: Chris@16: namespace detail{ Chris@16: Chris@16: template Chris@16: struct series_factor_calc Chris@16: { Chris@16: static T get() Chris@16: { Chris@16: return ldexp(T(1.0), 1 - Digits::value); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct series_factor_calc Chris@16: { Chris@16: static T get() Chris@16: { Chris@16: return boost::math::tools::epsilon(); Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct series_factor_calc Chris@16: { Chris@16: static T get() Chris@16: { Chris@16: static const boost::uintmax_t v = static_cast(1u) << (Digits::value - 1); Chris@16: return 1 / static_cast(v); Chris@16: } Chris@16: }; Chris@16: template Chris@16: struct series_factor_calc Chris@16: { Chris@16: static T get() Chris@16: { Chris@16: return boost::math::tools::epsilon(); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: inline T get_epsilon_imp(mpl::true_ const&) Chris@16: { Chris@16: #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS Chris@16: BOOST_STATIC_ASSERT( ::std::numeric_limits::is_specialized); Chris@16: BOOST_STATIC_ASSERT( ::std::numeric_limits::radix == 2); Chris@16: #else Chris@16: BOOST_ASSERT(::std::numeric_limits::is_specialized); Chris@16: BOOST_ASSERT(::std::numeric_limits::radix == 2); Chris@16: #endif Chris@16: typedef typename boost::math::policies::precision::type p_t; Chris@16: typedef mpl::bool_::digits> is_small_int; Chris@16: typedef mpl::bool_= std::numeric_limits::digits> is_default_value; Chris@16: return series_factor_calc::get(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline T get_epsilon_imp(mpl::false_ const&) Chris@16: { Chris@16: return tools::epsilon(); Chris@16: } Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: template Chris@16: inline T get_epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) Chris@16: { Chris@16: typedef mpl::bool_< (std::numeric_limits::is_specialized && (std::numeric_limits::radix == 2)) > tag_type; Chris@16: return detail::get_epsilon_imp(tag_type()); Chris@16: } Chris@16: Chris@16: namespace detail{ Chris@16: Chris@16: template Chris@16: char test_is_policy(const policy*); Chris@16: double test_is_policy(...); Chris@16: Chris@16: template Chris@16: struct is_policy_imp Chris@16: { Chris@16: BOOST_STATIC_CONSTANT(bool, value = (sizeof(::boost::math::policies::detail::test_is_policy(static_cast(0))) == 1)); Chris@16: }; Chris@16: Chris@16: } Chris@16: Chris@16: template Chris@16: struct is_policy : public mpl::bool_< ::boost::math::policies::detail::is_policy_imp

::value> {}; Chris@16: Chris@16: // Chris@16: // Helper traits class for distribution error handling: Chris@16: // Chris@16: template Chris@16: struct constructor_error_check Chris@16: { Chris@16: typedef typename Policy::domain_error_type domain_error_type; Chris@16: typedef typename mpl::if_c< Chris@16: (domain_error_type::value == throw_on_error) || (domain_error_type::value == user_error), Chris@16: mpl::true_, Chris@16: mpl::false_>::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct method_error_check Chris@16: { Chris@16: typedef typename Policy::domain_error_type domain_error_type; Chris@16: typedef typename mpl::if_c< Chris@16: (domain_error_type::value == throw_on_error) && (domain_error_type::value != user_error), Chris@16: mpl::false_, Chris@16: mpl::true_>::type type; Chris@16: }; Chris@16: Chris@16: }}} // namespaces Chris@16: Chris@16: #endif // BOOST_MATH_POLICY_HPP Chris@16: Chris@16: Chris@16: