Skip to content

Instantly share code, notes, and snippets.

@frostiq
Created December 6, 2013 17:31
Show Gist options
  • Save frostiq/7828857 to your computer and use it in GitHub Desktop.
Save frostiq/7828857 to your computer and use it in GitHub Desktop.
#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