PhilippeSigaud/D-templates-tutorial — Issue #13: Add another example
Author: AndrejMitrovic
Created: 2012-02-29 10:02:41+00:00
State: open

Just posted this to the newsgroups and thought it would be worth including in the book as an example:

import std.algorithm;
import std.conv;
import std.string;
import std.stdio;
import std.range;

struct Foo
{
int one = 1;
@property int test() { return 1; }
int three = 3;
string[string] aa;
string toString() { return prettyFieldsString(this); }
}

string prettyFieldsString(T)(T t)
if (is(T == struct) || is(T == class))
{
Appender!string result;
Appender!(string[]) fields;
Appender!(string[]) values;

foreach (member; __traits(allMembers, T))
{
mixin("
static if (!is( FunctionTypeOf!(t." ~ member ~ ") ))
{
static if (member != " ~ `"toString"` ~ ")
{
fields.put(member);
values.put(to!string(__traits(getMember, t, " ~ `"` ~ member ~ `"` ~ ")));
}
}
");
}

size_t spaceLen = 1;
foreach (field; fields.data)
spaceLen = max(spaceLen, field.length);

alias std.array.replicate replicate;
string spaceString = replicate(" ", spaceLen);

foreach (field, value; lockstep(fields.data, values.data))
result.put(format("%s: %s%s\n", field, replicate(" ", spaceLen - field.length), value));

return result.data;
}

void main()
{
Foo foo;
foo.aa["foo"] = "bar";
writeln(foo);
}

Sample output: http://paste.pocoo.org/show/558492/

Maybe this has more to do with static introspection than templates, but I thought I'd be nice for the book.