#define _TRAIT_H_
namespace redwolf
{
namespace base
{
template<typename T>
class AccumulationTraits{};
template<typename T>
class MulitTraits;
template<>
class AccumulationTraits<char>
{
public:
typedef int AccT;
static AccT zero(){
return 0;
}
};
template<>
class AccumulationTraits<int>
{
public:
typedef long AccT;
static AccT zero(){
return 0;
}
};
template<>
class AccumulationTraits<float>
{
public:
typedef float AccT;
static AccT zero(){
return 0.0;
}
};
template<>
class MulitTraits<char>
{
public:
typedef int AccT;
static AccT zero(){
return 1;
}
};
template<>
class MulitTraits<int>
{
public:
typedef long AccT;
static AccT zero(){
return 1;
}
};
template<>
class MulitTraits<float>
{
public:
typedef float AccT;
static AccT zero(){
return 1.0;
}
};
class SumPolicy
{
public:
template<typename T1, typename T2>
static void accumlation(T1& total, const T2& value){
total+=value;
}
protected:
private:
};
class MulitPolicy
{
public:
template<typename T1, typename T2>
static void accumlation(T1& total, const T2& value){
total*=value;
}
protected:
private:
};
template< typename T, typename AT=AccumulationTraits<T>, typename PY=SumPolicy>
class Accum
{
public:
static typename AT::AccT accum(const T* _beg, const T* _end){
typedef typename AT::AccT AccT;
AccT r=AT::zero();
while(_beg!=_end)
{
PY::accumlation(r, (*_beg));
++_beg;
}
return r;
}
};
template<typename T>//現行C++標準不支持函數模板的形參缺省值
inline typename AccumulationTraits<T>::AccT accum(const T* _beg, const T* _end)
{
return Accum<T>::accum(_beg, _end);
}
template<typename T, typename Traits, typename Policy>
inline typename Traits::AccT accum(const T* _beg, const T* _end){
return Accum<T, Traits, Policy>::accum(_beg, _end);
}
#define TRAIT_TEST
#ifdef TRAIT_TEST
void traittest0()
{
float f[5]={1.0, 2.0, 3.0, 4.0, 5.0};
int a[5]={1,2,3,4,5};
char name[]="templates";
int length=sizeof(name)-1;
//Accum<int> a0;
//Accum<char> a1;
//Accum<float> a2;
//Accum<float, AccumulationTraits<int> > a3;
long sum0=0;
int sum1=0;
double sum2=0;
long sum4=0;
//sum0=a0.accum(a, a+5)/5;
//sum1=a1.accum(name, name+length)/length;
//sum2=a2.accum(f, f+5)/5;
//sum4=a3.accum(f, f+5)/5;
sum0=accum(a, a+5);
sum1=accum(name, name+length);
sum2=accum(f, f+5);
(sum0=sum1=0,sum2=0);
sum0=accum<int, AccumulationTraits<int>, SumPolicy >(a, a+5);
sum1=accum<char, AccumulationTraits<char>, SumPolicy >(name, name+length);
sum2=accum<float, AccumulationTraits<float>, SumPolicy >(f, f+5);
(sum0=sum1=0,sum2=0);
sum0=accum<int, MulitTraits<int>, MulitPolicy >(a, a+5);
sum1=accum<char, MulitTraits<char>, MulitPolicy >(name, name+length);//結果越界
sum2=accum<float, MulitTraits<float>, MulitPolicy >(f, f+5);
(sum0=sum1=0,sum2=0);
sum0=accum<int, MulitTraits<int>, MulitPolicy>(a, a+5);
sum1=accum<char, MulitTraits<char>, MulitPolicy >(name, name+length);//結果越界
sum2=accum<float, MulitTraits<float>, MulitPolicy >(f, f+5);
}
#endif
};
};
#endif