Identifier hierarchy

Stefan Koch uplink.coder at googlemail.com
Mon Jun 11 20:49:01 UTC 2018


On Monday, 11 June 2018 at 13:47:41 UTC, Luís Marques wrote:
> On Monday, 11 June 2018 at 13:39:22 UTC, Basile B. wrote:
>> the FQN is working here but i find the first message a bit 
>> confuse. Not sure if this small runnable represents the issue ?
>>
>>
>> ---
>> module runnable;
>>
>> import std.stdio, std.traits;
>>
>> struct foo {  struct bar { static int baz;} }
>>
>> template Test(alias arg)
>> {
>>     pragma(msg, fullyQualifiedName!arg);
>> }
>>
>> void main()
>> {
>>     alias t = Test!(foo.bar.baz); // runnable.foo.bar.baz
>> }
>
> That gets the types foo, bar, baz. I wanted the identifiers. 
> Something like this:
>
> struct Parent
> {
>     Son son;
> }
>
> struct Son
> {
>     int value;
> }
>
> void main()
> {
>     Parent parent;
>     alias t = Magic!(parent.son); // t is now parent (not 
> Parent)
> }

this can only work unambiguously if Son is defined nested inside 
Parent.
Otherwise it's lexical parent will be the module.
So let's assume we have this structure

struct Parent
{
    double d;
    struct Son { int value; }
    Son son;
}

void main()
{
     Parent p;
     p.d = 3.141;
     auto pfs = Magic(p.son);
     static assert(is(typeof(pfs) == Parent*));
     assert(&pfs.son == &p.son);
     assert(pfs.d == 3.141);
}

auto Magic(S)(ref S s)
{
     alias P = typeof(__traits(parent, S).init);
     enum s_index =
     () {
         foreach(i,m;[__traits(allMembers, P)])
         {
             if (__traits(identifier, S) == m)
             {
                 return i;
             }
         }
         assert(0);
     } ();
     enum s_offset = P.init.tupleof[s_index].offsetof;
     return cast(P*)( (cast(void*)&s) - s_offset);
}





More information about the Digitalmars-d mailing list