]> git.donarmstrong.com Git - rsem.git/blob - boost/math/special_functions/pow.hpp
Added error detection for cases such as a read's two mates having different names...
[rsem.git] / boost / math / special_functions / pow.hpp
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/policies/policy.hpp>
17 #include <boost/math/policies/error_handling.hpp>
18 #include <boost/math/tools/promotion.hpp>
19 #include <boost/mpl/greater_equal.hpp>
20
21
22 namespace boost {
23 namespace math {
24
25
26 namespace detail {
27
28
29 template <int N, int M = N%2>
30 struct positive_power
31 {
32     template <typename T>
33     static T result(T base)
34     {
35         T power = positive_power<N/2>::result(base);
36         return power * power;
37     }
38 };
39
40 template <int N>
41 struct positive_power<N, 1>
42 {
43     template <typename T>
44     static T result(T base)
45     {
46         T power = positive_power<N/2>::result(base);
47         return base * power * power;
48     }
49 };
50
51 template <>
52 struct positive_power<1, 1>
53 {
54     template <typename T>
55     static T result(T base){ return base; }
56 };
57
58
59 template <int N, bool>
60 struct power_if_positive
61 {
62     template <typename T, class Policy>
63     static T result(T base, const Policy&)
64     { return positive_power<N>::result(base); }
65 };
66
67 template <int N>
68 struct power_if_positive<N, false>
69 {
70     template <typename T, class Policy>
71     static T result(T base, const Policy& policy)
72     {
73         if (base == 0)
74         {
75             return policies::raise_overflow_error<T>(
76                        "boost::math::pow(%1%)",
77                        "Attempted to compute a negative power of 0",
78                        policy
79                    );
80         }
81
82         return T(1) / positive_power<-N>::result(base);
83     }
84 };
85
86 template <>
87 struct power_if_positive<0, true>
88 {
89     template <typename T, class Policy>
90     static T result(T base, const Policy& policy)
91     {
92         if (base == 0)
93         {
94             return policies::raise_indeterminate_result_error<T>(
95                        "boost::math::pow(%1%)",
96                        "The result of pow<0>(%1%) is undetermined",
97                        base,
98                        T(1),
99                        policy
100                    );
101         }
102
103         return T(1);
104     }
105 };
106
107
108 template <int N>
109 struct select_power_if_positive
110 {
111     typedef typename mpl::greater_equal<
112                          mpl::int_<N>,
113                          mpl::int_<0>
114                      >::type is_positive;
115
116     typedef power_if_positive<N, is_positive::value> type;
117 };
118
119
120 }  // namespace detail
121
122
123 template <int N, typename T, class Policy>
124 inline typename tools::promote_args<T>::type pow(T base, const Policy& policy)
125
126    typedef typename tools::promote_args<T>::type result_type;
127    return detail::select_power_if_positive<N>::type::result(static_cast<result_type>(base), policy); 
128 }
129
130
131 template <int N, typename T>
132 inline typename tools::promote_args<T>::type pow(T base)
133 { return pow<N>(base, policies::policy<>()); }
134
135
136 }  // namespace math
137 }  // namespace boost
138
139
140 #endif