Commit 9e74e4c1f8
Changed files (1)
lib
std
lib/std/bit_set.zig
@@ -192,6 +192,68 @@ pub fn IntegerBitSet(comptime size: u16) type {
return index;
}
+ /// Returns true iff every corresponding bit in both
+ /// bit sets are the same.
+ pub fn eql(self: Self, other: Self) bool {
+ return bit_length == 0 or self.mask == other.mask;
+ }
+
+ /// Returns iff the first bit set is the subset of the
+ /// second one.
+ pub fn subsetOf(self: Self, other: Self) bool {
+ return self.intersectWith(other).eql(self);
+ }
+
+ /// Returns iff the first bit set is the superset of the
+ /// second one.
+ pub fn supersetOf(self: Self, other: Self) bool {
+ return other.subsetOf(self);
+ }
+
+ /// Returns the complement bit sets. Bits in the result
+ /// are set if the corresponding bits were not set.
+ pub fn complement(self: Self) Self {
+ var result = self;
+ result.toggleAll();
+ return result;
+ }
+
+ /// Returns the union of two bit sets. Bits in the
+ /// result are set if the corresponding bits were set
+ /// in both inputs.
+ pub fn unionWith(self: Self, other: Self) Self {
+ var result = self;
+ result.setUnion(other);
+ return result;
+ }
+
+ /// Returns the intersection of two bit sets. Bits in
+ /// the result are set if the corresponding bits were
+ /// set in both inputs.
+ pub fn intersectWith(self: Self, other: Self) Self {
+ var result = self;
+ result.setIntersection(other);
+ return result;
+ }
+
+ /// Returns the xor of two bit sets. Bits in the
+ /// result are set if the corresponding bits were
+ /// set in not the same in both inputs.
+ pub fn xorWith(self: Self, other: Self) Self {
+ var result = self;
+ result.toggleSet(other);
+ return result;
+ }
+
+ /// Returns the difference of two bit sets. Bits in
+ /// the result are set if set in the first but not
+ /// set in the second set.
+ pub fn differenceWith(self: Self, other: Self) Self {
+ var result = self;
+ result.setIntersection(other.complement());
+ return result;
+ }
+
/// Iterates through the items in the set, according to the options.
/// The default options (.{}) will iterate indices of set bits in
/// ascending order. Modifications to the underlying bit set may
@@ -491,6 +553,76 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type {
return offset + index;
}
+ /// Returns true iff every corresponding bit in both
+ /// bit sets are the same.
+ pub fn eql(self: Self, other: Self) bool {
+ if (bit_length == 0) {
+ return true;
+ }
+ var i: usize = 0;
+ return while (i < num_masks) : (i += 1) {
+ if (self.masks[i] != other.masks[i]) {
+ break false;
+ }
+ } else true;
+ }
+
+ /// Returns iff the first bit set is the subset of the
+ /// second one.
+ pub fn subsetOf(self: Self, other: Self) bool {
+ return self.intersectWith(other).eql(self);
+ }
+
+ /// Returns iff the first bit set is the superset of the
+ /// second one.
+ pub fn supersetOf(self: Self, other: Self) bool {
+ return other.subsetOf(self);
+ }
+
+ /// Returns the complement bit sets. Bits in the result
+ /// are set if the corresponding bits were not set.
+ pub fn complement(self: Self) Self {
+ var result = self;
+ result.toggleAll();
+ return result;
+ }
+
+ /// Returns the union of two bit sets. Bits in the
+ /// result are set if the corresponding bits were set
+ /// in both inputs.
+ pub fn unionWith(self: Self, other: Self) Self {
+ var result = self;
+ result.setUnion(other);
+ return result;
+ }
+
+ /// Returns the intersection of two bit sets. Bits in
+ /// the result are set if the corresponding bits were
+ /// set in both inputs.
+ pub fn intersectWith(self: Self, other: Self) Self {
+ var result = self;
+ result.setIntersection(other);
+ return result;
+ }
+
+ /// Returns the xor of two bit sets. Bits in the
+ /// result are set if the corresponding bits were
+ /// set in not the same in both inputs.
+ pub fn xorWith(self: Self, other: Self) Self {
+ var result = self;
+ result.toggleSet(other);
+ return result;
+ }
+
+ /// Returns the difference of two bit sets. Bits in
+ /// the result are set if set in the first but not
+ /// set in the second set.
+ pub fn differenceWith(self: Self, other: Self) Self {
+ var result = self;
+ result.setIntersection(other.complement());
+ return result;
+ }
+
/// Iterates through the items in the set, according to the options.
/// The default options (.{}) will iterate indices of set bits in
/// ascending order. Modifications to the underlying bit set may
@@ -1320,6 +1452,115 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void {
}
}
+fn testPureBitSet(comptime Set: type) !void {
+ const empty = Set.initEmpty();
+ const full = Set.initFull();
+
+ const even = even: {
+ var bit_set = Set.initEmpty();
+ var i: usize = 0;
+ while (i < Set.bit_length) : (i += 1) {
+ bit_set.setValue(i, i & 1 == 0);
+ }
+ break :even bit_set;
+ };
+
+ const odd = odd: {
+ var bit_set = Set.initEmpty();
+ var i: usize = 0;
+ while (i < Set.bit_length) : (i += 1) {
+ bit_set.setValue(i, i & 1 == 1);
+ }
+ break :odd bit_set;
+ };
+
+ try testing.expect(empty.eql(empty));
+ try testing.expect(full.eql(full));
+ switch (Set.bit_length) {
+ 0 => {
+ try testing.expect(empty.eql(full));
+ try testing.expect(full.eql(empty));
+ try testing.expect(even.eql(odd));
+ try testing.expect(odd.eql(even));
+ },
+ else => {
+ try testing.expect(!empty.eql(full));
+ try testing.expect(!full.eql(empty));
+ try testing.expect(!even.eql(odd));
+ try testing.expect(!odd.eql(even));
+ },
+ }
+
+ try testing.expect(empty.subsetOf(empty));
+ try testing.expect(empty.subsetOf(full));
+ try testing.expect(full.subsetOf(full));
+ switch (Set.bit_length) {
+ 0 => {
+ try testing.expect(even.subsetOf(odd));
+ try testing.expect(odd.subsetOf(even));
+ },
+ 1 => {
+ try testing.expect(!even.subsetOf(odd));
+ try testing.expect(odd.subsetOf(even));
+ },
+ else => {
+ try testing.expect(!even.subsetOf(odd));
+ try testing.expect(!odd.subsetOf(even));
+ },
+ }
+
+ try testing.expect(full.supersetOf(full));
+ try testing.expect(full.supersetOf(empty));
+ try testing.expect(empty.supersetOf(empty));
+ switch (Set.bit_length) {
+ 0 => {
+ try testing.expect(even.supersetOf(odd));
+ try testing.expect(odd.supersetOf(even));
+ },
+ 1 => {
+ try testing.expect(even.supersetOf(odd));
+ try testing.expect(!odd.supersetOf(even));
+ },
+ else => {
+ try testing.expect(!even.supersetOf(odd));
+ try testing.expect(!odd.supersetOf(even));
+ },
+ }
+
+ try testing.expect(empty.complement().eql(full));
+ try testing.expect(full.complement().eql(empty));
+ try testing.expect(even.complement().eql(odd));
+ try testing.expect(odd.complement().eql(even));
+
+ try testing.expect(empty.unionWith(empty).eql(empty));
+ try testing.expect(empty.unionWith(full).eql(full));
+ try testing.expect(full.unionWith(full).eql(full));
+ try testing.expect(full.unionWith(empty).eql(full));
+ try testing.expect(even.unionWith(odd).eql(full));
+ try testing.expect(odd.unionWith(even).eql(full));
+
+ try testing.expect(empty.intersectWith(empty).eql(empty));
+ try testing.expect(empty.intersectWith(full).eql(empty));
+ try testing.expect(full.intersectWith(full).eql(full));
+ try testing.expect(full.intersectWith(empty).eql(empty));
+ try testing.expect(even.intersectWith(odd).eql(empty));
+ try testing.expect(odd.intersectWith(even).eql(empty));
+
+ try testing.expect(empty.xorWith(empty).eql(empty));
+ try testing.expect(empty.xorWith(full).eql(full));
+ try testing.expect(full.xorWith(full).eql(empty));
+ try testing.expect(full.xorWith(empty).eql(full));
+ try testing.expect(even.xorWith(odd).eql(full));
+ try testing.expect(odd.xorWith(even).eql(full));
+
+ try testing.expect(empty.differenceWith(empty).eql(empty));
+ try testing.expect(empty.differenceWith(full).eql(empty));
+ try testing.expect(full.differenceWith(full).eql(empty));
+ try testing.expect(full.differenceWith(empty).eql(full));
+ try testing.expect(full.differenceWith(odd).eql(even));
+ try testing.expect(full.differenceWith(even).eql(odd));
+}
+
fn testStaticBitSet(comptime Set: type) !void {
var a = Set.initEmpty();
var b = Set.initFull();
@@ -1327,6 +1568,8 @@ fn testStaticBitSet(comptime Set: type) !void {
try testing.expectEqual(@as(usize, Set.bit_length), b.count());
try testBitSet(&a, &b, Set.bit_length);
+
+ try testPureBitSet(Set);
}
test "IntegerBitSet" {