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); }
}

Reply via email to