Is it possible to use an UDA to generate a struct inside a class ?

Basile Burg via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Dec 30 11:18:40 PST 2014


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.


More information about the Digitalmars-d-learn mailing list