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);
}



Reply via email to