Hi!

I've made a two dimensional vector structure (x, y) which is very
primitive, the only real thing that I want to do with this structure
is support for nearly all operators and support for D3DXVECTOR2 and
POINT structures.

While writing this structure the boilerplate code has steadily
increased. Since I am new to D I mainly wanted to ask if there are any
solutions to prevent this amount of boilerplate code with mixins etc...

The unittest, also, fail to compile. When I am trying to use the
in-place assignment operator the compiler complains saying this;

Error: function dx.directx.DVECTOR2.opAssign (ref const const(DVECTOR2) rhs) is not callable using argument types (DVECTOR2) Error: cannot implicitly convert expression (this.opBinary(rhs)) of type DVECTOR2 to float Error: template instance dx.directx.DVECTOR2.opOpAssign!("+") error instantiating

The first two errors origins from the last opOpAssign operator (taking
a float argument) whilst the last error is from the "test += 2f"
statement.

struct DVECTOR2
{
        float x = 0f;
        float y = 0f;
        
        this(float x, float y)
        {
                this.x = x;
                this.y = y;
        }
        
        this(float xy)
        {
                this.x = xy;
                this.y = xy;
        }
        
        // Implement D3DXVECTOR2 support
        this(const ref D3DXVECTOR2 vec)
        {
                this.x = vec.x;
                this.y = vec.y;
        }
        
        // Implement POINT support
        this(const ref POINT pnt)
        {
                this.x = pnt.x;
                this.y = pnt.y;
        }
        
        // Return a inverse vector
        DVECTOR2 opUnary(string op)() if(op == "-") { return DVECTOR2(-x, -y); }
        
        // The Binary Operators
DVECTOR2 opBinary(string op)(DVECTOR2 rhs) { return DVECTOR2(mixin("x" ~ op ~ "rhs.x"), mixin("y" ~ op ~ "rhs.y")); } DVECTOR2 opBinary(string op)(D3DXVECTOR2 rhs) { return opBinary!op(DVECTOR2(rhs)); } DVECTOR2 opBinary(string op)(POINT rhs) { return opBinary!op(DVECTOR2(rhs)); } DVECTOR2 opBinary(string op)(float rhs) { return opBinary!op(DVECTOR2(rhs)); }
        
        // Right Operators Support
DVECTOR2 opBinaryRight(string op)(DVECTOR2 lhs) { return lhs.opBinary!op(this); } DVECTOR2 opBinaryRight(string op)(D3DXVECTOR2 lhs) { return DVECTOR2(lhs).opBinary!op(this); } DVECTOR2 opBinaryRight(string op)(POINT lhs) { return DVECTOR2(lhs).opBinary!op(this); } DVECTOR2 opBinaryRight(string op)(float lhs) { return DVECTOR2(lhs).opBinary!op(this); }
        
        // Assignment Operator
ref DVECTOR2 opAssign(const ref DVECTOR2 rhs) { x = rhs.x; y = rhs.y; return this; } ref DVECTOR2 opAssign(const ref D3DXVECTOR2 rhs) { return (this.opAssign(DVECTOR2(rhs))); } ref DVECTOR2 opAssign(const ref POINT rhs) { return (this.opAssign(DVECTOR2(rhs))); }
        ref DVECTOR2 opAssign(float rhs) { return 
(this.opAssign(DVECTOR2(rhs))); }

        // In-Place Assignment Operators
ref DVECTOR2 opOpAssign(string op)(DVECTOR2 rhs) { return (this.opAssign(opBinary!op(rhs))); } ref DVECTOR2 opOpAssign(string op)(D3DXVECTOR2 rhs) { return (this.opAssign(opBinary!op(rhs))); } ref DVECTOR2 opOpAssign(string op)(POINT rhs) { return (this.opAssign(opBinary!op(rhs))); }

        // This is where the two first errors occur
ref DVECTOR2 opOpAssign(string op)(float rhs) { return (this.opAssign(opBinary!op(rhs))); }
        
        // Operator Casts
D3DXVECTOR2 opCast(T)() if(is(T == D3DXVECTOR2)) { return D3DXVECTOR2(x, y); } POINT opCast(T)() if(is(T == POINT)) { return POINT(cast(int) x, cast(int) y); }
}

unittest
{
        DVECTOR2 test = DVECTOR2(2f, 2f);
        test += 2f; // This is where the last error occurs
        
        assert(test.x == 4f);
}

Reply via email to