module math.vector; private enum options : bool { name_xyzw = true, } struct vector(T, uint N) { this(U...)(U values) if (U.length == N) { assign!(N)(values); } void assign(uint P, U...)(U values) { elems_[P - 1] = values[P - 1]; static if(P > 1) assign!(P-1)(values); } void swizzle(string s, uint P, U)(ref U m) { static if(s[P-1] == 'x' || s[P-1] == 'r') m.elems_[P-1] = elems_[0]; else static if(s[P-1] == 'y' || s[P-1] == 'g') m.elems_[P-1] = elems_[1]; else static if(s[P-1] == 'z' || s[P-1] == 'b') m.elems_[P-1] = elems_[2]; else static if(s[P-1] == 'w' || s[P-1] == 'a') m.elems_[P-1] = elems_[3]; else static assert(0); static if(P > 1) swizzle!(s, P-1)(m); } vector!(T, s.length) opDispatch(string s)() { typeof(return) m; swizzle!(s, s.length)(m); return m; } private T[N] elems_; } alias vector!(float, 2) vec2; alias vector!(float, 3) vec3; alias vector!(float, 4) vec4; alias vector!(float, 9) vec9; private import std.stdio : writeln; unittest { vec2 a = vec2(1.0f, 2.0f); vec3 b = vec3(1.0f, 2.0f, 3.0f); vec4 c = vec4(1.0f, 2.0f, 3.0f, 4.0f); vec4 d = b.zzzz; vec4 e = a.xyxy; vec9 f = c.wwwwwwwww; vec9 g = c.bbbbbbbbb; assert(a != b.xx); assert(a == b.xy); assert(b.xyz == c.xyz); assert(c.wwzy == vec4(4, 4, 3, 2)); assert(c.zzz == vec3(3, 3, 3)); assert(f == vec9(4, 4, 4, 4, 4, 4, 4, 4, 4)); assert(g == vec9(3, 3, 3, 3, 3, 3, 3, 3, 3)); writeln("a: ", a.tupleof); writeln("b: ", b.tupleof); writeln("c: ", c.tupleof); writeln("d: ", d.tupleof); writeln("e: ", e.tupleof); writeln("f: ", f.tupleof); writeln("g: ", g.tupleof); } int main() { return 0; }