Files
vulkan-zig/generator/flags.zig
Robin Voetter 687e1dd300 FlagTraits
2020-05-20 01:41:04 +02:00

68 lines
2.0 KiB
Zig

const std = @import("std");
const testing = std.testing;
fn FlagTraits(comptime Self: type) type {
return struct {
pub fn init(flags: var) Self {
var self: u32 = 0;
inline for (std.meta.fields(@TypeOf(flags))) |field| {
self |= @enumToInt(@as(Self, @field(flags, field.name)));
}
return @intToEnum(Self, self);
}
pub fn merge(lhs: Self, rhs: Self) Self {
return @intToEnum(Self, @enumToInt(lhs) | @enumToInt(rhs));
}
pub fn intersect(lhs: Self, rhs: Self) Self {
return @intToEnum(Self, @enumToInt(lhs) & @enumToInt(rhs));
}
pub fn subtract(lhs: Self, rhs: Self) Self {
return @intToEnum(Self, @enumToInt(lhs) & @enumToInt(rhs.complement()));
}
pub fn complement(self: Self) Self {
const all = comptime blk: {
var flags: u32 = 0;
for (std.meta.fields(Self)) |field| {
flags |= field.value;
}
break :blk flags;
};
return @intToEnum(Self, ~@enumToInt(self) & all);
}
pub fn contains(lhs: Self, rhs: Self) bool {
return @enumToInt(lhs) & @enumToInt(rhs) == @enumToInt(rhs);
}
pub fn format(
self: Self,
fmt: []const u8,
options: std.fmt.FormatOptions,
out_stream: var
) @TypeOf(out_stream).Error!void {
const bits = @enumToInt(self);
var first = true;
inline for (std.meta.fields(Self)) |field| {
if (@popCount(u32, field.value) != 1) continue;
if (bits & field.value == field.value) {
if (first) {
first = false;
} else {
try std.fmt.formatBuf(" | ", options, out_stream);
}
try std.fmt.formatBuf(field.name, options, out_stream);
}
}
}
};
}