On 2021-02-21 07:12, Jack wrote:
I've had a struct like this:

struct Attr
{
     string value;
}

struct Foo
{
     @(Attr("a attr"))
     enum a = Foo(10);

     @(Attr("b attr"))
     enum b = Foo(11);


     int x;
     int y;
     bool doY = true;

     int value()
     {

         return x;
     }

}

I'd like to get that atrribute's value at compile time, something like this:

     enum s = Foo.a.baa;
     enum s2 = Foo.b.baa;
     writeln(s); // a attr
     writeln(s2); // b attr

I did this:

     string baa()
     {
         import std.traits : getUDAs, hasUDA;

         static foreach(field; __traits(allMembers, Foo))
         {{
             alias m = __traits(getMember, Foo, field);
             static if(is(typeof(m) == Foo))
             {
                 if(m.value == this.value)
                     return getUDAs!(m, Attr)[0].value;
             }
         }}

         return null;
     }

that was working fine, but I needed to switch value property from Foo struct, so that I can't read this value at CTFE anymore, so this fails now:

             if(m.value == this.value)
                     return getUDAs!(m, Attr)[0].value;

How can I solve this?

You can't look at the value when trying to find the correct member. You need to look at the name. I don't think it's possible to solve that with the exact same API as you have used above. The simplest solution would be to just use `__traits(getAttributes)` and wrap that in a help function:

string getAttribute(T, string name)()
{
     return __traits(getAttributes, mixin(T.stringof, ".", name))[0].value;
}

void main()
{
    writeln(getAttribute!(Foo, "a"));
}

Or you can create a proxy struct and use opDispatch like this, to get something a bit closer to your original example:

// add this to the Foo struct
static Proxy attributes()
{
    return Proxy();
}

struct Proxy
{
    string opDispatch(string name)()
    {
        return __traits(getAttributes, mixin("Foo.", name))[0].value;
    }
}

void main()
{
    writeln(Foo.attributes.a);
}

--
/Jacob Carlborg

Reply via email to