From 880d7add00fecbd043ff91c8f31a3d92265361cb Mon Sep 17 00:00:00 2001 From: Janne Hellsten Date: Fri, 25 Sep 2026 16:52:06 +0300 Subject: [PATCH] std.bit_set: add setAll/unsetAll to all bitsets, fix padding bug in Dynamic.setAll - Add imperative setAll/unsetAll methods to all bitset types. Previously setAll/unsetAll were declared only for Dynamic. - Fix a padding bug in Dynamic.setAll the last mask set to all ones. - Add tests for previously untested setAll, unsetAll --- lib/std/bit_set.zig | 52 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/lib/std/bit_set.zig b/lib/std/bit_set.zig index 1a31e3b1a50b55cb8f26aa63789c1a04e9f6bc84..f3e477cff91fb5ea7da76b9235ac7d3cfa47d512 100644 --- a/lib/std/bit_set.zig +++ b/lib/std/bit_set.zig @@ -163,6 +163,16 @@ pub fn Integer(comptime size: u16) type { self.mask = ~self.mask; } + /// Set all bits to 0. + pub fn unsetAll(self: *Self) void { + self.mask = 0; + } + + /// Set all bits to 1. + pub fn setAll(self: *Self) void { + self.mask = ~self.mask; + } + /// Performs a union of two bit sets, and stores the /// result in the first one. Bits in the result are /// set if the corresponding bits were set in either input. @@ -521,6 +531,23 @@ pub fn Array(comptime MaskIntType: type, comptime size: usize) type { } } + /// Set all bits to 0. + pub fn unsetAll(self: *Self) void { + for (&self.masks) |*mask| { + mask.* = 0; + } + } + + /// Set all bits to 1. + pub fn setAll(self: *Self) void { + for (&self.masks) |*mask| { + mask.* = ~@as(MaskInt, 0); + } + if (num_masks > 0) { + self.masks[num_masks - 1] &= last_item_mask; + } + } + /// Performs a union of two bit sets, and stores the /// result in the first one. Bits in the result are /// set if the corresponding bits were set in either input. @@ -896,8 +923,13 @@ pub const Dynamic = struct { /// Set all bits to 1. pub fn setAll(self: *Self) void { - const masks_len = numMasks(self.bit_length); - @memset(self.masks[0..masks_len], std.math.maxInt(MaskInt)); + const num_masks = numMasks(self.bit_length); + @memset(self.masks[0..num_masks], std.math.maxInt(MaskInt)); + if (num_masks > 0) { + const padding_bits = num_masks * @bitSizeOf(MaskInt) - self.bit_length; + const last_item_mask = (~@as(MaskInt, 0)) >> @as(ShiftInt, @intCast(padding_bits)); + self.masks[num_masks - 1] = last_item_mask; + } } /// Flips a specific bit in the bit set @@ -1207,6 +1239,16 @@ pub const DynamicManaged = struct { self.unmanaged.setIntersection(other.unmanaged); } + /// Set all bits to 0. + pub fn unsetAll(self: *Self) void { + self.unmanaged.unsetAll(); + } + + /// Set all bits to 1. + pub fn setAll(self: *Self) void { + self.unmanaged.setAll(); + } + /// Finds the index of the first set bit. /// If no bits are set, returns null. pub fn findFirstSet(self: Self) ?usize { @@ -1625,6 +1667,12 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void { try testing.expect(!a.isSet(len - 1)); } } + + a.unsetAll(); + try testing.expectEqual(0, a.count()); + + a.setAll(); + try testing.expectEqual(len, a.count()); } fn fillEven(set: anytype, len: usize) void { -- 2.54.0