Skip to content

Instantly share code, notes, and snippets.

@aldanor
Created December 17, 2014 22:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aldanor/ddc45b2710a2deb9ee2b to your computer and use it in GitHub Desktop.
Save aldanor/ddc45b2710a2deb9ee2b to your computer and use it in GitHub Desktop.
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