Re: constructing labels for static foreach inside switch inside foreach

2020-07-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/8/20 9:38 AM, ag0aep6g wrote:

On 08.07.20 14:24, Steven Schveighoffer wrote:
I solved it for now by extrapolating the inner code into a local 
template function. But this is definitely an awkward situation for 
static foreach.


FWIW, you can write the extra function like this:

     static foreach (T; Types)
     () {
     innerloop: while (haveMoreData)
     {
     ...
     break innerloop;
     ...
     }
     } ();



Ooh, that's a good idea. That avoids having to declare a template 
function before the loop (I can't declare it inside because, then 
multiple functions of the same name would exist lol).


Works like a charm, thanks!

-Steve


Re: constructing labels for static foreach inside switch inside foreach

2020-07-08 Thread ag0aep6g via Digitalmars-d-learn

On 08.07.20 14:24, Steven Schveighoffer wrote:
I solved it for now by extrapolating the inner code into a local 
template function. But this is definitely an awkward situation for 
static foreach.


FWIW, you can write the extra function like this:

static foreach (T; Types)
() {
innerloop: while (haveMoreData)
{
...
break innerloop;
...
}
} ();


Re: constructing labels for static foreach inside switch inside foreach

2020-07-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/8/20 6:13 AM, Stanislav Blinov wrote:

On Wednesday, 8 July 2020 at 02:06:01 UTC, Steven Schveighoffer wrote:

Seems simple enough, except that this inner portion is unrolled, and 
if I have more than one type to run this on, I already have an 
"innerloop" label defined.


Is there a way to define a label using a mixin or something? or do I 
have to wrap this in a function?


Is there another way to approach this?


Can't you put a single label after your outer foreach and goto it?


There is potentially code after the while loop that needs to run, but I 
could move that code somewhere else. However it still won't work, 
because static foreach requires a label for break. So if I fix the loop 
problem, I will still have a label problem, because I need to label the 
switch and use labeled breaks on that.


This is really an issue with:

a) static foreach-ing case clauses requires a labeled break.
b) static foreach (or foreach on a tuple) unrolls all the code inside, 
including labels

c) labels have to be unique within the function.

I solved it for now by extrapolating the inner code into a local 
template function. But this is definitely an awkward situation for 
static foreach.


I was hoping I could use mixins or something to make new label names, 
but it appears I cannot (without mixing in the entire loop contents).


-Steve


Re: constructing labels for static foreach inside switch inside foreach

2020-07-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/8/20 5:10 AM, cc wrote:


I think I ran into similar problems due to the requirement to use a 
labeled break inside static foreach.  I got around it by defining enums 
when my target was found and checking if it existed via 
__traits(compiles) to "ignore" the rest of the loop.


Thanks for the suggestion. I've used that trick too, but in this case, I 
still have a problem with the switch label as well (I need to use 
labeled breaks inside the static foreach that generates case clauses).


And in this case, the loop I'm breaking is NOT a static loop, it's a 
regular while loop. And I don't want to ignore the rest of the static loop.


-Steve


Re: constructing labels for static foreach inside switch inside foreach

2020-07-08 Thread Stanislav Blinov via Digitalmars-d-learn
On Wednesday, 8 July 2020 at 02:06:01 UTC, Steven Schveighoffer 
wrote:


Seems simple enough, except that this inner portion is 
unrolled, and if I have more than one type to run this on, I 
already have an "innerloop" label defined.


Is there a way to define a label using a mixin or something? or 
do I have to wrap this in a function?


Is there another way to approach this?


Can't you put a single label after your outer foreach and goto it?


Re: constructing labels for static foreach inside switch inside foreach

2020-07-08 Thread cc via Digitalmars-d-learn
On Wednesday, 8 July 2020 at 02:06:01 UTC, Steven Schveighoffer 
wrote:
OK, so I have a situation where I'm foreaching over a 
compile-time list of types. Inside the loop, I'm using a second 
loop over a set of input.


Inside that loop, I'm using a switch on the input, and inside 
the switch, I'm foreaching over the type's members, to 
construct a switch that can handle member names (this is for 
serialization).


If I encounter a certain name, then I want to break out of the 
inner loop (it's a while loop)


So naturally, I have to use break statements with labels like:

innerloop:
while(haveMoreData)
   switchstmt:
   switch(nextDataElement) {
  static foreach(name; __traits(allMembers, T)) {
  case name:
 ... // handle it
 break switchstmt;
  }
  case "STOP":
 break innerloop;
   }

Seems simple enough, except that this inner portion is 
unrolled, and if I have more than one type to run this on, I 
already have an "innerloop" label defined.


Is there a way to define a label using a mixin or something? or 
do I have to wrap this in a function?


Is there another way to approach this?

-Steve


I think I ran into similar problems due to the requirement to use 
a labeled break inside static foreach.  I got around it by 
defining enums when my target was found and checking if it 
existed via __traits(compiles) to "ignore" the rest of the loop.
Sorry if I got what you're trying to accomplish wrong or this is 
too ugly:


class Foo {
@(RPC) bar(int x, float f, string s) {
// ...
}
}

class Remoter(T) {
void opDispatch(string s, SA...)(SA sargs) {
alias A = getSymbolsByUDA!(T, RPC);
static foreach (idx, FUNC; A) {
			static if (!__traits(compiles, FOUND) && hasUDA!(FUNC, RPC) && 
FUNCNAME!FUNC == s && SA.length == (Parameters!FUNC).length) {

version(CheckImplicitlyConvertibleArgs) {
static foreach (argi; 0 .. SA.length) {
		static if (!__traits(compiles, mixin(format("MISMATCH_%d", 
idx {
			static if (isImplicitlyConvertible!(SA[argi], 
(Parameters!FUNC)[argi])) {
//pragma(msg, format("implc ok: %s => %s", 
SA[argi].stringof, (Parameters!FUNC)[argi].stringof));

// Parameter Ok
} else {
pragma(msg, format("RPC argument[%s] of %s is not 
implicitly convertible: %s => %s", argi, FUNCNAME!FUNC, 
SA[argi].stringof, (Parameters!FUNC)[argi].stringof));

mixin(`enum bool 
`~format("MISMATCH_%d", idx)~` = true;`);
}
}
}
	static if (!__traits(compiles, mixin(format("MISMATCH_%d", 
idx {

enum FOUND = idx;
//pragma(msg, format("and we found: 
%s", FOUND));
}
} else {
enum FOUND = idx;
}
}
}
static if (__traits(compiles, FOUND)) {
alias FUNC = A[FOUND];

			// generate a packet to transmit that corresponds to RPC 
function call


} else {
			static assert(0, format("No matching function found for %s%s", 
s, SA.stringof));

}
}
}

Remoter!foo remote;
remote.bar(4, 3.14f, "hello"); // succeeds
remote.bar("hi", 12); // static assert fail



Re: constructing labels for static foreach inside switch inside foreach

2020-07-07 Thread bauss via Digitalmars-d-learn
On Wednesday, 8 July 2020 at 02:06:01 UTC, Steven Schveighoffer 
wrote:
OK, so I have a situation where I'm foreaching over a 
compile-time list of types. Inside the loop, I'm using a second 
loop over a set of input.


Inside that loop, I'm using a switch on the input, and inside 
the switch, I'm foreaching over the type's members, to 
construct a switch that can handle member names (this is for 
serialization).


If I encounter a certain name, then I want to break out of the 
inner loop (it's a while loop)


So naturally, I have to use break statements with labels like:

innerloop:
while(haveMoreData)
   switchstmt:
   switch(nextDataElement) {
  static foreach(name; __traits(allMembers, T)) {
  case name:
 ... // handle it
 break switchstmt;
  }
  case "STOP":
 break innerloop;
   }

Seems simple enough, except that this inner portion is 
unrolled, and if I have more than one type to run this on, I 
already have an "innerloop" label defined.


Is there a way to define a label using a mixin or something? or 
do I have to wrap this in a function?


Is there another way to approach this?

-Steve


Unfortunately mixin does not support labels so I don't think you 
can do what you want to do.


Kind of surprised me tbh


constructing labels for static foreach inside switch inside foreach

2020-07-07 Thread Steven Schveighoffer via Digitalmars-d-learn
OK, so I have a situation where I'm foreaching over a compile-time list 
of types. Inside the loop, I'm using a second loop over a set of input.


Inside that loop, I'm using a switch on the input, and inside the 
switch, I'm foreaching over the type's members, to construct a switch 
that can handle member names (this is for serialization).


If I encounter a certain name, then I want to break out of the inner 
loop (it's a while loop)


So naturally, I have to use break statements with labels like:

innerloop:
while(haveMoreData)
   switchstmt:
   switch(nextDataElement) {
  static foreach(name; __traits(allMembers, T)) {
  case name:
 ... // handle it
 break switchstmt;
  }
  case "STOP":
 break innerloop;
   }

Seems simple enough, except that this inner portion is unrolled, and if 
I have more than one type to run this on, I already have an "innerloop" 
label defined.


Is there a way to define a label using a mixin or something? or do I 
have to wrap this in a function?


Is there another way to approach this?

-Steve