| ... | ... | @@ -431,6 +431,30 @@ pub fn BoundedEnumMultiset(comptime E: type, comptime CountSize: type) type { |
| 431 | 431 | return true; |
| 432 | 432 | } |
| 433 | 433 | |
| 434 | /// Returns true iff all key counts less than or |
| 435 | /// equal to the given multiset. |
| 436 | pub fn subsetOf(self: Self, other: Self) bool { |
| 437 | inline for (@typeInfo(E).Enum.fields) |field| { |
| 438 | const key = @intToEnum(E, field.value); |
| 439 | if (self.getCount(key) > other.getCount(key)) { |
| 440 | return false; |
| 441 | } |
| 442 | } |
| 443 | return true; |
| 444 | } |
| 445 | |
| 446 | /// Returns true iff all key counts greater than or |
| 447 | /// equal to the given multiset. |
| 448 | pub fn supersetOf(self: Self, other: Self) bool { |
| 449 | inline for (@typeInfo(E).Enum.fields) |field| { |
| 450 | const key = @intToEnum(E, field.value); |
| 451 | if (self.getCount(key) < other.getCount(key)) { |
| 452 | return false; |
| 453 | } |
| 454 | } |
| 455 | return true; |
| 456 | } |
| 457 | |
| 434 | 458 | /// Returns a multiset with the total key count of this |
| 435 | 459 | /// multiset and the other multiset. Caller asserts |
| 436 | 460 | /// operation will not overflow any key. |
| ... | ... | @@ -582,6 +606,38 @@ test "EnumMultiset" { |
| 582 | 606 | try testing.expect(!r0_g1_b2.eql(ten_of_each)); |
| 583 | 607 | try testing.expect(!ten_of_each.eql(empty)); |
| 584 | 608 | |
| 609 | try testing.expect(empty.subsetOf(empty)); |
| 610 | try testing.expect(r0_g1_b2.subsetOf(r0_g1_b2)); |
| 611 | try testing.expect(empty.subsetOf(r0_g1_b2)); |
| 612 | try testing.expect(r0_g1_b2.subsetOf(ten_of_each)); |
| 613 | try testing.expect(!ten_of_each.subsetOf(r0_g1_b2)); |
| 614 | try testing.expect(!r0_g1_b2.subsetOf(empty)); |
| 615 | |
| 616 | try testing.expect(empty.supersetOf(empty)); |
| 617 | try testing.expect(r0_g1_b2.supersetOf(r0_g1_b2)); |
| 618 | try testing.expect(r0_g1_b2.supersetOf(empty)); |
| 619 | try testing.expect(ten_of_each.supersetOf(r0_g1_b2)); |
| 620 | try testing.expect(!r0_g1_b2.supersetOf(ten_of_each)); |
| 621 | try testing.expect(!empty.supersetOf(r0_g1_b2)); |
| 622 | |
| 623 | { |
| 624 | // with multisets it could be the case where two |
| 625 | // multisets are neither subset nor superset of each |
| 626 | // other. |
| 627 | |
| 628 | const r10 = EnumMultiset(Ball).init(.{ |
| 629 | .red = 10, |
| 630 | }); |
| 631 | const b10 = EnumMultiset(Ball).init(.{ |
| 632 | .blue = 10, |
| 633 | }); |
| 634 | |
| 635 | try testing.expect(!r10.subsetOf(b10)); |
| 636 | try testing.expect(!b10.subsetOf(r10)); |
| 637 | try testing.expect(!r10.supersetOf(b10)); |
| 638 | try testing.expect(!b10.supersetOf(r10)); |
| 639 | } |
| 640 | |
| 585 | 641 | { |
| 586 | 642 | const result = r0_g1_b2.plusAssertSafe(ten_of_each); |
| 587 | 643 | try testing.expectEqual(result.getCount(.red), 10); |