module main; import std.stdio; import std.process; import std.conv; private immutable (char[][]) elementNames = [['x', 'y', 'z', 'w'], ['r', 'g', 'b', 'a'], ['s', 't', 'p', 'q']]; int main(string[] argv) { alias Vec!4 Vec4; Vec4 v = Vec4(1, 2, 3, 4); writeln(v.bgra); // Prints Vec!(4)([3, 2, 1, 4]) writeln(v.rg); // Prints Vec!(2)([1, 2]) return 0; } struct Vec(size_t size) { alias size Size; mixin(generateConstructor(Size)); mixin(generateProperties(Size)); auto opDispatch(string s)() { mixin(generateSwizzle(s)); } float v[Size]; } private string generateConstructor(size_t size) { string constructorParams; string constructorBody; foreach(i; 0..size) { string paramName = "v" ~ to!string(i); constructorParams ~= "float " ~ paramName ~ "=0,"; constructorBody ~= "v[" ~ to!string(i) ~ "] = " ~ paramName ~ ";"; } return "this(" ~ constructorParams[0..$-1] ~ "){" ~ constructorBody ~ "}"; } private string generateProperties(size_t size) { string props; foreach(names; elementNames) { foreach(i, name; names[0..size]) { props ~= "@property float " ~ name ~ "() const { return v[" ~ to!string(i) ~ "]; }"; props ~= "@property void " ~ name ~ "(float f) { v[" ~ to!string(i) ~ "] = f; }"; } } return props; } private string generateSwizzle(string elements) { string swizzleImpl = "return Vec!" ~ to!string(elements.length) ~ "("; foreach(e; elements) { swizzleImpl ~= e ~ ","; } return swizzleImpl[0..$-1] ~ ");"; }