pub struct ArrayIndexStack<const INDEX_BITS: u32, const N: usize> { /* private fields */ }Expand description
An owned standalone stack: head and links fused into one object. A
lock-free LIFO free-list of indices with a STRICTLY MONOTONIC generation
tag packed into the head word that ELIMINATES ABA outright at every
permitted INDEX_BITS — it never wraps; a push that would need to bump
the tag past TaggedIndex::TAG_MAX is refused instead
(Err(TagExhausted)), sealing the stack (pops are unaffected and
keep draining). The pushes-until-sealed lifetime is derived in the
crate-root docs’ “Tag-width budget” section. Const-generic over the
index width INDEX_BITS and the link capacity N.
Fusion is ALSO the structural closure of the shared-head hazard: this
type deliberately does NOT implement the public StackStorage trait
(its head↔links binding is served by a crate-internal sealed accessor
instead), its head field is private, and no trait impl hands out a
&StackHead for it — so the public API cannot construct a competing
binding around a standalone ArrayIndexStack. The seal is
instantiation-independent: the private head and the crate’s coherence
boundary enforce it for every INDEX_BITS, N. The remaining binding
obligations apply to custom StackStorage implementors and are stated
in that trait’s # Safety contract.
The simple push/pop inherent methods exist
for standalone callers (push is an unsafe fn, carrying
StackOps::push_index’s # Safety contract); a fresh stack is EMPTY (lazy links) — the
caller pushes indices as they become free. Custom implementors with
slot-resident links do not use this type: they implement StackStorage
instead and call the StackOps methods. N is constrained at
construction to N <= TaggedIndex::<INDEX_BITS>::INDEX_MASK; link access
still checks index < N, so a caller must stay inside the owned domain.
Implementations§
Source§impl<const B: u32, const N: usize> ArrayIndexStack<B, N>
impl<const B: u32, const N: usize> ArrayIndexStack<B, N>
Sourcepub const fn new() -> Self
pub const fn new() -> Self
A fresh, EMPTY stack (head = the bootstrap empty sentinel, tag 0; every
link at 0). Under --cfg loom this cannot be const (loom’s atomics
have no const ctor).
Sourcepub unsafe fn push(&self, index: u32) -> Result<(), TagExhausted>
pub unsafe fn push(&self, index: u32) -> Result<(), TagExhausted>
Push index onto the stack, driving the crate-internal CAS-retry
algorithm (push_index_impl) directly. This type deliberately does
NOT implement the public StackStorage trait (see the type doc), so
it does not go through StackOps::push_index’s blanket impl — the
identical algorithm body is crate-internal. See
StackOps::push_index’s doc for the algorithm, its # Safety
section (the caller contract) and # Panics.
§Safety
Same contract as StackOps::push_index’s # Safety — see there
(one normative location; this crate cross-references it).
§Errors
Same as StackOps::push_index’s # Errors — see there.
Sourcepub fn pop(&self) -> Option<u32>
pub fn pop(&self) -> Option<u32>
Pop the top index off the stack, or None if empty — driving the
crate-internal CAS-retry algorithm (pop_index_impl) directly. This
type deliberately does NOT implement the public StackStorage trait
(see the type doc), so it does not go through
StackOps::pop_index’s blanket impl — the identical algorithm body
is crate-internal. See StackOps::pop_index’s doc for the
algorithm and # Panics.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether the stack is currently empty. Advisory Relaxed check — see
StackHead::is_empty.
Sourcepub fn pushes_remaining(&self) -> u64
pub fn pushes_remaining(&self) -> u64
Successful pushes this head can still accept before push starts
refusing with Err(TagExhausted) — forwarder to
StackHead::pushes_remaining.