Operator Overloading and boilerplate code
Loopback
elliott.darfink at gmail.com
Sun Jul 3 05:15:54 PDT 2011
Thank you!
How excellent you handled the boilerplate code. Works perfectly fine as
well, except one little thing. I cannot declare this DVECTOR2 structure
immutable because the compiler complains saying this:
Error: variable __ctmp1485 cannot be read at compile time
Error: cannot evaluate __ctmp1485.this(0F,1F,0F) at compile time
As I mentioned before, I am new to D and I do not understand why the
compiler cannot evaluate the expression at compile time.
One more thing which I also am wondering is how opCast really works.
To trigger opCast you need to do an explicit cast (tell me if I'm wrong)
and when you do this, does it also work for cases like this:
cast(D3DXVECTOR2) &vector2
Does this code trigger the defined opCast (vector2 is a DVECTOR2
structure in this case) or do I have to define a new opCast in
cases where the address operator is used or is the compiler
able to distinguish the cases and cast opCast before the address
operator is evaluated?
struct DVECTOR2
{
// Controls that the parameter is a valid type
template Accepts(T) { enum Accepts = is(T == DVECTOR2) || is(T ==
float) || is(T == D3DXVECTOR2) || is(T == POINT); }
// Whether the parameter is a float or not
template isScalar(T) { enum isScalar = is(T == float); }
// The Variables
float x = 0f;
float y = 0f;
// Default Constructor
this()(float x, float y)
{
this.x = x;
this.y = y;
}
// Float Constructor
this()(float xy) { this(xy, xy); }
// Implement D3DXVECTOR2 and POINT support
this(T)(T arg) if(Accepts!T && !isScalar!T) { this(arg.tupleof); }
// Inverse the vector
DVECTOR2 opUnary(string op)() if(op == "-") { return DVECTOR2(-x, -y); }
// Binary Operations
DVECTOR2 opBinary(string op, T)(T rhs) if(Accepts!T)
{
enum rx = isScalar!T ? "" : ".x";
enum ry = isScalar!T ? "" : ".y";
return DVECTOR2(mixin("x" ~ op ~ "rhs" ~ rx), mixin("y" ~ op ~ "rhs" ~
ry));
}
// Right Binary Operator
DVECTOR2 opBinaryRight(string op, T)(T lhs) if(Accepts!T) { return
DVECTOR2(lhs).opBinary!op(this); }
// Assign Operator
ref DVECTOR2 opAssign(T)(T rhs) if(Accepts!T)
{
static if(isScalar!T)
x = y = rhs;
else
{
x = rhs.x;
y = rhs.y;
}
return this;
}
// In-Place Assignment Operators
ref DVECTOR2 opOpAssign(string op, T)(T rhs) if(Accepts!T) {
return(this.opAssign(opBinary!op(rhs))); }
// Cast Operators (to D3DXVECTOR2 and POINT)
T opCast(T)() if(Accepts!T && !isScalar!T) { return T(x, y); }
}
More information about the Digitalmars-d-learn
mailing list