| ... | ... | @@ -184,6 +184,14 @@ pub fn IntegerBitSet(comptime size: u16) type { |
| 184 | 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 | 195 | /// Finds the index of the first set bit, and unsets it. |
| 188 | 196 | /// If no bits are set, returns null. |
| 189 | 197 | pub fn toggleFirstSet(self: *Self) ?usize { |
| ... | ... | @@ -542,6 +550,24 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type { |
| 542 | 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 | 571 | /// Finds the index of the first set bit, and unsets it. |
| 546 | 572 | /// If no bits are set, returns null. |
| 547 | 573 | pub fn toggleFirstSet(self: *Self) ?usize { |
| ... | ... | @@ -941,6 +967,24 @@ pub const DynamicBitSetUnmanaged = struct { |
| 941 | 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 | 988 | /// Finds the index of the first set bit, and unsets it. |
| 945 | 989 | /// If no bits are set, returns null. |
| 946 | 990 | pub fn toggleFirstSet(self: *Self) ?usize { |
| ... | ... | @@ -1160,6 +1204,12 @@ pub const DynamicBitSet = struct { |
| 1160 | 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 | 1213 | /// Finds the index of the first set bit, and unsets it. |
| 1164 | 1214 | /// If no bits are set, returns null. |
| 1165 | 1215 | pub fn toggleFirstSet(self: *Self) ?usize { |
| ... | ... | @@ -1514,8 +1564,10 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void { |
| 1514 | 1564 | } |
| 1515 | 1565 | } |
| 1516 | 1566 | try testing.expectEqual(@as(?usize, null), a.findFirstSet()); |
| 1567 | try testing.expectEqual(@as(?usize, null), a.findLastSet()); |
| 1517 | 1568 | try testing.expectEqual(@as(?usize, null), a.toggleFirstSet()); |
| 1518 | 1569 | try testing.expectEqual(@as(?usize, null), a.findFirstSet()); |
| 1570 | try testing.expectEqual(@as(?usize, null), a.findLastSet()); |
| 1519 | 1571 | try testing.expectEqual(@as(?usize, null), a.toggleFirstSet()); |
| 1520 | 1572 | try testing.expectEqual(@as(usize, 0), a.count()); |
| 1521 | 1573 | |