|
18 | 18 | #define BOOST_ALGORITHM_HPP |
19 | 19 |
|
20 | 20 | #include <boost/utility/enable_if.hpp> // for boost::disable_if |
| 21 | +#include <boost/type_traits/is_integral.hpp> |
21 | 22 |
|
22 | 23 | namespace boost { namespace algorithm { |
23 | 24 |
|
| 25 | +template <typename T> |
| 26 | +T identity_operation ( std::multiplies<T> ) { return T(1); } |
| 27 | + |
| 28 | +template <typename T> |
| 29 | +T identity_operation ( std::plus<T> ) { return T(0); } |
| 30 | + |
| 31 | + |
24 | 32 | /// \fn power ( T x, Integer n ) |
25 | 33 | /// \return the value "x" raised to the power "n" |
26 | 34 | /// |
27 | 35 | /// \param x The value to be exponentiated |
28 | | -/// \param n The exponent |
| 36 | +/// \param n The exponent (must be >= 0) |
29 | 37 | /// |
30 | | -// \remark Taken from Knuth, The Art of Computer Programming, Volume 2: |
31 | | -// Seminumerical Algorithms, Section 4.6.3 |
| 38 | +// \remark Taken from Knuth, The Art of Computer Programming, Volume 2: |
| 39 | +// Seminumerical Algorithms, Section 4.6.3 |
32 | 40 | template <typename T, typename Integer> |
33 | | -T power (T x, Integer n) { |
34 | | - T y = 1; // Should be "T y{1};" |
35 | | - if (n == 0) return y; |
36 | | - while (true) { |
37 | | - if (n % 2 == 1) { |
38 | | - y = x * y; |
39 | | - if (n == 1) |
40 | | - return y; |
41 | | - } |
42 | | - n = n / 2; |
43 | | - x = x * x; |
44 | | - } |
45 | | - return y; |
46 | | - } |
| 41 | +typename boost::enable_if<boost::is_integral<Integer>, T>::type |
| 42 | +power (T x, Integer n) { |
| 43 | + T y = 1; // Should be "T y{1};" |
| 44 | + if (n == 0) return y; |
| 45 | + while (true) { |
| 46 | + if (n % 2 == 1) { |
| 47 | + y = x * y; |
| 48 | + if (n == 1) |
| 49 | + return y; |
| 50 | + } |
| 51 | + n = n / 2; |
| 52 | + x = x * x; |
| 53 | + } |
| 54 | + return y; |
| 55 | + } |
| 56 | + |
| 57 | +/// \fn power ( T x, Integer n, Operation op ) |
| 58 | +/// \return the value "x" raised to the power "n" |
| 59 | +/// using the operaton "op". |
| 60 | +/// |
| 61 | +/// \param x The value to be exponentiated |
| 62 | +/// \param n The exponent (must be >= 0) |
| 63 | +/// \param op The operation used |
| 64 | +/// |
| 65 | +// \remark Taken from Knuth, The Art of Computer Programming, Volume 2: |
| 66 | +// Seminumerical Algorithms, Section 4.6.3 |
| 67 | +template <typename T, typename Integer, typename Operation> |
| 68 | +typename boost::enable_if<boost::is_integral<Integer>, T>::type |
| 69 | +power (T x, Integer n, Operation op) { |
| 70 | + T y = identity_operation(op); |
| 71 | + if (n == 0) return y; |
| 72 | + while (true) { |
| 73 | + if (n % 2 == 1) { |
| 74 | + y = op(x, y); |
| 75 | + if (n == 1) |
| 76 | + return y; |
| 77 | + } |
| 78 | + n = n / 2; |
| 79 | + x = op(x, x); |
| 80 | + } |
| 81 | + return y; |
| 82 | + } |
47 | 83 |
|
48 | 84 | }} |
49 | 85 |
|
|
0 commit comments