1// Boost pow.hpp header file
2// Computes a power with exponent known at compile-time
3
4// (C) Copyright Bruno Lalande 2008.
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9// See http://www.boost.org for updates, documentation, and revision history.
10
11
12#ifndef BOOST_MATH_POW_HPP
13#define BOOST_MATH_POW_HPP
14
15
16#include <boost/math/special_functions/math_fwd.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
22namespace boost {
23namespace math {
24
25#ifdef _MSC_VER
26#pragma warning(push)
27#pragma warning(disable:4702) // Unreachable code, only triggered in release mode and /W4
28#endif
29
30namespace detail {
31
32
33template <int N, int M = N%2>
34struct positive_power
35{
36 template <typename T>
37 static BOOST_CXX14_CONSTEXPR T result(T base)
38 {
39 T power = positive_power<N/2>::result(base);
40 return power * power;
41 }
42};
43
44template <int N>
45struct positive_power<N, 1>
46{
47 template <typename T>
48 static BOOST_CXX14_CONSTEXPR T result(T base)
49 {
50 T power = positive_power<N/2>::result(base);
51 return base * power * power;
52 }
53};
54
55template <>
56struct positive_power<1, 1>
57{
58 template <typename T>
59 static BOOST_CXX14_CONSTEXPR T result(T base){ return base; }
60};
61
62
63template <int N, bool>
64struct power_if_positive
65{
66 template <typename T, class Policy>
67 static BOOST_CXX14_CONSTEXPR T result(T base, const Policy&)
68 { return positive_power<N>::result(base); }
69};
70
71template <int N>
72struct power_if_positive<N, false>
73{
74 template <typename T, class Policy>
75 static BOOST_CXX14_CONSTEXPR T result(T base, const Policy& policy)
76 {
77 if (base == 0)
78 {
79 return policies::raise_overflow_error<T>(
80 "boost::math::pow(%1%)",
81 "Attempted to compute a negative power of 0",
82 policy
83 );
84 }
85
86 return T(1) / positive_power<-N>::result(base);
87 }
88};
89
90template <>
91struct power_if_positive<0, true>
92{
93 template <typename T, class Policy>
94 static BOOST_CXX14_CONSTEXPR T result(T base, const Policy& policy)
95 {
96 if (base == 0)
97 {
98 return policies::raise_indeterminate_result_error<T>(
99 "boost::math::pow(%1%)",
100 "The result of pow<0>(%1%) is undetermined",
101 base,
102 T(1),
103 policy
104 );
105 }
106
107 return T(1);
108 }
109};
110
111
112template <int N>
113struct select_power_if_positive
114{
115 using type = power_if_positive<N, (N >= 0)>;
116};
117
118
119} // namespace detail
120
121
122template <int N, typename T, class Policy>
123BOOST_CXX14_CONSTEXPR inline typename tools::promote_args<T>::type pow(T base, const Policy& policy)
124{
125 using result_type = typename tools::promote_args<T>::type;
126 return detail::select_power_if_positive<N>::type::result(static_cast<result_type>(base), policy);
127}
128
129template <int N, typename T>
130BOOST_CXX14_CONSTEXPR inline typename tools::promote_args<T>::type pow(T base)
131{ return pow<N>(base, policies::policy<>()); }
132
133#ifdef _MSC_VER
134#pragma warning(pop)
135#endif
136
137} // namespace math
138} // namespace boost
139
140
141#endif
142

source code of include/boost/math/special_functions/pow.hpp