00001
00002 #ifndef _INSTIGATE_STL_INTERNAL_HEADER_IN_ALGORITHM
00003 #error This is an internal header file used to implement Instigate STL.\
00004 It should never be included directly by a program.
00005 #endif
00006
00007 #ifndef INSTIGATE_STL_POWER_HPP
00008 #define INSTIGATE_STL_POWER_HPP
00009
00058
00059 #include "concept.hpp"
00060 #include "_basis.hpp"
00061
00062
00063
00064
00065 #include <cassert>
00066
00067
00068 namespace instigate {
00069 namespace stl {
00070 template <typename T, typename I>
00071 inline T power(T, I);
00072
00073 template <typename T, typename I, typename M>
00074 inline T power(T, I, M);
00075
00076 namespace implementation {
00077 template <typename T, typename I, typename M>
00078 T power_aux(T, I, M);
00079 }
00080 }
00081 }
00082
00105 template <typename T, typename I>
00106 inline T instigate::stl::power(T a, I n)
00107 {
00108 assert(0 <= n);
00109 return implementation::power_aux(a, n, stl::multiplies<T>());
00110 }
00111
00134 template <typename T, typename I, typename M>
00135 inline T instigate::stl::power(T a, I n, M o)
00136 {
00137 CHECK(stl::binary_function::requirements<M>);
00138 assert(0 <= n);
00139 return implementation::power_aux(a, n, o);
00140 }
00141
00148 template <typename T, typename I, typename M>
00149 inline T instigate::stl::implementation::power_aux(T a, I n, M o)
00150 {
00151 char p[sizeof(T)];
00152 T* r = 0;
00153 assign(r, initialize<T>(p));
00154 assert(0 != r);
00155 if (equal(0, n)) {
00156 assign(*r, 1);
00157 return *r;
00158 } else {
00159 while (equal(0, (n & 1))) {
00160 n >>= 1;
00161 assign(a, invoke(o, a, a));
00162 }
00163 assign(*r, a);
00164 n >>= 1;
00165 while (!equal(0, n)) {
00166 assign(a, invoke(o, a, a));
00167 if (!equal(0, (n & 1)))
00168 assign(*r, invoke(o, *r, a));
00169 n >>= 1;
00170 }
00171 return *r;
00172 }
00173 return *r;
00174 }
00175
00176
00177
00178 #endif // INSTIGATE_STL_POWER_HPP