I’m trying to simplify a set of chained if-elses
if( time < duration_1 ) {
return computation( time, factor_1, offset_1 );
}
else if( time < duration_1 + duration_2 ) {
return computation( time - duration_1, factor_2, offset_2 );
}
# ...
else {
return final;
}
By using a macro-like function to turn a list of constraints into the above logic:
const Step = struct { duration: i32, factor: i32, offset: i32, ... };
fn Compute( time: i32, final: i32, steps: []const Step ) i32 {
var base_time = time;
for (steps) |step| {
if( base_time < step.duration ) {
return computation( base_time, step.duration, step.offset );
}
base_time -= step.duration;
}
return final;
}
fn run(...) {
# ...
result = Compute( time, final, ([_]Step {
Step.init( duration_1, factor_1, offset_1 ),
Step.init( duration_2, factor_2, offset_2 ),
})[0..] );
}
Which works, but the complexity of the ([_]Step { ... })[0..]
makes me think I’m doing something wrong. I think it should be possible to do something like fmt since all I want is a comptime macro-like expansion. But I can’t figure out to tell the compiler that “steps” is a variable-length comptime-known list of Step structures.
I.e. simplify the appearance at time of use to something like
result = Compute( time, final, .{
Step.init( duration_1, factor_1, offset_1 ),
Step.init( duration_2, factor_2, offset_2 ),
});