Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
June 11, 2018 Identifier hierarchy | ||||
---|---|---|---|---|
| ||||
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? |
June 11, 2018 Re: Identifier hierarchy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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 |
June 11, 2018 Re: Identifier hierarchy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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:
>> 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 ?
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.
--
Simen
|
June 11, 2018 Re: Identifier hierarchy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | 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:
>> 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 ?
>
> 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.
>
> --
> Simen
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
}
---
|
June 11, 2018 Re: Identifier hierarchy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | 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)
}
|
June 11, 2018 Re: Identifier hierarchy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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)
> }
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.
|
June 11, 2018 Re: Identifier hierarchy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luís Marques | 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); } |
June 11, 2018 Re: Identifier hierarchy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | 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.
|
Copyright © 1999-2021 by the D Language Foundation