| ... | @@ -184,6 +184,14 @@ pub fn IntegerBitSet(comptime size: u16) type { | ... | @@ -184,6 +184,14 @@ pub fn IntegerBitSet(comptime size: u16) type { |
| 184 | return @ctz(mask); | 184 | return @ctz(mask); |
| 185 | } | 185 | } |
| 186 | | 186 | |
| | 187 | /// Finds the index of the last set bit. |
| | 188 | /// If no bits are set, returns null. |
| | 189 | pub fn findLastSet(self: Self) ?usize { |
| | 190 | const mask = self.mask; |
| | 191 | if (mask == 0) return null; |
| | 192 | return bit_length - @clz(mask) - 1; |
| | 193 | } |
| | 194 | |
| 187 | /// Finds the index of the first set bit, and unsets it. | 195 | /// Finds the index of the first set bit, and unsets it. |
| 188 | /// If no bits are set, returns null. | 196 | /// If no bits are set, returns null. |
| 189 | pub fn toggleFirstSet(self: *Self) ?usize { | 197 | pub fn toggleFirstSet(self: *Self) ?usize { |
| ... | @@ -542,6 +550,24 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type { | ... | @@ -542,6 +550,24 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type { |
| 542 | return offset + @ctz(mask); | 550 | return offset + @ctz(mask); |
| 543 | } | 551 | } |
| 544 | | 552 | |
| | 553 | /// Finds the index of the last set bit. |
| | 554 | /// If no bits are set, returns null. |
| | 555 | pub fn findLastSet(self: Self) ?usize { |
| | 556 | if (bit_length == 0) return null; |
| | 557 | const bs = @bitSizeOf(MaskInt); |
| | 558 | var len = bit_length / bs; |
| | 559 | if (bit_length % bs != 0) len += 1; |
| | 560 | var offset: usize = len * bs; |
| | 561 | var idx: usize = len - 1; |
| | 562 | while (self.masks[idx] == 0) : (idx -= 1) { |
| | 563 | offset -= bs; |
| | 564 | if (idx == 0) return null; |
| | 565 | } |
| | 566 | offset -= @clz(self.masks[idx]); |
| | 567 | offset -= 1; |
| | 568 | return offset; |
| | 569 | } |
| | 570 | |
| 545 | /// Finds the index of the first set bit, and unsets it. | 571 | /// Finds the index of the first set bit, and unsets it. |
| 546 | /// If no bits are set, returns null. | 572 | /// If no bits are set, returns null. |
| 547 | pub fn toggleFirstSet(self: *Self) ?usize { | 573 | pub fn toggleFirstSet(self: *Self) ?usize { |
| ... | @@ -941,6 +967,24 @@ pub const DynamicBitSetUnmanaged = struct { | ... | @@ -941,6 +967,24 @@ pub const DynamicBitSetUnmanaged = struct { |
| 941 | return offset + @ctz(mask[0]); | 967 | return offset + @ctz(mask[0]); |
| 942 | } | 968 | } |
| 943 | | 969 | |
| | 970 | /// Finds the index of the last set bit. |
| | 971 | /// If no bits are set, returns null. |
| | 972 | pub fn findLastSet(self: Self) ?usize { |
| | 973 | if (self.bit_length == 0) return null; |
| | 974 | const bs = @bitSizeOf(MaskInt); |
| | 975 | var len = self.bit_length / bs; |
| | 976 | if (self.bit_length % bs != 0) len += 1; |
| | 977 | var offset: usize = len * bs; |
| | 978 | var idx: usize = len - 1; |
| | 979 | while (self.masks[idx] == 0) : (idx -= 1) { |
| | 980 | offset -= bs; |
| | 981 | if (idx == 0) return null; |
| | 982 | } |
| | 983 | offset -= @clz(self.masks[idx]); |
| | 984 | offset -= 1; |
| | 985 | return offset; |
| | 986 | } |
| | 987 | |
| 944 | /// Finds the index of the first set bit, and unsets it. | 988 | /// Finds the index of the first set bit, and unsets it. |
| 945 | /// If no bits are set, returns null. | 989 | /// If no bits are set, returns null. |
| 946 | pub fn toggleFirstSet(self: *Self) ?usize { | 990 | pub fn toggleFirstSet(self: *Self) ?usize { |
| ... | @@ -1160,6 +1204,12 @@ pub const DynamicBitSet = struct { | ... | @@ -1160,6 +1204,12 @@ pub const DynamicBitSet = struct { |
| 1160 | return self.unmanaged.findFirstSet(); | 1204 | return self.unmanaged.findFirstSet(); |
| 1161 | } | 1205 | } |
| 1162 | | 1206 | |
| | 1207 | /// Finds the index of the last set bit. |
| | 1208 | /// If no bits are set, returns null. |
| | 1209 | pub fn findLastSet(self: Self) ?usize { |
| | 1210 | return self.unmanaged.findLastSet(); |
| | 1211 | } |
| | 1212 | |
| 1163 | /// Finds the index of the first set bit, and unsets it. | 1213 | /// Finds the index of the first set bit, and unsets it. |
| 1164 | /// If no bits are set, returns null. | 1214 | /// If no bits are set, returns null. |
| 1165 | pub fn toggleFirstSet(self: *Self) ?usize { | 1215 | pub fn toggleFirstSet(self: *Self) ?usize { |
| ... | @@ -1514,8 +1564,10 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void { | ... | @@ -1514,8 +1564,10 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void { |
| 1514 | } | 1564 | } |
| 1515 | } | 1565 | } |
| 1516 | try testing.expectEqual(@as(?usize, null), a.findFirstSet()); | 1566 | try testing.expectEqual(@as(?usize, null), a.findFirstSet()); |
| | 1567 | try testing.expectEqual(@as(?usize, null), a.findLastSet()); |
| 1517 | try testing.expectEqual(@as(?usize, null), a.toggleFirstSet()); | 1568 | try testing.expectEqual(@as(?usize, null), a.toggleFirstSet()); |
| 1518 | try testing.expectEqual(@as(?usize, null), a.findFirstSet()); | 1569 | try testing.expectEqual(@as(?usize, null), a.findFirstSet()); |
| | 1570 | try testing.expectEqual(@as(?usize, null), a.findLastSet()); |
| 1519 | try testing.expectEqual(@as(?usize, null), a.toggleFirstSet()); | 1571 | try testing.expectEqual(@as(?usize, null), a.toggleFirstSet()); |
| 1520 | try testing.expectEqual(@as(usize, 0), a.count()); | 1572 | try testing.expectEqual(@as(usize, 0), a.count()); |
| 1521 | | 1573 | |