digitalmars.D - Identifier hierarchy
- =?UTF-8?B?THXDrXM=?= Marques (10/10) Jun 11 2018 Just to check. If you have a piece of code like "foo.bar.baz",
- Mike Franklin (4/7) Jun 11 2018 Are you looking for this:
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (18/27) Jun 11 2018 That only works for modules and types - Luís mentioned that
- Basile B. (16/45) Jun 11 2018 the FQN is working here but i find the first message a bit
- =?UTF-8?B?THXDrXM=?= Marques (16/30) Jun 11 2018 That gets the types foo, bar, baz. I wanted the identifiers.
- Basile B. (18/55) Jun 11 2018 thanks that's clear now... it's indeed not possible
- Stefan Koch (37/74) Jun 11 2018 this can only work unambiguously if Son is defined nested inside
- =?UTF-8?B?THXDrXM=?= Marques (3/5) Jun 11 2018 Thanks for your solution. Unfortunately, it really doesn't cover
Just to check. If you have a piece of code like "foo.bar.baz", you can get the full hierarchy, for instance with stringof: static assert(foo.bar.baz.stringof == "foo.bar.bar"); But once you pass foo.bar.baz to a template, there's no way to recover the full path, is there? You only get baz. You can ask for the __traits(parent, baz), but you only get the type of bar, not the identifier. Assuming you pass the foo.bar.baz normally (alias arg) to the template (not as a string, for instance), there's no workaround for this, is there?
Jun 11 2018
On Monday, 11 June 2018 at 12:38:33 UTC, Luís Marques wrote:Just to check. If you have a piece of code like "foo.bar.baz", you can get the full hierarchy, for instance with stringof: static assert(foo.bar.baz.stringof == "foo.bar.bar");Are you looking for this: https://dlang.org/phobos/std_traits.html#fullyQualifiedName ? Mike
Jun 11 2018
On Monday, 11 June 2018 at 12:59:01 UTC, Mike Franklin wrote:On Monday, 11 June 2018 at 12:38:33 UTC, Luís Marques wrote:That only works for modules and types - Luís mentioned that __traits(identifier) only returns the type, not the identifier. Consider: module foo; import std.traits; struct S { int n; } unittest { S s; // Prints "s.n" pragma(msg, s.n.stringof); // Prints "foo.S.n". pragma(msg, fullyQualifiedName!(s.n)); } As for getting the name s.n inside a template, I don't think that's currently possible. -- SimenJust to check. If you have a piece of code like "foo.bar.baz", you can get the full hierarchy, for instance with stringof: static assert(foo.bar.baz.stringof == "foo.bar.bar");Are you looking for this: https://dlang.org/phobos/std_traits.html#fullyQualifiedName ?
Jun 11 2018
On Monday, 11 June 2018 at 13:19:17 UTC, Simen Kjærås wrote:On Monday, 11 June 2018 at 12:59:01 UTC, Mike Franklin 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 } ---On Monday, 11 June 2018 at 12:38:33 UTC, Luís Marques wrote:That only works for modules and types - Luís mentioned that __traits(identifier) only returns the type, not the identifier. Consider: module foo; import std.traits; struct S { int n; } unittest { S s; // Prints "s.n" pragma(msg, s.n.stringof); // Prints "foo.S.n". pragma(msg, fullyQualifiedName!(s.n)); } As for getting the name s.n inside a template, I don't think that's currently possible. -- SimenJust to check. If you have a piece of code like "foo.bar.baz", you can get the full hierarchy, for instance with stringof: static assert(foo.bar.baz.stringof == "foo.bar.bar");Are you looking for this: https://dlang.org/phobos/std_traits.html#fullyQualifiedName ?
Jun 11 2018
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) }
Jun 11 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:thanks that's clear now... it's indeed not possible --- module runnable; import std.stdio, std.traits; struct Foo {struct Bar{static int baz;} Bar bar;} Foo foo; template Test(alias arg) { // challenge: get "foo.bar.baz" here... } void main() { alias t = Test!(foo.bar.baz); } --- Maybe something with opDispatch but it sounds complicated at first glance.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) }
Jun 11 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: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); }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) }
Jun 11 2018
On Monday, 11 June 2018 at 20:49:01 UTC, Stefan Koch wrote:this can only work unambiguously if Son is defined nested inside Parent.Thanks for your solution. Unfortunately, it really doesn't cover my use case.
Jun 11 2018