-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Feature proposal: Enumflagset (zig bit flags type) #4185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This will probably be rejected for the reasons given in #2115 (comment) |
Thanks for your input. I guess you refer to this part:
This proposal is meant to be orthogonal to "normal" enums. If you want an enum, extern or otherwise, you will use that. If you want bit flags, you might want this proposed feature instead of using non-exhaustive enums or plain unsigned integers for some extra ergonomics, safety and clarity.
Would enforcing something like this in non-exhaustive enums be possible for example? |
More importantly I was referring to this:
A better way to do bit flags is to use a packed struct with bools: const WidgetAnchor = packed struct{
left: bool,
right: bool,
top: bool,
bottom: bool,
};
@bitSizeOf(WidgetAnchor) == @bitSizeOf(u4) |
Thanks. I didn't realize packed bools only require one bit. Guess so 👍 ⚡ test "bit flags" {
const Bools8 = packed struct {
a: bool = false,
b: bool = false,
c: bool = false,
d: bool = false,
e: bool = false,
f: bool = false,
g: bool = false,
h: bool = false,
const Self = @This();
pub fn as_u8(self: Self) u8 {
return @bitCast(u8, self);
}
};
assert(@sizeOf(Bools8) == @sizeOf(u4));
assert(@sizeOf(Bools8) == @sizeOf(u8));
var bools = Bools8{};
bools.b = true;
var i: u4 = 0;
const as_u8 = bools.as_u8();
while (i < 8) : (i += 1) {
const b = (as_u8 & (@as(u16, 1) << i)) != 0;
assert(if (i == 1) b else !b);
}
inline for (std.meta.fields(Bools8)) |f, j| {
const b = @field(bools, f.name);
warn("{}: {}\n", .{ f.name, b });
assert(if (j == 1) b else !b);
}
} |
Does assert(@sizeOf(Bools8) == @sizeOf(u4));
assert(@sizeOf(Bools8) == @sizeOf(u8)); succeed? Or was assert(@sizeOf(Bools8) == @sizeOf(u4));
assert(@sizeOf(Bools8.as_u8()) == @sizeOf(u8)); intended? |
There is also bitset-zig. |
Below is what I imagine the entry in the zig docs would look like if this feature was implemented.
Edit: added "tag type" and "_SPARE field" to the example below.
Enumflagset
Zig provides
enumflagset
as a safer and more ergonomic way to implement bit flags, as opposed to using plain integers.An
enumflagset
behaves as an integer that is configured with a set of default (power of 2) values, that can be combined with set operations only:union
,intersection
,complement
andequality
. (respectively, bitwise:or
,and
,not
,equals
). These set operations are closed for theenumflagset
, except the equals operator which can accept a0
as an operand.The complement operation (bitwise not) is restricted to the bits in use, so masking is not necessary.
The text was updated successfully, but these errors were encountered: