I'm writing a small library right now. The objective is to allow the user to manipulate objects which are a function of time transparently. For instance, I would write:
time::value<double> polynomial = 2.0 * time::t * time::t + 3.0 * time::t + 1.0;
time::value<double> linear = 3.0 * polynomial + 2.0;
std::cout << linear(time::now) << std::endl;
This library works based on expression templates. This requires me to define, for every operator, three versions: two with a single time-based member, and one with two time-based members. The code for all of them is extremely similar: the differences have been underlined:
template<typename T,typename LI,typename RI>
struct Sum
{
LI l;
RI r;
Sum(const LI & l, const RI & r) : l(l), r(r) { }
T eval(time t) { return l.eval(t) + r.eval(t); }
};
template<typename RI, typename T>
Wrap< Sum<T,Const<T>,RI>,T>
operator+(const T & left, const Wrap<RI,T> & right)
{ return Sum<T,Const<T>,RI>(left,right.impl); }
template<typename LI, typename T>
Wrap< Sum<T,LI,Const<T> >,T>
operator+(const Wrap<LI,T> & left, const T & right)
{ return Sum<T,LI,Const<T> >(left.impl,right); }
template<typename LI, typename RI, typename T>
Wrap< Sum<LI,RI>,T>
operator+(const Wrap<LI,T> & left, const Wrap<RI,T> & right)
{ return Sum<T,LI,RI>(left.impl,right.impl); }
So, first question: how to reduce the amount of repetitiveness, in order to generate all operators with as little code as possible?
Second question: how do I handle operations which have different argument types (such as scalar * vector) ?