Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:20

0001 //   Boost pow.hpp header file
0002 //   Computes a power with exponent known at compile-time
0003 
0004 //  (C) Copyright Bruno Lalande 2008.
0005 //  Distributed under the Boost Software License, Version 1.0.
0006 //  (See accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 //  See http://www.boost.org for updates, documentation, and revision history.
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) // Unreachable code, only triggered in release mode and /W4
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 }  // namespace detail
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 }  // namespace math
0138 }  // namespace boost
0139 
0140 
0141 #endif