Creating switch cases programmatically

Hello.

I am wondering if there a way to create switch cases programatically. in other words:

const E = enum ( do, re, mi, fa, su, la, si };

pub fn is_one_of(
	info: *const Info,
	comptime flags: anytype, // pass in .{do, re} here
) bool {
    if (some_check(info)) return false;
    
    const c = category(info);
    return switch (c) {
        of_subset(flags) => true,
        else => false,
    };
}

i.e. avoid using a runtime loop ..

my current solution is something like this

pub fn is_one_of(
	info: *const Info,
	comptime flags: anytype, // pass in .{do, re} here
) bool {
    if (some_check(info)) return false;
    
	const c = category(info);
	inline for (flags) |tag| {
		if (c == tag) return true;
	} else return false;
}

this code base uses bitshifts into a mask to make the comparison as quick as possible but i am looking for a more readable way of doing it. I checked before in godbolt, and a switch into an enum more or less compiles the same assembly as the bitshifting. but here I need to “feed” the cases in somehow to avoid duplicating some_check all over the codebase.

You want inline else, which turns a runtime value into a comptime known value by duplicated the switch statements.

Eg,

return switch (tag) {
  inline else => |t| comptime some_condition(t),
}

I would also say the inline for over the allowed flags is a good solution for this specific case. The optimizer should be able to equally optimize such a simple chain of ifs as it could a switch.

5 Likes