Commit 972cab5bb0
Changed files (1)
lib
std
lib/std/bit_set.zig
@@ -184,6 +184,14 @@ pub fn IntegerBitSet(comptime size: u16) type {
return @ctz(mask);
}
+ /// Finds the index of the last set bit.
+ /// If no bits are set, returns null.
+ pub fn findLastSet(self: Self) ?usize {
+ const mask = self.mask;
+ if (mask == 0) return null;
+ return bit_length - @clz(mask) - 1;
+ }
+
/// Finds the index of the first set bit, and unsets it.
/// If no bits are set, returns null.
pub fn toggleFirstSet(self: *Self) ?usize {
@@ -542,6 +550,24 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type {
return offset + @ctz(mask);
}
+ /// Finds the index of the last set bit.
+ /// If no bits are set, returns null.
+ pub fn findLastSet(self: Self) ?usize {
+ if (bit_length == 0) return null;
+ const bs = @bitSizeOf(MaskInt);
+ var len = bit_length / bs;
+ if (bit_length % bs != 0) len += 1;
+ var offset: usize = len * bs;
+ var idx: usize = len - 1;
+ while (self.masks[idx] == 0) : (idx -= 1) {
+ offset -= bs;
+ if (idx == 0) return null;
+ }
+ offset -= @clz(self.masks[idx]);
+ offset -= 1;
+ return offset;
+ }
+
/// Finds the index of the first set bit, and unsets it.
/// If no bits are set, returns null.
pub fn toggleFirstSet(self: *Self) ?usize {
@@ -941,6 +967,24 @@ pub const DynamicBitSetUnmanaged = struct {
return offset + @ctz(mask[0]);
}
+ /// Finds the index of the last set bit.
+ /// If no bits are set, returns null.
+ pub fn findLastSet(self: Self) ?usize {
+ if (self.bit_length == 0) return null;
+ const bs = @bitSizeOf(MaskInt);
+ var len = self.bit_length / bs;
+ if (self.bit_length % bs != 0) len += 1;
+ var offset: usize = len * bs;
+ var idx: usize = len - 1;
+ while (self.masks[idx] == 0) : (idx -= 1) {
+ offset -= bs;
+ if (idx == 0) return null;
+ }
+ offset -= @clz(self.masks[idx]);
+ offset -= 1;
+ return offset;
+ }
+
/// Finds the index of the first set bit, and unsets it.
/// If no bits are set, returns null.
pub fn toggleFirstSet(self: *Self) ?usize {
@@ -1160,6 +1204,12 @@ pub const DynamicBitSet = struct {
return self.unmanaged.findFirstSet();
}
+ /// Finds the index of the last set bit.
+ /// If no bits are set, returns null.
+ pub fn findLastSet(self: Self) ?usize {
+ return self.unmanaged.findLastSet();
+ }
+
/// Finds the index of the first set bit, and unsets it.
/// If no bits are set, returns null.
pub fn toggleFirstSet(self: *Self) ?usize {
@@ -1514,8 +1564,10 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void {
}
}
try testing.expectEqual(@as(?usize, null), a.findFirstSet());
+ try testing.expectEqual(@as(?usize, null), a.findLastSet());
try testing.expectEqual(@as(?usize, null), a.toggleFirstSet());
try testing.expectEqual(@as(?usize, null), a.findFirstSet());
+ try testing.expectEqual(@as(?usize, null), a.findLastSet());
try testing.expectEqual(@as(?usize, null), a.toggleFirstSet());
try testing.expectEqual(@as(usize, 0), a.count());