Created
December 6, 2013 17:31
-
-
Save frostiq/7828857 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <math.h> | |
#include <iterator> | |
#include <vector> | |
template <typename T> | |
struct AccumTraits | |
{ | |
typedef T TAccum; | |
}; | |
template<> | |
struct AccumTraits <int> | |
{ | |
typedef __int64 TAccum; | |
}; | |
template <typename S, typename T> | |
struct plcAdd | |
{ | |
void AccumOp(S& sum, const T& e) | |
{ | |
sum += e; | |
} | |
static T TAccumZero(T arg) {return 0;} | |
}; | |
template <typename S, typename T> | |
struct plcMul | |
{ | |
void AccumOp(S& sum, const T& e) | |
{ | |
sum *= e; | |
} | |
static T TAccumZero(T arg) {return 1;} | |
}; | |
template <typename S, typename T> | |
struct plcPolynom | |
{ | |
int x, n; | |
plcPolynom(): x(2), n(0){} | |
void AccumOp(S& sum, const T& e) | |
{ | |
sum += e * static_cast<int>(pow(x, n)); | |
++n; | |
} | |
static T TAccumZero(T arg) {return 0;} | |
}; | |
template <typename S, typename T> | |
struct plcMax | |
{ | |
void AccumOp(S& max, const T& e) | |
{ | |
if (e > max) max = e; | |
} | |
static T TAccumZero(T arg) {return arg;} | |
}; | |
template <typename S, typename T> | |
struct plcMin | |
{ | |
void AccumOp(S& min, const T& e) | |
{ | |
if (e < min) min = e; | |
} | |
static T TAccumZero(T arg) {return arg;} | |
}; | |
template <typename T, template <typename,typename> class Policy = plcAdd , | |
typename Traits = AccumTraits<typename std::iterator_traits<T>::value_type> > | |
class KAccum | |
{ | |
public: | |
typedef typename Traits::TAccum TAccum; | |
typedef Policy<TAccum, typename std::iterator_traits<T>::value_type> Policy; | |
static TAccum Accum(T pbeg, T pend) | |
{ | |
TAccum s = Policy::TAccumZero(*pbeg); | |
Policy plc; | |
while (pbeg != pend) | |
plc.AccumOp(s, *pbeg++); | |
return s; | |
} | |
}; | |
template <typename T> | |
typename KAccum<T>::TAccum AccumAdd (T pbeg, T pend) | |
{ | |
return KAccum<T,plcAdd>::Accum(pbeg, pend); | |
} | |
template <typename T> | |
typename KAccum<T>::TAccum AccumMul (T pbeg, T pend) | |
{ | |
return KAccum<T,plcMul>::Accum(pbeg, pend); | |
} | |
template <typename T> | |
typename KAccum<T>::TAccum AccumPolynom (T pbeg, T pend) | |
{ | |
return KAccum<T,plcPolynom>::Accum(pbeg, pend); | |
} | |
template <typename T> | |
typename KAccum<T>::TAccum AccumMax (T pbeg, T pend) | |
{ | |
return KAccum<T,plcMax>::Accum(pbeg, pend); | |
} | |
template <typename T> | |
typename KAccum<T>::TAccum AccumMin (T pbeg, T pend) | |
{ | |
return KAccum<T,plcMin>::Accum(pbeg, pend); | |
} | |
int main() | |
{ | |
int a[]={1,1,1}; | |
std::cout << AccumPolynom(a,a+3) << std::endl; | |
std::vector<double> b(5, std::atan(1)*4); | |
std::cout << AccumMul(b.begin(), b.end()) << ' ' << AccumAdd(b.begin(), b.end()) << std::endl; | |
char c[]={'d','g','y','d','q','z','a'}; | |
std::cout << AccumMax(c,c+7) << ' ' << AccumMin(c,c+7) << std::endl; | |
system("pause"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment