Files
bun.sh/src/bits.zig
chloe caruso a3809676e9 remove all usingnamespace in css (#19067)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-04-17 14:17:08 -07:00

61 lines
1.8 KiB
Zig

//! Bitfield helper functions. T should be a packed struct of booleans.
/// If the right side is known at compile time, you should just perform field accesses
///
/// intersects(T, a, .{ .flag = true }) --> a.flag
///
pub inline fn intersects(comptime T: type, lhs: T, rhs: T) bool {
return asInt(T, lhs) & asInt(T, rhs) != 0;
}
pub inline fn @"and"(comptime T: type, lhs: T, rhs: T) T {
return fromInt(T, asInt(T, lhs) & asInt(T, rhs));
}
pub inline fn @"or"(comptime T: type, lhs: T, rhs: T) T {
return fromInt(T, asInt(T, lhs) | asInt(T, rhs));
}
pub inline fn invert(comptime T: type, value: T) T {
return fromInt(T, ~asInt(T, value));
}
/// Prefer a property assignment when possible
///
/// insert(T, &a, .{ .flag = true }) --> a.flag = true;
///
pub inline fn insert(comptime T: type, lhs: *T, rhs: T) void {
lhs.* = @"or"(T, lhs.*, rhs);
}
pub inline fn contains(comptime T: type, lhs: T, rhs: T) bool {
return (asInt(T, lhs) & asInt(T, rhs)) != 0;
}
pub inline fn maskOut(comptime T: type, lhs: *T, rhs: T) T {
return @"and"(T, lhs, invert(T, rhs));
}
pub inline fn remove(comptime T: type, lhs: *T, rhs: T) void {
lhs.* = @"and"(T, lhs.*, invert(T, rhs));
}
pub inline fn leadingZeros(comptime T: type, value: T) LeadingZerosInt(T) {
return @clz(asInt(T, value));
}
pub fn LeadingZerosInt(comptime T: type) type {
const backing_int = @typeInfo(T).@"struct".backing_integer.?;
return std.math.IntFittingRange(0, @typeInfo(backing_int).int.bits);
}
pub inline fn fromInt(comptime T: type, bits: @typeInfo(T).@"struct".backing_integer.?) T {
return @bitCast(bits);
}
pub inline fn asInt(comptime T: type, value: T) @typeInfo(T).@"struct".backing_integer.? {
return @bitCast(value);
}
const std = @import("std");