| ... | @@ -192,6 +192,68 @@ pub fn IntegerBitSet(comptime size: u16) type { | ... | @@ -192,6 +192,68 @@ pub fn IntegerBitSet(comptime size: u16) type { |
| 192 | return index; | 192 | return index; |
| 193 | } | 193 | } |
| 194 | | 194 | |
| | 195 | /// Returns true iff every corresponding bit in both |
| | 196 | /// bit sets are the same. |
| | 197 | pub fn eql(self: Self, other: Self) bool { |
| | 198 | return bit_length == 0 or self.mask == other.mask; |
| | 199 | } |
| | 200 | |
| | 201 | /// Returns iff the first bit set is the subset of the |
| | 202 | /// second one. |
| | 203 | pub fn subsetOf(self: Self, other: Self) bool { |
| | 204 | return self.intersectWith(other).eql(self); |
| | 205 | } |
| | 206 | |
| | 207 | /// Returns iff the first bit set is the superset of the |
| | 208 | /// second one. |
| | 209 | pub fn supersetOf(self: Self, other: Self) bool { |
| | 210 | return other.subsetOf(self); |
| | 211 | } |
| | 212 | |
| | 213 | /// Returns the complement bit sets. Bits in the result |
| | 214 | /// are set if the corresponding bits were not set. |
| | 215 | pub fn complement(self: Self) Self { |
| | 216 | var result = self; |
| | 217 | result.toggleAll(); |
| | 218 | return result; |
| | 219 | } |
| | 220 | |
| | 221 | /// Returns the union of two bit sets. Bits in the |
| | 222 | /// result are set if the corresponding bits were set |
| | 223 | /// in both inputs. |
| | 224 | pub fn unionWith(self: Self, other: Self) Self { |
| | 225 | var result = self; |
| | 226 | result.setUnion(other); |
| | 227 | return result; |
| | 228 | } |
| | 229 | |
| | 230 | /// Returns the intersection of two bit sets. Bits in |
| | 231 | /// the result are set if the corresponding bits were |
| | 232 | /// set in both inputs. |
| | 233 | pub fn intersectWith(self: Self, other: Self) Self { |
| | 234 | var result = self; |
| | 235 | result.setIntersection(other); |
| | 236 | return result; |
| | 237 | } |
| | 238 | |
| | 239 | /// Returns the xor of two bit sets. Bits in the |
| | 240 | /// result are set if the corresponding bits were |
| | 241 | /// set in not the same in both inputs. |
| | 242 | pub fn xorWith(self: Self, other: Self) Self { |
| | 243 | var result = self; |
| | 244 | result.toggleSet(other); |
| | 245 | return result; |
| | 246 | } |
| | 247 | |
| | 248 | /// Returns the difference of two bit sets. Bits in |
| | 249 | /// the result are set if set in the first but not |
| | 250 | /// set in the second set. |
| | 251 | pub fn differenceWith(self: Self, other: Self) Self { |
| | 252 | var result = self; |
| | 253 | result.setIntersection(other.complement()); |
| | 254 | return result; |
| | 255 | } |
| | 256 | |
| 195 | /// Iterates through the items in the set, according to the options. | 257 | /// Iterates through the items in the set, according to the options. |
| 196 | /// The default options (.{}) will iterate indices of set bits in | 258 | /// The default options (.{}) will iterate indices of set bits in |
| 197 | /// ascending order. Modifications to the underlying bit set may | 259 | /// ascending order. Modifications to the underlying bit set may |
| ... | @@ -491,6 +553,76 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type { | ... | @@ -491,6 +553,76 @@ pub fn ArrayBitSet(comptime MaskIntType: type, comptime size: usize) type { |
| 491 | return offset + index; | 553 | return offset + index; |
| 492 | } | 554 | } |
| 493 | | 555 | |
| | 556 | /// Returns true iff every corresponding bit in both |
| | 557 | /// bit sets are the same. |
| | 558 | pub fn eql(self: Self, other: Self) bool { |
| | 559 | if (bit_length == 0) { |
| | 560 | return true; |
| | 561 | } |
| | 562 | var i: usize = 0; |
| | 563 | return while (i < num_masks) : (i += 1) { |
| | 564 | if (self.masks[i] != other.masks[i]) { |
| | 565 | break false; |
| | 566 | } |
| | 567 | } else true; |
| | 568 | } |
| | 569 | |
| | 570 | /// Returns iff the first bit set is the subset of the |
| | 571 | /// second one. |
| | 572 | pub fn subsetOf(self: Self, other: Self) bool { |
| | 573 | return self.intersectWith(other).eql(self); |
| | 574 | } |
| | 575 | |
| | 576 | /// Returns iff the first bit set is the superset of the |
| | 577 | /// second one. |
| | 578 | pub fn supersetOf(self: Self, other: Self) bool { |
| | 579 | return other.subsetOf(self); |
| | 580 | } |
| | 581 | |
| | 582 | /// Returns the complement bit sets. Bits in the result |
| | 583 | /// are set if the corresponding bits were not set. |
| | 584 | pub fn complement(self: Self) Self { |
| | 585 | var result = self; |
| | 586 | result.toggleAll(); |
| | 587 | return result; |
| | 588 | } |
| | 589 | |
| | 590 | /// Returns the union of two bit sets. Bits in the |
| | 591 | /// result are set if the corresponding bits were set |
| | 592 | /// in both inputs. |
| | 593 | pub fn unionWith(self: Self, other: Self) Self { |
| | 594 | var result = self; |
| | 595 | result.setUnion(other); |
| | 596 | return result; |
| | 597 | } |
| | 598 | |
| | 599 | /// Returns the intersection of two bit sets. Bits in |
| | 600 | /// the result are set if the corresponding bits were |
| | 601 | /// set in both inputs. |
| | 602 | pub fn intersectWith(self: Self, other: Self) Self { |
| | 603 | var result = self; |
| | 604 | result.setIntersection(other); |
| | 605 | return result; |
| | 606 | } |
| | 607 | |
| | 608 | /// Returns the xor of two bit sets. Bits in the |
| | 609 | /// result are set if the corresponding bits were |
| | 610 | /// set in not the same in both inputs. |
| | 611 | pub fn xorWith(self: Self, other: Self) Self { |
| | 612 | var result = self; |
| | 613 | result.toggleSet(other); |
| | 614 | return result; |
| | 615 | } |
| | 616 | |
| | 617 | /// Returns the difference of two bit sets. Bits in |
| | 618 | /// the result are set if set in the first but not |
| | 619 | /// set in the second set. |
| | 620 | pub fn differenceWith(self: Self, other: Self) Self { |
| | 621 | var result = self; |
| | 622 | result.setIntersection(other.complement()); |
| | 623 | return result; |
| | 624 | } |
| | 625 | |
| 494 | /// Iterates through the items in the set, according to the options. | 626 | /// Iterates through the items in the set, according to the options. |
| 495 | /// The default options (.{}) will iterate indices of set bits in | 627 | /// The default options (.{}) will iterate indices of set bits in |
| 496 | /// ascending order. Modifications to the underlying bit set may | 628 | /// ascending order. Modifications to the underlying bit set may |
| ... | @@ -1320,6 +1452,115 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void { | ... | @@ -1320,6 +1452,115 @@ fn testBitSet(a: anytype, b: anytype, len: usize) !void { |
| 1320 | } | 1452 | } |
| 1321 | } | 1453 | } |
| 1322 | | 1454 | |
| | 1455 | fn testPureBitSet(comptime Set: type) !void { |
| | 1456 | const empty = Set.initEmpty(); |
| | 1457 | const full = Set.initFull(); |
| | 1458 | |
| | 1459 | const even = even: { |
| | 1460 | var bit_set = Set.initEmpty(); |
| | 1461 | var i: usize = 0; |
| | 1462 | while (i < Set.bit_length) : (i += 1) { |
| | 1463 | bit_set.setValue(i, i & 1 == 0); |
| | 1464 | } |
| | 1465 | break :even bit_set; |
| | 1466 | }; |
| | 1467 | |
| | 1468 | const odd = odd: { |
| | 1469 | var bit_set = Set.initEmpty(); |
| | 1470 | var i: usize = 0; |
| | 1471 | while (i < Set.bit_length) : (i += 1) { |
| | 1472 | bit_set.setValue(i, i & 1 == 1); |
| | 1473 | } |
| | 1474 | break :odd bit_set; |
| | 1475 | }; |
| | 1476 | |
| | 1477 | try testing.expect(empty.eql(empty)); |
| | 1478 | try testing.expect(full.eql(full)); |
| | 1479 | switch (Set.bit_length) { |
| | 1480 | 0 => { |
| | 1481 | try testing.expect(empty.eql(full)); |
| | 1482 | try testing.expect(full.eql(empty)); |
| | 1483 | try testing.expect(even.eql(odd)); |
| | 1484 | try testing.expect(odd.eql(even)); |
| | 1485 | }, |
| | 1486 | else => { |
| | 1487 | try testing.expect(!empty.eql(full)); |
| | 1488 | try testing.expect(!full.eql(empty)); |
| | 1489 | try testing.expect(!even.eql(odd)); |
| | 1490 | try testing.expect(!odd.eql(even)); |
| | 1491 | }, |
| | 1492 | } |
| | 1493 | |
| | 1494 | try testing.expect(empty.subsetOf(empty)); |
| | 1495 | try testing.expect(empty.subsetOf(full)); |
| | 1496 | try testing.expect(full.subsetOf(full)); |
| | 1497 | switch (Set.bit_length) { |
| | 1498 | 0 => { |
| | 1499 | try testing.expect(even.subsetOf(odd)); |
| | 1500 | try testing.expect(odd.subsetOf(even)); |
| | 1501 | }, |
| | 1502 | 1 => { |
| | 1503 | try testing.expect(!even.subsetOf(odd)); |
| | 1504 | try testing.expect(odd.subsetOf(even)); |
| | 1505 | }, |
| | 1506 | else => { |
| | 1507 | try testing.expect(!even.subsetOf(odd)); |
| | 1508 | try testing.expect(!odd.subsetOf(even)); |
| | 1509 | }, |
| | 1510 | } |
| | 1511 | |
| | 1512 | try testing.expect(full.supersetOf(full)); |
| | 1513 | try testing.expect(full.supersetOf(empty)); |
| | 1514 | try testing.expect(empty.supersetOf(empty)); |
| | 1515 | switch (Set.bit_length) { |
| | 1516 | 0 => { |
| | 1517 | try testing.expect(even.supersetOf(odd)); |
| | 1518 | try testing.expect(odd.supersetOf(even)); |
| | 1519 | }, |
| | 1520 | 1 => { |
| | 1521 | try testing.expect(even.supersetOf(odd)); |
| | 1522 | try testing.expect(!odd.supersetOf(even)); |
| | 1523 | }, |
| | 1524 | else => { |
| | 1525 | try testing.expect(!even.supersetOf(odd)); |
| | 1526 | try testing.expect(!odd.supersetOf(even)); |
| | 1527 | }, |
| | 1528 | } |
| | 1529 | |
| | 1530 | try testing.expect(empty.complement().eql(full)); |
| | 1531 | try testing.expect(full.complement().eql(empty)); |
| | 1532 | try testing.expect(even.complement().eql(odd)); |
| | 1533 | try testing.expect(odd.complement().eql(even)); |
| | 1534 | |
| | 1535 | try testing.expect(empty.unionWith(empty).eql(empty)); |
| | 1536 | try testing.expect(empty.unionWith(full).eql(full)); |
| | 1537 | try testing.expect(full.unionWith(full).eql(full)); |
| | 1538 | try testing.expect(full.unionWith(empty).eql(full)); |
| | 1539 | try testing.expect(even.unionWith(odd).eql(full)); |
| | 1540 | try testing.expect(odd.unionWith(even).eql(full)); |
| | 1541 | |
| | 1542 | try testing.expect(empty.intersectWith(empty).eql(empty)); |
| | 1543 | try testing.expect(empty.intersectWith(full).eql(empty)); |
| | 1544 | try testing.expect(full.intersectWith(full).eql(full)); |
| | 1545 | try testing.expect(full.intersectWith(empty).eql(empty)); |
| | 1546 | try testing.expect(even.intersectWith(odd).eql(empty)); |
| | 1547 | try testing.expect(odd.intersectWith(even).eql(empty)); |
| | 1548 | |
| | 1549 | try testing.expect(empty.xorWith(empty).eql(empty)); |
| | 1550 | try testing.expect(empty.xorWith(full).eql(full)); |
| | 1551 | try testing.expect(full.xorWith(full).eql(empty)); |
| | 1552 | try testing.expect(full.xorWith(empty).eql(full)); |
| | 1553 | try testing.expect(even.xorWith(odd).eql(full)); |
| | 1554 | try testing.expect(odd.xorWith(even).eql(full)); |
| | 1555 | |
| | 1556 | try testing.expect(empty.differenceWith(empty).eql(empty)); |
| | 1557 | try testing.expect(empty.differenceWith(full).eql(empty)); |
| | 1558 | try testing.expect(full.differenceWith(full).eql(empty)); |
| | 1559 | try testing.expect(full.differenceWith(empty).eql(full)); |
| | 1560 | try testing.expect(full.differenceWith(odd).eql(even)); |
| | 1561 | try testing.expect(full.differenceWith(even).eql(odd)); |
| | 1562 | } |
| | 1563 | |
| 1323 | fn testStaticBitSet(comptime Set: type) !void { | 1564 | fn testStaticBitSet(comptime Set: type) !void { |
| 1324 | var a = Set.initEmpty(); | 1565 | var a = Set.initEmpty(); |
| 1325 | var b = Set.initFull(); | 1566 | var b = Set.initFull(); |
| ... | @@ -1327,6 +1568,8 @@ fn testStaticBitSet(comptime Set: type) !void { | ... | @@ -1327,6 +1568,8 @@ fn testStaticBitSet(comptime Set: type) !void { |
| 1327 | try testing.expectEqual(@as(usize, Set.bit_length), b.count()); | 1568 | try testing.expectEqual(@as(usize, Set.bit_length), b.count()); |
| 1328 | | 1569 | |
| 1329 | try testBitSet(&a, &b, Set.bit_length); | 1570 | try testBitSet(&a, &b, Set.bit_length); |
| | 1571 | |
| | 1572 | try testPureBitSet(Set); |
| 1330 | } | 1573 | } |
| 1331 | | 1574 | |
| 1332 | test "IntegerBitSet" { | 1575 | test "IntegerBitSet" { |