authorgravatar for pyrogx1133@gmail.comRonald Chen <pyrogx1133@gmail.com> 2022-12-11 12:39:06-08:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-12 06:23:56+02:00
log552ecc286a5d244895c107a39c7a086bb74aa34b
treee229b25edaeb0008fdfe376c692c890c6ecd9e1a
parent5238f9c409cdf40db6a1484ab79a7bc518f8f6ad

std: implement subsetOf and supersetOf for DynamicBitSet


1 files changed, 121 insertions(+), 64 deletions(-)

lib/std/bit_set.zig+121-64
...@@ -30,7 +30,7 @@...@@ -30,7 +30,7 @@
30//! A variant of DynamicBitSet which does not store a pointer to its30//! A variant of DynamicBitSet which does not store a pointer to its
31//! allocator, in order to save space.31//! allocator, in order to save space.
3232
33const std = @import("std");33const std = @import("std.zig");
34const assert = std.debug.assert;34const assert = std.debug.assert;
35const Allocator = std.mem.Allocator;35const Allocator = std.mem.Allocator;
3636
...@@ -198,14 +198,14 @@ pub fn IntegerBitSet(comptime size: u16) type {...@@ -198,14 +198,14 @@ pub fn IntegerBitSet(comptime size: u16) type {
198 return bit_length == 0 or self.mask == other.mask;198 return bit_length == 0 or self.mask == other.mask;
199 }199 }
200200
201 /// Returns iff the first bit set is the subset of the201 /// Returns true iff the first bit set is the subset
202 /// second one.202 /// of the second one.
203 pub fn subsetOf(self: Self, other: Self) bool {203 pub fn subsetOf(self: Self, other: Self) bool {
204 return self.intersectWith(other).eql(self);204 return self.intersectWith(other).eql(self);
205 }205 }
206206
207 /// Returns iff the first bit set is the superset of the207 /// Returns true iff the first bit set is the superset
208 /// second one.208 /// of the second one.
209 pub fn supersetOf(self: Self, other: Self) bool {209 pub fn supersetOf(self: Self, other: Self) bool {
210 return other.subsetOf(self);210 return other.subsetOf(self);
211 }211 }
...@@ -564,14 +564,14 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type {...@@ -564,14 +564,14 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type {
564 } else true;564 } else true;
565 }565 }
566566
567 /// Returns iff the first bit set is the subset of the567 /// Returns true iff the first bit set is the subset
568 /// second one.568 /// of the second one.
569 pub fn subsetOf(self: Self, other: Self) bool {569 pub fn subsetOf(self: Self, other: Self) bool {
570 return self.intersectWith(other).eql(self);570 return self.intersectWith(other).eql(self);
571 }571 }
572572
573 /// Returns iff the first bit set is the superset of the573 /// Returns true iff the first bit set is the superset
574 /// second one.574 /// of the second one.
575 pub fn supersetOf(self: Self, other: Self) bool {575 pub fn supersetOf(self: Self, other: Self) bool {
576 return other.subsetOf(self);576 return other.subsetOf(self);
577 }577 }
...@@ -957,6 +957,36 @@ pub const DynamicBitSetUnmanaged = struct {...@@ -957,6 +957,36 @@ pub const DynamicBitSetUnmanaged = struct {
957 } else true;957 } else true;
958 }958 }
959959
960 /// Returns true iff the first bit set is the subset
961 /// of the second one.
962 pub fn subsetOf(self: Self, other: Self) bool {
963 if (self.bit_length != other.bit_length) {
964 return false;
965 }
966 const num_masks = numMasks(self.bit_length);
967 var i: usize = 0;
968 return while (i < num_masks) : (i += 1) {
969 if (self.masks[i] & other.masks[i] != self.masks[i]) {
970 break false;
971 }
972 } else true;
973 }
974
975 /// Returns true iff the first bit set is the superset
976 /// of the second one.
977 pub fn supersetOf(self: Self, other: Self) bool {
978 if (self.bit_length != other.bit_length) {
979 return false;
980 }
981 const num_masks = numMasks(self.bit_length);
982 var i: usize = 0;
983 return while (i < num_masks) : (i += 1) {
984 if (self.masks[i] & other.masks[i] != other.masks[i]) {
985 break false;
986 }
987 } else true;
988 }
989
960 /// Iterates through the items in the set, according to the options.990 /// Iterates through the items in the set, according to the options.
961 /// The default options (.{}) will iterate indices of set bits in991 /// The default options (.{}) will iterate indices of set bits in
962 /// ascending order. Modifications to the underlying bit set may992 /// ascending order. Modifications to the underlying bit set may
...@@ -1287,6 +1317,46 @@ fn testEql(empty: anytype, full: anytype, len: usize) !void {...@@ -1287,6 +1317,46 @@ fn testEql(empty: anytype, full: anytype, len: usize) !void {
1287 }1317 }
1288}1318}
12891319
1320fn testSubsetOf(empty: anytype, full: anytype, even: anytype, odd: anytype, len: usize) !void {
1321 try testing.expect(empty.subsetOf(empty));
1322 try testing.expect(empty.subsetOf(full));
1323 try testing.expect(full.subsetOf(full));
1324 switch (len) {
1325 0 => {
1326 try testing.expect(even.subsetOf(odd));
1327 try testing.expect(odd.subsetOf(even));
1328 },
1329 1 => {
1330 try testing.expect(!even.subsetOf(odd));
1331 try testing.expect(odd.subsetOf(even));
1332 },
1333 else => {
1334 try testing.expect(!even.subsetOf(odd));
1335 try testing.expect(!odd.subsetOf(even));
1336 },
1337 }
1338}
1339
1340fn testSupersetOf(empty: anytype, full: anytype, even: anytype, odd: anytype, len: usize) !void {
1341 try testing.expect(full.supersetOf(full));
1342 try testing.expect(full.supersetOf(empty));
1343 try testing.expect(empty.supersetOf(empty));
1344 switch (len) {
1345 0 => {
1346 try testing.expect(even.supersetOf(odd));
1347 try testing.expect(odd.supersetOf(even));
1348 },
1349 1 => {
1350 try testing.expect(even.supersetOf(odd));
1351 try testing.expect(!odd.supersetOf(even));
1352 },
1353 else => {
1354 try testing.expect(!even.supersetOf(odd));
1355 try testing.expect(!odd.supersetOf(even));
1356 },
1357 }
1358}
1359
1290fn testBitSet(a: anytype, b: anytype, len: usize) !void {1360fn testBitSet(a: anytype, b: anytype, len: usize) !void {
1291 try testing.expectEqual(len, a.capacity());1361 try testing.expectEqual(len, a.capacity());
1292 try testing.expectEqual(len, b.capacity());1362 try testing.expectEqual(len, b.capacity());
...@@ -1485,63 +1555,38 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void {...@@ -1485,63 +1555,38 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void {
1485 }1555 }
1486}1556}
14871557
1558fn fillEven(set: anytype, len: usize) void {
1559 var i: usize = 0;
1560 while (i < len) : (i += 1) {
1561 set.setValue(i, i & 1 == 0);
1562 }
1563}
1564
1565fn fillOdd(set: anytype, len: usize) void {
1566 var i: usize = 0;
1567 while (i < len) : (i += 1) {
1568 set.setValue(i, i & 1 == 1);
1569 }
1570}
1571
1488fn testPureBitSet(comptime Set: type) !void {1572fn testPureBitSet(comptime Set: type) !void {
1489 const empty = Set.initEmpty();1573 const empty = Set.initEmpty();
1490 const full = Set.initFull();1574 const full = Set.initFull();
14911575
1492 const even = even: {1576 const even = even: {
1493 var bit_set = Set.initEmpty();1577 var bit_set = Set.initEmpty();
1494 var i: usize = 0;1578 fillEven(&bit_set, Set.bit_length);
1495 while (i < Set.bit_length) : (i += 1) {
1496 bit_set.setValue(i, i & 1 == 0);
1497 }
1498 break :even bit_set;1579 break :even bit_set;
1499 };1580 };
15001581
1501 const odd = odd: {1582 const odd = odd: {
1502 var bit_set = Set.initEmpty();1583 var bit_set = Set.initEmpty();
1503 var i: usize = 0;1584 fillOdd(&bit_set, Set.bit_length);
1504 while (i < Set.bit_length) : (i += 1) {
1505 bit_set.setValue(i, i & 1 == 1);
1506 }
1507 break :odd bit_set;1585 break :odd bit_set;
1508 };1586 };
15091587
1510 try testing.expect(empty.subsetOf(empty));1588 try testSubsetOf(empty, full, even, odd, Set.bit_length);
1511 try testing.expect(empty.subsetOf(full));1589 try testSupersetOf(empty, full, even, odd, Set.bit_length);
1512 try testing.expect(full.subsetOf(full));
1513 switch (Set.bit_length) {
1514 0 => {
1515 try testing.expect(even.subsetOf(odd));
1516 try testing.expect(odd.subsetOf(even));
1517 },
1518 1 => {
1519 try testing.expect(!even.subsetOf(odd));
1520 try testing.expect(odd.subsetOf(even));
1521 },
1522 else => {
1523 try testing.expect(!even.subsetOf(odd));
1524 try testing.expect(!odd.subsetOf(even));
1525 },
1526 }
1527
1528 try testing.expect(full.supersetOf(full));
1529 try testing.expect(full.supersetOf(empty));
1530 try testing.expect(empty.supersetOf(empty));
1531 switch (Set.bit_length) {
1532 0 => {
1533 try testing.expect(even.supersetOf(odd));
1534 try testing.expect(odd.supersetOf(even));
1535 },
1536 1 => {
1537 try testing.expect(even.supersetOf(odd));
1538 try testing.expect(!odd.supersetOf(even));
1539 },
1540 else => {
1541 try testing.expect(!even.supersetOf(odd));
1542 try testing.expect(!odd.supersetOf(even));
1543 },
1544 }
15451590
1546 try testing.expect(empty.complement().eql(full));1591 try testing.expect(empty.complement().eql(full));
1547 try testing.expect(full.complement().eql(empty));1592 try testing.expect(full.complement().eql(empty));
...@@ -1621,33 +1666,45 @@ test "DynamicBitSetUnmanaged" {...@@ -1621,33 +1666,45 @@ test "DynamicBitSetUnmanaged" {
1621 for ([_]usize{ 1, 2, 31, 32, 33, 0, 65, 64, 63, 500, 254, 3000 }) |size| {1666 for ([_]usize{ 1, 2, 31, 32, 33, 0, 65, 64, 63, 500, 254, 3000 }) |size| {
1622 const old_len = a.capacity();1667 const old_len = a.capacity();
16231668
1624 var tmp = try a.clone(allocator);1669 var empty = try a.clone(allocator);
1625 defer tmp.deinit(allocator);1670 defer empty.deinit(allocator);
1626 try testing.expectEqual(old_len, tmp.capacity());1671 try testing.expectEqual(old_len, empty.capacity());
1627 var i: usize = 0;1672 var i: usize = 0;
1628 while (i < old_len) : (i += 1) {1673 while (i < old_len) : (i += 1) {
1629 try testing.expectEqual(a.isSet(i), tmp.isSet(i));1674 try testing.expectEqual(a.isSet(i), empty.isSet(i));
1630 }1675 }
16311676
1632 a.toggleSet(a); // zero a1677 a.toggleSet(a); // zero a
1633 tmp.toggleSet(tmp);1678 empty.toggleSet(empty);
16341679
1635 try a.resize(allocator, size, true);1680 try a.resize(allocator, size, true);
1636 try tmp.resize(allocator, size, false);1681 try empty.resize(allocator, size, false);
16371682
1638 if (size > old_len) {1683 if (size > old_len) {
1639 try testing.expectEqual(size - old_len, a.count());1684 try testing.expectEqual(size - old_len, a.count());
1640 } else {1685 } else {
1641 try testing.expectEqual(@as(usize, 0), a.count());1686 try testing.expectEqual(@as(usize, 0), a.count());
1642 }1687 }
1643 try testing.expectEqual(@as(usize, 0), tmp.count());1688 try testing.expectEqual(@as(usize, 0), empty.count());
16441689
1645 var b = try DynamicBitSetUnmanaged.initFull(allocator, size);1690 var full = try DynamicBitSetUnmanaged.initFull(allocator, size);
1646 defer b.deinit(allocator);1691 defer full.deinit(allocator);
1647 try testing.expectEqual(@as(usize, size), b.count());1692 try testing.expectEqual(@as(usize, size), full.count());
16481693
1649 try testEql(tmp, b, size);1694 try testEql(empty, full, size);
1650 try testBitSet(&a, &b, size);1695 {
1696 var even = try DynamicBitSetUnmanaged.initEmpty(allocator, size);
1697 defer even.deinit(allocator);
1698 fillEven(&even, size);
1699
1700 var odd = try DynamicBitSetUnmanaged.initEmpty(allocator, size);
1701 defer odd.deinit(allocator);
1702 fillOdd(&odd, size);
1703
1704 try testSubsetOf(empty, full, even, odd, size);
1705 try testSupersetOf(empty, full, even, odd, size);
1706 }
1707 try testBitSet(&a, &full, size);
1651 }1708 }
1652}1709}
16531710