www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - is this even possible? newbie + mixin template + foreach (allMembers)

reply Carlos Navarro <carlos.ns gmail.com> writes:
QUESTION:

Obviously I'm no geting mixins/templates nor traits and I'm 
failing miserably to find/identify the right examples or 
documentation to help me tackle this thing. What is wrong in this 
code? is this pattern sintactically possible? what I'm getting 
wrong?

CONTEXT:
I'm a newbie trying to extend a struct using a mixin template 
like this one:

struct World {
	float	 rotation;
	bool	 active;
	mixin BuildStuff;
}

mixin template BuildStuff() {
	foreach(elem; __traits(allMembers, typeof(this))) {
		//pragma(msg, elem);
	}
} //full example here: https://run.dlang.io/is/OeXS4j

COMPILER OUTPUT:

2.067.1 to 2.071.2: Failure with output:
-----
onlineapp.d(18): Error: declaration expected, not 'foreach'
onlineapp.d(18): Error: declaration expected, not '__traits'
onlineapp.d(22): Error: template member expected
-----

2.072.2 to 2.075.1: Failure with output:
-----
onlineapp.d(18): Error: declaration expected, not 'foreach'
onlineapp.d(18): Error: declaration expected, not '__traits'
onlineapp.d(22): Error: matching '}' expected, not EOF
-----

Since      2.076.1: Segfault and no output
Apr 03 2018
next sibling parent reply WebFreak001 <d.forum webfreak.org> writes:
On Tuesday, 3 April 2018 at 18:49:00 UTC, Carlos Navarro wrote:
 QUESTION:

 Obviously I'm no geting mixins/templates nor traits and I'm 
 failing miserably to find/identify the right examples or 
 documentation to help me tackle this thing. What is wrong in 
 this code? is this pattern sintactically possible? what I'm 
 getting wrong?

 CONTEXT:
 I'm a newbie trying to extend a struct using a mixin template 
 like this one:

 struct World {
 	float	 rotation;
 	bool	 active;
 	mixin BuildStuff;
 }

 mixin template BuildStuff() {
 	foreach(elem; __traits(allMembers, typeof(this))) {
 		//pragma(msg, elem);
 	}
 } //full example here: https://run.dlang.io/is/OeXS4j

 COMPILER OUTPUT:

 2.067.1 to 2.071.2: Failure with output:
 -----
 onlineapp.d(18): Error: declaration expected, not 'foreach'
 onlineapp.d(18): Error: declaration expected, not '__traits'
 onlineapp.d(22): Error: template member expected
 -----

 2.072.2 to 2.075.1: Failure with output:
 -----
 onlineapp.d(18): Error: declaration expected, not 'foreach'
 onlineapp.d(18): Error: declaration expected, not '__traits'
 onlineapp.d(22): Error: matching '}' expected, not EOF
 -----

 Since      2.076.1: Segfault and no output
you need to use a static foreach for this. You can insert a static foreach basically where you can insert a function definition like void foo() {} foreach is more like a function call like foo(), so you can't put it in the mixin template. A mixin template is basically expected to be mixin-able in global scope or in a class/struct so it can't have any things like function calls because that would be the same as writing `foo();` at global level instead of in the main function. static foreach on the other hand allows exactly that because it literally unrolls the contents and inserts it multiple times, so you can also put it in mixin templates if the content of the loop is valid in mixin templates. If you need to support older compilers you can use normal foreach with ctfe by generating a code string or do recursive templates, but I would really encourage you to use static foreach instead, it is cleaner and faster.
Apr 03 2018
parent Alex <sascha.orlov gmail.com> writes:
On Tuesday, 3 April 2018 at 18:57:29 UTC, WebFreak001 wrote:
 you need to use a static foreach for this. You can insert a 
 static foreach basically where you can insert a function 
 definition like void foo() {}

 foreach is more like a function call like foo(), so you can't 
 put it in the mixin template.

 A mixin template is basically expected to be mixin-able in 
 global scope or in a class/struct so it can't have any things 
 like function calls because that would be the same as writing 
 `foo();` at global level instead of in the main function.

 static foreach on the other hand allows exactly that because it 
 literally unrolls the contents and inserts it multiple times, 
 so you can also put it in mixin templates if the content of the 
 loop is valid in mixin templates.

 If you need to support older compilers you can use normal 
 foreach with ctfe by generating a code string or do recursive 
 templates, but I would really encourage you to use static 
 foreach instead, it is cleaner and faster.
I think, the OP has something other in mind. Look at this: ´´´ void main(){} struct World { float rotation; bool active; //mixin BuildStuff!(); } mixin BuildStuff!(); mixin template BuildStuff() { static foreach(elem; __traits(allMembers, World)) { pragma(msg, elem); } } ´´´ While the outer mixin works as expected, the inner one results in a seg fault. No idea why, however, too...
Apr 03 2018
prev sibling parent Seb <seb wilzba.ch> writes:
On Tuesday, 3 April 2018 at 18:49:00 UTC, Carlos Navarro wrote:
 QUESTION:

 Obviously I'm no geting mixins/templates nor traits and I'm 
 failing miserably to find/identify the right examples or 
 documentation to help me tackle this thing. What is wrong in 
 this code? is this pattern sintactically possible? what I'm 
 getting wrong?

 [...]
ICEs (compiler segfault) should _always_ be reported on Bugzilla. The compiler should never ever segfault - even on invalid code. I just did so for you: https://issues.dlang.org/show_bug.cgi?id=18718
Apr 03 2018