| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038 | //  Copyright John Maddock 2007.//  Use, modification and distribution are subject to the//  Boost Software License, Version 1.0. (See accompanying file//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)#ifndef BOOST_MATH_POLICY_HPP#define BOOST_MATH_POLICY_HPP#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/mpl/comparison.hpp>#include <boost/type_traits/is_same.hpp>#include <boost/static_assert.hpp>#include <boost/assert.hpp>#include <boost/math/tools/config.hpp>#include <limits>// Sadly we do need the .h versions of these to be sure of getting// FLT_MANT_DIG etc.#include <limits.h>#include <stdlib.h>#include <stddef.h>#include <math.h>namespace boost{ namespace math{ namespace tools{template <class T>BOOST_MATH_CONSTEXPR int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_NOEXCEPT;template <class T>BOOST_MATH_CONSTEXPR T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T);}namespace policies{//// Define macros for our default policies, if they're not defined already://// Special cases for exceptions disabled first://#ifdef BOOST_NO_EXCEPTIONS#  ifndef BOOST_MATH_DOMAIN_ERROR_POLICY#    define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error#  endif#  ifndef BOOST_MATH_POLE_ERROR_POLICY#     define BOOST_MATH_POLE_ERROR_POLICY errno_on_error#  endif#  ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY#     define BOOST_MATH_OVERFLOW_ERROR_POLICY errno_on_error#  endif#  ifndef BOOST_MATH_EVALUATION_ERROR_POLICY#     define BOOST_MATH_EVALUATION_ERROR_POLICY errno_on_error#  endif#  ifndef BOOST_MATH_ROUNDING_ERROR_POLICY#     define BOOST_MATH_ROUNDING_ERROR_POLICY errno_on_error#  endif#endif//// Then the regular cases://#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_ROUNDING_ERROR_POLICY#define BOOST_MATH_ROUNDING_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_INDETERMINATE_RESULT_ERROR_POLICY#define BOOST_MATH_INDETERMINATE_RESULT_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#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS#define BOOST_MATH_PROMOTE_DOUBLE_POLICY false#else#define BOOST_MATH_PROMOTE_DOUBLE_POLICY true#endif#endif#ifndef BOOST_MATH_DISCRETE_QUANTILE_POLICY#define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards#endif#ifndef BOOST_MATH_ASSERT_UNDEFINED_POLICY#define BOOST_MATH_ASSERT_UNDEFINED_POLICY true#endif#ifndef BOOST_MATH_MAX_SERIES_ITERATION_POLICY#define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000#endif#ifndef BOOST_MATH_MAX_ROOT_ITERATION_POLICY#define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200#endif#if !defined(__BORLANDC__)#define BOOST_MATH_META_INT(type, name, Default)\   template <type N = Default> struct name : public boost::integral_constant<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::integral_constant<bool, ::boost::math::policies::detail::is_##name##_imp<T>::value>{};#define BOOST_MATH_META_BOOL(name, Default)\   template <bool N = Default> struct name : public boost::integral_constant<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::integral_constant<bool, ::boost::math::policies::detail::is_##name##_imp<T>::value>{};#else#define BOOST_MATH_META_INT(Type, name, Default)\   template <Type N = Default> struct name : public boost::integral_constant<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( ::boost::math::policies::detail::is_##name##_tester<T>::test(inst)) == 1);\   };\   }\   template <class T> struct is_##name : public boost::integral_constant<bool, ::boost::math::policies::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::integral_constant<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( ::boost::math::policies::detail::is_##name##_tester<T>::test(inst)) == 1);\   };\   }\   template <class T> struct is_##name : public boost::integral_constant<bool, ::boost::math::policies::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)BOOST_MATH_META_INT(error_policy_type, rounding_error, BOOST_MATH_ROUNDING_ERROR_POLICY)BOOST_MATH_META_INT(error_policy_type, indeterminate_result_error, BOOST_MATH_INDETERMINATE_RESULT_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)BOOST_MATH_META_BOOL(assert_undefined, BOOST_MATH_ASSERT_UNDEFINED_POLICY)//// Policy types for discrete quantiles://enum discrete_quantile_policy_type{   real,   integer_round_outwards,   integer_round_inwards,   integer_round_down,   integer_round_up,   integer_round_nearest};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)//// Iterations://BOOST_MATH_META_INT(unsigned long, max_series_iterations, BOOST_MATH_MAX_SERIES_ITERATION_POLICY)BOOST_MATH_META_INT(unsigned long, max_root_iterations, BOOST_MATH_MAX_ROOT_ITERATION_POLICY)//// 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::policies::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(::boost::math::policies::detail::test_is_valid_arg(static_cast<T*>(0))) == 1);};template <class T>struct is_default_policy_imp{   BOOST_STATIC_CONSTANT(bool, value = sizeof(::boost::math::policies::detail::test_is_default_arg(static_cast<T*>(0))) == 1);};template <class T> struct is_valid_policy : public boost::integral_constant<bool, ::boost::math::policies::detail::is_valid_policy_imp<T>::value>{};template <class T> struct is_default_policy : public boost::integral_constant<bool, ::boost::math::policies::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,          class A12 = default_policy,          class A13 = default_policy>struct policy{private:   //   // Validate all our arguments:   //   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A1>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A2>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A3>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A4>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A5>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A6>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A7>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A8>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A9>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A10>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A11>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A12>::value);   BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A13>::value);   //   // Typelist of the arguments:   //   typedef mpl::list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13> 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;   typedef typename detail::find_arg<arg_list, is_rounding_error<mpl::_1>, rounding_error<> >::type rounding_error_type;   typedef typename detail::find_arg<arg_list, is_indeterminate_result_error<mpl::_1>, indeterminate_result_error<> >::type indeterminate_result_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 promote_float_type;   typedef typename detail::find_arg<arg_list, is_promote_double<mpl::_1>, promote_double<> >::type promote_double_type;   //   // Discrete quantiles:   //   typedef typename detail::find_arg<arg_list, is_discrete_quantile<mpl::_1>, discrete_quantile<> >::type discrete_quantile_type;   //   // Mathematically undefined properties:   //   typedef typename detail::find_arg<arg_list, is_assert_undefined<mpl::_1>, assert_undefined<> >::type assert_undefined_type;   //   // Max iterations:   //   typedef typename detail::find_arg<arg_list, is_max_series_iterations<mpl::_1>, max_series_iterations<> >::type max_series_iterations_type;   typedef typename detail::find_arg<arg_list, is_max_root_iterations<mpl::_1>, max_root_iterations<> >::type max_root_iterations_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;   typedef rounding_error<> rounding_error_type;   typedef indeterminate_result_error<> indeterminate_result_error_type;#if BOOST_MATH_DIGITS10_POLICY == 0   typedef digits2<> precision_type;#else   typedef detail::precision<digits10<>, digits2<> >::type precision_type;#endif   typedef promote_float<> promote_float_type;   typedef promote_double<> promote_double_type;   typedef discrete_quantile<> discrete_quantile_type;   typedef assert_undefined<> assert_undefined_type;   typedef max_series_iterations<> max_series_iterations_type;   typedef max_root_iterations<> max_root_iterations_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;   typedef rounding_error<> rounding_error_type;   typedef indeterminate_result_error<> indeterminate_result_error_type;#if BOOST_MATH_DIGITS10_POLICY == 0   typedef digits2<> precision_type;#else   typedef detail::precision<digits10<>, digits2<> >::type precision_type;#endif   typedef promote_float<false> promote_float_type;   typedef promote_double<false> promote_double_type;   typedef discrete_quantile<> discrete_quantile_type;   typedef assert_undefined<> assert_undefined_type;   typedef max_series_iterations<> max_series_iterations_type;   typedef max_root_iterations<> max_root_iterations_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,          class A12 = default_policy,          class A13 = default_policy>struct normalise{private:   typedef mpl::list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13> 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;   typedef typename detail::find_arg<arg_list, is_rounding_error<mpl::_1>, typename Policy::rounding_error_type >::type rounding_error_type;   typedef typename detail::find_arg<arg_list, is_indeterminate_result_error<mpl::_1>, typename Policy::indeterminate_result_error_type >::type indeterminate_result_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::promote_float_type >::type promote_float_type;   typedef typename detail::find_arg<arg_list, is_promote_double<mpl::_1>, typename Policy::promote_double_type >::type promote_double_type;   //   // Discrete quantiles:   //   typedef typename detail::find_arg<arg_list, is_discrete_quantile<mpl::_1>, typename Policy::discrete_quantile_type >::type discrete_quantile_type;   //   // Mathematically undefined properties:   //   typedef typename detail::find_arg<arg_list, is_assert_undefined<mpl::_1>, typename Policy::assert_undefined_type >::type assert_undefined_type;   //   // Max iterations:   //   typedef typename detail::find_arg<arg_list, is_max_series_iterations<mpl::_1>, typename Policy::max_series_iterations_type>::type max_series_iterations_type;   typedef typename detail::find_arg<arg_list, is_max_root_iterations<mpl::_1>, typename Policy::max_root_iterations_type>::type max_root_iterations_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,      rounding_error_type,      indeterminate_result_error_type,      precision_type,      promote_float_type,      promote_double_type,      discrete_quantile_type,      assert_undefined_type,      max_series_iterations_type,      max_root_iterations_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, (14 - ::boost::mpl::size<reduced_list>::value)>::type result_type;public:   typedef policy<      typename mpl::at<result_type, boost::integral_constant<int, 0> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 1> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 2> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 3> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 4> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 5> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 6> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 7> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 8> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 9> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 10> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 11> >::type,      typename mpl::at<result_type, boost::integral_constant<int, 12> >::type > type;};//// Full specialisation to speed up compilation of the common case://template <>struct normalise<policy<>,           promote_float<false>,           promote_double<false>,           discrete_quantile<>,          assert_undefined<>,          default_policy,          default_policy,          default_policy,          default_policy,          default_policy,          default_policy,          default_policy>{   typedef policy<detail::forwarding_arg1, detail::forwarding_arg2> type;};template <>struct normalise<policy<detail::forwarding_arg1, detail::forwarding_arg2>,          promote_float<false>,          promote_double<false>,          discrete_quantile<>,          assert_undefined<>,          default_policy,          default_policy,          default_policy,          default_policy,          default_policy,          default_policy,          default_policy>{   typedef policy<detail::forwarding_arg1, detail::forwarding_arg2> type;};inline BOOST_MATH_CONSTEXPR policy<> make_policy() BOOST_NOEXCEPT{ return policy<>(); }template <class A1>inline BOOST_MATH_CONSTEXPR typename normalise<policy<>, A1>::type make_policy(const A1&) BOOST_NOEXCEPT{    typedef typename normalise<policy<>, A1>::type result_type;   return result_type(); }template <class A1, class A2>inline BOOST_MATH_CONSTEXPR typename normalise<policy<>, A1, A2>::type make_policy(const A1&, const A2&) BOOST_NOEXCEPT{    typedef typename normalise<policy<>, A1, A2>::type result_type;   return result_type(); }template <class A1, class A2, class A3>inline BOOST_MATH_CONSTEXPR typename normalise<policy<>, A1, A2, A3>::type make_policy(const A1&, const A2&, const A3&) BOOST_NOEXCEPT{    typedef typename normalise<policy<>, A1, A2, A3>::type result_type;   return result_type(); }template <class A1, class A2, class A3, class A4>inline BOOST_MATH_CONSTEXPR typename normalise<policy<>, A1, A2, A3, A4>::type make_policy(const A1&, const A2&, const A3&, const A4&) BOOST_NOEXCEPT{    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 BOOST_MATH_CONSTEXPR typename normalise<policy<>, A1, A2, A3, A4, A5>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&) BOOST_NOEXCEPT{    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 BOOST_MATH_CONSTEXPR typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&) BOOST_NOEXCEPT{    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 BOOST_MATH_CONSTEXPR 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&) BOOST_NOEXCEPT{    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 BOOST_MATH_CONSTEXPR 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&) BOOST_NOEXCEPT{    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 BOOST_MATH_CONSTEXPR 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&) BOOST_NOEXCEPT{    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 BOOST_MATH_CONSTEXPR 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&) BOOST_NOEXCEPT{    typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::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, class A11>inline BOOST_MATH_CONSTEXPR typename normalise<policy<>, 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&) BOOST_NOEXCEPT{   typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::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::promote_float_type, double, float>::type type;};template <class Policy>struct evaluation<double, Policy>{   typedef typename mpl::if_<typename Policy::promote_double_type, long double, double>::type type;};#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTStemplate <class Real>struct basic_digits : public boost::integral_constant<int, 0>{ };template <>struct basic_digits<float> : public boost::integral_constant<int, FLT_MANT_DIG>{ };template <>struct basic_digits<double> : public boost::integral_constant<int, DBL_MANT_DIG>{ };template <>struct basic_digits<long double> : public boost::integral_constant<int, LDBL_MANT_DIG>{ };template <class Real, class Policy>struct precision{   BOOST_STATIC_ASSERT( ::std::numeric_limits<Real>::radix == 2);   typedef typename Policy::precision_type precision_type;   typedef basic_digits<Real> digits_t;   typedef typename mpl::if_<      mpl::equal_to<digits_t, boost::integral_constant<int, 0> >,      // Possibly unknown precision:      precision_type,      typename mpl::if_<         mpl::or_<mpl::less_equal<digits_t, precision_type>, mpl::less_equal<precision_type, boost::integral_constant<int, 0> > >,         // Default case, full precision for RealType:         digits2< ::std::numeric_limits<Real>::digits>,         // User customised precision:         precision_type      >::type   >::type type;};template <class Policy>struct precision<float, Policy>{   typedef digits2<FLT_MANT_DIG> type;};template <class Policy>struct precision<double, Policy>{   typedef digits2<DBL_MANT_DIG> type;};template <class Policy>struct precision<long double, Policy>{   typedef digits2<LDBL_MANT_DIG> type;};#elsetemplate <class Real, class Policy>struct precision{   BOOST_STATIC_ASSERT((::std::numeric_limits<Real>::radix == 2) || ((::std::numeric_limits<Real>::is_specialized == 0) || (::std::numeric_limits<Real>::digits == 0)));#ifndef __BORLANDC__   typedef typename Policy::precision_type precision_type;   typedef typename mpl::if_c<      ((::std::numeric_limits<Real>::is_specialized == 0) || (::std::numeric_limits<Real>::digits == 0)),      // Possibly unknown precision:      precision_type,      typename mpl::if_c<         ((::std::numeric_limits<Real>::digits <= precision_type::value)          || (Policy::precision_type::value <= 0)),         // Default case, full precision for RealType:         digits2< ::std::numeric_limits<Real>::digits>,         // User customised precision:         precision_type      >::type   >::type type;#else   typedef typename Policy::precision_type precision_type;   typedef boost::integral_constant<int, ::std::numeric_limits<Real>::digits> digits_t;   typedef boost::integral_constant<bool, ::std::numeric_limits<Real>::is_specialized> spec_t;   typedef typename mpl::if_<      mpl::or_<mpl::equal_to<spec_t, boost::true_type>, mpl::equal_to<digits_t, boost::integral_constant<int, 0> > >,      // Possibly unknown precision:      precision_type,      typename mpl::if_<         mpl::or_<mpl::less_equal<digits_t, precision_type>, mpl::less_equal<precision_type, boost::integral_constant<int, 0> > >,         // Default case, full precision for RealType:         digits2< ::std::numeric_limits<Real>::digits>,         // User customised precision:         precision_type      >::type   >::type type;#endif};#endif#ifdef BOOST_MATH_USE_FLOAT128template <class Policy>struct precision<BOOST_MATH_FLOAT128_TYPE, Policy>{   typedef boost::integral_constant<int, 113> type;};#endifnamespace detail{template <class T, class Policy>inline BOOST_MATH_CONSTEXPR int digits_imp(boost::true_type const&) BOOST_NOEXCEPT{#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS   BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);#else   BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);#endif   typedef typename boost::math::policies::precision<T, Policy>::type p_t;   return p_t::value;}template <class T, class Policy>inline BOOST_MATH_CONSTEXPR int digits_imp(boost::false_type const&) BOOST_NOEXCEPT{   return tools::digits<T>();}} // namespace detailtemplate <class T, class Policy>inline BOOST_MATH_CONSTEXPR int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_NOEXCEPT{   typedef boost::integral_constant<bool, std::numeric_limits<T>::is_specialized > tag_type;   return detail::digits_imp<T, Policy>(tag_type());}template <class T, class Policy>inline BOOST_MATH_CONSTEXPR int digits_base10(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_NOEXCEPT{   return boost::math::policies::digits<T, Policy>() * 301 / 1000L;}template <class Policy>inline BOOST_MATH_CONSTEXPR unsigned long get_max_series_iterations() BOOST_NOEXCEPT{   typedef typename Policy::max_series_iterations_type iter_type;   return iter_type::value;}template <class Policy>inline BOOST_MATH_CONSTEXPR unsigned long get_max_root_iterations() BOOST_NOEXCEPT{   typedef typename Policy::max_root_iterations_type iter_type;   return iter_type::value;}namespace detail{template <class T, class Digits, class Small, class Default>struct series_factor_calc{   static T get() BOOST_MATH_NOEXCEPT(T)   {      return ldexp(T(1.0), 1 - Digits::value);   }};template <class T, class Digits>struct series_factor_calc<T, Digits, boost::true_type, boost::true_type>{   static BOOST_MATH_CONSTEXPR T get() BOOST_MATH_NOEXCEPT(T)   {      return boost::math::tools::epsilon<T>();   }};template <class T, class Digits>struct series_factor_calc<T, Digits, boost::true_type, boost::false_type>{   static BOOST_MATH_CONSTEXPR T get() BOOST_MATH_NOEXCEPT(T)   {      return 1 / static_cast<T>(static_cast<boost::uintmax_t>(1u) << (Digits::value - 1));   }};template <class T, class Digits>struct series_factor_calc<T, Digits, boost::false_type, boost::true_type>{   static BOOST_MATH_CONSTEXPR T get() BOOST_MATH_NOEXCEPT(T)   {      return boost::math::tools::epsilon<T>();   }};template <class T, class Policy>inline BOOST_MATH_CONSTEXPR T get_epsilon_imp(boost::true_type const&) BOOST_MATH_NOEXCEPT(T){#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS   BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);   BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::radix == 2);#else   BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);   BOOST_ASSERT(::std::numeric_limits<T>::radix == 2);#endif   typedef typename boost::math::policies::precision<T, Policy>::type p_t;   typedef boost::integral_constant<bool, p_t::value <= std::numeric_limits<boost::uintmax_t>::digits> is_small_int;   typedef boost::integral_constant<bool, p_t::value >= std::numeric_limits<T>::digits> is_default_value;   return series_factor_calc<T, p_t, is_small_int, is_default_value>::get();}template <class T, class Policy>inline BOOST_MATH_CONSTEXPR T get_epsilon_imp(boost::false_type const&) BOOST_MATH_NOEXCEPT(T){   return tools::epsilon<T>();}} // namespace detailtemplate <class T, class Policy>inline BOOST_MATH_CONSTEXPR T get_epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T){   typedef boost::integral_constant<bool, (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::radix == 2)) > tag_type;   return detail::get_epsilon_imp<T, Policy>(tag_type());}namespace detail{template <class A1,           class A2,           class A3,          class A4,          class A5,          class A6,          class A7,          class A8,          class A9,          class A10,          class A11>char test_is_policy(const policy<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11>*);double test_is_policy(...);template <class P>struct is_policy_imp{   BOOST_STATIC_CONSTANT(bool, value = (sizeof(::boost::math::policies::detail::test_is_policy(static_cast<P*>(0))) == 1));};}template <class P>struct is_policy : public boost::integral_constant<bool, ::boost::math::policies::detail::is_policy_imp<P>::value> {};//// Helper traits class for distribution error handling://template <class Policy>struct constructor_error_check{   typedef typename Policy::domain_error_type domain_error_type;   typedef typename mpl::if_c<      (domain_error_type::value == throw_on_error) || (domain_error_type::value == user_error) || (domain_error_type::value == errno_on_error),      boost::true_type,      boost::false_type>::type type;};template <class Policy>struct method_error_check{   typedef typename Policy::domain_error_type domain_error_type;   typedef typename mpl::if_c<      (domain_error_type::value == throw_on_error) && (domain_error_type::value != user_error),      boost::false_type,      boost::true_type>::type type;};//// Does the Policy ever throw on error?//template <class Policy>struct is_noexcept_error_policy{   typedef typename Policy::domain_error_type               t1;   typedef typename Policy::pole_error_type                 t2;   typedef typename Policy::overflow_error_type             t3;   typedef typename Policy::underflow_error_type            t4;   typedef typename Policy::denorm_error_type               t5;   typedef typename Policy::evaluation_error_type           t6;   typedef typename Policy::rounding_error_type             t7;   typedef typename Policy::indeterminate_result_error_type t8;   BOOST_STATIC_CONSTANT(bool, value =       ((t1::value != throw_on_error) && (t1::value != user_error)      && (t2::value != throw_on_error) && (t2::value != user_error)      && (t3::value != throw_on_error) && (t3::value != user_error)      && (t4::value != throw_on_error) && (t4::value != user_error)      && (t5::value != throw_on_error) && (t5::value != user_error)      && (t6::value != throw_on_error) && (t6::value != user_error)      && (t7::value != throw_on_error) && (t7::value != user_error)      && (t8::value != throw_on_error) && (t8::value != user_error)));};}}} // namespaces#endif // BOOST_MATH_POLICY_HPP
 |