Operator Overloading and boilerplate code
Timon Gehr
timon.gehr at gmx.ch
Sat Jul 2 15:23:52 PDT 2011
Your example with reduced boilerplate code:
struct DVECTOR2 {
template Accepts(T){enum Accepts=is(T==DVECTOR2) || is(T==float) ||
is(T==D3DXVECTOR2) || is(T==POINT);}
template isScalar(T){enum isScalar=is(T==float);}
float x = 0f, y=0f;
this()(float x, float y) {
this.x = x;
this.y = y;
}
this()(float xy) { this(xy,xy); }
// Implement D3DXVECTOR2 and POINT support
this(T)(T arg) if(Accepts!T && !isScalar!T) {
this.x = arg.x;
this.y = arg.y;
}
DVECTOR2 opUnary(string op)() if(op == "-") { return DVECTOR2(-x, -y); }
DVECTOR2 opBinary(string op,T)(T rhs) if(Accepts!T) {
enum rx="rhs"~isScalar!T?"":".x", ry=isScalar!T?"":".y";
return DVECTOR2(mixin("x" ~ op ~ "rhs"~rx), mixin("y" ~ op ~ "rhs"~ry));
}
DVECTOR2 opBinaryRight(string op,T)(T lhs) if(Accepts!T) { return
DVECTOR2(lhs).opBinary!op(this); }
ref DVECTOR2 opAssign(T)(T rhs) if(Accepts!T) {
static if(isScalar!T) x=y=rhs; else x=rhs.y, y=rhs.y; return this;
}
ref DVECTOR2 opOpAssign(string op,T)(T rhs) if(Accepts!T) {
return(this.opAssign(opBinary!op(rhs))); }
T opCast(T)() if(Accepts!T && !isScalar!T) { return T(x, y); }
}
unittest
{
DVECTOR2 test = DVECTOR2(2f, 2f);
test += 2f;
assert(test.x == 4f);
}
Should work.
Cheers,
-Timon
More information about the Digitalmars-d-learn
mailing list