145 lines · plain
1// Boost pow.hpp header file2// Computes a power with exponent known at compile-time3 4// (C) Copyright Bruno Lalande 2008.5// (C) Copyright Matt Borland 2024.6// Distributed under the Boost Software License, Version 1.0.7// (See accompanying file LICENSE_1_0.txt or copy at8// http://www.boost.org/LICENSE_1_0.txt)9 10// See http://www.boost.org for updates, documentation, and revision history.11 12 13#ifndef BOOST_MATH_POW_HPP14#define BOOST_MATH_POW_HPP15 16#include <boost/math/tools/config.hpp>17#include <boost/math/policies/policy.hpp>18#include <boost/math/policies/error_handling.hpp>19#include <boost/math/tools/promotion.hpp>20 21#ifndef BOOST_MATH_HAS_NVRTC22#include <boost/math/special_functions/math_fwd.hpp>23#endif24 25namespace boost {26namespace math {27 28#ifdef _MSC_VER29#pragma warning(push)30#pragma warning(disable:4702) // Unreachable code, only triggered in release mode and /W431#endif32 33namespace detail {34 35 36template <int N, int M = N%2>37struct positive_power38{39 template <typename T>40 BOOST_MATH_GPU_ENABLED static constexpr T result(T base)41 {42 T power = positive_power<N/2>::result(base);43 return power * power;44 }45};46 47template <int N>48struct positive_power<N, 1>49{50 template <typename T>51 BOOST_MATH_GPU_ENABLED static constexpr T result(T base)52 {53 T power = positive_power<N/2>::result(base);54 return base * power * power;55 }56};57 58template <>59struct positive_power<1, 1>60{61 template <typename T>62 BOOST_MATH_GPU_ENABLED static constexpr T result(T base){ return base; }63};64 65 66template <int N, bool>67struct power_if_positive68{69 template <typename T, class Policy>70 BOOST_MATH_GPU_ENABLED static constexpr T result(T base, const Policy&)71 { return positive_power<N>::result(base); }72};73 74template <int N>75struct power_if_positive<N, false>76{77 template <typename T, class Policy>78 BOOST_MATH_GPU_ENABLED static constexpr T result(T base, const Policy& policy)79 {80 if (base == 0)81 {82 return policies::raise_overflow_error<T>(83 "boost::math::pow(%1%)",84 "Attempted to compute a negative power of 0",85 policy86 );87 }88 89 return T(1) / positive_power<-N>::result(base);90 }91};92 93template <>94struct power_if_positive<0, true>95{96 template <typename T, class Policy>97 BOOST_MATH_GPU_ENABLED static constexpr T result(T base, const Policy& policy)98 {99 if (base == 0)100 {101 return policies::raise_indeterminate_result_error<T>(102 "boost::math::pow(%1%)",103 "The result of pow<0>(%1%) is undetermined",104 base,105 T(1),106 policy107 );108 }109 110 return T(1);111 }112};113 114 115template <int N>116struct select_power_if_positive117{118 using type = power_if_positive<N, (N >= 0)>;119};120 121 122} // namespace detail123 124 125template <int N, typename T, class Policy>126BOOST_MATH_GPU_ENABLED constexpr inline typename tools::promote_args<T>::type pow(T base, const Policy& policy)127{ 128 using result_type = typename tools::promote_args<T>::type;129 return detail::select_power_if_positive<N>::type::result(static_cast<result_type>(base), policy); 130}131 132template <int N, typename T>133BOOST_MATH_GPU_ENABLED constexpr inline typename tools::promote_args<T>::type pow(T base)134{ return pow<N>(base, policies::policy<>()); }135 136#ifdef _MSC_VER137#pragma warning(pop)138#endif139 140} // namespace math141} // namespace boost142 143 144#endif145