diff options
author | 2023-02-05 02:26:20 -0800 | |
---|---|---|
committer | 2023-02-05 02:26:20 -0800 | |
commit | f913a468c2d9d57e6e21ed9f5b07d6cce12cc09b (patch) | |
tree | c058ac9f09f58bed54997dad1753d77a18dcde83 /src/bit_set.zig | |
parent | bd4d8bdb6a7fa3a67a0e7efee3fa375b831317b7 (diff) | |
download | bun-f913a468c2d9d57e6e21ed9f5b07d6cce12cc09b.tar.gz bun-f913a468c2d9d57e6e21ed9f5b07d6cce12cc09b.tar.zst bun-f913a468c2d9d57e6e21ed9f5b07d6cce12cc09b.zip |
WIP
Diffstat (limited to 'src/bit_set.zig')
-rw-r--r-- | src/bit_set.zig | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/src/bit_set.zig b/src/bit_set.zig index f334ae826..f3ca18df7 100644 --- a/src/bit_set.zig +++ b/src/bit_set.zig @@ -781,10 +781,8 @@ pub const DynamicBitSetUnmanaged = struct { return (self.masks[maskIndex(index)] & maskBit(index)) != 0; } - pub fn byteRange(self: Self, start: usize, len: usize) []const u8 { - assert(start < self.bit_length); - const offset = maskIndex(start); - return std.mem.sliceAsBytes(self.masks[offset .. offset + len]); + pub fn bytes(self: Self) []const u8 { + return std.mem.sliceAsBytes(self.masks[0 .. numMasks(self.bit_length) + 1]); } /// Returns the total number of set bits in this bit set. @@ -1056,6 +1054,62 @@ pub const DynamicBitSetUnmanaged = struct { } }; +pub const AutoBitSet = union(enum) { + const Static = ArrayBitSet(usize, (@bitSizeOf(DynamicBitSetUnmanaged) - 1)); + + static: Static, + dynamic: DynamicBitSetUnmanaged, + + pub fn needsDynamic(bit_length: usize) bool { + return bit_length > Static.bit_length; + } + + pub fn initEmpty(allocator: Allocator, bit_length: usize) !AutoBitSet { + if (bit_length <= Static.bit_length) { + return AutoBitSet{ .static = Static.initEmpty() }; + } else { + return AutoBitSet{ .dynamic = try DynamicBitSetUnmanaged.initEmpty(allocator, bit_length) }; + } + } + + pub fn isSet(this: *const AutoBitSet, index: usize) bool { + return switch (std.meta.activeTag(this.*)) { + .static => this.static.isSet(index), + .dynamic => this.dynamic.*.isSet(index), + }; + } + + pub fn clone(this: *const AutoBitSet, allocator: std.mem.Allocator) AutoBitSet { + return switch (std.meta.activeTag(this.*)) { + .static => AutoBitSet{ .static = this.static }, + .dynamic => AutoBitSet{ .dynamic = this.dynamic.*.clone(allocator) }, + }; + } + + pub fn set(this: *const AutoBitSet, index: usize) void { + switch (std.meta.activeTag(this.*)) { + .static => this.static.set(index), + .dynamic => this.dynamic.set(index), + } + } + + pub fn bytes(this: *const AutoBitSet) []const u8 { + return switch (std.meta.activeTag(this.*)) { + .static => std.mem.asBytes(&this.static.masks), + .dynamic => this.dynamic.*.bytes(), + }; + } + + pub fn deinit(this: *AutoBitSet, allocator: std.mem.Allocator) void { + switch (std.meta.activeTag(this.*)) { + .static => {}, + .dynamic => { + this.dynamic.deinit(allocator); + }, + } + } +}; + /// A bit set with runtime-known size, backed by an allocated slice /// of usize. Thin wrapper around DynamicBitSetUnmanaged which keeps /// track of the allocator instance. |