Type Function BoundedEnumMultiset [src]

A multiset of enum elements up to CountSize. Backed by an EnumArray. This type does no dynamic allocation and can be copied by value.

Prototype

pub fn BoundedEnumMultiset(comptime E: type, comptime CountSize: type) type

Parameters

E: typeCountSize: type

Source

pub fn BoundedEnumMultiset(comptime E: type, comptime CountSize: type) type { return struct { const Self = @This(); counts: EnumArray(E, CountSize), /// Initializes the multiset using a struct of counts. pub fn init(init_counts: EnumFieldStruct(E, CountSize, 0)) Self { @setEvalBranchQuota(2 * @typeInfo(E).@"enum".fields.len); var self = initWithCount(0); inline for (@typeInfo(E).@"enum".fields) |field| { const c = @field(init_counts, field.name); const key = @as(E, @enumFromInt(field.value)); self.counts.set(key, c); } return self; } /// Initializes the multiset with a count of zero. pub fn initEmpty() Self { return initWithCount(0); } /// Initializes the multiset with all keys at the /// same count. pub fn initWithCount(comptime c: CountSize) Self { return .{ .counts = EnumArray(E, CountSize).initDefault(c, .{}), }; } /// Returns the total number of key counts in the multiset. pub fn count(self: Self) usize { var sum: usize = 0; for (self.counts.values) |c| { sum += c; } return sum; } /// Checks if at least one key in multiset. pub fn contains(self: Self, key: E) bool { return self.counts.get(key) > 0; } /// Removes all instance of a key from multiset. Same as /// setCount(key, 0). pub fn removeAll(self: *Self, key: E) void { return self.counts.set(key, 0); } /// Increases the key count by given amount. Caller asserts /// operation will not overflow. pub fn addAssertSafe(self: *Self, key: E, c: CountSize) void { self.counts.getPtr(key).* += c; } /// Increases the key count by given amount. pub fn add(self: *Self, key: E, c: CountSize) error{Overflow}!void { self.counts.set(key, try std.math.add(CountSize, self.counts.get(key), c)); } /// Decreases the key count by given amount. If amount is /// greater than the number of keys in multset, then key count /// will be set to zero. pub fn remove(self: *Self, key: E, c: CountSize) void { self.counts.getPtr(key).* -= @min(self.getCount(key), c); } /// Returns the count for a key. pub fn getCount(self: Self, key: E) CountSize { return self.counts.get(key); } /// Set the count for a key. pub fn setCount(self: *Self, key: E, c: CountSize) void { self.counts.set(key, c); } /// Increases the all key counts by given multiset. Caller /// asserts operation will not overflow any key. pub fn addSetAssertSafe(self: *Self, other: Self) void { inline for (@typeInfo(E).@"enum".fields) |field| { const key = @as(E, @enumFromInt(field.value)); self.addAssertSafe(key, other.getCount(key)); } } /// Increases the all key counts by given multiset. pub fn addSet(self: *Self, other: Self) error{Overflow}!void { inline for (@typeInfo(E).@"enum".fields) |field| { const key = @as(E, @enumFromInt(field.value)); try self.add(key, other.getCount(key)); } } /// Decreases the all key counts by given multiset. If /// the given multiset has more key counts than this, /// then that key will have a key count of zero. pub fn removeSet(self: *Self, other: Self) void { inline for (@typeInfo(E).@"enum".fields) |field| { const key = @as(E, @enumFromInt(field.value)); self.remove(key, other.getCount(key)); } } /// Returns true iff all key counts are the same as /// given multiset. pub fn eql(self: Self, other: Self) bool { inline for (@typeInfo(E).@"enum".fields) |field| { const key = @as(E, @enumFromInt(field.value)); if (self.getCount(key) != other.getCount(key)) { return false; } } return true; } /// Returns true iff all key counts less than or /// equal to the given multiset. pub fn subsetOf(self: Self, other: Self) bool { inline for (@typeInfo(E).@"enum".fields) |field| { const key = @as(E, @enumFromInt(field.value)); if (self.getCount(key) > other.getCount(key)) { return false; } } return true; } /// Returns true iff all key counts greater than or /// equal to the given multiset. pub fn supersetOf(self: Self, other: Self) bool { inline for (@typeInfo(E).@"enum".fields) |field| { const key = @as(E, @enumFromInt(field.value)); if (self.getCount(key) < other.getCount(key)) { return false; } } return true; } /// Returns a multiset with the total key count of this /// multiset and the other multiset. Caller asserts /// operation will not overflow any key. pub fn plusAssertSafe(self: Self, other: Self) Self { var result = self; result.addSetAssertSafe(other); return result; } /// Returns a multiset with the total key count of this /// multiset and the other multiset. pub fn plus(self: Self, other: Self) error{Overflow}!Self { var result = self; try result.addSet(other); return result; } /// Returns a multiset with the key count of this /// multiset minus the corresponding key count in the /// other multiset. If the other multiset contains /// more key count than this set, that key will have /// a count of zero. pub fn minus(self: Self, other: Self) Self { var result = self; result.removeSet(other); return result; } pub const Entry = EnumArray(E, CountSize).Entry; pub const Iterator = EnumArray(E, CountSize).Iterator; /// Returns an iterator over this multiset. Keys with zero /// counts are included. Modifications to the set during /// iteration may or may not be observed by the iterator, /// but will not invalidate it. pub fn iterator(self: *Self) Iterator { return self.counts.iterator(); } }; }