Static Foreach + Marking "compile time" variables
Chris Katko
ckatko at gmail.com
Wed Mar 28 15:46:42 UTC 2018
On Wednesday, 28 March 2018 at 08:05:55 UTC, Simen Kjærås wrote:
> On Wednesday, 28 March 2018 at 07:45:59 UTC, Chris Katko wrote:
>> I have a static foreach that goes through the parameter list
>> and if it sees a class like "rotate", ideally, I want it to
>> mark a boolean "has_rotate=true"
>>
>> Then simply later on, once I've parsed the list, I pick an
>> output path:
>>
>> static if(has_rotate && has_position && has_scale)
>> {
>> //call C function al_draw_rotated_scaled_bitmap(...);
>> }
>>
>> So I pass a bunch of "options" and then based on those
>> options, it picks the right function to call instead of me
>> manually writing
>> draw_fixed_centered_rotated_scaled_colored_compressed_bitmap()
>> manually.
>>
>> The problem is, I can foreach through those parameters all
>> just fine... but I can't "set" a marker.
>>
>> The error message makes perfect sense in retrospect:
>>
>> variable has_position cannot be read at compile time
>>
>> has_position isn't a static/compile-time variable. The
>> question is... do they exist in D? Because otherwise, I'll be
>> going from a really clean, elegant solution that simply passes
>> through each parameter, and then reacts to the combined
>> result, and end up with something that has to "step toward"
>> the result, or perhaps, test every possible permutation
>> individually--so as to not need variables.
>
> D does not have compile-time variables. The way you'd generally
> do what you describe is with the templates in std.meta. Instead
> of something like this:
>
> bool hasRotate= false;
> static foreach (e; MyTuple) {
> hasRotate |= is(e == Rotate);
> }
> static if (hasRotate) { // Fails, since b is a runtime
> variable.
> // Stuff
> }
>
> You'd be using a more functional style:
>
> template isa(T) {
> enum isa(U) = is(U == T);
> }
>
> enum hasRotate = anySatisfy!(isa!Rotate, MyTuple);
> static if (hasRotate) {
> // Stuff
> }
>
> --
> Simen
Thank you for the reply! But I'm unable to get that code to
compile. For example:
/usr/local/bin/../import/std/meta.d(883): Error: template
instance F!(_param_1) does not match template declaration
isIntegral(T)
/usr/local/bin/../import/std/meta.d(888): Error: template
instance extra.funct2!(int, int,
int).funct2.anySatisfy!(isIntegral, _param_1) error instantiating
extra.d(264): instantiated from here:
anySatisfy!(isIntegral, _param_1, _param_2, _param_3)
extra.d(385): instantiated from here: funct2!(int, int,
int)
/usr/local/bin/../import/std/meta.d(883): Error: template
instance F!(_param_2) does not match template declaration
isIntegral(T)
/usr/local/bin/../import/std/meta.d(888): Error: template
instance extra.funct2!(int, int,
int).funct2.anySatisfy!(isIntegral, _param_2) error instantiating
/usr/local/bin/../import/std/meta.d(889): instantiated
from here: anySatisfy!(isIntegral, _param_2, _param_3)
extra.d(264): instantiated from here:
anySatisfy!(isIntegral, _param_1, _param_2, _param_3)
extra.d(385): instantiated from here: funct2!(int, int,
int)
/usr/local/bin/../import/std/meta.d(883): Error: template
instance F!(_param_3) does not match template declaration
isIntegral(T)
/usr/local/bin/../import/std/meta.d(889): Error: template
instance extra.funct2!(int, int,
int).funct2.anySatisfy!(isIntegral, _param_3) error instantiating
/usr/local/bin/../import/std/meta.d(889): instantiated
from here: anySatisfy!(isIntegral, _param_2, _param_3)
extra.d(264): instantiated from here:
anySatisfy!(isIntegral, _param_1, _param_2, _param_3)
extra.d(385): instantiated from here: funct2!(int, int,
int)
Perhaps I should post more of my code because there may be subtle
differences that are important:
struct pos{float x, y;}
struct scale{float f;}
struct rotate{ float a; }
void test_inst()
{
funct2(tile_bmp, pos(100,100), scale(2), rotate(0.0f));
//this worked with the foreach version
// in the case that it compiled and read the arguments
}
Then I use your version:
template isa(T) {
enum isa(U) = is(U == T); //is(typeof(U) == T) doesn't
work either.
}
void funct2(A...)(ALLEGRO_BITMAP *bitmap_bmp, A a)
{
enum hasRotate = anySatisfy!( isa(pos), a); //if of type "pos"
static if (hasRotate)
{
// Stuff
}
}
More information about the Digitalmars-d-learn
mailing list