On 3/21/12, Andrei Alexandrescu <seewebsiteforem...@erdani.org> wrote: > I think the liability here is that b needs to appear in two places.
Andrei, how about this: import std.stdio; import std.conv; struct NonSerialized(T) { enum isNonSerialized = true; T payload; alias payload this; } struct Foo { this(int x, string name, string lastName, string extra) { this.x = x; this.name = name; this.lastName = lastName; this.extra = extra; } int x; NonSerialized!string name; NonSerialized!string lastName; string extra; } string serialize(T)(T input) { string result; foreach (i, field; input.tupleof) { static if (skipSerialize!(typeof(field))) result ~= to!string(typeof(field).init) ~ "\n"; else result ~= to!string(field) ~ "\n"; } return result; } template skipSerialize(T) { enum bool skipSerialize = hasValidMember!(T, "isNonSerialized"); } template hasValidMember(T, string member) { static if (__traits(hasMember, T, member)) { enum bool hasValidMember = mixin("T." ~ member); } else enum bool hasValidMember = false; } void main() { Foo foo = Foo(10, "Foo", "Bar", "Doo"); string bin = serialize(foo); writeln(bin); } Note that I've had to make a constructor because I can't implicitly assign a string to a NonSerialized!string inside of a struct literal (but I think this is just a DMD frontend bug).