www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Trying to get type and name at compile time

reply Edwin van Leeuwen <edder tkwsping.nl> writes:
Hi all,

I am trying to get the type and name of a field at compile time, 
but can't get the following to work. Anyone any idea of why test 
is not of the type AliasSeq!(double, "x")?


```
import std.meta : AliasSeq;

struct Point { double x; double y; }

alias test = AliasSeq!(
     typeof(__traits(getMember, Point, "x")),
     "x"
);

// I expected AliasSeq!(double,"x")???
pragma(msg,test); // tuple((double), "x")

static assert(is(test == AliasSeq!(double,"x")));

void main() {}
```

Cheers, Edwin
May 24 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 24 May 2016 at 15:01:33 UTC, Edwin van Leeuwen wrote:
 // I expected AliasSeq!(double,"x")???
 pragma(msg,test); // tuple((double), "x")
What Phobos calls AliasSeq is called tuple inside the compiler. They are the same thing, just different names.
 static assert(is(test == AliasSeq!(double,"x")));
AliasSeq is not comparable as a type. You can test the individual pieces of it (`is(test[0] == double) && test[1] == "x"`) or wrap it in a struct or something.
May 24 2016
parent reply Edwin van Leeuwen <edder tkwsping.nl> writes:
On Tuesday, 24 May 2016 at 15:09:43 UTC, Adam D. Ruppe wrote:
 On Tuesday, 24 May 2016 at 15:01:33 UTC, Edwin van Leeuwen 
 wrote:
 // I expected AliasSeq!(double,"x")???
 pragma(msg,test); // tuple((double), "x")
What Phobos calls AliasSeq is called tuple inside the compiler. They are the same thing, just different names.
That's what I assumed at first.. So why does the following fail with: cannot interpret double at compile time? I assumed staticMap would automatically flatten the resulting AliasSeqs. ``` import std.meta : AliasSeq, ApplyLeft, staticMap; struct Point { double x; double y; } template addType(T,alias name) { alias addType = AliasSeq!( typeof(__traits(getMember, Point, name)), name ); } alias test3 = addType!( Point, "x" ); // I expected AliasSeq!(double,"x")??? pragma(msg,test3); // tuple((double), "x") //static assert(is(test == AliasSeq!(double,"x"))); alias ts = AliasSeq!("x","y"); alias addTypeP = ApplyLeft!(addType,Point); alias mapped = staticMap!(addTypeP,ts); pragma(msg,mapped); void main() { } ``` Looking at it now, I guess it is because staticMap does not work with alias values, only with actual type lists. Is that correct? Any ideas on how to do this?
 static assert(is(test == AliasSeq!(double,"x")));
AliasSeq is not comparable as a type. You can test the individual pieces of it (`is(test[0] == double) && test[1] == "x"`) or wrap it in a struct or something.
I thought so, but a lot of the documentation does seem to compare it (see the example here): https://dlang.org/library/std/meta/static_map.html
May 24 2016
parent reply ag0aep6g <anonymous example.com> writes:
On 05/24/2016 06:22 PM, Edwin van Leeuwen wrote:
 That's what I assumed at first.. So why does the following fail with:
 cannot interpret double at compile time? I assumed staticMap would
 automatically flatten the resulting AliasSeqs.

 ```
 import std.meta : AliasSeq, ApplyLeft, staticMap;

 struct Point { double x; double y; }

 template addType(T,alias name)
 {
      alias addType = AliasSeq!( typeof(__traits(getMember, Point, name)),
          name );
 }

 alias test3 = addType!( Point, "x" );

 // I expected AliasSeq!(double,"x")???
 pragma(msg,test3); // tuple((double), "x")

 //static assert(is(test == AliasSeq!(double,"x")));
 alias ts = AliasSeq!("x","y");
 alias addTypeP = ApplyLeft!(addType,Point);
 alias mapped = staticMap!(addTypeP,ts);

 pragma(msg,mapped);

 void main() {
 }
 ```
Seems to be a problem in ApplyLeft: ---- import std.meta: AliasSeq, ApplyLeft; alias addType(T, string name) = AliasSeq!(T, name); alias addTypeInt = ApplyLeft!(addType, int); alias FullyInstantiated = addTypeInt!"foo"; ---- Fails with: "std/meta.d(1114): Error: cannot interpret int at compile time". I've filed an issue: https://issues.dlang.org/show_bug.cgi?id=16070 [...]
 I thought so, but a lot of the documentation does seem to compare it
 (see the example here):
 https://dlang.org/library/std/meta/static_map.html
Using `is(...)` with an AliasSeq of only types is ok. But you can't use it when there's a non-type in the sequence.
May 24 2016
parent Edwin van Leeuwen <edder tkwsping.nl> writes:
On Tuesday, 24 May 2016 at 18:44:45 UTC, ag0aep6g wrote:
 Seems to be a problem in ApplyLeft:

 ----
 import std.meta: AliasSeq, ApplyLeft;
 alias addType(T, string name) = AliasSeq!(T, name);
 alias addTypeInt = ApplyLeft!(addType, int);
 alias FullyInstantiated = addTypeInt!"foo";
 ----

 Fails with: "std/meta.d(1114): Error: cannot interpret int at 
 compile time".

 I've filed an issue:
 https://issues.dlang.org/show_bug.cgi?id=16070
Thanks! I've worked around it for now with some recursion :)
 Using `is(...)` with an AliasSeq of only types is ok. But you 
 can't use it when there's a non-type in the sequence.
That makes sense. Thanks for the help, Edwin
May 24 2016