pub struct SmallDeque<T, const N: usize> { /* private fields */ }Expand description
A double-ended queue that lives on the stack for up to N items, then spills to
a heap-allocated VecDeque transparently.
§Stack representation
Items are stored in a ring buffer of [MaybeUninit<T>; N] with a head cursor and
a len counter. Two helpers, wrap_add and wrap_sub, implement the modular
arithmetic using a bitmask (requires N to be a power of two — enforced by a
const assertion in new).
§Spill behaviour
When push_back or push_front causes len > capacity on the stack, the ring
buffer is drained in logical order into a freshly heap-allocated VecDeque via
spill_to_heap. After a spill, all subsequent mutations go directly to the
VecDeque; the struct never returns to stack storage.
§Generic parameters
| Parameter | Meaning |
|---|---|
T | Element type |
N | Stack capacity; must be a power of two |
§Compile-time assertions
new() uses const { assert!(...) } to verify:
size_of::<Self>() <= 16 KiB— prevents accidental blowing of the stack frame.N.is_power_of_two()— required for bitmask ring-buffer arithmetic.
Implementations§
Source§impl<T, const N: usize> SmallDeque<T, N>
impl<T, const N: usize> SmallDeque<T, N>
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new empty deque backed by stack storage.
§Panics (compile-time)
Asserts that size_of::<Self>() <= 16 KiB and that N is a power of two.
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a deque that starts on the heap if capacity > N, otherwise on the stack.
Useful when the caller already knows the required size will exceed N.
Sourcepub fn is_on_stack(&self) -> bool
pub fn is_on_stack(&self) -> bool
Returns true if the deque is currently using stack storage.
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the current capacity (not necessarily N after a spill).
Sourcepub fn get(&self, index: usize) -> Option<&T>
pub fn get(&self, index: usize) -> Option<&T>
Returns a shared reference to the element at logical index, or None.
Logical index 0 is the front (oldest element).
Sourcepub fn get_mut(&mut self, index: usize) -> Option<&mut T>
pub fn get_mut(&mut self, index: usize) -> Option<&mut T>
Returns an exclusive reference to the element at logical index, or None.
Sourcepub fn reserve(&mut self, additional: usize)
pub fn reserve(&mut self, additional: usize)
Reserves capacity for at least additional more elements, spilling to the heap
if necessary.
Sourcepub fn push_back(&mut self, item: T)
pub fn push_back(&mut self, item: T)
Appends item to the back of the deque. Spills to heap if the stack is full.
Sourcepub fn push_front(&mut self, item: T)
pub fn push_front(&mut self, item: T)
Prepends item to the front of the deque. Spills to heap if the stack is full.
Sourcepub fn pop_back(&mut self) -> Option<T>
pub fn pop_back(&mut self) -> Option<T>
Removes and returns the last element, or None if empty.
Sourcepub fn pop_front(&mut self) -> Option<T>
pub fn pop_front(&mut self) -> Option<T>
Removes and returns the first element, or None if empty.
Sourcepub fn remove(&mut self, index: usize) -> Option<T>
pub fn remove(&mut self, index: usize) -> Option<T>
Removes the element at logical index and returns it, or None if out of bounds.
Chooses whether to shift from the front or back depending on which is cheaper (shift the shorter half).
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Shortens the deque to len, dropping all elements beyond that point.
If len >= self.len(), this is a no-op.
Sourcepub fn truncate(&mut self, len: usize)
pub fn truncate(&mut self, len: usize)
Shortens the deque to at most len elements, dropping those beyond.
Sourcepub fn front(&self) -> Option<&T>
pub fn front(&self) -> Option<&T>
Returns a shared reference to the front element, or None if empty.
Sourcepub fn back(&self) -> Option<&T>
pub fn back(&self) -> Option<&T>
Returns a shared reference to the back element, or None if empty.
Sourcepub fn front_mut(&mut self) -> Option<&mut T>
pub fn front_mut(&mut self) -> Option<&mut T>
Returns an exclusive reference to the front element, or None if empty.
Sourcepub fn back_mut(&mut self) -> Option<&mut T>
pub fn back_mut(&mut self) -> Option<&mut T>
Returns an exclusive reference to the back element, or None if empty.
Sourcepub fn as_slices(&self) -> (&[T], &[T])
pub fn as_slices(&self) -> (&[T], &[T])
Returns up to two contiguous slices covering the logical range [0, len).
Returns (head_slice, &[]) when the ring buffer hasn’t wrapped, or
(head_slice, tail_slice) when it has. On the heap path delegates to
VecDeque::as_slices.
Sourcepub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T])
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T])
Mutable counterpart of as_slices.
Trait Implementations§
Source§impl<T, const N: usize> AnyDeque<T> for SmallDeque<T, N>
impl<T, const N: usize> AnyDeque<T> for SmallDeque<T, N>
Source§fn push_front(&mut self, item: T)
fn push_front(&mut self, item: T)
Source§fn pop_back(&mut self) -> Option<T>
fn pop_back(&mut self) -> Option<T>
None if empty.Source§fn pop_front(&mut self) -> Option<T>
fn pop_front(&mut self) -> Option<T>
None if empty.Source§fn remove(&mut self, index: usize) -> Option<T>
fn remove(&mut self, index: usize) -> Option<T>
index, or None if out of bounds.Source§fn front(&self) -> Option<&T>
fn front(&self) -> Option<&T>
None if empty.Source§fn back(&self) -> Option<&T>
fn back(&self) -> Option<&T>
None if empty.Source§fn front_mut(&mut self) -> Option<&mut T>
fn front_mut(&mut self) -> Option<&mut T>
None if empty.Source§impl<T, const N: usize> Default for SmallDeque<T, N>
impl<T, const N: usize> Default for SmallDeque<T, N>
Source§impl<T, const N: usize> Drop for SmallDeque<T, N>
impl<T, const N: usize> Drop for SmallDeque<T, N>
Source§impl<T, const N: usize> Extend<T> for SmallDeque<T, N>
impl<T, const N: usize> Extend<T> for SmallDeque<T, N>
Source§fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)Source§impl<T, const N: usize> FromIterator<T> for SmallDeque<T, N>
impl<T, const N: usize> FromIterator<T> for SmallDeque<T, N>
Source§fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
Source§impl<T: Ord, const N: usize> Ord for SmallDeque<T, N>
impl<T: Ord, const N: usize> Ord for SmallDeque<T, N>
Source§impl<T: PartialOrd, const N: usize> PartialOrd for SmallDeque<T, N>
impl<T: PartialOrd, const N: usize> PartialOrd for SmallDeque<T, N>
impl<T: Eq, const N: usize> Eq for SmallDeque<T, N>
Auto Trait Implementations§
impl<T, const N: usize> Freeze for SmallDeque<T, N>where
T: Freeze,
impl<T, const N: usize> RefUnwindSafe for SmallDeque<T, N>where
T: RefUnwindSafe,
impl<T, const N: usize> Send for SmallDeque<T, N>where
T: Send,
impl<T, const N: usize> Sync for SmallDeque<T, N>where
T: Sync,
impl<T, const N: usize> Unpin for SmallDeque<T, N>where
T: Unpin,
impl<T, const N: usize> UnsafeUnpin for SmallDeque<T, N>where
T: UnsafeUnpin,
impl<T, const N: usize> UnwindSafe for SmallDeque<T, N>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.