1 // Copyright John Maddock 2007.
2 // Use, modification and distribution are subject to the
3 // Boost Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_MATH_POLICY_HPP
7 #define BOOST_MATH_POLICY_HPP
9 #include <boost/mpl/list.hpp>
10 #include <boost/mpl/contains.hpp>
11 #include <boost/mpl/if.hpp>
12 #include <boost/mpl/find_if.hpp>
13 #include <boost/mpl/remove_if.hpp>
14 #include <boost/mpl/vector.hpp>
15 #include <boost/mpl/push_back.hpp>
16 #include <boost/mpl/at.hpp>
17 #include <boost/mpl/size.hpp>
18 #include <boost/mpl/comparison.hpp>
19 #include <boost/type_traits/is_same.hpp>
20 #include <boost/static_assert.hpp>
21 #include <boost/assert.hpp>
22 #include <boost/math/tools/config.hpp>
24 // Sadly we do need the .h versions of these to be sure of getting
31 namespace boost{ namespace math{
36 int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T));
38 T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T));
45 // Define macros for our default policies, if they're not defined already:
47 #ifndef BOOST_MATH_DOMAIN_ERROR_POLICY
48 #define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error
50 #ifndef BOOST_MATH_POLE_ERROR_POLICY
51 #define BOOST_MATH_POLE_ERROR_POLICY throw_on_error
53 #ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY
54 #define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error
56 #ifndef BOOST_MATH_EVALUATION_ERROR_POLICY
57 #define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error
59 #ifndef BOOST_MATH_ROUNDING_ERROR_POLICY
60 #define BOOST_MATH_ROUNDING_ERROR_POLICY throw_on_error
62 #ifndef BOOST_MATH_UNDERFLOW_ERROR_POLICY
63 #define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error
65 #ifndef BOOST_MATH_DENORM_ERROR_POLICY
66 #define BOOST_MATH_DENORM_ERROR_POLICY ignore_error
68 #ifndef BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY
69 #define BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY ignore_error
71 #ifndef BOOST_MATH_DIGITS10_POLICY
72 #define BOOST_MATH_DIGITS10_POLICY 0
74 #ifndef BOOST_MATH_PROMOTE_FLOAT_POLICY
75 #define BOOST_MATH_PROMOTE_FLOAT_POLICY true
77 #ifndef BOOST_MATH_PROMOTE_DOUBLE_POLICY
78 #ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
79 #define BOOST_MATH_PROMOTE_DOUBLE_POLICY false
81 #define BOOST_MATH_PROMOTE_DOUBLE_POLICY true
84 #ifndef BOOST_MATH_DISCRETE_QUANTILE_POLICY
85 #define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards
87 #ifndef BOOST_MATH_ASSERT_UNDEFINED_POLICY
88 #define BOOST_MATH_ASSERT_UNDEFINED_POLICY true
90 #ifndef BOOST_MATH_MAX_SERIES_ITERATION_POLICY
91 #define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000
93 #ifndef BOOST_MATH_MAX_ROOT_ITERATION_POLICY
94 #define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200
97 #if !defined(__BORLANDC__) \
98 && !(defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ <= 2))
99 #define BOOST_MATH_META_INT(type, name, Default)\
100 template <type N = Default> struct name : public boost::mpl::int_<N>{};\
103 char test_is_valid_arg(const name<N>*);\
104 char test_is_default_arg(const name<Default>*);\
105 template <class T> struct is_##name##_imp\
107 template <type N> static char test(const name<N>*);\
108 static double test(...);\
109 BOOST_STATIC_CONSTANT(bool, value = sizeof(test(static_cast<T*>(0))) == 1);\
112 template <class T> struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp<T>::value>{};
114 #define BOOST_MATH_META_BOOL(name, Default)\
115 template <bool N = Default> struct name : public boost::mpl::bool_<N>{};\
118 char test_is_valid_arg(const name<N>*);\
119 char test_is_default_arg(const name<Default>*);\
120 template <class T> struct is_##name##_imp\
122 template <bool N> static char test(const name<N>*);\
123 static double test(...);\
124 BOOST_STATIC_CONSTANT(bool, value = sizeof(test(static_cast<T*>(0))) == 1);\
127 template <class T> struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp<T>::value>{};
129 #define BOOST_MATH_META_INT(Type, name, Default)\
130 template <Type N = Default> struct name : public boost::mpl::int_<N>{};\
133 char test_is_valid_arg(const name<N>*);\
134 char test_is_default_arg(const name<Default>*);\
135 template <class T> struct is_##name##_tester\
137 template <Type N> static char test(const name<N>&);\
138 static double test(...);\
140 template <class T> struct is_##name##_imp\
143 BOOST_STATIC_CONSTANT(bool, value = sizeof( ::boost::math::policies::detail::is_##name##_tester<T>::test(inst)) == 1);\
146 template <class T> struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp<T>::value>\
148 template <class U> struct apply{ typedef is_##name<U> type; };\
151 #define BOOST_MATH_META_BOOL(name, Default)\
152 template <bool N = Default> struct name : public boost::mpl::bool_<N>{};\
155 char test_is_valid_arg(const name<N>*);\
156 char test_is_default_arg(const name<Default>*);\
157 template <class T> struct is_##name##_tester\
159 template <bool N> static char test(const name<N>&);\
160 static double test(...);\
162 template <class T> struct is_##name##_imp\
165 BOOST_STATIC_CONSTANT(bool, value = sizeof( ::boost::math::policies::detail::is_##name##_tester<T>::test(inst)) == 1);\
168 template <class T> struct is_##name : public boost::mpl::bool_< ::boost::math::policies::detail::is_##name##_imp<T>::value>\
170 template <class U> struct apply{ typedef is_##name<U> type; };\
174 // Begin by defining policy types for error handling:
176 enum error_policy_type
184 BOOST_MATH_META_INT(error_policy_type, domain_error, BOOST_MATH_DOMAIN_ERROR_POLICY)
185 BOOST_MATH_META_INT(error_policy_type, pole_error, BOOST_MATH_POLE_ERROR_POLICY)
186 BOOST_MATH_META_INT(error_policy_type, overflow_error, BOOST_MATH_OVERFLOW_ERROR_POLICY)
187 BOOST_MATH_META_INT(error_policy_type, underflow_error, BOOST_MATH_UNDERFLOW_ERROR_POLICY)
188 BOOST_MATH_META_INT(error_policy_type, denorm_error, BOOST_MATH_DENORM_ERROR_POLICY)
189 BOOST_MATH_META_INT(error_policy_type, evaluation_error, BOOST_MATH_EVALUATION_ERROR_POLICY)
190 BOOST_MATH_META_INT(error_policy_type, rounding_error, BOOST_MATH_ROUNDING_ERROR_POLICY)
191 BOOST_MATH_META_INT(error_policy_type, indeterminate_result_error, BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY)
194 // Policy types for internal promotion:
196 BOOST_MATH_META_BOOL(promote_float, BOOST_MATH_PROMOTE_FLOAT_POLICY)
197 BOOST_MATH_META_BOOL(promote_double, BOOST_MATH_PROMOTE_DOUBLE_POLICY)
198 BOOST_MATH_META_BOOL(assert_undefined, BOOST_MATH_ASSERT_UNDEFINED_POLICY)
200 // Policy types for discrete quantiles:
202 enum discrete_quantile_policy_type
205 integer_round_outwards,
206 integer_round_inwards,
209 integer_round_nearest
212 BOOST_MATH_META_INT(discrete_quantile_policy_type, discrete_quantile, BOOST_MATH_DISCRETE_QUANTILE_POLICY)
216 BOOST_MATH_META_INT(int, digits10, BOOST_MATH_DIGITS10_POLICY)
217 BOOST_MATH_META_INT(int, digits2, 0)
221 BOOST_MATH_META_INT(unsigned long, max_series_iterations, BOOST_MATH_MAX_SERIES_ITERATION_POLICY)
222 BOOST_MATH_META_INT(unsigned long, max_root_iterations, BOOST_MATH_MAX_ROOT_ITERATION_POLICY)
224 // Define the names for each possible policy:
226 #define BOOST_MATH_PARAMETER(name)\
227 BOOST_PARAMETER_TEMPLATE_KEYWORD(name##_name)\
228 BOOST_PARAMETER_NAME(name##_name)
230 struct default_policy{};
234 // Trait to work out bits precision from digits10 and digits2:
236 template <class Digits10, class Digits2>
240 // Now work out the precision:
242 typedef typename mpl::if_c<
243 (Digits10::value == 0),
245 digits2<((Digits10::value + 1) * 1000L) / 301L>
246 >::type digits2_type;
249 typedef typename mpl::if_c<
250 (Digits2::value > ::boost::math::policies::detail::precision<Digits10,Digits2>::digits2_type::value),
251 Digits2, digits2_type>::type type;
253 typedef typename mpl::if_c<
254 (Digits2::value > digits2_type::value),
255 Digits2, digits2_type>::type type;
259 template <class A, class B, bool b>
264 template <class A, class B>
265 struct select_result<A, B, false>
267 typedef typename mpl::deref<B>::type type;
270 template <class Seq, class Pred, class DefaultType>
274 typedef typename mpl::find_if<Seq, Pred>::type iter;
275 typedef typename mpl::end<Seq>::type end_type;
277 typedef typename select_result<
279 ::boost::is_same<iter, end_type>::value>::type type;
282 double test_is_valid_arg(...);
283 double test_is_default_arg(...);
284 char test_is_valid_arg(const default_policy*);
285 char test_is_default_arg(const default_policy*);
288 struct is_valid_policy_imp
290 BOOST_STATIC_CONSTANT(bool, value = sizeof(::boost::math::policies::detail::test_is_valid_arg(static_cast<T*>(0))) == 1);
294 struct is_default_policy_imp
296 BOOST_STATIC_CONSTANT(bool, value = sizeof(::boost::math::policies::detail::test_is_default_arg(static_cast<T*>(0))) == 1);
299 template <class T> struct is_valid_policy
301 ::boost::math::policies::detail::is_valid_policy_imp<T>::value>
304 template <class T> struct is_default_policy
306 ::boost::math::policies::detail::is_default_policy_imp<T>::value>
311 typedef is_default_policy<U> type;
315 template <class Seq, class T, int N>
318 typedef typename mpl::push_back<Seq, T>::type new_seq;
319 typedef typename append_N<new_seq, T, N-1>::type type;
322 template <class Seq, class T>
323 struct append_N<Seq, T, 0>
329 // Traits class to work out what template parameters our default
330 // policy<> class will have when modified for forwarding:
332 template <bool f, bool d>
335 typedef promote_float<false> arg1;
336 typedef promote_double<false> arg2;
340 struct default_args<false, false>
342 typedef default_policy arg1;
343 typedef default_policy arg2;
347 struct default_args<true, false>
349 typedef promote_float<false> arg1;
350 typedef default_policy arg2;
354 struct default_args<false, true>
356 typedef promote_double<false> arg1;
357 typedef default_policy arg2;
360 typedef default_args<BOOST_MATH_PROMOTE_FLOAT_POLICY, BOOST_MATH_PROMOTE_DOUBLE_POLICY>::arg1 forwarding_arg1;
361 typedef default_args<BOOST_MATH_PROMOTE_FLOAT_POLICY, BOOST_MATH_PROMOTE_DOUBLE_POLICY>::arg2 forwarding_arg2;
365 // Now define the policy type with enough arguments to handle all
368 template <class A1 = default_policy,
369 class A2 = default_policy,
370 class A3 = default_policy,
371 class A4 = default_policy,
372 class A5 = default_policy,
373 class A6 = default_policy,
374 class A7 = default_policy,
375 class A8 = default_policy,
376 class A9 = default_policy,
377 class A10 = default_policy,
378 class A11 = default_policy,
379 class A12 = default_policy,
380 class A13 = default_policy>
385 // Validate all our arguments:
387 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A1>::value);
388 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A2>::value);
389 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A3>::value);
390 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A4>::value);
391 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A5>::value);
392 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A6>::value);
393 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A7>::value);
394 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A8>::value);
395 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A9>::value);
396 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A10>::value);
397 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A11>::value);
398 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A12>::value);
399 BOOST_STATIC_ASSERT(::boost::math::policies::detail::is_valid_policy<A13>::value);
401 // Typelist of the arguments:
403 typedef mpl::list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13> arg_list;
406 typedef typename detail::find_arg<arg_list, is_domain_error<mpl::_1>, domain_error<> >::type domain_error_type;
407 typedef typename detail::find_arg<arg_list, is_pole_error<mpl::_1>, pole_error<> >::type pole_error_type;
408 typedef typename detail::find_arg<arg_list, is_overflow_error<mpl::_1>, overflow_error<> >::type overflow_error_type;
409 typedef typename detail::find_arg<arg_list, is_underflow_error<mpl::_1>, underflow_error<> >::type underflow_error_type;
410 typedef typename detail::find_arg<arg_list, is_denorm_error<mpl::_1>, denorm_error<> >::type denorm_error_type;
411 typedef typename detail::find_arg<arg_list, is_evaluation_error<mpl::_1>, evaluation_error<> >::type evaluation_error_type;
412 typedef typename detail::find_arg<arg_list, is_rounding_error<mpl::_1>, rounding_error<> >::type rounding_error_type;
413 typedef typename detail::find_arg<arg_list, is_indeterminate_result_error<mpl::_1>, indeterminate_result_error<> >::type indeterminate_result_error_type;
416 // Now work out the precision:
418 typedef typename detail::find_arg<arg_list, is_digits10<mpl::_1>, digits10<> >::type digits10_type;
419 typedef typename detail::find_arg<arg_list, is_digits2<mpl::_1>, digits2<> >::type bits_precision_type;
421 typedef typename detail::precision<digits10_type, bits_precision_type>::type precision_type;
423 // Internal promotion:
425 typedef typename detail::find_arg<arg_list, is_promote_float<mpl::_1>, promote_float<> >::type promote_float_type;
426 typedef typename detail::find_arg<arg_list, is_promote_double<mpl::_1>, promote_double<> >::type promote_double_type;
428 // Discrete quantiles:
430 typedef typename detail::find_arg<arg_list, is_discrete_quantile<mpl::_1>, discrete_quantile<> >::type discrete_quantile_type;
432 // Mathematically undefined properties:
434 typedef typename detail::find_arg<arg_list, is_assert_undefined<mpl::_1>, discrete_quantile<> >::type assert_undefined_type;
438 typedef typename detail::find_arg<arg_list, is_max_series_iterations<mpl::_1>, max_series_iterations<> >::type max_series_iterations_type;
439 typedef typename detail::find_arg<arg_list, is_max_root_iterations<mpl::_1>, max_root_iterations<> >::type max_root_iterations_type;
442 // These full specializations are defined to reduce the amount of
443 // template instantiations that have to take place when using the default
444 // policies, they have quite a large impact on compile times:
447 struct policy<default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy, default_policy>
450 typedef domain_error<> domain_error_type;
451 typedef pole_error<> pole_error_type;
452 typedef overflow_error<> overflow_error_type;
453 typedef underflow_error<> underflow_error_type;
454 typedef denorm_error<> denorm_error_type;
455 typedef evaluation_error<> evaluation_error_type;
456 typedef rounding_error<> rounding_error_type;
457 typedef indeterminate_result_error<> indeterminate_result_error_type;
458 #if BOOST_MATH_DIGITS10_POLICY == 0
459 typedef digits2<> precision_type;
461 typedef detail::precision<digits10<>, digits2<> >::type precision_type;
463 typedef promote_float<> promote_float_type;
464 typedef promote_double<> promote_double_type;
465 typedef discrete_quantile<> discrete_quantile_type;
466 typedef assert_undefined<> assert_undefined_type;
467 typedef max_series_iterations<> max_series_iterations_type;
468 typedef max_root_iterations<> max_root_iterations_type;
472 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>
475 typedef domain_error<> domain_error_type;
476 typedef pole_error<> pole_error_type;
477 typedef overflow_error<> overflow_error_type;
478 typedef underflow_error<> underflow_error_type;
479 typedef denorm_error<> denorm_error_type;
480 typedef evaluation_error<> evaluation_error_type;
481 typedef rounding_error<> rounding_error_type;
482 typedef indeterminate_result_error<> indeterminate_result_error_type;
483 #if BOOST_MATH_DIGITS10_POLICY == 0
484 typedef digits2<> precision_type;
486 typedef detail::precision<digits10<>, digits2<> >::type precision_type;
488 typedef promote_float<false> promote_float_type;
489 typedef promote_double<false> promote_double_type;
490 typedef discrete_quantile<> discrete_quantile_type;
491 typedef assert_undefined<> assert_undefined_type;
492 typedef max_series_iterations<> max_series_iterations_type;
493 typedef max_root_iterations<> max_root_iterations_type;
496 template <class Policy,
497 class A1 = default_policy,
498 class A2 = default_policy,
499 class A3 = default_policy,
500 class A4 = default_policy,
501 class A5 = default_policy,
502 class A6 = default_policy,
503 class A7 = default_policy,
504 class A8 = default_policy,
505 class A9 = default_policy,
506 class A10 = default_policy,
507 class A11 = default_policy,
508 class A12 = default_policy,
509 class A13 = default_policy>
513 typedef mpl::list<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13> arg_list;
514 typedef typename detail::find_arg<arg_list, is_domain_error<mpl::_1>, typename Policy::domain_error_type >::type domain_error_type;
515 typedef typename detail::find_arg<arg_list, is_pole_error<mpl::_1>, typename Policy::pole_error_type >::type pole_error_type;
516 typedef typename detail::find_arg<arg_list, is_overflow_error<mpl::_1>, typename Policy::overflow_error_type >::type overflow_error_type;
517 typedef typename detail::find_arg<arg_list, is_underflow_error<mpl::_1>, typename Policy::underflow_error_type >::type underflow_error_type;
518 typedef typename detail::find_arg<arg_list, is_denorm_error<mpl::_1>, typename Policy::denorm_error_type >::type denorm_error_type;
519 typedef typename detail::find_arg<arg_list, is_evaluation_error<mpl::_1>, typename Policy::evaluation_error_type >::type evaluation_error_type;
520 typedef typename detail::find_arg<arg_list, is_rounding_error<mpl::_1>, typename Policy::rounding_error_type >::type rounding_error_type;
521 typedef typename detail::find_arg<arg_list, is_indeterminate_result_error<mpl::_1>, typename Policy::indeterminate_result_error_type >::type indeterminate_result_error_type;
523 // Now work out the precision:
525 typedef typename detail::find_arg<arg_list, is_digits10<mpl::_1>, digits10<> >::type digits10_type;
526 typedef typename detail::find_arg<arg_list, is_digits2<mpl::_1>, typename Policy::precision_type >::type bits_precision_type;
527 typedef typename detail::precision<digits10_type, bits_precision_type>::type precision_type;
529 // Internal promotion:
531 typedef typename detail::find_arg<arg_list, is_promote_float<mpl::_1>, typename Policy::promote_float_type >::type promote_float_type;
532 typedef typename detail::find_arg<arg_list, is_promote_double<mpl::_1>, typename Policy::promote_double_type >::type promote_double_type;
534 // Discrete quantiles:
536 typedef typename detail::find_arg<arg_list, is_discrete_quantile<mpl::_1>, typename Policy::discrete_quantile_type >::type discrete_quantile_type;
538 // Mathematically undefined properties:
540 typedef typename detail::find_arg<arg_list, is_assert_undefined<mpl::_1>, discrete_quantile<> >::type assert_undefined_type;
544 typedef typename detail::find_arg<arg_list, is_max_series_iterations<mpl::_1>, max_series_iterations<> >::type max_series_iterations_type;
545 typedef typename detail::find_arg<arg_list, is_max_root_iterations<mpl::_1>, max_root_iterations<> >::type max_root_iterations_type;
547 // Define a typelist of the policies:
553 underflow_error_type,
555 evaluation_error_type,
557 indeterminate_result_error_type,
561 discrete_quantile_type,
562 assert_undefined_type,
563 max_series_iterations_type,
564 max_root_iterations_type> result_list;
566 // Remove all the policies that are the same as the default:
568 typedef typename mpl::remove_if<result_list, detail::is_default_policy<mpl::_> >::type reduced_list;
570 // Pad out the list with defaults:
572 typedef typename detail::append_N<reduced_list, default_policy, (14 - ::boost::mpl::size<reduced_list>::value)>::type result_type;
575 typename mpl::at<result_type, mpl::int_<0> >::type,
576 typename mpl::at<result_type, mpl::int_<1> >::type,
577 typename mpl::at<result_type, mpl::int_<2> >::type,
578 typename mpl::at<result_type, mpl::int_<3> >::type,
579 typename mpl::at<result_type, mpl::int_<4> >::type,
580 typename mpl::at<result_type, mpl::int_<5> >::type,
581 typename mpl::at<result_type, mpl::int_<6> >::type,
582 typename mpl::at<result_type, mpl::int_<7> >::type,
583 typename mpl::at<result_type, mpl::int_<8> >::type,
584 typename mpl::at<result_type, mpl::int_<9> >::type,
585 typename mpl::at<result_type, mpl::int_<10> >::type,
586 typename mpl::at<result_type, mpl::int_<11> >::type,
587 typename mpl::at<result_type, mpl::int_<12> >::type > type;
590 // Full specialisation to speed up compilation of the common case:
593 struct normalise<policy<>,
594 promote_float<false>,
595 promote_double<false>,
606 typedef policy<detail::forwarding_arg1, detail::forwarding_arg2> type;
610 struct normalise<policy<detail::forwarding_arg1, detail::forwarding_arg2>,
611 promote_float<false>,
612 promote_double<false>,
623 typedef policy<detail::forwarding_arg1, detail::forwarding_arg2> type;
626 inline policy<> make_policy()
627 { return policy<>(); }
630 inline typename normalise<policy<>, A1>::type make_policy(const A1&)
632 typedef typename normalise<policy<>, A1>::type result_type;
633 return result_type();
636 template <class A1, class A2>
637 inline typename normalise<policy<>, A1, A2>::type make_policy(const A1&, const A2&)
639 typedef typename normalise<policy<>, A1, A2>::type result_type;
640 return result_type();
643 template <class A1, class A2, class A3>
644 inline typename normalise<policy<>, A1, A2, A3>::type make_policy(const A1&, const A2&, const A3&)
646 typedef typename normalise<policy<>, A1, A2, A3>::type result_type;
647 return result_type();
650 template <class A1, class A2, class A3, class A4>
651 inline typename normalise<policy<>, A1, A2, A3, A4>::type make_policy(const A1&, const A2&, const A3&, const A4&)
653 typedef typename normalise<policy<>, A1, A2, A3, A4>::type result_type;
654 return result_type();
657 template <class A1, class A2, class A3, class A4, class A5>
658 inline typename normalise<policy<>, A1, A2, A3, A4, A5>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&)
660 typedef typename normalise<policy<>, A1, A2, A3, A4, A5>::type result_type;
661 return result_type();
664 template <class A1, class A2, class A3, class A4, class A5, class A6>
665 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&)
667 typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6>::type result_type;
668 return result_type();
671 template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
672 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&)
674 typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7>::type result_type;
675 return result_type();
678 template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
679 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&)
681 typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8>::type result_type;
682 return result_type();
685 template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
686 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&)
688 typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type result_type;
689 return result_type();
692 template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
693 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&)
695 typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type result_type;
696 return result_type();
699 template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10, class A11>
700 inline 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&)
702 typedef typename normalise<policy<>, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type result_type;
703 return result_type();
707 // Traits class to handle internal promotion:
709 template <class Real, class Policy>
715 template <class Policy>
716 struct evaluation<float, Policy>
718 typedef typename mpl::if_<typename Policy::promote_float_type, double, float>::type type;
721 template <class Policy>
722 struct evaluation<double, Policy>
724 typedef typename mpl::if_<typename Policy::promote_double_type, long double, double>::type type;
727 #ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
729 template <class Real>
730 struct basic_digits : public mpl::int_<0>{ };
732 struct basic_digits<float> : public mpl::int_<FLT_MANT_DIG>{ };
734 struct basic_digits<double> : public mpl::int_<DBL_MANT_DIG>{ };
736 struct basic_digits<long double> : public mpl::int_<LDBL_MANT_DIG>{ };
738 template <class Real, class Policy>
741 BOOST_STATIC_ASSERT( ::std::numeric_limits<Real>::radix == 2);
742 typedef typename Policy::precision_type precision_type;
743 typedef basic_digits<Real> digits_t;
744 typedef typename mpl::if_<
745 mpl::equal_to<digits_t, mpl::int_<0> >,
746 // Possibly unknown precision:
749 mpl::or_<mpl::less_equal<digits_t, precision_type>, mpl::less_equal<precision_type, mpl::int_<0> > >,
750 // Default case, full precision for RealType:
751 digits2< ::std::numeric_limits<Real>::digits>,
752 // User customised precision:
758 template <class Policy>
759 struct precision<float, Policy>
761 typedef digits2<FLT_MANT_DIG> type;
763 template <class Policy>
764 struct precision<double, Policy>
766 typedef digits2<DBL_MANT_DIG> type;
768 template <class Policy>
769 struct precision<long double, Policy>
771 typedef digits2<LDBL_MANT_DIG> type;
776 template <class Real, class Policy>
779 BOOST_STATIC_ASSERT((::std::numeric_limits<Real>::radix == 2) || ((::std::numeric_limits<Real>::is_specialized == 0) || (::std::numeric_limits<Real>::digits == 0)));
781 typedef typename Policy::precision_type precision_type;
782 typedef typename mpl::if_c<
783 ((::std::numeric_limits<Real>::is_specialized == 0) || (::std::numeric_limits<Real>::digits == 0)),
784 // Possibly unknown precision:
787 ((::std::numeric_limits<Real>::digits <= precision_type::value)
788 || (Policy::precision_type::value <= 0)),
789 // Default case, full precision for RealType:
790 digits2< ::std::numeric_limits<Real>::digits>,
791 // User customised precision:
796 typedef typename Policy::precision_type precision_type;
797 typedef mpl::int_< ::std::numeric_limits<Real>::digits> digits_t;
798 typedef mpl::bool_< ::std::numeric_limits<Real>::is_specialized> spec_t;
799 typedef typename mpl::if_<
800 mpl::or_<mpl::equal_to<spec_t, mpl::false_>, mpl::equal_to<digits_t, mpl::int_<0> > >,
801 // Possibly unknown precision:
804 mpl::or_<mpl::less_equal<digits_t, precision_type>, mpl::less_equal<precision_type, mpl::int_<0> > >,
805 // Default case, full precision for RealType:
806 digits2< ::std::numeric_limits<Real>::digits>,
807 // User customised precision:
818 template <class T, class Policy>
819 inline int digits_imp(mpl::true_ const&)
821 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
822 BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
824 BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
826 typedef typename boost::math::policies::precision<T, Policy>::type p_t;
830 template <class T, class Policy>
831 inline int digits_imp(mpl::false_ const&)
833 return tools::digits<T>();
836 } // namespace detail
838 template <class T, class Policy>
839 inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
841 typedef mpl::bool_< std::numeric_limits<T>::is_specialized > tag_type;
842 return detail::digits_imp<T, Policy>(tag_type());
845 template <class Policy>
846 inline unsigned long get_max_series_iterations()
848 typedef typename Policy::max_series_iterations_type iter_type;
849 return iter_type::value;
852 template <class Policy>
853 inline unsigned long get_max_root_iterations()
855 typedef typename Policy::max_root_iterations_type iter_type;
856 return iter_type::value;
861 template <class T, class Digits, class Small, class Default>
862 struct series_factor_calc
866 return ldexp(T(1.0), 1 - Digits::value);
870 template <class T, class Digits>
871 struct series_factor_calc<T, Digits, mpl::true_, mpl::true_>
875 return boost::math::tools::epsilon<T>();
878 template <class T, class Digits>
879 struct series_factor_calc<T, Digits, mpl::true_, mpl::false_>
883 static const boost::uintmax_t v = static_cast<boost::uintmax_t>(1u) << (Digits::value - 1);
884 return 1 / static_cast<T>(v);
887 template <class T, class Digits>
888 struct series_factor_calc<T, Digits, mpl::false_, mpl::true_>
892 return boost::math::tools::epsilon<T>();
896 template <class T, class Policy>
897 inline T get_epsilon_imp(mpl::true_ const&)
899 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
900 BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
901 BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::radix == 2);
903 BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
904 BOOST_ASSERT(::std::numeric_limits<T>::radix == 2);
906 typedef typename boost::math::policies::precision<T, Policy>::type p_t;
907 typedef mpl::bool_<p_t::value <= std::numeric_limits<boost::uintmax_t>::digits> is_small_int;
908 typedef mpl::bool_<p_t::value >= std::numeric_limits<T>::digits> is_default_value;
909 return series_factor_calc<T, p_t, is_small_int, is_default_value>::get();
912 template <class T, class Policy>
913 inline T get_epsilon_imp(mpl::false_ const&)
915 return tools::epsilon<T>();
918 } // namespace detail
920 template <class T, class Policy>
921 inline T get_epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
923 typedef mpl::bool_< (std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::radix == 2)) > tag_type;
924 return detail::get_epsilon_imp<T, Policy>(tag_type());
940 char test_is_policy(const policy<A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11>*);
941 double test_is_policy(...);
946 BOOST_STATIC_CONSTANT(bool, value = (sizeof(::boost::math::policies::detail::test_is_policy(static_cast<P*>(0))) == 1));
952 struct is_policy : public mpl::bool_< ::boost::math::policies::detail::is_policy_imp<P>::value> {};
956 #endif // BOOST_MATH_POLICY_HPP