Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Clipsham | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Clipsham | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Clipsham | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lutger Blijdestijn | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Clipsham | 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 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | 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/ |
Copyright © 1999-2021 by the D Language Foundation