Set
Set is a heap-owned hash set (an NSMutableSet) of unique elements, each
any Hashable + Comparable Object*. Membership is by value, and every
stored element is held with a strong reference.
#import "Set.xc" // or the Foundation umbrellaOverview
Section titled “Overview”A Set stores its elements in a single power-of-two slot table (one cell per
slot) using open addressing with linear probing, and keeps a parallel dense
_order array so enumAt is O(1) and iteration is deterministic. It
inherits from Object and needs a real heap
(-falloc=heap, the default on the xt 6502 layout and every native backend).
Set is a generic container only at compile time: the element type
parameter is a check the compiler erases, and the slots are type-erased
pointer cells at runtime.
Elements must conform to both Hashable (for
slot selection) and Comparable (for
collision-chain equality). Foundation’s Number,
String and Data conform to
both. A user element type adds <Hashable, Comparable> to its class line and
supplies the two methods.
Uniqueness by value. add uses the element’s equals on the probe
chain, so re-adding a value-equal element is a no-op (no duplicate, no extra
retain). contains is value membership, not identity.
Ownership (ARC). The Set holds a strong reference on every element.
add retains a fresh element; remove /
removeAll release what they drop; dealloc releases
every element and frees the table. The set-algebra methods and
copy return new sets that hold their own strong reference to every
element. These are shallow: the elements are shared.
Load factor. The table grows (doubling) when it would pass α > 0.75, so membership stays close to O(1). Removed entries leave a tombstone rather than clearing, so later entries’ probe chains still resolve.
Conforms to
Section titled “Conforms to”Enumerable:enumLength/enumAt, sofor (Object* e in s)walks the elements.Copying:copyreturns an independent (shallow) duplicate.
Every Set* is also an Object* and fits anywhere one is expected.
Topics
Section titled “Topics”Creating · withCapacity · withArray · init
Accessing · add · contains · count · isEmpty
Set algebra · unionWith · intersect · subtract · symmetricDifference
Relations · isSubsetOf · isSupersetOf · intersects · isDisjointFrom · equalsSet
Conversion · allObjects
Iterating · enumLength · enumAt
Creating
Section titled “Creating”withCapacity
Section titled “withCapacity”static Set* withCapacity(u32 cap)Pre-allocates the slot table rounded up to a power of two (minimum 16), skipping
a future resize copy when the rough upper bound is known. A bare new Set()
allocates lazily on the first add.
withArray
Section titled “withArray”static Set* withArray(Array* items)A new Set of the distinct elements of items (null and duplicate entries are
dropped). A null argument yields an empty Set.
void init(void)The default initializer: an empty Set with no allocation. Prefer new Set() or
the with… constructors; you rarely call init directly.
Accessing
Section titled “Accessing”void add(Hashable* elem)Adds elem if no value-equal element is already present, retaining it and
appending it to the insertion order. Re-adding an existing value is a no-op.
Triggers a resize first if the table would pass α > 0.75.
contains
Section titled “contains”bool contains(Hashable* elem)true if a value-equal element is a member. O(1) average.
u32 count(void)Number of live elements (excludes tombstones). O(1).
isEmpty
Section titled “isEmpty”bool isEmpty(void)true when count is zero.
Removing
Section titled “Removing”remove
Section titled “remove”void remove(Hashable* elem)Removes the value-equal element (plants a tombstone, closes the gap in the insertion order, releases the element). A missing element is a no-op.
removeAll
Section titled “removeAll”void removeAll(void)Releases every element and empties the table.
Set algebra
Section titled “Set algebra”Each returns a new Set; the receiver and the argument are untouched. The result holds its own strong reference to every element it contains.
unionWith
Section titled “unionWith”Set* unionWith(Set* other)Everything in either set.
intersect
Section titled “intersect”Set* intersect(Set* other)Only what is in both sets.
subtract
Section titled “subtract”Set* subtract(Set* other)What is in the receiver but not in other.
symmetricDifference
Section titled “symmetricDifference”Set* symmetricDifference(Set* other)What is in one set or the other, but not both.
Relations
Section titled “Relations”Predicates over two sets; none of them allocate a result set.
isSubsetOf
Section titled “isSubsetOf”bool isSubsetOf(Set* other)true if every element of the receiver is in other. The empty set is a subset
of anything (including a null other).
isSupersetOf
Section titled “isSupersetOf”bool isSupersetOf(Set* other)true if the receiver contains every element of other (other.isSubsetOf(self)).
intersects
Section titled “intersects”bool intersects(Set* other)true if the two sets share at least one element.
isDisjointFrom
Section titled “isDisjointFrom”bool isDisjointFrom(Set* other)true if the two sets share no element (!intersects(other)).
equalsSet
Section titled “equalsSet”bool equalsSet(Set* other)true if the two sets have the same members, in any order (same count, and the
receiver is a subset of other).
Conversion
Section titled “Conversion”allObjects
Section titled “allObjects”Array* allObjects(void)The members as a new Array, in iteration order (a Set
has no meaningful order of its own).
Iterating
Section titled “Iterating”The Enumerable hooks; you normally use
for (Object* e in s) rather than calling these directly.
enumLength
Section titled “enumLength”u32 enumLength(void)Number of elements the for-in driver will visit (== count).
enumAt
Section titled “enumAt”Object* enumAt(u32 i)The i-th element for the for-in driver. A plain O(1) index, because _order
is dense.
Lifecycle
Section titled “Lifecycle”Set* copy(void)A new Set holding the same elements. The copy is shallow: the elements are
shared, each retained by the new Set. This is the
Copying method.
dealloc
Section titled “dealloc”void dealloc(void)Releases every element, then frees the slot and order buffers. ARC calls it when the last reference goes away; you do not call it directly.
Worked example
Section titled “Worked example”#import "Stdio.xc"#import "Foundation.xc"
i32 main(void){ Set* a = new Set(); a.add(Number.with((i32)1)); a.add(Number.with((i32)2)); a.add(Number.with((i32)2)); // duplicate value — ignored
Set* b = new Set(); b.add(Number.with((i32)2)); b.add(Number.with((i32)3));
Set* both = a.intersect(b); // { 2 } Stdio.printf("count(a)=%d shared=%d\n", (i16)a.count(), (i16)both.count()); return 0;}count(a)=2 shared=1