Skip to content
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

Should flags be represented as enums? #4

Open
xtian opened this issue May 31, 2021 · 8 comments
Open

Should flags be represented as enums? #4

xtian opened this issue May 31, 2021 · 8 comments

Comments

@xtian
Copy link

xtian commented May 31, 2021

Regarding this TODO:

try writer.line("// TODO: This Enum is marked as [Flags], what do I do with this?");

Is there a big benefit to representing these values as non-exhaustive enums? My impression is that the common case is combining multiple bitmask values together which is awkward with the current setup. For example:

const std = @import("std");
const win32 = @import("win32").everything;

const class = std.mem.zeroInit(win32.WNDCLASSEXA, .{
    .style = @intToEnum(win32.WNDCLASS_STYLES, @enumToInt(win32.CS_HREDRAW) | @enumToInt(win32.CS_VREDRAW) | @enumToInt(win32.CS_OWNDC)),
});
@marler8997
Copy link
Collaborator

Yeah I agree that in the case of enum flags, you always have to convert to an int and back to the enum which throws type safety out the window. I'd be curious if anyone has a better idea than just raw integer types though.

@marler8997
Copy link
Collaborator

marler8997 commented Jun 1, 2021

Looks like this zig proposal could be a solution: ziglang/zig#5049

It updates packed structs to specify an underlying integer type so they are compatible with the C abi. If that proposal is going to be accepted, we might be able to start transitioning to it beforehand.

@marler8997
Copy link
Collaborator

Ok I came up with one idea, I've added an initFlags method to all enum flag types for now. So your example could become this:

const class = std.mem.zeroInit(win32.WNDCLASSEXA, .{
    .style = win32.WNDCLASS_STYLES.initFlags(.{.HREDRAW = 1, .VREDRAW = 1, .OWNDC = 1});
});

Full API diff for this change is here: marlersoft/zigwin32@89203c6#diff-bd4f828bddb85d1324457f27ad66278624ef2539c5036de4c596d3b15a695820R3458

It affected 11,500 lines!

@xtian
Copy link
Author

xtian commented Jun 2, 2021

@marler8997 Ok that seems like a decent solution for now. I like the idea of integer-backed packed structs though.

Here's at least one case that your solution doesn't handle:

VIRTUAL_ALLOCATION_TYPE is evidently not marked as "Flags", but VirtualAlloc can be called with MEM_COMMIT | MEM_RESERVE. VIRTUAL_ALLOCATION_TYPE also isn't a non-exhaustive enum, so the @intToEnum method doesn't work either.

@marler8997
Copy link
Collaborator

@xtian good catch. I've created an issue with the win32metadata project here: microsoft/win32metadata#507

@marler8997
Copy link
Collaborator

marler8997 commented Jun 7, 2021

Just did a new zigwin32 release. Looks like VIRTUAL_ALLOCATION_TYPE is now properly marked with the [Flags] attribute (see https://github.com/marlersoft/zigwin32/blob/146598875015d7b1597af579ce0d41a93e1f4144/win32/system/memory.zig#L374).

@capthehacker99
Copy link

So how do you check if a flag exist?
Mentioned in this issue: marlersoft/zigwin32#28

@marler8997
Copy link
Collaborator

zigwin32 has moved on to using packed structs to represent flags which are very nice to use, so this issue should be addressed now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants