kj4tmp
1
I’ve got these two functions that work in zig 0.15.2 but I need to migrate to zig master:
pub fn Exhaustive(@"enum": type) type {
comptime assert(@typeInfo(@"enum").@"enum".is_exhaustive == false);
var type_info = @typeInfo(@"enum");
type_info.@"enum".is_exhaustive = true;
return @Type(type_info);
}
pub fn NonExhaustive(@"enum": type) type {
comptime assert(@typeInfo(@"enum").@"enum".is_exhaustive == true);
var type_info = @typeInfo(@"enum");
type_info.@"enum".is_exhaustive = false;
return @Type(type_info);
}
test Exhaustive {
const MyEnum = enum(u8) {
zero,
one,
two,
_,
};
const NewEnum = Exhaustive(MyEnum);
try std.testing.expect(@typeInfo(NewEnum).@"enum".is_exhaustive);
try std.testing.expectEqual(0, @intFromEnum(NewEnum.zero));
try std.testing.expectEqual(1, @intFromEnum(NewEnum.one));
try std.testing.expectEqual(2, @intFromEnum(NewEnum.two));
}
How do I do this with the new @Enum builtin?
kj4tmp
2
fn EnumWithNewMode(@"enum": type, mode: std.builtin.Type.Enum.Mode) type {
const enum_len = std.meta.fieldNames(@"enum").len;
const enum_values = comptime blk: {
var result: [enum_len]@typeInfo(@"enum").@"enum".tag_type = undefined;
for (&result, std.enums.values(@"enum")) |*r, f| {
r.* = @intFromEnum(f);
}
const final = result;
break :blk &final;
};
return @Enum(
@typeInfo(@"enum").@"enum".tag_type,
mode,
std.meta.fieldNames(@"enum"),
enum_values,
);
}
pub fn Exhaustive(@"enum": type) type {
comptime assert(@typeInfo(@"enum").@"enum".is_exhaustive == false);
return EnumWithNewMode(@"enum", .exhaustive);
}
pub fn NonExhaustive(@"enum": type) type {
comptime assert(@typeInfo(@"enum").@"enum".is_exhaustive == true);
return EnumWithNewMode(@"enum", .nonexhaustive);
}
vulpesx
3
beat me too it, heres what i did anyway:
fn NonExhaustive(en: type) type {
var info = @typeInfo(en).@"enum";
std.debug.assert(info.is_exhaustive == true);
var names: [info.fields.len][]const u8 = undefined;
var values: [info.fields.len]info.tag_type = undefined;
for (info.fields, 0..) |f, i| {
names[i] = f.name;
values[i] = f.value;
}
return @Enum(info.tag_type, .nonexhaustive, &names, &values);
}
kj4tmp
4
I like yours best, has less dependence on std.