int_set #
line 47func int_set() -> &IntSet
An empty IntSet.
Source
func int_set() -> &IntSet { return new IntSet { entries: int_map() }; }
Reed's standard library. Imported with use std.set; not on disk.
| int_set | An empty IntSet. |
| int_set_with_capacity | An empty IntSet with room for capacity members before the first rehash. |
| int_set_from | An IntSet holding every distinct value in values. |
| bit_set | An empty BitSet able to hold members 0..capacity. |
func int_set() -> &IntSet
An empty IntSet.
func int_set() -> &IntSet { return new IntSet { entries: int_map() }; }
func int_set_with_capacity(capacity: i32) -> &IntSet
An empty IntSet with room for capacity members before the first rehash.
func int_set_with_capacity(capacity: i32) -> &IntSet { return new IntSet { entries: int_map_with_capacity(capacity) }; }
func int_set_from(values: &I32Values) -> &IntSet
An IntSet holding every distinct value in values.
func int_set_from(values: &I32Values) -> &IntSet { let out: &IntSet = int_set_with_capacity(#values); for i in 0..#values { out.add(values[i]); } return out; }
func bit_set(capacity: i32) -> &BitSet
An empty BitSet able to hold members 0..capacity.
A capacity below zero is treated as zero.
func bit_set(capacity: i32) -> &BitSet { let n: i32 = capacity < 0 ? 0 : capacity; // Round up to whole 32-bit words. return new BitSet { words: new I32Values[(n + 31) / 32]{}, capacity: n }; }
| IntSet.len | How many members the set holds. |
| IntSet.is_empty | Whether the set holds no members. |
| IntSet.add | Adds value to the set. |
| IntSet.contains | Whether value is a member. |
| IntSet.remove | Removes value from the set. |
| IntSet.clear | Removes every member, keeping the allocated capacity. |
| IntSet.to_list | Every member, in unspecified order. |
| IntSet.union | A new set holding every member of either set. |
| IntSet.intersect | A new set holding the members present in both sets. |
| IntSet.difference | A new set holding the members of self that are not in other. |
| IntSet.is_subset | Whether every member of self is also a member of other. |
| BitSet.capacity | The exclusive upper bound on membership, as given at construction. |
| BitSet.add | Adds value to the set. |
| BitSet.contains | Whether value is a member. |
| BitSet.remove | Removes value from the set. |
| BitSet.toggle | Adds value if absent and removes it if present. |
| BitSet.len | How many members the set holds. |
| BitSet.is_empty | Whether the set holds no members. |
| BitSet.clear | Removes every member. |
| BitSet.fill_all | Adds every member of 0..capacity. |
| BitSet.next | The smallest member at or above from, or -1 when there is none. |
| BitSet.to_array | Every member, in ascending order. |
| BitSet.union_with | Adds every member of other to self, in place. |
| BitSet.intersect_with | Removes from self every member not also in other, in place. |
| BitSet.subtract | Removes from self every member also in other, in place. |
| BitSet.trim | Clears any bits at or above capacity in the final word. |
func IntSet.len(self: &IntSet) -> i32
How many members the set holds.
func IntSet.len(self: &IntSet) -> i32 { return self->entries.len(); }
func IntSet.is_empty(self: &IntSet) -> i32
Whether the set holds no members.
func IntSet.is_empty(self: &IntSet) -> i32 { return self->entries.len() == 0; }
func IntSet.add(self: &IntSet, value: i32) -> i32
Adds value to the set.
func IntSet.add(self: &IntSet, value: i32) -> i32 { if (self->entries.contains(value)) { return 0; } self->entries.put(value, 1); return 1; }
func IntSet.contains(self: &IntSet, value: i32) -> i32
Whether value is a member.
func IntSet.contains(self: &IntSet, value: i32) -> i32 { return self->entries.contains(value); }
func IntSet.remove(self: &IntSet, value: i32) -> i32
Removes value from the set.
func IntSet.remove(self: &IntSet, value: i32) -> i32 { return self->entries.remove(value); }
func IntSet.clear(self: &IntSet) -> void
Removes every member, keeping the allocated capacity.
func IntSet.clear(self: &IntSet) { self->entries.clear(); }
func IntSet.to_list(self: &IntSet) -> &IntList
Every member, in unspecified order.
func IntSet.to_list(self: &IntSet) -> &IntList { return self->entries.keys(); }
func IntSet.union(self: &IntSet, other: &IntSet) -> &IntSet
A new set holding every member of either set.
func IntSet.union(self: &IntSet, other: &IntSet) -> &IntSet { let out: &IntSet = int_set_with_capacity(self.len() + other.len()); let mine: &IntList = self.to_list(); for i in 0..mine.len() { out.add(mine.at(i)); } let theirs: &IntList = other.to_list(); for i in 0..theirs.len() { out.add(theirs.at(i)); } return out; }
func IntSet.intersect(self: &IntSet, other: &IntSet) -> &IntSet
A new set holding the members present in both sets.
Iterates the smaller set and probes the larger, so the cost is proportional to the smaller operand rather than to whichever happens to be the receiver.
func IntSet.intersect(self: &IntSet, other: &IntSet) -> &IntSet { let out: &IntSet = int_set(); let smaller: &IntSet = self.len() <= other.len() ? self : other; let larger: &IntSet = self.len() <= other.len() ? other : self; let members: &IntList = smaller.to_list(); for i in 0..members.len() { let value: i32 = members.at(i); if (larger.contains(value)) { out.add(value); } } return out; }
func IntSet.difference(self: &IntSet, other: &IntSet) -> &IntSet
A new set holding the members of self that are not in other.
func IntSet.difference(self: &IntSet, other: &IntSet) -> &IntSet { let out: &IntSet = int_set(); let members: &IntList = self.to_list(); for i in 0..members.len() { let value: i32 = members.at(i); if (other.contains(value) == 0) { out.add(value); } } return out; }
func IntSet.is_subset(self: &IntSet, other: &IntSet) -> i32
Whether every member of self is also a member of other.
The empty set is a subset of everything.
func IntSet.is_subset(self: &IntSet, other: &IntSet) -> i32 { let members: &IntList = self.to_list(); for i in 0..members.len() { if (other.contains(members.at(i)) == 0) { return 0; } } return 1; }
func BitSet.capacity(self: &BitSet) -> i32
The exclusive upper bound on membership, as given at construction.
func BitSet.capacity(self: &BitSet) -> i32 { return self->capacity; }
func BitSet.add(self: &BitSet, value: i32) -> i32
Adds value to the set.
A value outside 0..capacity is ignored rather than trapping or growing the set: a BitSet's bound is chosen by its creator and silently extending it would break the memory guarantee that is the whole point of the type.
func BitSet.add(self: &BitSet, value: i32) -> i32 { if (value < 0 || value >= self->capacity) { return 0; } let word: i32 = value >>> 5; let bit: i32 = 1 << (value & 31); if ((self->words[word] & bit) != 0) { return 0; } self->words[word] = self->words[word] | bit; return 1; }
func BitSet.contains(self: &BitSet, value: i32) -> i32
Whether value is a member.
A value out of range is never a member.
func BitSet.contains(self: &BitSet, value: i32) -> i32 { if (value < 0 || value >= self->capacity) { return 0; } return (self->words[value >>> 5] >>> (value & 31)) & 1; }
func BitSet.remove(self: &BitSet, value: i32) -> i32
Removes value from the set.
func BitSet.remove(self: &BitSet, value: i32) -> i32 { if (value < 0 || value >= self->capacity) { return 0; } let word: i32 = value >>> 5; let bit: i32 = 1 << (value & 31); if ((self->words[word] & bit) == 0) { return 0; } self->words[word] = self->words[word] & ~bit; return 1; }
func BitSet.toggle(self: &BitSet, value: i32) -> i32
Adds value if absent and removes it if present.
func BitSet.toggle(self: &BitSet, value: i32) -> i32 { if (value < 0 || value >= self->capacity) { return 0; } let word: i32 = value >>> 5; let bit: i32 = 1 << (value & 31); self->words[word] = self->words[word] ^ bit; return (self->words[word] & bit) != 0; }
func BitSet.len(self: &BitSet) -> i32
How many members the set holds.
Counts set bits a word at a time with popcnt, so this is 32 members per instruction rather than a per-member loop.
func BitSet.len(self: &BitSet) -> i32 { var total: i32 = 0; for i in 0..#self->words { total = total + self->words[i].popcnt(); } return total; }
func BitSet.is_empty(self: &BitSet) -> i32
Whether the set holds no members.
func BitSet.is_empty(self: &BitSet) -> i32 { for i in 0..#self->words { if (self->words[i] != 0) { return 0; } } return 1; }
func BitSet.clear(self: &BitSet) -> void
Removes every member.
func BitSet.clear(self: &BitSet) { self->words.fill(0, 0, #self->words); }
func BitSet.fill_all(self: &BitSet) -> void
Adds every member of 0..capacity.
Sets only the bits below capacity, leaving the word array's padding bits clear -- if they were set, len would over-count.
func BitSet.fill_all(self: &BitSet) { self->words.fill(0, -1, #self->words); let extra: i32 = #self->words * 32 - self->capacity; if (extra > 0) { self->words[#self->words - 1] = self->words[#self->words - 1] & (-1 >>> extra); } }
func BitSet.next(self: &BitSet, from: i32) -> i32
The smallest member at or above from, or -1 when there is none.
Iterating with this is how a BitSet is enumerated: var i: i32 = s.next(0); loop { if (i < 0) break; ...; i = s.next(i + 1); }. It skips empty words wholesale and uses ctz within a word, so scanning a sparse set costs time proportional to the words, not to the capacity.
func BitSet.next(self: &BitSet, from: i32) -> i32 { var at: i32 = from < 0 ? 0 : from; if (at >= self->capacity) { return -1; } var word: i32 = at >>> 5; // Mask off the bits below `at` in the first word, so the scan starts exactly at `from`. var bits: i32 = self->words[word] & (-1 << (at & 31)); loop scan() { if (bits != 0) { let found: i32 = word * 32 + bits.ctz(); return found < self->capacity ? found : -1; } word = word + 1; if (word >= #self->words) { break scan(); } bits = self->words[word]; continue scan(); } return -1; }
func BitSet.to_array(self: &BitSet) -> &I32Values
Every member, in ascending order.
func BitSet.to_array(self: &BitSet) -> &I32Values { let out: &I32Values = new I32Values[self.len()]{}; var index: i32 = 0; var value: i32 = self.next(0); loop collect() { if (value < 0) { break collect(); } out[index] = value; index = index + 1; value = self.next(value + 1); continue collect(); } return out; }
func BitSet.union_with(self: &BitSet, other: &BitSet) -> void
Adds every member of other to self, in place.
A capacity mismatch is handled by operating on the words both sets have; members of other beyond self's capacity are dropped, matching add's out-of-range rule.
func BitSet.union_with(self: &BitSet, other: &BitSet) { let n: i32 = #self->words < #other->words ? #self->words : #other->words; for i in 0..n { self->words[i] = self->words[i] | other->words[i]; } self.trim(); }
func BitSet.intersect_with(self: &BitSet, other: &BitSet) -> void
Removes from self every member not also in other, in place.
func BitSet.intersect_with(self: &BitSet, other: &BitSet) { for i in 0..#self->words { let mask: i32 = i < #other->words ? other->words[i] : 0; self->words[i] = self->words[i] & mask; } }
func BitSet.subtract(self: &BitSet, other: &BitSet) -> void
Removes from self every member also in other, in place.
func BitSet.subtract(self: &BitSet, other: &BitSet) { let n: i32 = #self->words < #other->words ? #self->words : #other->words; for i in 0..n { self->words[i] = self->words[i] & ~other->words[i]; } }
func BitSet.trim(self: &BitSet) -> void
Clears any bits at or above capacity in the final word.
The invariant every operation must restore: padding bits are never set, so len and is_empty can read whole words without masking.
func BitSet.trim(self: &BitSet) { if (#self->words == 0) { return; } let extra: i32 = #self->words * 32 - self->capacity; if (extra > 0) { self->words[#self->words - 1] = self->words[#self->words - 1] & (-1 >>> extra); } }
| IntSet | A hash set of i32 members. |
| BitSet | A dense set of members drawn from 0..capacity, stored one bit each. |
struct IntSet { entries: mut &IntMap, }
A hash set of i32 members.
struct IntSet { entries: mut &IntMap, }
struct BitSet { words: mut &I32Values, capacity: mut i32, }
A dense set of members drawn from 0..capacity, stored one bit each.
struct BitSet { words: mut &I32Values, /// The exclusive upper bound on membership. Kept separately because the word array /// rounds up to a multiple of 32 and the padding bits must never be reported as members. capacity: mut i32, }