View mode: basic / threaded / horizontal-split · Log in · Help
May 07, 2011
Cannot interpret struct at compile time
Hey all,

I was wondering if anyone could enlighten me as to why the following 
code does not compile (dmd2, latest release or the beta):
----
struct Foo
{
    int a;
}

string test()
{
        string str = "struct " ~ Foo.stringof ~ "_{";
        foreach (j, f; Foo.tupleof)
        {
            enum fullFieldName = Foo.tupleof[j].stringof;
            str ~= typeof(f).stringof ~ ' ' ~ 
fullFieldName[Foo.stringof.length + 3 .. $];
        }
        return str ~ "}";
}

void main()
{
    mixin(test());
}
----
If fails with the errors:
test.d(9): Error: Cannot interpret Foo at compile time
test.d(19): Error: cannot evaluate test() at compile time
test.d(19): Error: argument to mixin must be a string, not (test())
test.d(19): Error: cannot evaluate test() at compile time
test.d(19): Error: argument to mixin must be a string, not (test())

Thanks,

-- 
Robert
http://octarineparrot.com/
May 07, 2011
Re: Cannot interpret struct at compile time
Not too sure, CTFE is a pain in the ass sometimes. What exactly are
you trying to do, print field names in a custom way?

I have this piece of code I use for printing values, maybe you can
customize it for own your needs:

import std.stdio;
import std.conv;
import std.algorithm;

struct Foo
{
   int abc;
   int foobar;
}

void printFields(T)(T args)
{
   auto values = args.tupleof;

   size_t max;
   size_t temp;
   foreach (index, value; values)
   {
       temp = T.tupleof[index].stringof.length;
       if (max < temp) max = temp;
   }
   max += 1;

   foreach (index, value; values)
   {
       writefln("%-" ~ to!string(max) ~ "s %s",
T.tupleof[index].stringof, value);
   }
}


void main()
{
   writeln();

   Foo foo = Foo(1, 2);
   printFields(foo);
}
May 07, 2011
Re: Cannot interpret struct at compile time
On 07/05/2011 23:36, Andrej Mitrovic wrote:
> Not too sure, CTFE is a pain in the ass sometimes. What exactly are
> you trying to do, print field names in a custom way?

No, I have a struct that I don't have access to in the scope I'm in, I 
do however have its type - by using the above, I can create a local 
clone of the type which acts the same (at least for my purposes), which 
I can then do things with. Except that it fails with that error message D;

-- 
Robert
http://octarineparrot.com/
May 07, 2011
Re: Cannot interpret struct at compile time
One simplistic solution is to use alias this to simulate the same type:

struct Foo
{
   int x, y;
}

string structClone(T)()
{
   return "struct " ~ T.stringof ~ "_ { "
       ~ T.stringof ~ " _inner;
       alias _inner this;
       this(T...)(T t) { _inner = typeof(_inner)(t);  } };";
}

void main()
{
   mixin(structClone!Foo);
   Foo_ foo = Foo_(1, 2);

   assert(foo.x == 1);
   assert(foo.y == 2);
}

Field initializations and ctors will work thanks to the templated ctor
that just forwards to the _inner struct.
May 08, 2011
Re: Cannot interpret struct at compile time
On 08/05/2011 00:39, Andrej Mitrovic wrote:
> One simplistic solution is to use alias this to simulate the same type:
>
> struct Foo
> {
>      int x, y;
> }
>
> string structClone(T)()
> {
>      return "struct " ~ T.stringof ~ "_ { "
>          ~ T.stringof ~ " _inner;
>          alias _inner this;
>          this(T...)(T t) { _inner = typeof(_inner)(t);  } };";
> }
>
> void main()
> {
>      mixin(structClone!Foo);
>      Foo_ foo = Foo_(1, 2);
>
>      assert(foo.x == 1);
>      assert(foo.y == 2);
> }
>
> Field initializations and ctors will work thanks to the templated ctor
> that just forwards to the _inner struct.

Unfortunately this won't do what I need - I need to be able to iterate 
over the members of the resulting struct using .tupleof, which I can't 
do with alias this.

-- 
Robert
http://octarineparrot.com/
May 08, 2011
Re: Cannot interpret struct at compile time
Robert Clipsham wrote:

> Hey all,
> 
> I was wondering if anyone could enlighten me as to why the following
> code does not compile (dmd2, latest release or the beta):
> ----
> struct Foo
> {
>      int a;
> }
> 
> string test()
> {
>          string str = "struct " ~ Foo.stringof ~ "_{";
>          foreach (j, f; Foo.tupleof)
>          {
>              enum fullFieldName = Foo.tupleof[j].stringof;
>              str ~= typeof(f).stringof ~ ' ' ~
> fullFieldName[Foo.stringof.length + 3 .. $];
>          }
>          return str ~ "}";
> }
> 
> void main()
> {
>      mixin(test());
> }
> ----
> If fails with the errors:
> test.d(9): Error: Cannot interpret Foo at compile time
> test.d(19): Error: cannot evaluate test() at compile time
> test.d(19): Error: argument to mixin must be a string, not (test())
> test.d(19): Error: cannot evaluate test() at compile time
> test.d(19): Error: argument to mixin must be a string, not (test())
> 
> Thanks,
> 

test also doesn't compile normally on my box, dmd errors on Foo.tupleof. Not 
sure if this is illegal or not. I think you want the allMembers trait or 
something similar. Something like this:

import std.traits;

string test(T)()
{
   string str = "struct " ~ T.stringof ~ "_{";
   alias FieldTypeTuple!T FieldTypes;
   foreach (i, fieldName; __traits(allMembers, T ) )
   {
       str ~= FieldTypes[i].stringof ~ " " ~ fieldName ~ ";";
   }
   return str ~ "}";
}

This works for your example but is a bit crude, I'm sorry for that, you'll 
have to modify it. ( allMembers also returns functions, including ctors 
while FieldTypeTuple doesn't. I also haven't read anything about the order 
in which FieldTypeTuple and allMembers return their elements )
May 08, 2011
Re: Cannot interpret struct at compile time
On 08/05/2011 19:19, Lutger Blijdestijn wrote:
> test also doesn't compile normally on my box, dmd errors on Foo.tupleof. Not
> sure if this is illegal or not. I think you want the allMembers trait or
> something similar. Something like this:
>
> import std.traits;
>
> string test(T)()
> {
>      string str = "struct " ~ T.stringof ~ "_{";
>      alias FieldTypeTuple!T FieldTypes;
>      foreach (i, fieldName; __traits(allMembers, T ) )
>      {
>          str ~= FieldTypes[i].stringof ~ " " ~ fieldName ~ ";";
>      }
>      return str ~ "}";
> }
>
> This works for your example but is a bit crude, I'm sorry for that, you'll
> have to modify it. ( allMembers also returns functions, including ctors
> while FieldTypeTuple doesn't. I also haven't read anything about the order
> in which FieldTypeTuple and allMembers return their elements )

This seems to do what I need, thanks! :D

-- 
Robert
http://octarineparrot.com/
May 09, 2011
Re: Cannot interpret struct at compile time
Robert Clipsham wrote:
> Hey all,
> 
> I was wondering if anyone could enlighten me as to why the following 
> code does not compile (dmd2, latest release or the beta):

Added as bug 5969.
May 09, 2011
Re: Cannot interpret struct at compile time
On 09/05/2011 16:36, Don wrote:
> Robert Clipsham wrote:
>> Hey all,
>>
>> I was wondering if anyone could enlighten me as to why the following
>> code does not compile (dmd2, latest release or the beta):
>
> Added as bug 5969.

Thanks for this, I wasn't sure if it was a bug or not :)

-- 
Robert
http://octarineparrot.com/
Top | Discussion index | About this forum | D home