Static Foreach + Marking "compile time" variables

Chris Katko ckatko at gmail.com
Wed Mar 28 23:02:53 UTC 2018


On Wednesday, 28 March 2018 at 17:42:45 UTC, Steven Schveighoffer 
wrote:
> On 3/28/18 11:46 AM, Chris Katko wrote:
>
>>      enum hasRotate = anySatisfy!( isa(pos), a);  //if of type 
>> "pos"
>
> anySatisfy!(isa!pos, a)
>
> anySatisfy takes a template alias (in this case, an 
> instantiation of isa with a specific type), and then applies 
> the template to all the elements of the alias sequence, 
> returning true if any statisfy.
>
> -Steve

Yeah, that was one of my errors during my 4 AM binge. But I 
forgot/missed to update that when I posted.

So far, everything is working with some dummy calls, and now I 
just have to start doing the annoying work of writing the code.

It's just... I wish it was a little more elegant. Right now, I'm 
stuck with like tons of static if cases. [see code at end of 
post] If I add "centered position" vs "position" now, I have to 
figure out how to add that into a single compound statement to 
fit into a unique static if. As opposed to simply, "if centered 
pos, take position, and just change it by subtracting width and 
height."  In that case, I can get away with leaving them run-time 
statements, but more complex features not-so-much. The point is 
to use compile-time/static/templates to build the correct 
statement. Because at the core of what I'm doing... it IS all 
statically / compile-time knowable information.

And having TONS of static ifs means there's TONS of room for 
human error as its maintained.

If I wrote a Python/whatever script that pre-processed my D code 
from the AST, I'd have no theoretical reason to prevent me from 
doing this (though, clearly with much added frustration of 
implementation and debugging!).

I'm starting to wonder if a mixin will somehow help... hmm. I'm 
going to keep thinking about the problem.

Some code will probably help explain what I'm talking about:

funct2(g.tile_bmp, pos(100,100), scale(2), rotate(0.0f), 
center());

template isa(T){enum isa(U) = is(U == T); }

void funct2(A...)(ALLEGRO_BITMAP *bit, A a)
	{
	enum hasPosition = anySatisfy!(isa!(pos), typeof(a));
	enum hasCenteredPosition = anySatisfy!(isa!(center), typeof(a));

	enum hasRotate 		= anySatisfy!(isa!(rotate), typeof(a));
	enum hasScale 		= anySatisfy!(isa!(scale), typeof(a));

     static if (hasPosition && hasCenteredPosition)
		{
		float temp_x=a[staticIndexOf!(pos, typeof(a))].x - bit.w/2;
		float temp_y=a[staticIndexOf!(pos, typeof(a))].y - bit.h/2;
		}else{
		float temp_x=a[staticIndexOf!(pos, typeof(a))].x;
		float temp_y=a[staticIndexOf!(pos, typeof(a))].y;
		}

     static if (!hasPosition)
		{
		assert(0, "Need to pass a position!");
		}

     static if (hasPosition && !hasRotate && !hasScale)
		{
         // Stuff
		pragma(msg, "Class 1");
		writeln("x ", a[staticIndexOf!(pos, typeof(a))].x);
		writeln("y ", a[staticIndexOf!(pos, typeof(a))].y);
		
		al_draw_bitmap(bit,
			temp_x,
			temp_y,
			0);
		}

     static if (hasPosition && hasRotate && !hasScale)
		{
         // Stuff
		pragma(msg, "Class 2");
		writeln("x ", a[staticIndexOf!(pos, typeof(a))].x);
		writeln("y ", a[staticIndexOf!(pos, typeof(a))].y);
		
		al_draw_rotated_bitmap(bit,
			bit.w/2,
			bit.h/2,
			temp_x,
			temp_y,
			a[staticIndexOf!(rotate, typeof(a))].a,
			0);
				
		}


     static if (hasPosition && !hasRotate && hasScale)
		{
		pragma(msg, "Class 3");
		}

     static if (hasPosition && hasRotate && hasScale)
		{
		pragma(msg, "Class 4");
		}




	}


More information about the Digitalmars-d-learn mailing list