www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to use the result of __traits( allMembers , T ) with string mixins

reply "ParticlePeter" <ParticlePeter gmx.de> writes:
DMD tells me "Error: variable m cannot be read at compile time", 
but why ?

[code]
struct MyStruct {
	float float_value = 0.0f ;
	ubyte ubyte_value = 2 ;
}

enum members = [ __traits( allMembers , MyStruct ) ] ;

foreach( m ; members )  {
	mixin( "writeln( " ~ m ~ " , \" : \" , ( MyStruct." ~ m ~ 
".offsetof ) ;" ) ;
}
[\code]

I also tried ref m and foreach( i ; 0..members.length ) with 
m[i]. A simple writeln( m or m[i] ) always  worked.
I read the limitation of "String Mixins and Compile Time Function 
Execution" here: http://dlang.org/function.html#interpretation
But it doesn't make sense to me as members are enum values and 
known at compile time.

What am I doing wrong, and how could it be done ?

Regards, ParticlePeter
Apr 28 2014
parent reply "Andrej Mitrovic" <andrej.mitrovich gmail.com> writes:
On Monday, 28 April 2014 at 13:52:52 UTC, ParticlePeter wrote:
 DMD tells me "Error: variable m cannot be read at compile 
 time", but why ?
Because 'static foreach' is not an explicit feature yet, so it depends on the context. When you wrap the trait via: [__traits(allMembers, MyStruct)] You're creating an array, and foreach will *not* by default attempt to become a static foreach, even if the array is known at compile-time. If you remove the parentheses it will work. You've had a few bugs in the mixin code though, anyway here's the working sample: ----- import std.stdio; struct MyStruct { float float_value = 0.0f; ubyte ubyte_value = 2; } enum members = __traits(allMembers, MyStruct); void main() { foreach (m; members) { mixin("writeln( `" ~ m ~ "` , \" : \" , ( MyStruct." ~ m ~ ".offsetof ) );"); } } -----
Apr 28 2014
parent reply "ParticlePeter" <ParticlePeter gmx.de> writes:
On Monday, 28 April 2014 at 13:57:56 UTC, Andrej Mitrovic wrote:
 On Monday, 28 April 2014 at 13:52:52 UTC, ParticlePeter wrote:
 DMD tells me "Error: variable m cannot be read at compile 
 time", but why ?
Because 'static foreach' is not an explicit feature yet, so it depends on the context. When you wrap the trait via: [__traits(allMembers, MyStruct)] You're creating an array, and foreach will *not* by default attempt to become a static foreach, even if the array is known at compile-time. If you remove the parentheses it will work. You've had a few bugs in the mixin code though, anyway here's the working sample: ----- import std.stdio; struct MyStruct { float float_value = 0.0f; ubyte ubyte_value = 2; } enum members = __traits(allMembers, MyStruct); void main() { foreach (m; members) { mixin("writeln( `" ~ m ~ "` , \" : \" , ( MyStruct." ~ m ~ ".offsetof ) );"); } } -----
Thank you very much, it works. I never came so far to see those mixin errors at all :-) I found the code with parenthesis in the dlang __traits docs and also Philippe Sigauds "D Templates", and I haven't seen any other example which works without them. So, when to use which syntax ( for which purpose ) ? Is this clarified somewhere ? Regards, ParticlePeter
Apr 28 2014
next sibling parent Andrej Mitrovic via Digitalmars-d-learn writes:
On 4/28/14, ParticlePeter via Digitalmars-d-learn
<digitalmars-d-learn puremagic.com> wrote:
 I found the code with parenthesis in the dlang __traits docs and
 also Philippe Sigauds "D Templates", and I haven't seen any other
 example which works without them. So, when to use which syntax (
 for which purpose ) ?
If you need to store the tuple as an array to some variable, then you would use that syntax. It all depends on what you're trying to do from the call site. Ultimately it won't matter much once we finally get a proper 'static foreach' feature in D.
Apr 28 2014
prev sibling parent reply Philippe Sigaud via Digitalmars-d-learn writes:
On Mon, Apr 28, 2014 at 5:45 PM, Andrej Mitrovic via
Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 If you need to store the tuple as an array to some variable, then you
 would use that syntax. It all depends on what you're trying to do from
 the call site. Ultimately it won't matter much once we finally get a
 proper 'static foreach' feature in D.
I guess a common use case is to create an array with [__traits(...)], and use it inside a function, iterating on it and creating a string with the elements. The string is then mixed in with a CTFE call. string makeCode(...) { enum members = [ __traits(allMembers, MyStruct) ]; string result; foreach (m; members) { result ~= "writeln( `" ~ m ~ "` , \" : \" , ( MyStruct." ~ m ~ ".offsetof ) );"); } return result; } mixin(makeCode()); I don't know what I used it for in the tutorial, though :-)
Apr 28 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 28 April 2014 at 17:40:54 UTC, Philippe Sigaud via 
Digitalmars-d-learn wrote:
 On Mon, Apr 28, 2014 at 5:45 PM, Andrej Mitrovic via
 Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 If you need to store the tuple as an array to some variable, 
 then you
 would use that syntax. It all depends on what you're trying to 
 do from
 the call site. Ultimately it won't matter much once we finally 
 get a
 proper 'static foreach' feature in D.
I guess a common use case is to create an array with [__traits(...)], and use it inside a function, iterating on it and creating a string with the elements. The string is then mixed in with a CTFE call. string makeCode(...) { enum members = [ __traits(allMembers, MyStruct) ]; string result; foreach (m; members) { result ~= "writeln( `" ~ m ~ "` , \" : \" , ( MyStruct." ~ m ~ ".offsetof ) );"); } return result; } mixin(makeCode()); I don't know what I used it for in the tutorial, though :-)
You can do the same iterating directly over allMembers list, why would you prefer array here?
Apr 28 2014
parent Philippe Sigaud via Digitalmars-d-learn writes:
On Mon, Apr 28, 2014 at 8:20 PM, Dicebot via Digitalmars-d-learn
<digitalmars-d-learn puremagic.com> wrote:

 You can do the same iterating directly over allMembers list, why would you
 prefer array here?
Hmm, indeed. One advantage would be to get a range, and thus the power and filtering, mapping and co.
Apr 28 2014