matklad
1
It is possible to use usingnamespace
hack to conditionally include declarations into a struct based on some comptime parameters, like here:
Is there something analogues for fields?
I know that I can use
if (comptime_condition) {
return struct { foo: i32 };
} else {
return struct { bar: bool };
}
but that requires duplicating everything else that’s common.
I also can do something like
var fields: []StructField = []
if (comptime_condition) {
fields = fields ++ ... ;
} else {
fields = fields ++ ... ;
}
return @Type(.Struct = { .fields = fields });
This gets rid of duplication, at the cost of constructing the whole thing through reflection.
What I’d ideally want is something along the lines of
return struct {
if (comptime_condition) {
foo: i32,
} else {
bar: bool,
}
}
Is this possible in today’s Zig somehow?
3 Likes
Something I’ve seen the standard library do pretty often for this type of thing would be:
const Foo = struct {
foo: if (comptime_condition) i32 else void,
bar: if (!comptime_condition) bool else void,
}
Here’s an example from the GPA:
(note also the @TypeOf
usage in total_requested_bytes
/requested_memory_limit
/mutex
to make the pattern slightly nicer)
5 Likes
You can do something similar with reflection and tuple concatenation:
return createStruct (
.{"first", bool}
++ if (comptime_condition) {
.{"foo", i32}
} else {
.{"bar", bool}
}
++ .{"baz", f32}
++ ...
)
Where createStruct
parses the tuple and creates the struct fields:
fn createStruct(comptime tuple: anytype) type {
var fields: []StructField = []
var i: usize = 0;
while(i < tuple.len): (i += 2) {
fields = fields ++ .{.name = tuple[i], .type = tuple[i+1], ...};
}
return @Type(.Struct = { .fields = fields });
}
3 Likes