
Vector swizzles in D
By: a guest on
Mar 20th, 2012 | syntax:
D | size: 1.52 KB | hits: 92 | expires: Never
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] ~ ");";
}