aboutsummaryrefslogtreecommitdiff
path: root/src/bit_set.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/bit_set.zig')
-rw-r--r--src/bit_set.zig62
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.