slabigator/
lib.rs

1#![doc = include_str!("../README.md")]
2#![warn(rustdoc::broken_intra_doc_links)]
3#![warn(missing_docs)]
4#![warn(clippy::pedantic)]
5#![allow(clippy::module_name_repetitions)]
6#![allow(clippy::missing_errors_doc)]
7#![allow(clippy::cast_possible_truncation)]
8
9//! # Slabigator
10//!
11//! A high-performance linked list with fixed capacity that doesn't perform dynamic memory
12//! allocations after initialization. It provides O(1) operations for adding, removing,
13//! and accessing elements.
14//!
15//! ## Overview
16//!
17//! Slabigator is designed for scenarios where memory allocation predictability is critical
18//! and you need stable references to elements. It allocates all memory upfront and provides
19//! slot numbers as stable references to elements.
20//!
21//! ## Key Features
22//!
23//! - Fixed capacity - no allocations during operations
24//! - O(1) push_front operation
25//! - O(1) pop_back operation
26//! - O(1) removal of any element by slot
27//! - Slots provide stable references to elements
28//! - Implements useful Rust traits like `FromIterator` and `Extend`
29//!
30//! ## Basic Usage
31//!
32//! ```rust
33//! use slabigator::Slab;
34//!
35//! // Create a slab with capacity for 3 elements
36//! let mut slab = Slab::with_capacity(3).unwrap();
37//!
38//! // Push elements to the front (returns slot numbers)
39//! let a = slab.push_front("a").unwrap();
40//! let b = slab.push_front("b").unwrap();
41//! let c = slab.push_front("c").unwrap();
42//!
43//! // Access by slot
44//! assert_eq!(slab.get(a).unwrap(), &"a");
45//! assert_eq!(slab.get(b).unwrap(), &"b");
46//! assert_eq!(slab.get(c).unwrap(), &"c");
47//!
48//! // Remove an element
49//! slab.remove(b).unwrap();
50//! assert_eq!(slab.len(), 2);
51//!
52//! // Iterate (order is from head to tail)
53//! let elements: Vec<_> = slab.iter().collect();
54//! assert_eq!(elements, vec![&"c", &"a"]);
55//!
56//! // Pop from the back (FIFO queue behavior)
57//! assert_eq!(slab.pop_back().unwrap(), "a");
58//! assert_eq!(slab.pop_back().unwrap(), "c");
59//! assert!(slab.is_empty());
60//! ```
61//!
62//! ## Advanced Features
63//!
64//! ### Default capacity
65//!
66//! ```rust
67//! use slabigator::Slab;
68//!
69//! // Creates a slab with default capacity (16)
70//! let slab: Slab<i32> = Slab::default();
71//! assert_eq!(slab.capacity(), 16);
72//! ```
73//!
74//! ### Creating from an iterator
75//!
76//! ```rust
77//! use slabigator::Slab;
78//!
79//! let values = vec![1, 2, 3, 4, 5];
80//! let slab: Slab<_> = values.iter().copied().collect();
81//!
82//! assert_eq!(slab.len(), 5);
83//! ```
84//!
85//! ### Extending a slab
86//!
87//! ```rust
88//! use slabigator::Slab;
89//!
90//! let mut slab = Slab::with_capacity(5).unwrap();
91//! slab.push_front(1).unwrap();
92//! slab.push_front(2).unwrap();
93//!
94//! // Extend with more elements
95//! slab.extend(vec![3, 4, 5]);
96//! assert_eq!(slab.len(), 5);
97//! ```
98
99use std::iter::Iterator;
100
101#[cfg(all(feature = "slot_u64", not(feature = "slot_usize")))]
102/// Slot type used for element references.
103/// This is u64 when the `slot_u64` feature is enabled.
104pub type Slot = u64;
105#[cfg(feature = "slot_usize")]
106/// Slot type used for element references.
107/// This is usize when the `slot_usize` feature is enabled.
108pub type Slot = usize;
109#[cfg(not(any(
110    all(feature = "slot_u64", not(feature = "slot_usize")),
111    feature = "slot_usize"
112)))]
113/// Slot type used for element references.
114/// This is u32 by default or when the `slot_u32` feature is enabled.
115pub type Slot = u32;
116
117const NUL: Slot = Slot::MAX;
118
119/// A fixed-capacity linked list that doesn't perform dynamic memory allocations after initialization.
120///
121/// # Overview
122///
123/// `Slab<D>` is a specialized data structure that allocates all of its memory upfront and provides
124/// stable slot numbers as references to elements. This makes it ideal for performance-critical
125/// applications where:
126///
127/// - Memory allocation patterns need to be predictable
128/// - You need stable references to elements
129/// - Fast O(1) operations are required
130/// - You know the maximum capacity in advance
131///
132/// # Core Operations
133///
134/// - **`push_front`**: Add elements to the head of the list in O(1) time
135/// - **`pop_back`**: Remove and return an element from the tail in O(1) time
136/// - **remove**: Delete any element by its slot number in O(1) time
137/// - **`get/get_mut`**: Access any element by its slot number in O(1) time
138///
139/// # Memory Behavior
140///
141/// The slab allocates all memory during creation with `with_capacity()`. No further allocations
142/// occur during subsequent operations. This provides predictable memory usage and avoids
143/// allocation-related performance issues.
144///
145/// # Implementation Details
146///
147/// Internally, the slab maintains:
148/// - A vector of elements
149/// - A linked list structure for tracking the order of elements
150/// - A free list for quick reuse of slots
151/// - A bitmap for validating slot access (when not using `releasefast` feature)
152///
153/// # Examples
154///
155/// ## Basic Operations
156///
157/// ```
158/// use slabigator::Slab;
159///
160/// // Create a new slab with capacity for 3 elements
161/// let mut slab = Slab::with_capacity(3).unwrap();
162///
163/// // Push elements to the front - each operation returns a slot number
164/// // The slot numbers are stable references that won't change
165/// // even when other elements are added or removed
166/// let slot_a = slab.push_front("a").unwrap();
167/// let slot_b = slab.push_front("b").unwrap();
168/// let slot_c = slab.push_front("c").unwrap();
169///
170/// // Slab is now full
171/// assert!(slab.is_full());
172/// assert_eq!(slab.len(), 3);
173///
174/// // Access elements by slot - these are direct lookups
175/// assert_eq!(slab.get(slot_a).unwrap(), &"a");
176/// assert_eq!(slab.get(slot_b).unwrap(), &"b");
177/// assert_eq!(slab.get(slot_c).unwrap(), &"c");
178///
179/// // Remove an element by slot
180/// slab.remove(slot_b).unwrap();
181/// assert_eq!(slab.len(), 2);
182/// #[cfg(not(feature = "releasefast"))]
183/// assert!(slab.get(slot_b).is_err()); // Slot b is no longer valid
184///
185/// // Pop elements from the back (FIFO order)
186/// let value = slab.pop_back().unwrap();
187/// assert_eq!(value, "a");
188/// assert_eq!(slab.len(), 1);
189///
190/// let value = slab.pop_back().unwrap();
191/// assert_eq!(value, "c");
192/// assert!(slab.is_empty());
193/// ```
194///
195/// ## Using as a FIFO Queue
196///
197/// ```
198/// use slabigator::Slab;
199///
200/// let mut queue = Slab::with_capacity(10).unwrap();
201///
202/// // Enqueue items (push to front)
203/// queue.push_front("first").unwrap();
204/// queue.push_front("second").unwrap();
205/// queue.push_front("third").unwrap();
206///
207/// // Dequeue items (pop from back) - FIFO order
208/// assert_eq!(queue.pop_back().unwrap(), "first");
209/// assert_eq!(queue.pop_back().unwrap(), "second");
210/// assert_eq!(queue.pop_back().unwrap(), "third");
211/// ```
212///
213/// ## Using for Object Pooling
214///
215/// ```
216/// use slabigator::Slab;
217///
218/// #[derive(Debug, PartialEq)]
219/// struct GameObject {
220///     id: u32,
221///     active: bool,
222/// }
223///
224/// // Create a pool of game objects
225/// let mut pool = Slab::with_capacity(100).unwrap();
226///
227/// // Create and add objects to the pool
228/// let slot1 = pool.push_front(GameObject { id: 1, active: true }).unwrap();
229/// let slot2 = pool.push_front(GameObject { id: 2, active: true }).unwrap();
230///
231/// // Deactivate an object (by mutating it)
232/// if let Ok(object) = pool.get_mut(slot1) {
233///     object.active = false;
234/// }
235///
236/// // Remove an object from the pool when no longer needed
237/// pool.remove(slot2).unwrap();
238/// ```
239#[derive(Debug)]
240pub struct Slab<D: Sized> {
241    vec_next: Vec<Slot>,
242    vec_prev: Vec<Slot>,
243    free_head: Slot,
244    head: Slot,
245    tail: Slot,
246    len: usize,
247    data: Vec<Option<D>>,
248    #[cfg(not(feature = "releasefast"))]
249    bitmap: Vec<u8>,
250}
251
252/// Error types that can occur during Slab operations.
253///
254/// The Slab API follows a design philosophy where operations that could fail return
255/// a `Result<T, Error>` rather than panicking. This allows error handling to be more
256/// explicit and gives the caller control over how to handle error conditions.
257///
258/// # Examples
259///
260/// ```
261/// use slabigator::{Slab, Error};
262///
263/// let mut slab = Slab::with_capacity(1).unwrap();
264/// slab.push_front("only element").unwrap();
265///
266/// // Attempt to add another element when slab is full
267/// match slab.push_front("one too many") {
268///     Ok(_) => println!("Element added successfully"),
269///     Err(Error::Full) => println!("Cannot add element: slab is full"),
270///     Err(_) => println!("Other error occurred"),
271/// }
272///
273/// // Attempt to access an invalid slot
274/// match slab.get(999) {
275///     Ok(_) => println!("Element retrieved"),
276///     Err(Error::InvalidSlot) => println!("Invalid slot"),
277///     Err(_) => println!("Other error occurred"),
278/// }
279/// ```
280#[derive(Debug, Clone, Hash, PartialEq, Eq)]
281pub enum Error {
282    /// Returned when the requested capacity during creation is too large for the
283    /// selected slot type. This occurs when the capacity would cause the slot index
284    /// to exceed the maximum value for the slot type (u32, u64, or usize).
285    TooLarge,
286
287    /// Returned when attempting to add an element to a slab that already contains
288    /// its maximum capacity of elements. Check `is_full()` before adding elements
289    /// or handle this error to implement graceful fallbacks.
290    Full,
291
292    /// Returned when:
293    /// - Accessing a slot that is out of bounds (>= capacity)
294    /// - Accessing a slot that doesn't contain an element (was never set or was removed)
295    /// - Attempting to remove an element from a slot that is invalid
296    ///
297    /// When not using the `releasefast` feature, all slot validity is checked.
298    InvalidSlot,
299
300    /// Returned when attempting to access or remove elements from an empty slab.
301    /// Check `is_empty()` before these operations or handle this error appropriately.
302    Empty,
303}
304
305impl std::error::Error for Error {}
306
307impl std::fmt::Display for Error {
308    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
309        match self {
310            Error::TooLarge => write!(f, "Capacity is too large for the slot type"),
311            Error::Full => write!(f, "Slab is full and cannot accept more elements"),
312            Error::InvalidSlot => write!(f, "Invalid slot or slot doesn't contain an element"),
313            Error::Empty => write!(f, "Slab is empty"),
314        }
315    }
316}
317
318impl<D: Sized> Slab<D> {
319    /// Creates a new slab with the given capacity.
320    ///
321    /// # Arguments
322    ///
323    /// * `capacity` - The maximum number of elements the slab can hold.
324    ///
325    /// # Returns
326    ///
327    /// * `Ok(Slab<D>)` - A new slab with the requested capacity.
328    /// * `Err(Error::TooLarge)` - If the capacity is too large for the slot type.
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// use slabigator::Slab;
334    ///
335    /// let slab = Slab::<String>::with_capacity(10).unwrap();
336    /// assert_eq!(slab.capacity(), 10);
337    /// assert_eq!(slab.len(), 0);
338    /// assert!(slab.is_empty());
339    /// ```
340    pub fn with_capacity(capacity: usize) -> Result<Self, Error> {
341        if capacity as Slot == NUL {
342            return Err(Error::TooLarge);
343        }
344        let mut vec_next = Vec::with_capacity(capacity);
345        for i in 0..(capacity - 1) {
346            vec_next.push(i as Slot + 1);
347        }
348        vec_next.push(NUL);
349
350        let mut vec_prev = Vec::with_capacity(capacity);
351        vec_prev.push(NUL);
352        for i in 1..capacity {
353            vec_prev.push(i as Slot - 1);
354        }
355
356        // Initialize data with None values instead of MaybeUninit
357        let mut data = Vec::with_capacity(capacity);
358        for _ in 0..capacity {
359            data.push(None);
360        }
361
362        #[cfg(not(feature = "releasefast"))]
363        let bitmap_size = (capacity + 7) / 8; // TODO: Replace with capacity.div_ceil(8) when stable
364
365        Ok(Self {
366            vec_next,
367            vec_prev,
368            free_head: 0,
369            head: NUL,
370            tail: NUL,
371            len: 0,
372            data,
373            #[cfg(not(feature = "releasefast"))]
374            bitmap: vec![0u8; bitmap_size],
375        })
376    }
377
378    /// Returns the capacity of the slab.
379    ///
380    /// # Examples
381    ///
382    /// ```
383    /// use slabigator::Slab;
384    ///
385    /// let slab = Slab::<i32>::with_capacity(10).unwrap();
386    /// assert_eq!(slab.capacity(), 10);
387    /// ```
388    #[inline]
389    #[must_use]
390    pub fn capacity(&self) -> usize {
391        self.data.capacity()
392    }
393
394    /// Returns the number of elements in the slab.
395    ///
396    /// # Examples
397    ///
398    /// ```
399    /// use slabigator::Slab;
400    ///
401    /// let mut slab = Slab::with_capacity(10).unwrap();
402    /// assert_eq!(slab.len(), 0);
403    ///
404    /// slab.push_front(42).unwrap();
405    /// assert_eq!(slab.len(), 1);
406    /// ```
407    #[inline]
408    #[must_use]
409    pub fn len(&self) -> usize {
410        self.len
411    }
412
413    /// Returns the number of elements that can still be stored.
414    ///
415    /// # Examples
416    ///
417    /// ```
418    /// use slabigator::Slab;
419    ///
420    /// let mut slab = Slab::with_capacity(3).unwrap();
421    /// assert_eq!(slab.free(), 3);
422    ///
423    /// slab.push_front(42).unwrap();
424    /// assert_eq!(slab.free(), 2);
425    /// ```
426    #[inline]
427    #[must_use]
428    pub fn free(&self) -> usize {
429        self.capacity() - self.len()
430    }
431
432    /// Returns `true` if the slab contains no elements.
433    ///
434    /// # Examples
435    ///
436    /// ```
437    /// use slabigator::Slab;
438    ///
439    /// let mut slab = Slab::with_capacity(10).unwrap();
440    /// assert!(slab.is_empty());
441    ///
442    /// slab.push_front(42).unwrap();
443    /// assert!(!slab.is_empty());
444    /// ```
445    #[inline]
446    #[must_use]
447    pub fn is_empty(&self) -> bool {
448        self.len() == 0
449    }
450
451    /// Returns `true` if the slab cannot hold any more elements.
452    ///
453    /// # Examples
454    ///
455    /// ```
456    /// use slabigator::Slab;
457    ///
458    /// let mut slab = Slab::with_capacity(2).unwrap();
459    /// assert!(!slab.is_full());
460    ///
461    /// slab.push_front(1).unwrap();
462    /// slab.push_front(2).unwrap();
463    /// assert!(slab.is_full());
464    /// ```
465    #[inline]
466    #[must_use]
467    pub fn is_full(&self) -> bool {
468        self.free_head == NUL
469    }
470
471    /// Returns a reference to an element given its slot number.
472    ///
473    /// # Arguments
474    ///
475    /// * `slot` - The slot number of the element to retrieve.
476    ///
477    /// # Returns
478    ///
479    /// * `Ok(&D)` - A reference to the element.
480    /// * `Err(Error::InvalidSlot)` - If the slot is invalid or doesn't contain an element.
481    ///
482    /// # Examples
483    ///
484    /// ```
485    /// use slabigator::Slab;
486    ///
487    /// let mut slab = Slab::with_capacity(10).unwrap();
488    /// let slot = slab.push_front("hello").unwrap();
489    ///
490    /// assert_eq!(slab.get(slot).unwrap(), &"hello");
491    /// ```
492    pub fn get(&self, slot: Slot) -> Result<&D, Error> {
493        let index = slot as usize;
494        if index >= self.capacity() {
495            return Err(Error::InvalidSlot);
496        }
497
498        #[cfg(not(feature = "releasefast"))]
499        {
500            if !self.bitmap_get(slot) {
501                return Err(Error::InvalidSlot);
502            }
503        }
504
505        // Use pattern matching to safely access the Option<D>
506        match &self.data[index] {
507            Some(value) => Ok(value),
508            None => Err(Error::InvalidSlot),
509        }
510    }
511
512    /// Returns a mutable reference to an element given its slot number.
513    ///
514    /// # Arguments
515    ///
516    /// * `slot` - The slot number of the element to retrieve.
517    ///
518    /// # Returns
519    ///
520    /// * `Ok(&mut D)` - A mutable reference to the element.
521    /// * `Err(Error::InvalidSlot)` - If the slot is invalid or doesn't contain an element.
522    ///
523    /// # Examples
524    ///
525    /// ```
526    /// use slabigator::Slab;
527    ///
528    /// let mut slab = Slab::with_capacity(10).unwrap();
529    /// let slot = slab.push_front("hello").unwrap();
530    ///
531    /// *slab.get_mut(slot).unwrap() = "world";
532    /// assert_eq!(slab.get(slot).unwrap(), &"world");
533    /// ```
534    pub fn get_mut(&mut self, slot: Slot) -> Result<&mut D, Error> {
535        let index = slot as usize;
536        if index >= self.capacity() {
537            return Err(Error::InvalidSlot);
538        }
539
540        #[cfg(not(feature = "releasefast"))]
541        {
542            if !self.bitmap_get(slot) {
543                return Err(Error::InvalidSlot);
544            }
545        }
546
547        // Use pattern matching to safely access the Option<D>
548        match &mut self.data[index] {
549            Some(value) => Ok(value),
550            None => Err(Error::InvalidSlot),
551        }
552    }
553
554    /// Prepends an element to the beginning of the slab.
555    ///
556    /// # Arguments
557    ///
558    /// * `value` - The value to prepend.
559    ///
560    /// # Returns
561    ///
562    /// * `Ok(Slot)` - The slot number of the newly added element.
563    /// * `Err(Error::Full)` - If the slab is full.
564    ///
565    /// # Examples
566    ///
567    /// ```
568    /// use slabigator::Slab;
569    ///
570    /// let mut slab = Slab::with_capacity(3).unwrap();
571    ///
572    /// let a = slab.push_front("a").unwrap();
573    /// let b = slab.push_front("b").unwrap();
574    /// let c = slab.push_front("c").unwrap();
575    ///
576    /// // Elements are in reverse order of insertion
577    /// let mut iter = slab.iter();
578    /// assert_eq!(iter.next(), Some(&"c"));
579    /// assert_eq!(iter.next(), Some(&"b"));
580    /// assert_eq!(iter.next(), Some(&"a"));
581    /// assert_eq!(iter.next(), None);
582    /// ```
583    pub fn push_front(&mut self, value: D) -> Result<Slot, Error> {
584        let free_slot = self.free_head;
585        if free_slot == NUL {
586            return Err(Error::Full);
587        }
588
589        let free_index = free_slot as usize;
590        let prev = self.vec_prev[free_index];
591        let next = self.vec_next[free_index];
592
593        if prev != NUL {
594            debug_assert_eq!(self.vec_next[prev as usize], free_slot);
595            self.vec_next[prev as usize] = next;
596        }
597
598        if next != NUL {
599            if !self.is_empty() {
600                debug_assert_eq!(self.vec_prev[next as usize], free_slot);
601            }
602            self.vec_prev[next as usize] = prev;
603        }
604
605        if self.head != NUL {
606            self.vec_prev[self.head as usize] = free_slot;
607        }
608
609        self.free_head = next;
610        self.vec_next[free_index] = self.head;
611        self.vec_prev[free_index] = NUL;
612
613        if self.head == NUL {
614            self.tail = free_slot;
615        }
616
617        self.head = free_slot;
618
619        // Store the value safely using Option
620        self.data[free_index] = Some(value);
621
622        self.len += 1;
623        debug_assert!(self.len <= self.capacity());
624
625        #[cfg(not(feature = "releasefast"))]
626        {
627            self.bitmap_set(free_slot);
628        }
629
630        Ok(free_slot)
631    }
632
633    /// Removes an element from the slab given its slot.
634    ///
635    /// # Arguments
636    ///
637    /// * `slot` - The slot number of the element to remove.
638    ///
639    /// # Returns
640    ///
641    /// * `Ok(())` - If the element was successfully removed.
642    /// * `Err(Error::InvalidSlot)` - If the slot is invalid or doesn't contain an element.
643    ///
644    /// # Examples
645    ///
646    /// ```
647    /// use slabigator::Slab;
648    ///
649    /// let mut slab = Slab::with_capacity(3).unwrap();
650    /// let a = slab.push_front("a").unwrap();
651    /// let b = slab.push_front("b").unwrap();
652    /// let c = slab.push_front("c").unwrap();
653    ///
654    /// assert_eq!(slab.len(), 3);
655    ///
656    /// slab.remove(b).unwrap();
657    /// assert_eq!(slab.len(), 2);
658    ///
659    /// // The element at slot `b` is no longer accessible
660    /// #[cfg(not(feature = "releasefast"))]
661    /// assert!(slab.get(b).is_err());
662    /// ```
663    pub fn remove(&mut self, slot: Slot) -> Result<(), Error> {
664        let index = slot as usize;
665        if index >= self.capacity() {
666            return Err(Error::InvalidSlot);
667        }
668
669        #[cfg(not(feature = "releasefast"))]
670        {
671            if !self.bitmap_get(slot) {
672                return Err(Error::InvalidSlot);
673            }
674        }
675
676        // Check if there's actually an element at this slot
677        if self.data[index].is_none() {
678            return Err(Error::InvalidSlot);
679        }
680
681        // Clear the data by replacing it with None
682        self.data[index] = None;
683
684        let prev = self.vec_prev[index];
685        let next = self.vec_next[index];
686
687        if prev != NUL {
688            debug_assert_eq!(self.vec_next[prev as usize], slot);
689            self.vec_next[prev as usize] = next;
690        }
691
692        if next != NUL {
693            if !self.is_empty() {
694                debug_assert_eq!(self.vec_prev[next as usize], slot);
695            }
696            self.vec_prev[next as usize] = prev;
697        }
698
699        if self.tail == slot {
700            self.tail = prev;
701        }
702
703        if self.head == slot {
704            self.head = next;
705        }
706
707        self.vec_prev[index] = NUL;
708        self.vec_next[index] = self.free_head;
709
710        if self.free_head != NUL {
711            self.vec_prev[self.free_head as usize] = slot;
712        }
713
714        self.free_head = slot;
715        debug_assert!(self.len > 0);
716        self.len -= 1;
717
718        #[cfg(not(feature = "releasefast"))]
719        {
720            self.bitmap_unset(slot);
721        }
722
723        Ok(())
724    }
725
726    /// Removes and returns the tail element of the slab.
727    ///
728    /// # Returns
729    ///
730    /// * `Some(D)` - The removed element.
731    /// * `None` - If the slab is empty.
732    ///
733    /// # Examples
734    ///
735    /// ```
736    /// use slabigator::Slab;
737    ///
738    /// let mut slab = Slab::with_capacity(3).unwrap();
739    /// slab.push_front("a").unwrap();
740    /// slab.push_front("b").unwrap();
741    /// slab.push_front("c").unwrap();
742    ///
743    /// assert_eq!(slab.pop_back(), Some("a"));
744    /// assert_eq!(slab.pop_back(), Some("b"));
745    /// assert_eq!(slab.pop_back(), Some("c"));
746    /// assert_eq!(slab.pop_back(), None);
747    /// ```
748    pub fn pop_back(&mut self) -> Option<D> {
749        let slot = self.tail;
750        if slot == NUL {
751            return None;
752        }
753
754        let index = slot as usize;
755
756        // Take the value out, replacing it with None
757        let value = self.data[index].take()?;
758
759        let prev = self.vec_prev[index];
760        debug_assert_eq!(self.vec_next[index], NUL);
761
762        if prev != NUL {
763            debug_assert_eq!(self.vec_next[prev as usize], slot);
764            self.vec_next[prev as usize] = NUL;
765        }
766
767        self.tail = prev;
768
769        if self.head == slot {
770            self.head = NUL;
771        }
772
773        self.vec_prev[index] = NUL;
774        self.vec_next[index] = self.free_head;
775
776        if self.free_head != NUL {
777            self.vec_prev[self.free_head as usize] = slot;
778        }
779
780        self.free_head = slot;
781        debug_assert!(self.len > 0);
782        self.len -= 1;
783
784        #[cfg(not(feature = "releasefast"))]
785        {
786            self.bitmap_unset(slot);
787        }
788
789        Some(value)
790    }
791
792    /// Returns an iterator over the elements of the slab.
793    ///
794    /// The iterator yields elements in order from head to tail.
795    ///
796    /// # Examples
797    ///
798    /// ```
799    /// use slabigator::Slab;
800    ///
801    /// let mut slab = Slab::with_capacity(3).unwrap();
802    /// slab.push_front("a").unwrap();
803    /// slab.push_front("b").unwrap();
804    /// slab.push_front("c").unwrap();
805    ///
806    /// let mut iter = slab.iter();
807    /// assert_eq!(iter.next(), Some(&"c"));
808    /// assert_eq!(iter.next(), Some(&"b"));
809    /// assert_eq!(iter.next(), Some(&"a"));
810    /// assert_eq!(iter.next(), None);
811    /// ```
812    #[must_use]
813    pub fn iter(&self) -> SlabIterator<D> {
814        SlabIterator {
815            list: self,
816            slot: None,
817        }
818    }
819
820    /// Checks if the slot contains an element.
821    ///
822    /// This method is only available when not using the `releasefast` feature.
823    ///
824    /// # Arguments
825    ///
826    /// * `slot` - The slot to check.
827    ///
828    /// # Returns
829    ///
830    /// * `true` - If the slot contains an element.
831    /// * `false` - If the slot is invalid or doesn't contain an element.
832    ///
833    /// # Examples
834    ///
835    /// ```
836    /// use slabigator::Slab;
837    ///
838    /// let mut slab = Slab::with_capacity(3).unwrap();
839    /// let slot = slab.push_front("hello").unwrap();
840    ///
841    /// assert!(slab.contains_slot(slot));
842    ///
843    /// slab.remove(slot).unwrap();
844    /// assert!(!slab.contains_slot(slot));
845    /// ```
846    #[cfg(not(feature = "releasefast"))]
847    #[must_use]
848    pub fn contains_slot(&self, slot: Slot) -> bool {
849        if (slot as usize) >= self.capacity() {
850            return false;
851        }
852        self.bitmap_get(slot)
853    }
854
855    #[cfg(not(feature = "releasefast"))]
856    #[inline]
857    fn bitmap_get(&self, slot: Slot) -> bool {
858        (self.bitmap[(slot as usize) / 8] & (1 << ((slot as usize) & 7))) != 0
859    }
860
861    #[cfg(not(feature = "releasefast"))]
862    #[inline]
863    fn bitmap_set(&mut self, slot: Slot) {
864        self.bitmap[(slot as usize) / 8] |= 1 << ((slot as usize) & 7);
865    }
866
867    #[cfg(not(feature = "releasefast"))]
868    #[inline]
869    fn bitmap_unset(&mut self, slot: Slot) {
870        self.bitmap[(slot as usize) / 8] &= !(1 << ((slot as usize) & 7));
871    }
872
873    /// Clears the slab, removing all elements.
874    ///
875    /// # Examples
876    ///
877    /// ```
878    /// use slabigator::Slab;
879    ///
880    /// let mut slab = Slab::with_capacity(3).unwrap();
881    /// slab.push_front("a").unwrap();
882    /// slab.push_front("b").unwrap();
883    ///
884    /// assert_eq!(slab.len(), 2);
885    /// slab.clear();
886    /// assert_eq!(slab.len(), 0);
887    /// assert!(slab.is_empty());
888    /// ```
889    pub fn clear(&mut self) {
890        // Drop all elements
891        let mut slot = self.head;
892        while slot != NUL {
893            let next = self.vec_next[slot as usize];
894            self.data[slot as usize] = None;
895
896            #[cfg(not(feature = "releasefast"))]
897            {
898                self.bitmap_unset(slot);
899            }
900
901            slot = next;
902        }
903
904        // Reset the slab state
905        let capacity = self.capacity();
906        for i in 0..(capacity - 1) {
907            self.vec_next[i] = (i + 1) as Slot;
908        }
909        self.vec_next[capacity - 1] = NUL;
910
911        self.vec_prev[0] = NUL;
912        for i in 1..capacity {
913            self.vec_prev[i] = (i - 1) as Slot;
914        }
915
916        self.free_head = 0;
917        self.head = NUL;
918        self.tail = NUL;
919        self.len = 0;
920    }
921}
922
923impl<D> Default for Slab<D> {
924    /// Creates a new empty slab with a default capacity.
925    ///
926    /// # Examples
927    ///
928    /// ```
929    /// use slabigator::Slab;
930    ///
931    /// let slab: Slab<i32> = Slab::default();
932    /// assert!(slab.is_empty());
933    /// assert_eq!(slab.capacity(), 16);
934    /// ```
935    fn default() -> Self {
936        Self::with_capacity(16).expect("Default capacity should always be valid")
937    }
938}
939
940impl<D> core::ops::Index<Slot> for Slab<D> {
941    type Output = D;
942
943    fn index(&self, slot: Slot) -> &Self::Output {
944        self.get(slot).expect("Invalid slot index")
945    }
946}
947
948impl<D> core::ops::IndexMut<Slot> for Slab<D> {
949    fn index_mut(&mut self, slot: Slot) -> &mut Self::Output {
950        self.get_mut(slot).expect("Invalid slot index")
951    }
952}
953
954/// An iterator over the elements of a slab.
955///
956/// This iterator yields elements from the slab in order from head to tail.
957#[derive(Debug)]
958pub struct SlabIterator<'a, D> {
959    list: &'a Slab<D>,
960    slot: Option<Slot>,
961}
962
963impl<'a, D> Iterator for SlabIterator<'a, D> {
964    type Item = &'a D;
965
966    fn next(&mut self) -> Option<Self::Item> {
967        let slot = self.slot.unwrap_or(self.list.head);
968        if slot == NUL {
969            return None;
970        }
971
972        let index = slot as usize;
973        let res = self.list.data[index].as_ref()?;
974
975        self.slot = Some(self.list.vec_next[index]);
976        Some(res)
977    }
978}
979
980impl<D> ExactSizeIterator for SlabIterator<'_, D> {
981    fn len(&self) -> usize {
982        self.list.len()
983    }
984}
985
986impl<'a, D> DoubleEndedIterator for SlabIterator<'a, D> {
987    fn next_back(&mut self) -> Option<&'a D> {
988        let slot = self.slot.unwrap_or(self.list.tail);
989        if slot == NUL {
990            return None;
991        }
992
993        let index = slot as usize;
994        let res = self.list.data[index].as_ref()?;
995
996        self.slot = Some(self.list.vec_prev[index]);
997        Some(res)
998    }
999}
1000
1001impl<'a, D> IntoIterator for &'a Slab<D> {
1002    type IntoIter = SlabIterator<'a, D>;
1003    type Item = &'a D;
1004
1005    fn into_iter(self) -> Self::IntoIter {
1006        self.iter()
1007    }
1008}
1009
1010impl<D: Clone> FromIterator<D> for Slab<D> {
1011    /// Creates a slab from an iterator.
1012    ///
1013    /// The slab will have a capacity equal to the number of elements in the iterator.
1014    /// Elements are inserted in reverse order, so that iterating the resulting slab
1015    /// will produce elements in the same order as the original iterator.
1016    ///
1017    /// # Examples
1018    ///
1019    /// ```
1020    /// use slabigator::Slab;
1021    ///
1022    /// let values = vec![1, 2, 3, 4, 5];
1023    /// let slab: Slab<_> = values.clone().into_iter().collect();
1024    ///
1025    /// // Verify size
1026    /// assert_eq!(slab.len(), 5);
1027    ///
1028    /// // Examine individual slots - elements are stored in reversed order
1029    /// // from the input sequence since push_front is used internally
1030    /// assert_eq!(*slab.get(0).unwrap(), 5);
1031    /// assert_eq!(*slab.get(1).unwrap(), 4);
1032    /// assert_eq!(*slab.get(2).unwrap(), 3);
1033    /// assert_eq!(*slab.get(3).unwrap(), 2);
1034    /// assert_eq!(*slab.get(4).unwrap(), 1);
1035    /// ```
1036    ///
1037    /// # Panics
1038    ///
1039    /// Panics if the iterator contains too many elements for the slot type.
1040    fn from_iter<I: IntoIterator<Item = D>>(iter: I) -> Self {
1041        let iter = iter.into_iter();
1042        let (min, max_size) = iter.size_hint();
1043
1044        // Use max_size if available, otherwise min
1045        let capacity = max_size.unwrap_or(min);
1046
1047        // Try to create a slab with the estimated capacity
1048        let mut slab = Self::with_capacity(capacity).expect("Iterator too large for slab capacity");
1049
1050        // Insert elements in reverse order (so iterating matches original order)
1051        let mut vec: Vec<D> = iter.collect();
1052        while let Some(item) = vec.pop() {
1053            if slab.push_front(item.clone()).is_err() {
1054                // If we get here, our size hint was wrong - try to recover by
1055                // creating a larger slab and moving elements
1056                let new_capacity = slab.capacity() * 2;
1057                let mut new_slab = Self::with_capacity(new_capacity)
1058                    .expect("Iterator too large for slab capacity");
1059
1060                // Move elements from old slab to new one
1061                while let Some(old_item) = slab.pop_back() {
1062                    new_slab
1063                        .push_front(old_item)
1064                        .expect("New slab should have enough capacity");
1065                }
1066
1067                // Add the current item
1068                new_slab
1069                    .push_front(item)
1070                    .expect("New slab should have enough capacity");
1071
1072                // Replace with the new slab
1073                slab = new_slab;
1074            }
1075        }
1076
1077        slab
1078    }
1079}
1080
1081impl<D: Clone> Extend<D> for Slab<D> {
1082    /// Extends the slab with the elements from an iterator.
1083    ///
1084    /// # Examples
1085    ///
1086    /// ```
1087    /// use slabigator::Slab;
1088    ///
1089    /// let mut slab = Slab::with_capacity(10).unwrap();
1090    /// slab.push_front(1).unwrap();
1091    /// slab.push_front(2).unwrap();
1092    ///
1093    /// slab.extend(vec![3, 4, 5]);
1094    /// assert_eq!(slab.len(), 5);
1095    ///
1096    /// // The slot assignment is not sequential but depends on the internal free list.
1097    /// // We can verify the order by iterating instead.
1098    /// let items: Vec<_> = slab.iter().copied().collect();
1099    /// assert_eq!(items, vec![5, 4, 3, 2, 1]);
1100    /// ```
1101    ///
1102    /// # Panics
1103    ///
1104    /// Panics if the slab doesn't have enough capacity for all elements in the iterator.
1105    fn extend<I: IntoIterator<Item = D>>(&mut self, iter: I) {
1106        for item in iter {
1107            self.push_front(item).expect("Slab full during extend");
1108        }
1109    }
1110}
1111
1112// Test implementations
1113#[test]
1114fn test() {
1115    let mut slab = Slab::with_capacity(3).unwrap();
1116    let a = slab.push_front(Box::new(1)).unwrap();
1117    let b = slab.push_front(Box::new(2)).unwrap();
1118    slab.push_front(Box::new(3)).unwrap();
1119    assert_eq!(slab.len(), 3);
1120    assert!(slab.push_front(Box::new(4)).is_err());
1121    slab.remove(a).unwrap();
1122    slab.remove(b).unwrap();
1123    assert_eq!(slab.len(), 1);
1124    let cv = slab.pop_back().unwrap();
1125    assert_eq!(*cv, 3);
1126}
1127
1128#[test]
1129fn test2() {
1130    use std::collections::VecDeque;
1131
1132    use rand::prelude::*;
1133
1134    let mut rng = rand::rng();
1135    let capacity = rng.random_range(1..=50);
1136    let mut slab = Slab::with_capacity(capacity).unwrap();
1137
1138    let mut c: u64 = 0;
1139    let mut expected_len: usize = 0;
1140    let mut deque = VecDeque::with_capacity(capacity);
1141    for _ in 0..1_000_000 {
1142        let x = rng.random_range(0..=3);
1143        match x {
1144            0 => match slab.push_front(c) {
1145                Err(_) => {
1146                    assert!(slab.is_full());
1147                    assert_eq!(slab.free(), 0);
1148                }
1149                Ok(idx) => {
1150                    deque.push_front(idx);
1151                    expected_len += 1;
1152                    assert!(expected_len <= capacity);
1153                    assert_eq!(slab.free(), capacity - expected_len);
1154                }
1155            },
1156            1 => match slab.pop_back() {
1157                None => {
1158                    assert!(slab.is_empty());
1159                    assert_eq!(slab.free(), capacity);
1160                }
1161                Some(_x) => {
1162                    deque.pop_back().unwrap();
1163                    expected_len -= 1;
1164                    assert_eq!(slab.free(), capacity - expected_len);
1165                    if expected_len == 0 {
1166                        assert!(slab.is_empty());
1167                    }
1168                }
1169            },
1170            2 => {
1171                if slab.is_empty() {
1172                    continue;
1173                }
1174                let deque_len = deque.len();
1175                if deque_len == 0 {
1176                    continue;
1177                }
1178                let r = rng.random_range(0..deque_len);
1179                let idx = deque.remove(r).unwrap();
1180                slab.remove(idx).unwrap();
1181                expected_len -= 1;
1182                assert_eq!(slab.free(), capacity - expected_len);
1183            }
1184            3 => {
1185                // Only test slots that we know are valid in the deque
1186                if deque.is_empty() {
1187                    continue;
1188                }
1189                let r = rng.random_range(0..deque.len());
1190                let slot = deque[r];
1191
1192                // Remove from the deque first
1193                let idx = deque.iter().position(|&x| x == slot).unwrap();
1194                deque.remove(idx);
1195
1196                // Then remove from the slab
1197                slab.remove(slot).unwrap();
1198                expected_len -= 1;
1199                assert_eq!(slab.free(), capacity - expected_len);
1200            }
1201            _ => unreachable!(),
1202        }
1203        assert_eq!(slab.len(), expected_len);
1204        c += 1;
1205    }
1206}
1207
1208#[test]
1209fn test_default() {
1210    let slab: Slab<i32> = Slab::default();
1211    assert_eq!(slab.capacity(), 16);
1212    assert_eq!(slab.len(), 0);
1213    assert!(slab.is_empty());
1214}
1215
1216#[test]
1217fn test_from_iterator() {
1218    // Create a vector of test values
1219    let values = vec![1, 2, 3, 4, 5];
1220
1221    // Create a slab from the vector
1222    let slab: Slab<i32> = values.clone().into_iter().collect();
1223
1224    // Verify the length
1225    assert_eq!(slab.len(), 5);
1226
1227    // Test the behavior more directly by comparing specific indices
1228
1229    // The FromIterator implementation uses push_front, which should reverse the order
1230    // Manual verification of the data through slots
1231    if slab.len() == 5 {
1232        assert_eq!(*slab.get(0).unwrap(), 5); // Last element in input, first in slab
1233        assert_eq!(*slab.get(1).unwrap(), 4);
1234        assert_eq!(*slab.get(2).unwrap(), 3);
1235        assert_eq!(*slab.get(3).unwrap(), 2);
1236        assert_eq!(*slab.get(4).unwrap(), 1); // First element in input, last in slab
1237    }
1238}
1239
1240#[test]
1241fn test_extend() {
1242    let mut slab = Slab::with_capacity(5).unwrap();
1243    slab.push_front(1).unwrap();
1244    slab.push_front(2).unwrap();
1245
1246    slab.extend(vec![3, 4, 5]);
1247    assert_eq!(slab.len(), 5);
1248
1249    // Collect the items to see what's actually there
1250    let items: Vec<_> = slab.iter().copied().collect();
1251
1252    // Elements appear in the reverse order of how they were added
1253    // push_front(1), push_front(2), then extend with [3,4,5]
1254    // The extend implementation uses push_front for each element
1255    assert_eq!(items, vec![5, 4, 3, 2, 1]);
1256}
1257
1258#[test]
1259fn test_clear() {
1260    let mut slab = Slab::with_capacity(3).unwrap();
1261    slab.push_front(1).unwrap();
1262    slab.push_front(2).unwrap();
1263    slab.push_front(3).unwrap();
1264
1265    assert_eq!(slab.len(), 3);
1266    assert!(slab.is_full());
1267
1268    slab.clear();
1269
1270    assert_eq!(slab.len(), 0);
1271    assert!(slab.is_empty());
1272    assert!(!slab.is_full());
1273
1274    // Should be able to add elements again
1275    let a = slab.push_front(4).unwrap();
1276    let b = slab.push_front(5).unwrap();
1277    let c = slab.push_front(6).unwrap();
1278
1279    assert_eq!(slab.len(), 3);
1280    assert!(slab.is_full());
1281
1282    // We can get elements by slot
1283    assert_eq!(*slab.get(a).unwrap(), 4);
1284    assert_eq!(*slab.get(b).unwrap(), 5);
1285    assert_eq!(*slab.get(c).unwrap(), 6);
1286}