moonbitstack/moonstl/seq does not have a README file

    BitSet

    pub struct BitSet {
    words : Array[UInt64]
    }

    A set of non-negative integers stored as bits: membership is a bit test, and the set operations run word by word. length counts the elements, not the range, because the range has no ceiling.

    test {
    let set : @seq.BitSet = @seq.BitSet::new()
    @test.assert_eq(set.insert(3), true)
    @test.assert_eq(set.insert(3), false)
    @test.assert_eq(set.contains(3), true)
    @test.assert_eq(set.length(), 1)
    @test.assert_eq(set.select(0), Some(3))
    @test.assert_eq(set.rank(4), 1)
    }
    impl Eq for BitSet
    impl Show for BitSet

    BitSet::clear

    fn BitSet::clear(self : BitSet) -> Unit

    BitSet::contains

    fn BitSet::contains(self : BitSet, index : Int) -> Bool

    BitSet::copy

    fn BitSet::copy(self : BitSet) -> BitSet

    BitSet::difference

    fn BitSet::difference(self : BitSet, other : BitSet) -> BitSet

    BitSet::difference_in_place

    fn BitSet::difference_in_place(self : BitSet, other : BitSet) -> Unit

    BitSet::equal

    fn BitSet::equal(self : BitSet, other : BitSet) -> Bool

    BitSet::insert

    fn BitSet::insert(self : BitSet, index : Int) -> Bool

    Adds index and reports whether it was new.

    BitSet::intersection

    fn BitSet::intersection(self : BitSet, other : BitSet) -> BitSet

    BitSet::intersection_in_place

    fn BitSet::intersection_in_place(self : BitSet, other : BitSet) -> Unit

    BitSet::is_disjoint

    fn BitSet::is_disjoint(self : BitSet, other : BitSet) -> Bool

    BitSet::is_empty

    fn BitSet::is_empty(self : BitSet) -> Bool

    BitSet::is_subset

    fn BitSet::is_subset(self : BitSet, other : BitSet) -> Bool

    BitSet::is_superset

    fn BitSet::is_superset(self : BitSet, other : BitSet) -> Bool

    BitSet::iter

    fn BitSet::iter(self : BitSet) -> Iter[Int]

    The elements in increasing order.

    BitSet::length

    fn BitSet::length(self : BitSet) -> Int

    The number of elements, not the span they cover.

    BitSet::new

    fn BitSet::new(capacity? : Int) -> BitSet

    BitSet::not_equal

    fn BitSet::not_equal(x : BitSet, y : BitSet) -> Bool

    BitSet::output

    fn BitSet::output(self : BitSet, logger : &Logger) -> Unit

    BitSet::rank

    fn BitSet::rank(self : BitSet, index : Int) -> Int

    How many elements are smaller than index, which is the position a select would report and the count of set bits in [0, index).

    BitSet::remove

    fn BitSet::remove(self : BitSet, index : Int) -> Bool

    BitSet::select

    fn BitSet::select(self : BitSet, n : Int) -> Int?

    The element at position n in increasing order, or None when the set holds no such position.

    BitSet::symmetric_difference

    fn BitSet::symmetric_difference(self : BitSet, other : BitSet) -> BitSet

    BitSet::to_array

    fn BitSet::to_array(self : BitSet) -> Array[Int]

    BitSet::to_string

    fn BitSet::to_string(self : BitSet) -> String

    BitSet::union

    fn BitSet::union(self : BitSet, other : BitSet) -> BitSet

    BitSet::union_in_place

    fn BitSet::union_in_place(self : BitSet, other : BitSet) -> Unit

    BitVec

    pub struct BitVec {
    words : Array[UInt64]
    bits : Int
    }

    A vector of bits with a length: bit i lives in word i / 64 at bit i % 64, and the bits past the length are always zero.

    test {
    let bits : @seq.BitVec = @seq.BitVec::new()
    bits.push(true)
    bits.push(false)
    bits.push(true)
    @test.assert_eq(bits.length(), 3)
    @test.assert_eq(bits.get(2), Some(true))
    @test.assert_eq(bits.count_ones(), 2)
    }
    impl Eq for BitVec
    impl Show for BitVec

    BitVec::at

    fn BitVec::at(self : BitVec, index : Int) -> Bool

    BitVec::blocks

    fn BitVec::blocks(self : BitVec) -> ArrayView[UInt64]

    The words themselves, so a caller can hash or compare a run of bits without walking them one at a time.

    BitVec::clear

    fn BitVec::clear(self : BitVec) -> Unit

    BitVec::copy

    fn BitVec::copy(self : BitVec) -> BitVec

    BitVec::count_ones

    fn BitVec::count_ones(self : BitVec) -> Int

    BitVec::equal

    fn BitVec::equal(self : BitVec, other : BitVec) -> Bool

    BitVec::get

    fn BitVec::get(self : BitVec, index : Int) -> Bool?

    BitVec::is_empty

    fn BitVec::is_empty(self : BitVec) -> Bool

    BitVec::iter

    fn BitVec::iter(self : BitVec) -> Iter[Bool]

    BitVec::length

    fn BitVec::length(self : BitVec) -> Int

    BitVec::new

    fn BitVec::new(capacity? : Int) -> BitVec

    BitVec::not_equal

    fn BitVec::not_equal(x : BitVec, y : BitVec) -> Bool

    BitVec::output

    fn BitVec::output(self : BitVec, logger : &Logger) -> Unit

    BitVec::pop

    fn BitVec::pop(self : BitVec) -> Bool?

    BitVec::push

    fn BitVec::push(self : BitVec, value : Bool) -> Unit

    BitVec::resize

    fn BitVec::resize(self : BitVec, length : Int) -> Unit

    Grows with zeroes or cuts the length; the bits past the new length are cleared, so a count_ones afterwards never counts them.

    BitVec::set

    fn BitVec::set(self : BitVec, index : Int, value : Bool) -> Unit

    Sets a bit that is already inside the length. Growing is resize, so a write cannot silently change how long the vector is.

    BitVec::to_string

    fn BitVec::to_string(self : BitVec) -> String

    DenseSlotMap

    pub struct DenseSlotMap[T] {
    values : Array[T?]
    generations : Array[UInt]
    dense : Array[Int]
    positions : Array[Int]
    free : Array[Int]
    len : Int
    }

    A slot map that also keeps the entries in a dense array, so iteration follows insertion order and a removal moves the last entry into the hole. The keys are the same SlotKeys a SlotMap hands out; what changes is that the entries are contiguous while they live, which is what a caller who walks the whole container wants.

    DenseSlotMap::at

    fn[T] DenseSlotMap::at(self : DenseSlotMap[T], key : SlotKey[T]) -> T

    DenseSlotMap::capacity

    fn[T] DenseSlotMap::capacity(self : DenseSlotMap[T]) -> Int

    DenseSlotMap::clear

    fn[T] DenseSlotMap::clear(self : DenseSlotMap[T]) -> Unit

    DenseSlotMap::contains

    fn[T] DenseSlotMap::contains(self : DenseSlotMap[T], key : SlotKey[T]) -> Bool

    DenseSlotMap::copy

    fn[T] DenseSlotMap::copy(self : DenseSlotMap[T]) -> DenseSlotMap[T]

    DenseSlotMap::get

    fn[T] DenseSlotMap::get(self : DenseSlotMap[T], key : SlotKey[T]) -> T?

    DenseSlotMap::insert

    fn[T] DenseSlotMap::insert(self : DenseSlotMap[T], value : T) -> SlotKey[T]

    DenseSlotMap::is_empty

    fn[T] DenseSlotMap::is_empty(self : DenseSlotMap[T]) -> Bool

    DenseSlotMap::iter

    fn[T] DenseSlotMap::iter(self : DenseSlotMap[T]) -> Iter[T]

    The entries in insertion order.

    DenseSlotMap::iter2

    fn[T] DenseSlotMap::iter2(self : DenseSlotMap[T]) -> Iter2[SlotKey[T], T]

    DenseSlotMap::keys

    fn[T] DenseSlotMap::keys(self : DenseSlotMap[T]) -> Iter[SlotKey[T]]

    DenseSlotMap::length

    fn[T] DenseSlotMap::length(self : DenseSlotMap[T]) -> Int

    DenseSlotMap::new

    fn[T] DenseSlotMap::new(capacity? : Int) -> DenseSlotMap[T]

    DenseSlotMap::remove

    fn[T] DenseSlotMap::remove(self : DenseSlotMap[T], key : SlotKey[T]) -> T?

    DenseSlotMap::set

    fn[T] DenseSlotMap::set(self : DenseSlotMap[T], key : SlotKey[T], value : T) -> Bool

    DenseSlotMap::to_array

    fn[T] DenseSlotMap::to_array(self : DenseSlotMap[T]) -> Array[T]

    GapBuffer

    pub struct GapBuffer[T] {
    before : Array[T]
    after : Array[T]
    }

    An array with a hole in it: the elements before the hole are kept in order, the ones after it are kept reversed, and moving the hole is the only operation that shifts more than one element. Typing at the hole is therefore constant time, which is what a text editor's buffer wants.

    test {
    let buffer : @seq.GapBuffer[Int32] = @seq.GapBuffer::new()
    buffer.insert(0, 1)
    buffer.insert(1, 3)
    buffer.insert(1, 2)
    @test.assert_eq(buffer.to_array(), [1, 2, 3])
    @test.assert_eq(buffer.remove(1), Some(2))
    @test.assert_eq(buffer.to_array(), [1, 3])
    }

    GapBuffer::at

    fn[T] GapBuffer::at(self : GapBuffer[T], index : Int) -> T

    GapBuffer::clear

    fn[T] GapBuffer::clear(self : GapBuffer[T]) -> Unit

    GapBuffer::copy

    fn[T] GapBuffer::copy(self : GapBuffer[T]) -> GapBuffer[T]

    GapBuffer::from_array

    fn[T] GapBuffer::from_array(values : ArrayView[T], capacity? : Int) -> GapBuffer[T]

    GapBuffer::get

    fn[T] GapBuffer::get(self : GapBuffer[T], index : Int) -> T?

    GapBuffer::insert

    fn[T] GapBuffer::insert(self : GapBuffer[T], index : Int, value : T) -> Unit

    Inserts at the hole, which is constant time once the hole is there.

    GapBuffer::is_empty

    fn[T] GapBuffer::is_empty(self : GapBuffer[T]) -> Bool

    GapBuffer::iter

    fn[T] GapBuffer::iter(self : GapBuffer[T]) -> Iter[T]

    GapBuffer::length

    fn[T] GapBuffer::length(self : GapBuffer[T]) -> Int

    GapBuffer::move_gap_to

    fn[T] GapBuffer::move_gap_to(self : GapBuffer[T], index : Int) -> Unit

    Puts the hole at index, moving as few elements as the distance allows.

    GapBuffer::new

    fn[T] GapBuffer::new(capacity? : Int) -> GapBuffer[T]

    GapBuffer::remove

    fn[T] GapBuffer::remove(self : GapBuffer[T], index : Int) -> T?

    GapBuffer::set

    fn[T] GapBuffer::set(self : GapBuffer[T], index : Int, value : T) -> Bool

    GapBuffer::to_array

    fn[T] GapBuffer::to_array(self : GapBuffer[T]) -> Array[T]

    LinkedList

    pub struct LinkedList[T] {
    head : LinkedListNode[T]?
    tail : LinkedListNode[T]?
    len : Int
    }

    A doubly linked list: splicing one list onto another and splitting a list in two are constant time, because neither moves an element — they only relink nodes. Indexing walks, which is the price of that.

    test {
    let list : @seq.LinkedList[Int32] = @seq.LinkedList::new()
    list.push_back(1)
    list.push_back(2)
    list.push_front(0)
    @test.assert_eq(list.to_array(), [0, 1, 2])
    @test.assert_eq(list.pop_front(), Some(0))
    @test.assert_eq(list.length(), 2)
    }

    LinkedList::append

    fn[T] LinkedList::append(self : LinkedList[T], other : LinkedList[T]) -> Unit

    The same as splice: the name a reader of Deque already knows.

    LinkedList::back

    fn[T] LinkedList::back(self : LinkedList[T]) -> T?

    LinkedList::clear

    fn[T] LinkedList::clear(self : LinkedList[T]) -> Unit

    LinkedList::front

    fn[T] LinkedList::front(self : LinkedList[T]) -> T?

    LinkedList::get

    fn[T] LinkedList::get(self : LinkedList[T], index : Int) -> T?

    LinkedList::insert_at

    fn[T] LinkedList::insert_at(self : LinkedList[T], index : Int, value : T) -> Unit

    LinkedList::is_empty

    fn[T] LinkedList::is_empty(self : LinkedList[T]) -> Bool

    LinkedList::iter

    fn[T] LinkedList::iter(self : LinkedList[T]) -> Iter[T]

    LinkedList::length

    fn[T] LinkedList::length(self : LinkedList[T]) -> Int

    LinkedList::new

    fn[T] LinkedList::new() -> LinkedList[T]

    LinkedList::pop_back

    fn[T] LinkedList::pop_back(self : LinkedList[T]) -> T?

    LinkedList::pop_front

    fn[T] LinkedList::pop_front(self : LinkedList[T]) -> T?

    LinkedList::push_back

    fn[T] LinkedList::push_back(self : LinkedList[T], value : T) -> Unit

    LinkedList::push_front

    fn[T] LinkedList::push_front(self : LinkedList[T], value : T) -> Unit

    LinkedList::remove_at

    fn[T] LinkedList::remove_at(self : LinkedList[T], index : Int) -> T?

    LinkedList::rev_iter

    fn[T] LinkedList::rev_iter(self : LinkedList[T]) -> Iter[T]

    LinkedList::splice

    fn[T] LinkedList::splice(self : LinkedList[T], other : LinkedList[T]) -> Unit

    Links other onto the end of this list. other is left empty, and no element is copied or moved: only four pointers change.

    LinkedList::split_off

    fn[T] LinkedList::split_off(self : LinkedList[T], index : Int) -> LinkedList[T]

    Cuts the list at index and returns the tail. The two halves share no node; only the link at the cut changes.

    LinkedList::to_array

    fn[T] LinkedList::to_array(self : LinkedList[T]) -> Array[T]

    LinkedListNode

    pub struct LinkedListNode[T] {
    value : T
    prev : LinkedListNode[T]?
    next : LinkedListNode[T]?
    }

    A node of a LinkedList. The list owns every node it links; a node is created by push_back/push_front/insert_at and is never constructed by a caller, which is why the type carries no public constructor.

    Overflow

    pub(all) enum Overflow {
    Overwrite
    Refuse
    } derive(Eq,
    Debug
    )

    What a full RingBuffer does with the element it cannot keep. Overwrite drops the element at the opposite end, which is how a fixed-size buffer of recent samples is usually written; Refuse leaves the buffer untouched and hands the new element back, so a caller that must not lose data sees the refusal in the return value instead of an exception.
    impl Show for Overflow

    Overflow::equal

    fn Overflow::equal(Overflow, Overflow) -> Bool

    Overflow::not_equal

    fn Overflow::not_equal(x : Overflow, y : Overflow) -> Bool

    Overflow::output

    fn Overflow::output(self : Overflow, logger : &Logger) -> Unit

    Overflow::to_repr

    Overflow::to_string

    fn Overflow::to_string(self : Overflow) -> String

    RingBuffer

    pub struct RingBuffer[T] {
    slots : Array[T]
    head : Int
    len : Int
    capacity : Int
    overflow : Overflow
    }

    A fixed-ceiling ring of elements. The storage is a plain array with the live elements starting at head and wrapping around, so every operation that touches an end is constant time whatever the length.

    capacity is a ceiling, not a reservation: the array starts empty and is doubled — up to the ceiling — as the buffer fills, and empty slots beyond len hold copies of an element already in the buffer. Those stale copies are outside every view the buffer hands out.
    impl Eq for RingBuffer[T]
    impl Hash for RingBuffer[T]
    impl Show for RingBuffer[T]

    RingBuffer::as_views

    fn[T] RingBuffer::as_views(self : RingBuffer[T]) -> (ArrayView[T], ArrayView[T])

    The live elements as one or two contiguous array views, in logical order: the run from the head to the end of the storage, then the run that wrapped around to the start. Either view may be empty. Reading both views in order visits the buffer without copying it.

    RingBuffer::at

    fn[T] RingBuffer::at(self : RingBuffer[T], index : Int) -> T

    The element index positions from the front. Aborts when out of range, as an array index does.

    RingBuffer::back

    fn[T] RingBuffer::back(self : RingBuffer[T]) -> T?

    The newest element without removing it.

    RingBuffer::capacity

    fn[T] RingBuffer::capacity(self : RingBuffer[T]) -> Int

    The ceiling this buffer was built with; the number of elements cannot exceed it.

    RingBuffer::clear

    fn[T] RingBuffer::clear(self : RingBuffer[T]) -> Unit

    Removes every element. The storage stays allocated so the buffer can be refilled without growing again.

    RingBuffer::copy

    fn[T] RingBuffer::copy(self : RingBuffer[T]) -> RingBuffer[T]

    An independent buffer with the same ceiling, policy and elements. Growing one afterwards does not touch the other.

    RingBuffer::equal

    fn[T : Eq] RingBuffer::equal(self : RingBuffer[T], other : RingBuffer[T]) -> Bool

    RingBuffer::from_array

    fn[T] RingBuffer::from_array(capacity~ : Int, values : ArrayView[T], overflow? : Overflow) -> RingBuffer[T] raise
    Refused

    A buffer holding values in order. When the run is longer than capacity, the policy decides which end survives: Overwrite keeps the last capacity elements, as pushing them one by one would, and Refuse keeps the first.

    RingBuffer::from_iter

    fn[T] RingBuffer::from_iter(capacity~ : Int, values : Iter[T], overflow? : Overflow) -> RingBuffer[T] raise
    Refused

    The lazy form of from_array; the same overflow rule picks which end of a run longer than the ceiling survives.

    RingBuffer::front

    fn[T] RingBuffer::front(self : RingBuffer[T]) -> T?

    The oldest element without removing it.

    RingBuffer::get

    fn[T] RingBuffer::get(self : RingBuffer[T], index : Int) -> T?

    The element index positions from the front, counting from zero, or None when there is no such element.

    RingBuffer::hash

    fn[T : Hash] RingBuffer::hash(self : RingBuffer[T]) -> Int

    RingBuffer::hash_combine

    fn[T : Hash] RingBuffer::hash_combine(self : RingBuffer[T], hasher : Hasher) -> Unit

    RingBuffer::is_empty

    fn[T] RingBuffer::is_empty(self : RingBuffer[T]) -> Bool

    Whether the buffer holds nothing.

    RingBuffer::is_full

    fn[T] RingBuffer::is_full(self : RingBuffer[T]) -> Bool

    Whether the buffer holds as many elements as its ceiling allows, which is the state that makes a push drop something.

    RingBuffer::iter

    fn[T] RingBuffer::iter(self : RingBuffer[T]) -> Iter[T]

    The elements from oldest to newest.

    RingBuffer::length

    fn[T] RingBuffer::length(self : RingBuffer[T]) -> Int

    The number of elements held.

    RingBuffer::linearize

    fn[T] RingBuffer::linearize(self : RingBuffer[T]) -> Unit

    Rotates the storage so the live elements start at index zero, which makes the first of as_views cover the whole buffer. Subsequent pushes and pops wrap again; nothing else depends on the layout.

    RingBuffer::new

    fn[T] RingBuffer::new(capacity~ : Int, overflow? : Overflow) -> RingBuffer[T] raise
    Refused

    An empty buffer with a ceiling of capacity elements. A ceiling of zero or less is refused because a buffer that can hold nothing could never accept a push.

    test {
    let buffer : @seq.RingBuffer[Int32] = @seq.RingBuffer::new(capacity=2)
    @test.assert_eq(buffer.capacity(), 2)
    assert_true(buffer.is_empty())
    }

    RingBuffer::not_equal

    fn[T : Eq] RingBuffer::not_equal(x : RingBuffer[T], y : RingBuffer[T]) -> Bool

    RingBuffer::output

    fn[T : Show] RingBuffer::output(self : RingBuffer[T], logger : &Logger) -> Unit

    RingBuffer::overflow

    fn[T] RingBuffer::overflow(self : RingBuffer[T]) -> Overflow

    The policy this buffer applies when full.

    RingBuffer::pop_back

    fn[T] RingBuffer::pop_back(self : RingBuffer[T]) -> T?

    Removes and returns the newest element, or None when the buffer is empty.

    RingBuffer::pop_front

    fn[T] RingBuffer::pop_front(self : RingBuffer[T]) -> T?

    Removes and returns the oldest element, or None when the buffer is empty.

    RingBuffer::push_back

    fn[T] RingBuffer::push_back(self : RingBuffer[T], value : T) -> T?

    Appends at the back. Returns the element dropped from the front when the buffer was full and the policy is Overwrite; returns the pushed element — and changes nothing — when the policy is Refuse and there is no room; and returns None when the element simply fitted.

    RingBuffer::push_front

    fn[T] RingBuffer::push_front(self : RingBuffer[T], value : T) -> T?

    Prepends at the front, with the mirror-image overflow rule: a full Overwrite buffer drops from the back, and a full Refuse buffer returns the element it was asked to hold.

    RingBuffer::resize_capacity

    fn[T] RingBuffer::resize_capacity(self : RingBuffer[T], capacity~ : Int) -> Unit raise
    Refused

    Changes the ceiling. A ceiling below the current length, or zero or less, is refused because the buffer would have to discard data to honour it. Storage shrinks only to the new ceiling and never grows eagerly.

    RingBuffer::rev_iter

    fn[T] RingBuffer::rev_iter(self : RingBuffer[T]) -> Iter[T]

    The elements from newest to oldest.

    RingBuffer::set

    fn[T] RingBuffer::set(self : RingBuffer[T], index : Int, value : T) -> Unit

    Replaces the element at index; aborts when out of range.

    RingBuffer::to_array

    fn[T] RingBuffer::to_array(self : RingBuffer[T]) -> Array[T]

    The elements in logical order, oldest first.

    RingBuffer::to_string

    fn[T : Show] RingBuffer::to_string(self : RingBuffer[T]) -> String

    SecondaryMap

    pub struct SecondaryMap[T] {
    values : Array[T?]
    slots : Int
    }

    A side table keyed by the slots of another map: it holds a value per slot and never invents a slot of its own. resize tells it how many slots the owner has; a key outside that range is refused, which is how a side table stays in step with the store it describes instead of quietly growing past it.

    SecondaryMap::at

    fn[T] SecondaryMap::at(self : SecondaryMap[T], key : SlotKey[T]) -> T

    SecondaryMap::clear

    fn[T] SecondaryMap::clear(self : SecondaryMap[T]) -> Unit

    SecondaryMap::contains

    fn[T] SecondaryMap::contains(self : SecondaryMap[T], key : SlotKey[T]) -> Bool

    SecondaryMap::copy

    fn[T] SecondaryMap::copy(self : SecondaryMap[T]) -> SecondaryMap[T]

    SecondaryMap::get

    fn[T] SecondaryMap::get(self : SecondaryMap[T], key : SlotKey[T]) -> T?

    SecondaryMap::is_empty

    fn[T] SecondaryMap::is_empty(self : SecondaryMap[T]) -> Bool

    SecondaryMap::iter

    fn[T] SecondaryMap::iter(self : SecondaryMap[T]) -> Iter[T]

    The values that are held, in slot order.

    SecondaryMap::length

    fn[T] SecondaryMap::length(self : SecondaryMap[T]) -> Int

    SecondaryMap::new

    fn[T] SecondaryMap::new() -> SecondaryMap[T]

    SecondaryMap::remove

    fn[T] SecondaryMap::remove(self : SecondaryMap[T], key : SlotKey[T]) -> T?

    SecondaryMap::resize

    fn[T] SecondaryMap::resize(self : SecondaryMap[T], slots~ : Int) -> Unit raise
    Refused

    Tells the side table how many slots the owning map has.

    SecondaryMap::set

    fn[T] SecondaryMap::set(self : SecondaryMap[T], key : SlotKey[T], value : T) -> Unit raise
    Refused

    Slab

    pub struct Slab[T] {
    values : Array[T?]
    free : Array[Int]
    len : Int
    }

    An index-addressed store that reuses the indices it frees. An index carries no generation, so a caller that keeps one past a remove and a later insert reaches the new occupant: that is the trade a Slab makes for handing out plain integers, and the reason SlotMap exists beside it.

    Slab::at

    fn[T] Slab::at(self : Slab[T], index : Int) -> T

    Slab::capacity

    fn[T] Slab::capacity(self : Slab[T]) -> Int

    The number of indices ever handed out, live or free.

    Slab::clear

    fn[T] Slab::clear(self : Slab[T]) -> Unit

    Slab::contains

    fn[T] Slab::contains(self : Slab[T], index : Int) -> Bool

    Slab::copy

    fn[T] Slab::copy(self : Slab[T]) -> Slab[T]

    Slab::get

    fn[T] Slab::get(self : Slab[T], index : Int) -> T?

    Slab::insert

    fn[T] Slab::insert(self : Slab[T], value : T) -> Int

    Stores value in the lowest free index, or at the end, and returns the index.

    Slab::is_empty

    fn[T] Slab::is_empty(self : Slab[T]) -> Bool

    Slab::iter

    fn[T] Slab::iter(self : Slab[T]) -> Iter[T]

    Slab::keys

    fn[T] Slab::keys(self : Slab[T]) -> Iter[Int]

    Slab::length

    fn[T] Slab::length(self : Slab[T]) -> Int

    Slab::new

    fn[T] Slab::new(capacity? : Int) -> Slab[T]

    Slab::remove

    fn[T] Slab::remove(self : Slab[T], index : Int) -> T?

    Slab::set

    fn[T] Slab::set(self : Slab[T], index : Int, value : T) -> Bool

    SlotKey

    pub(all) struct SlotKey[T] {
    index : Int
    generation : UInt
    } derive(Eq, Hash,
    Debug
    )

    A handle to a slot of a SlotMap or a DenseSlotMap. The index says which slot, the generation says which occupant of that slot: a slot that is freed and reused raises its generation, so a key handed out earlier can never reach the new occupant. The type parameter exists only to stop a key of one map from being passed to another; it carries no value.
    impl Show for SlotKey[T]
    impl ToJson for SlotKey[T]

    SlotKey::equal

    fn[T : Eq] SlotKey::equal(SlotKey[T], SlotKey[T]) -> Bool

    SlotKey::hash

    fn[T : Hash] SlotKey::hash(self : SlotKey[T]) -> Int

    SlotKey::hash_combine

    fn[T : Hash] SlotKey::hash_combine(SlotKey[T], Hasher) -> Unit

    SlotKey::not_equal

    fn[T : Eq] SlotKey::not_equal(x : SlotKey[T], y : SlotKey[T]) -> Bool

    SlotKey::output

    fn[T] SlotKey::output(self : SlotKey[T], logger : &Logger) -> Unit

    SlotKey::to_json

    fn[T] SlotKey::to_json(self : SlotKey[T]) ->
    Json

    SlotKey::to_string

    fn[T] SlotKey::to_string(self : SlotKey[T]) -> String

    SlotMap

    pub struct SlotMap[T] {
    values : Array[T?]
    generations : Array[UInt]
    free : Array[Int]
    len : Int
    }

    A store whose handles stay valid only while their slot keeps its occupant: every slot carries a generation, a key carries the generation it was handed out under, and a freed slot raises its generation when it is reused. A stale key therefore reads as absent instead of reaching a stranger.

    SlotMap::at

    fn[T] SlotMap::at(self : SlotMap[T], key : SlotKey[T]) -> T

    SlotMap::capacity

    fn[T] SlotMap::capacity(self : SlotMap[T]) -> Int

    SlotMap::clear

    fn[T] SlotMap::clear(self : SlotMap[T]) -> Unit

    SlotMap::contains

    fn[T] SlotMap::contains(self : SlotMap[T], key : SlotKey[T]) -> Bool

    SlotMap::copy

    fn[T] SlotMap::copy(self : SlotMap[T]) -> SlotMap[T]

    SlotMap::get

    fn[T] SlotMap::get(self : SlotMap[T], key : SlotKey[T]) -> T?

    SlotMap::insert

    fn[T] SlotMap::insert(self : SlotMap[T], value : T) -> SlotKey[T]

    SlotMap::is_empty

    fn[T] SlotMap::is_empty(self : SlotMap[T]) -> Bool

    SlotMap::iter

    fn[T] SlotMap::iter(self : SlotMap[T]) -> Iter[T]

    SlotMap::iter2

    fn[T] SlotMap::iter2(self : SlotMap[T]) -> Iter2[SlotKey[T], T]

    SlotMap::keys

    fn[T] SlotMap::keys(self : SlotMap[T]) -> Iter[SlotKey[T]]

    SlotMap::length

    fn[T] SlotMap::length(self : SlotMap[T]) -> Int

    SlotMap::new

    fn[T] SlotMap::new(capacity? : Int) -> SlotMap[T]

    SlotMap::remove

    fn[T] SlotMap::remove(self : SlotMap[T], key : SlotKey[T]) -> T?

    SlotMap::retain

    fn[T] SlotMap::retain(self : SlotMap[T], f : (SlotKey[T], T) -> Bool) -> Unit

    SlotMap::set

    fn[T] SlotMap::set(self : SlotMap[T], key : SlotKey[T], value : T) -> Bool

    SparseSet

    pub struct SparseSet[T] {
    dense : Array[T]
    positions : Map[T, Int]
    }

    A set whose elements are kept densely, one array for the elements and one index from element to its position. Membership is a lookup and iteration walks contiguous memory, which is what a caller who filters a dense collection wants; the price is a hash index beside the array.

    test {
    let set : @seq.SparseSet[String] = @seq.SparseSet::new()
    @test.assert_eq(set.insert("a"), true)
    @test.assert_eq(set.insert("a"), false)
    @test.assert_eq(set.contains("a"), true)
    @test.assert_eq(set.to_array(), ["a"])
    }

    SparseSet::clear

    fn[T] SparseSet::clear(self : SparseSet[T]) -> Unit

    SparseSet::contains

    fn[T : Hash + Eq] SparseSet::contains(self : SparseSet[T], value : T) -> Bool

    SparseSet::copy

    fn[T] SparseSet::copy(self : SparseSet[T]) -> SparseSet[T]

    SparseSet::get_index

    fn[T : Hash + Eq] SparseSet::get_index(self : SparseSet[T], value : T) -> Int?

    SparseSet::insert

    fn[T : Hash + Eq] SparseSet::insert(self : SparseSet[T], value : T) -> Bool

    SparseSet::is_empty

    fn[T] SparseSet::is_empty(self : SparseSet[T]) -> Bool

    SparseSet::iter

    fn[T] SparseSet::iter(self : SparseSet[T]) -> Iter[T]

    SparseSet::length

    fn[T] SparseSet::length(self : SparseSet[T]) -> Int

    SparseSet::new

    fn[T : Hash + Eq] SparseSet::new(capacity? : Int) -> SparseSet[T]

    SparseSet::remove

    fn[T : Hash + Eq] SparseSet::remove(self : SparseSet[T], value : T) -> Bool

    SparseSet::to_array

    fn[T] SparseSet::to_array(self : SparseSet[T]) -> Array[T]