Created
December 17, 2014 22:50
-
-
Save aldanor/ddc45b2710a2deb9ee2b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.traits; | |
import std.string; | |
import std.typetuple; | |
template ID(alias T) { | |
alias ID = T; | |
} | |
private bool _propertyNameMatches(alias parent, string suffix, alias name)() { | |
static if (!__traits(compiles, __traits(getMember, parent, name))) | |
return false; | |
else { | |
alias symbol = ID!(__traits(getMember, parent, name)); | |
enum name = __traits(identifier, symbol); | |
enum n = suffix.length; | |
static if (!is(symbol) && is(typeof(symbol))) | |
return (name.length > n) && (name[$ - n .. $] == suffix); | |
else | |
return false; | |
} | |
} | |
private mixin template _makeProperty(alias parent, string suffix, alias func, string name) { | |
mixin(("typeof(__traits(getMember, parent, name)) %s() @property " | |
~ "{ func(); return __traits(getMember, parent, name); }").format( | |
name[0 .. $ - suffix.length])); | |
} | |
private mixin template _makeProperties(alias parent, string suffix, alias func, names...) { | |
static if (names.length > 0) { | |
static if (_propertyNameMatches!(parent, suffix, names[0])) | |
mixin _makeProperty!(parent, suffix, func, names[0]); | |
mixin _makeProperties!(parent, suffix, func, names[1 .. $]); | |
} | |
} | |
mixin template makeProperties(alias parent, string suffix, alias func = {}) { | |
static if (__traits(compiles, __traits(allMembers, parent))) | |
mixin _makeProperties!(parent, suffix, func, __traits(allMembers, parent)); | |
} | |
mixin template makeModuleProperties(string suffix, alias func = {}) { | |
mixin makeProperties!(mixin(__MODULE__), suffix, func); | |
} | |
unittest { | |
struct Foo { | |
static int x_g = 1; | |
static int y_g = 2; | |
static int z = 3; | |
static mixin makeProperties!(Foo, "_g", { return 1; }); | |
} | |
int counter = 0; | |
mixin makeProperties!(Foo, "_g", { counter++; }); | |
assert(Foo.x == 1); | |
assert(Foo.y == 2); | |
assert(x == 1); | |
assert(counter == 1); | |
assert(y == 2); | |
assert(counter == 2); | |
static assert(!is(typeof(z))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment