On Tuesday, 30 December 2014 at 19:05:23 UTC, Ali Çehreli wrote:
On 12/30/2014 09:42 AM, Basile Burg wrote:
> Can a descriptor be created using my "attribute" ? How ?
Here is a quick and dirty solution:
import std.string;
struct PropertyDescriptor
{
string type;
string name;
string memberName() @property const
{
return name ~ "_";
}
string definition() @property const
{
return format("%s %s;", type, memberName);
}
string getter() @property const
{
return format("%s %s() @property const { return %s; }",
type, name, memberName);
}
string setter() @property const
{
return format("void %s(%s value) @property { %s =
value; }",
name, type, memberName);
}
}
unittest
{
const descr = PropertyDescriptor("int", "foo");
assert(descr.memberName == "foo_");
assert(descr.definition == q{int foo_;});
assert(descr.getter == q{int foo() @property const { return
foo_; }});
assert(descr.setter ==
q{void foo(int value) @property { foo_ = value; }});
}
struct Property
{
PropertyDescriptor[] properties;
string propertyCode() @property const
{
string result;
foreach (property; properties) {
result ~= property.definition ~ property.getter ~
property.setter;
}
return result;
}
}
string propertyInjections(T)()
{
string result;
foreach (attr; __traits(getAttributes, T)) {
static if (is (typeof(attr) == Property)) {
result ~= attr.propertyCode;
}
}
return result;
}
@Property([ PropertyDescriptor("int", "i"),
PropertyDescriptor("double", "d") ])
class C
{
mixin (propertyInjections!C);
}
void main()
{
auto c = new C();
c.i = 42;
assert(c.i == 42);
}
Ali
Ok, thx. I see the trick:
mixin (propertyInjections!C);
Introspection inside each class. I don't find this solution ugly
btw. I think there is no other way to do this.