import std.stdio;
import std.math;
import std.traits;
class Vector2D(T) {
public:
T x;
T y;
this() { }
/**
*
*/
static Vector2D!(T) opCall(U, V)(U x, V y) {
Vector2D!(T) vec = new Vector2D!(T)();
vec.x = cast(T) x;
vec.y = cast(T) y;
return vec;
}
/**
*
*/
static Vector2D!(T) opCall(U)(const Vector2D!(U) vec) {
assert(vec !is null);
return Vector2D!(T)(vec.x, vec.y);
}
U opCast(U)() const
if (is(Unqual!U == Vector2D!byte) ||
is(Unqual!U == Vector2D!ubyte) ||
is(Unqual!U == Vector2D!short) ||
is(Unqual!U == Vector2D!ushort) ||
is(Unqual!U == Vector2D!int) ||
is(Unqual!U == Vector2D!uint) ||
is(Unqual!U == Vector2D!long) ||
is(Unqual!U == Vector2D!ulong) ||
is(Unqual!U == Vector2D!float) ||
is(Unqual!U == Vector2D!double) ||
is(Unqual!U == Vector2D!real))
{
return U(this.x, this.y);
}
T opCast(T)()
if(isImplicitlyConvertible!(typeof(this), T))
{
return this;
}
const(T) opCast(T)() const
if(isImplicitlyConvertible!(typeof(this), const T))
{
return this;
}
/**
*
*/
Vector2D!(T) opBinary(string op, U)(const Vector2D!(U) vec) const {
not_null(vec);
float result_x, result_y;
switch (op) {
case "+":
result_x = this.x + vec.x;
result_y = this.y + vec.y;
break;
case "-":
result_x = this.x - vec.x;
result_y = this.y - vec.y;
break;
case "*":
result_x = this.x - vec.x;
result_y = this.y - vec.y;
break;
case "/":
result_x = this.x / vec.x;
result_y = this.y / vec.y;
break;
/*
case "^^":
result_x = this.x ^^ vec.x;
result_y = this.y ^^ vec.y;
break;
*/
default: return this;
}
return Vector2D!(T)(result_x, result_y);
}
/**
*
*/
Vector2D!(T) opBinary(string op)(float num) const {
float result_x, result_y;
switch (op) {
case "+":
result_x = this.x + num;
result_y = this.y + num;
break;
case "-":
result_x = this.x - num;
result_y = this.y - num;
break;
case "*":
result_x = this.x - num;
result_y = this.y - num;
break;
case "/":
result_x = this.x / num;
result_y = this.y / num;
break;
case "^^":
result_x = this.x^^num;
result_y = this.y^^num;
break;
default: return this;
}
return Vector2D!(T)(result_x, result_y);
}
/**
*
*/
typeof(this) opOpAssign(string op, U)(const Vector2D!(U) vec) {
not_null(vec);
float result_x, result_y;
switch (op) {
case "+":
result_x = this.x + vec.x;
result_y = this.y + vec.y;
break;
case "-":
result_x = this.x - vec.x;
result_y = this.y - vec.y;
break;
case "*":
result_x = this.x - vec.x;
result_y = this.y - vec.y;
break;
case "/":
result_x = this.x / vec.x;
result_y = this.y / vec.y;
break;
/*
case "^^":
result_x = this.x ^^ vec.x;
result_y = this.y ^^ vec.y;
break;
*/
default: return this;
}
this.x = result_x;
this.y = result_y;
return this;
}
/**
*
*/
typeof(this) opOpAssign(string op)(float num) {
float result_x, result_y;
switch (op) {
case "+":
result_x = this.x + num;
result_y = this.y + num;
break;
case "-":
result_x = this.x - num;
result_y = this.y - num;
break;
case "*":
result_x = this.x - num;
result_y = this.y - num;
break;
case "/":
result_x = this.x / num;
result_y = this.y / num;
break;
/*
case "^^":
result_x = this.x ^^ num;
result_y = this.y ^^ num;
break;
*/
default: return this;
}
this.x = result_x;
this.y = result_y;
return this;
}
/**
*
*/
override int opCmp(Object o) const {
if (o is null) {
return false;
}
const Vector2D!(T) vec = cast(Vector2D!(T)) o;
if (vec is this) {
return true;
}
/+
if (this.Summe() > vec.Summe()) {
return 1;
}
if (this.Summe() < vec.Summe()) {
return -1;
}
+/
return 0;
}
override bool opEquals(Object o) const {
writeln(o);
Vector2D!(T) vec = cast(Vector2D!(T)) o;
writeln(vec);
if (vec is this) {
return true;
}
return vec.x == this.x && vec.y == this.y;
}
}
void main() {
alias Vector2D!(short) Vector2s;
alias Vector2D!(float) Vector2f;
Vector2f vf = Vector2f(23, 42);
Vector2s vs = Vector2s(vf);
writefln("vs.x: %d, vs.y: %d", vs.x, vs.y);
Vector2s vs2 = Vector2s(23, 42);
if (vs2 == Vector2s(vf)) {
writeln("equal");
}
if (vs2 == vf) {
writeln("equal");
}
const Vector2s vs_ = cast(Vector2s)vf;
}