mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 10:58:56 +00:00
117 lines
3.4 KiB
Zig
117 lines
3.4 KiB
Zig
const std = @import("std");
|
|
|
|
pub fn Bitflags(comptime T: type) type {
|
|
const tyinfo = @typeInfo(T);
|
|
const IntType = tyinfo.@"struct".backing_integer.?;
|
|
const IntTypeInfo = @typeInfo(IntType);
|
|
const IntRepresentingNumOfBits = std.math.IntFittingRange(0, IntTypeInfo.int.bits);
|
|
|
|
return struct {
|
|
pub const IMPL_BITFLAGS: u0 = 0;
|
|
|
|
pub inline fn empty() T {
|
|
return @bitCast(@as(IntType, 0));
|
|
}
|
|
|
|
pub inline fn intersects(lhs: T, rhs: T) bool {
|
|
return asBits(lhs) & asBits(rhs) != 0;
|
|
}
|
|
|
|
pub inline fn fromName(comptime name: []const u8) T {
|
|
var this: T = .{};
|
|
@field(this, name) = true;
|
|
return this;
|
|
}
|
|
|
|
pub inline fn fromNames(comptime names: []const []const u8) T {
|
|
var this: T = .{};
|
|
inline for (names) |name| {
|
|
@field(this, name) = true;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
pub fn bitwiseOr(lhs: T, rhs: T) T {
|
|
return @bitCast(@as(IntType, @bitCast(lhs)) | @as(IntType, @bitCast(rhs)));
|
|
}
|
|
|
|
pub fn bitwiseAnd(lhs: T, rhs: T) T {
|
|
return @bitCast(@as(IntType, asBits(lhs) & asBits(rhs)));
|
|
}
|
|
|
|
pub inline fn intersect(lhs: T, rhs: T) T {
|
|
return bitwiseAnd(lhs, rhs);
|
|
}
|
|
|
|
pub inline fn insert(this: *T, other: T) void {
|
|
this.* = bitwiseOr(this.*, other);
|
|
}
|
|
|
|
pub inline fn remove(this: *T, other: T) void {
|
|
this.* = @bitCast(asBits(this.*) & ~asBits(other));
|
|
}
|
|
|
|
pub inline fn maskOut(this: T, other: T) T {
|
|
return @bitCast(asBits(this) & ~asBits(other));
|
|
}
|
|
|
|
pub fn contains(lhs: T, rhs: T) bool {
|
|
return @as(IntType, @bitCast(lhs)) & @as(IntType, @bitCast(rhs)) != 0;
|
|
}
|
|
|
|
pub inline fn leadingZeroes(this: T) IntRepresentingNumOfBits {
|
|
return @clz(asBits(this));
|
|
}
|
|
|
|
pub inline fn all() T {
|
|
var ret: T = @bitCast(@as(IntType, 0));
|
|
@setEvalBranchQuota(5000);
|
|
inline for (std.meta.fields(T)) |field| {
|
|
if (comptime !std.mem.eql(u8, field.name, "__unused")) {
|
|
@field(ret, field.name) = true;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
pub inline fn not(this: T) T {
|
|
return fromBitsTruncate(~asBits(this));
|
|
}
|
|
|
|
pub inline fn difference(lhs: T, rhs: T) T {
|
|
// 1100 1100 1100
|
|
// 1010 0101 0100
|
|
return @bitCast(asBits(lhs) & asBits(not(rhs)));
|
|
}
|
|
|
|
/// Convert from a bits value, unsetting any unknown bits.
|
|
pub inline fn fromBitsTruncate(bits: IntType) T {
|
|
return bitwiseAnd(@bitCast(bits), all());
|
|
}
|
|
|
|
pub inline fn asBits(this: T) IntType {
|
|
return @as(IntType, @bitCast(this));
|
|
}
|
|
|
|
pub fn isEmpty(this: T) bool {
|
|
return asBits(this) == 0;
|
|
}
|
|
|
|
pub fn eq(lhs: T, rhs: T) bool {
|
|
return asBits(lhs) == asBits(rhs);
|
|
}
|
|
|
|
pub fn eql(lhs: T, rhs: T) bool {
|
|
return eq(lhs, rhs);
|
|
}
|
|
|
|
pub fn neq(lhs: T, rhs: T) bool {
|
|
return asBits(lhs) != asBits(rhs);
|
|
}
|
|
|
|
pub fn hash(this: *const T, hasher: *std.hash.Wyhash) void {
|
|
hasher.update(std.mem.asBytes(this));
|
|
}
|
|
};
|
|
}
|