template fieldsOf (T)
{
const fieldsOf = fieldsOfImpl!(T, 0);
}
template fieldsOfImpl (T, size_t i)
{
static if (T.tupleof.length == 0)
const fieldsOfImpl = [""];
else static if (T.tupleof.length - 1 == i)
const fieldsOfImpl = [T.tupleof[i].stringof[1 + T.stringof.length + 2 .. $]];
else
const fieldsOfImpl = T.tupleof[i].stringof[1 + T.stringof.length + 2 .. $] ~ fieldsOfImpl!(T, i + 1);
}
template Fields ()
{
alias typeof(this) This;
static string __makeOpBinaryFields (string op) ()
{
string res;
foreach (field ; fieldsOf!(This))
res ~= "res." ~ field ~ " = this." ~ field ~ op ~ " rhs." ~ field ~ ";\n";
return res;
}
This opBinary (string op) (This rhs)
{
This res;
mixin(__makeOpBinaryFields!(op));
return res;
}
}
struct Foo
{
int x;
int y;
mixin Fields;
}
void main ()
{
Foo foo = Foo(3, 4);
Foo bar = Foo(5, 6);
auto r = foo + bar;
assert(r.x == 8);
}