File indexing completed on 2025-01-18 09:40:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_MATH_POW_HPP
0013 #define BOOST_MATH_POW_HPP
0014
0015
0016 #include <boost/math/special_functions/math_fwd.hpp>
0017 #include <boost/math/policies/policy.hpp>
0018 #include <boost/math/policies/error_handling.hpp>
0019 #include <boost/math/tools/promotion.hpp>
0020
0021
0022 namespace boost {
0023 namespace math {
0024
0025 #ifdef _MSC_VER
0026 #pragma warning(push)
0027 #pragma warning(disable:4702)
0028 #endif
0029
0030 namespace detail {
0031
0032
0033 template <int N, int M = N%2>
0034 struct positive_power
0035 {
0036 template <typename T>
0037 static BOOST_CXX14_CONSTEXPR T result(T base)
0038 {
0039 T power = positive_power<N/2>::result(base);
0040 return power * power;
0041 }
0042 };
0043
0044 template <int N>
0045 struct positive_power<N, 1>
0046 {
0047 template <typename T>
0048 static BOOST_CXX14_CONSTEXPR T result(T base)
0049 {
0050 T power = positive_power<N/2>::result(base);
0051 return base * power * power;
0052 }
0053 };
0054
0055 template <>
0056 struct positive_power<1, 1>
0057 {
0058 template <typename T>
0059 static BOOST_CXX14_CONSTEXPR T result(T base){ return base; }
0060 };
0061
0062
0063 template <int N, bool>
0064 struct power_if_positive
0065 {
0066 template <typename T, class Policy>
0067 static BOOST_CXX14_CONSTEXPR T result(T base, const Policy&)
0068 { return positive_power<N>::result(base); }
0069 };
0070
0071 template <int N>
0072 struct power_if_positive<N, false>
0073 {
0074 template <typename T, class Policy>
0075 static BOOST_CXX14_CONSTEXPR T result(T base, const Policy& policy)
0076 {
0077 if (base == 0)
0078 {
0079 return policies::raise_overflow_error<T>(
0080 "boost::math::pow(%1%)",
0081 "Attempted to compute a negative power of 0",
0082 policy
0083 );
0084 }
0085
0086 return T(1) / positive_power<-N>::result(base);
0087 }
0088 };
0089
0090 template <>
0091 struct power_if_positive<0, true>
0092 {
0093 template <typename T, class Policy>
0094 static BOOST_CXX14_CONSTEXPR T result(T base, const Policy& policy)
0095 {
0096 if (base == 0)
0097 {
0098 return policies::raise_indeterminate_result_error<T>(
0099 "boost::math::pow(%1%)",
0100 "The result of pow<0>(%1%) is undetermined",
0101 base,
0102 T(1),
0103 policy
0104 );
0105 }
0106
0107 return T(1);
0108 }
0109 };
0110
0111
0112 template <int N>
0113 struct select_power_if_positive
0114 {
0115 using type = power_if_positive<N, (N >= 0)>;
0116 };
0117
0118
0119 }
0120
0121
0122 template <int N, typename T, class Policy>
0123 BOOST_CXX14_CONSTEXPR inline typename tools::promote_args<T>::type pow(T base, const Policy& policy)
0124 {
0125 using result_type = typename tools::promote_args<T>::type;
0126 return detail::select_power_if_positive<N>::type::result(static_cast<result_type>(base), policy);
0127 }
0128
0129 template <int N, typename T>
0130 BOOST_CXX14_CONSTEXPR inline typename tools::promote_args<T>::type pow(T base)
0131 { return pow<N>(base, policies::policy<>()); }
0132
0133 #ifdef _MSC_VER
0134 #pragma warning(pop)
0135 #endif
0136
0137 }
0138 }
0139
0140
0141 #endif