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