Thread overview
Cannot interpret struct at compile time
May 07, 2011
Robert Clipsham
May 07, 2011
Andrej Mitrovic
May 07, 2011
Robert Clipsham
May 07, 2011
Andrej Mitrovic
May 08, 2011
Robert Clipsham
May 08, 2011
Lutger Blijdestijn
May 08, 2011
Robert Clipsham
May 09, 2011
Don
May 09, 2011
Robert Clipsham
May 07, 2011
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
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
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
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
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
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
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
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
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/