Skip to main content

obj_pool/
lib.rs

1//! A simple object pool.
2//!
3//! `ObjPool<T>` is basically just a `Vec<Option<T>>`, which allows you to:
4//!
5//! * Insert an object (reuse an existing `None` element, or append to the end) and get an `ObjId`
6//!   in return.
7//! * Remove object with a specified `ObjId`.
8//! * Access object with a specified `ObjId`.
9//! * Convert `ObjId` to index and back for specified `ObjPool`.
10//!
11//! # Limitations:
12//!
13//! * `ObjId` is always 32-bit long.
14//!
15//! # Examples
16//!
17//! Some data structures built using `ObjPool<T>`:
18//!
19//! * [Doubly linked list](https://github.com/artemshein/obj-pool/blob/master/examples/linked_list.rs)
20//! * [Splay tree](https://github.com/artemshein/obj-pool/blob/master/examples/splay_tree.rs)
21use std::{
22    fmt, iter, mem,
23    num::{NonZeroU32, ParseIntError},
24    ops::{Index, IndexMut},
25    ptr,
26    str::FromStr,
27    vec,
28};
29
30use std::ops::Deref;
31use std::slice;
32use unreachable::unreachable;
33
34#[cfg(feature = "serde_support")]
35use serde::{Deserialize, Serialize};
36
37mod par;
38pub use par::*;
39
40/// A slot, which is either vacant or occupied.
41///
42/// Vacant slots in object pool are linked together into a singly linked list. This allows the object pool to
43/// efficiently find a vacant slot before inserting a new object, or reclaiming a slot after
44/// removing an object.
45#[derive(Clone)]
46enum Slot<T> {
47    /// Vacant slot, containing index to the next slot in the linked list.
48    Vacant(u32),
49
50    /// Occupied slot, containing a value.
51    Occupied(T),
52}
53
54/// An id of the object in an `ObjPool`.
55///
56/// In release it is basically just an index in the underlying vector, but in debug it's an `index` +
57/// `ObjPool`-specific `offset`. This is made to be able to check `ObjId` if it's from the same
58/// `ObjPool` we are trying to get an object from.
59#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
60#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
61pub struct ObjId(pub NonZeroU32);
62
63impl ObjId {
64    pub fn from_index(index: u32) -> Self {
65        debug_assert!(index < u32::MAX, "index out of range");
66        // SAFETY: index + 1 is non-zero for any index < u32::MAX, which the
67        // debug assertion above guarantees. Using unchecked here makes the
68        // function side-effect-free in release builds so the compiler can
69        // eliminate ObjId construction when the result is unused (e.g. in
70        // iterator benchmarks that discard the key with `_`).
71        Self(unsafe { NonZeroU32::new_unchecked(index + 1) })
72    }
73
74    pub const fn into_index(self) -> u32 {
75        self.0.get() - 1
76    }
77}
78
79impl std::fmt::Display for ObjId {
80    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
81        self.0.fmt(f)
82    }
83}
84
85impl FromStr for ObjId {
86    type Err = ParseIntError;
87
88    fn from_str(s: &str) -> Result<Self, Self::Err> {
89        Ok(ObjId(s.parse::<NonZeroU32>()?))
90    }
91}
92
93impl Deref for ObjId {
94    type Target = NonZeroU32;
95
96    fn deref(&self) -> &Self::Target {
97        &self.0
98    }
99}
100
101impl From<NonZeroU32> for ObjId {
102    fn from(v: NonZeroU32) -> ObjId {
103        ObjId(v)
104    }
105}
106
107/// An object pool.
108///
109/// `ObjPool<T>` holds an array of slots for storing objects.
110/// Every slot is always in one of two states: occupied or vacant.
111///
112/// Essentially, this is equivalent to `Vec<Option<T>>`.
113///
114/// # Insert and remove
115///
116/// When inserting a new object into object pool, a vacant slot is found and then the object is placed
117/// into the slot. If there are no vacant slots, the array is reallocated with bigger capacity.
118/// The cost of insertion is amortized `O(1)`.
119///
120/// When removing an object, the slot containing it is marked as vacant and the object is returned.
121/// The cost of removal is `O(1)`.
122///
123/// ```
124/// use obj_pool::ObjPool;
125///
126/// let mut obj_pool = ObjPool::new();
127/// let a = obj_pool.insert(10);
128/// assert_eq!(a.into_index(), 0);
129/// let b = obj_pool.insert(20);
130/// assert_eq!(b.into_index(), 1);
131///
132/// assert_ne!(a, b); // ids are not the same
133///
134/// assert_eq!(obj_pool.remove(a), Some(10));
135/// assert_eq!(obj_pool.get(a), None); // there is no object with this `ObjId` anymore
136///
137/// assert_eq!(obj_pool.insert(30), a); // slot is reused, got the same `ObjId`
138/// ```
139///
140/// # Indexing
141///
142/// You can also access objects in an object pool by `ObjId`.
143/// However, accessing an object with invalid `ObjId` will result in panic.
144///
145/// ```
146/// use obj_pool::ObjPool;
147///
148/// let mut obj_pool = ObjPool::new();
149/// let a = obj_pool.insert(10);
150/// let b = obj_pool.insert(20);
151///
152/// assert_eq!(obj_pool[a], 10);
153/// assert_eq!(obj_pool[b], 20);
154///
155/// obj_pool[a] += obj_pool[b];
156/// assert_eq!(obj_pool[a], 30);
157/// ```
158///
159/// To access slots without fear of panicking, use `get` and `get_mut`, which return `Option`s.
160pub struct ObjPool<T> {
161    /// Slots in which objects are stored.
162    slots: Vec<Slot<T>>,
163
164    /// Number of occupied slots in the object pool.
165    len: u32,
166
167    /// Index of the first vacant slot in the linked list.
168    head: u32,
169}
170
171impl<T> AsRef<ObjPool<T>> for ObjPool<T> {
172    fn as_ref(&self) -> &ObjPool<T> {
173        self
174    }
175}
176
177impl<T> AsMut<ObjPool<T>> for ObjPool<T> {
178    fn as_mut(&mut self) -> &mut ObjPool<T> {
179        self
180    }
181}
182
183impl<T> ObjPool<T> {
184    /// Constructs a new, empty object pool.
185    ///
186    /// The object pool will not allocate until objects are inserted into it.
187    ///
188    /// # Examples
189    ///
190    /// ```
191    /// use obj_pool::ObjPool;
192    ///
193    /// let mut obj_pool: ObjPool<i32> = ObjPool::new();
194    /// ```
195    #[inline]
196    pub const fn new() -> Self {
197        ObjPool {
198            slots: Vec::new(),
199            len: 0,
200            head: u32::MAX,
201        }
202    }
203
204    /// Get an index in the `ObjPool` for the given `ObjId`.
205    #[inline]
206    pub const fn obj_id_to_index(obj_id: ObjId) -> u32 {
207        obj_id.into_index()
208    }
209
210    /// Make an `ObjId` from an index in this `ObjPool`.
211    #[inline]
212    pub fn index_to_obj_id(index: u32) -> ObjId {
213        ObjId::from_index(index)
214    }
215
216    /// Constructs a new, empty object pool with the specified capacity (number of slots).
217    ///
218    /// The object pool will be able to hold exactly `capacity` objects without reallocating.
219    /// If `capacity` is 0, the object pool will not allocate.
220    ///
221    /// # Examples
222    ///
223    /// ```
224    /// use obj_pool::ObjPool;
225    ///
226    /// let mut obj_pool = ObjPool::with_capacity(10);
227    ///
228    /// assert_eq!(obj_pool.len(), 0);
229    /// assert_eq!(obj_pool.capacity(), 10);
230    ///
231    /// // These inserts are done without reallocating...
232    /// for i in 0..10 {
233    ///     obj_pool.insert(i);
234    /// }
235    /// assert_eq!(obj_pool.capacity(), 10);
236    ///
237    /// // ... but this one will reallocate.
238    /// obj_pool.insert(11);
239    /// assert!(obj_pool.capacity() > 10);
240    /// ```
241    #[inline]
242    pub fn with_capacity(cap: usize) -> Self {
243        ObjPool {
244            slots: Vec::with_capacity(cap),
245            len: 0,
246            head: u32::MAX,
247        }
248    }
249
250    /// Returns the number of slots in the object pool.
251    ///
252    /// # Examples
253    ///
254    /// ```
255    /// use obj_pool::ObjPool;
256    ///
257    /// let obj_pool: ObjPool<i32> = ObjPool::with_capacity(10);
258    /// assert_eq!(obj_pool.capacity(), 10);
259    /// ```
260    #[inline]
261    pub fn capacity(&self) -> usize {
262        self.slots.capacity()
263    }
264
265    /// Returns the number of occupied slots in the object pool.
266    ///
267    /// # Examples
268    ///
269    /// ```
270    /// use obj_pool::ObjPool;
271    ///
272    /// let mut obj_pool = ObjPool::new();
273    /// assert_eq!(obj_pool.len(), 0);
274    ///
275    /// for i in 0..10 {
276    ///     obj_pool.insert(());
277    ///     assert_eq!(obj_pool.len(), i + 1);
278    /// }
279    /// ```
280    #[inline]
281    pub fn len(&self) -> u32 {
282        self.len
283    }
284
285    /// Returns `true` if all slots are vacant.
286    ///
287    /// # Examples
288    ///
289    /// ```
290    /// use obj_pool::ObjPool;
291    ///
292    /// let mut obj_pool = ObjPool::new();
293    /// assert!(obj_pool.is_empty());
294    ///
295    /// obj_pool.insert(1);
296    /// assert!(!obj_pool.is_empty());
297    /// ```
298    #[inline]
299    pub fn is_empty(&self) -> bool {
300        self.len == 0
301    }
302
303    /// Returns the `ObjId` of the next inserted object if no other
304    /// mutating calls take place in between.
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// use obj_pool::ObjPool;
310    ///
311    /// let mut obj_pool = ObjPool::new();
312    ///
313    /// let a = obj_pool.next_vacant();
314    /// let b = obj_pool.insert(1);
315    /// assert_eq!(a, b);
316    /// let c = obj_pool.next_vacant();
317    /// let d = obj_pool.insert(2);
318    /// assert_eq!(c, d);
319    /// ```
320    #[inline]
321    pub fn next_vacant(&mut self) -> ObjId {
322        Self::index_to_obj_id(if self.head == u32::MAX {
323            self.len
324        } else {
325            self.head
326        })
327    }
328
329    /// Inserts an object into the object pool and returns the `ObjId` of this object.
330    /// The object pool will reallocate if it's full.
331    ///
332    /// # Examples
333    ///
334    /// ```
335    /// use obj_pool::ObjPool;
336    ///
337    /// let mut obj_pool = ObjPool::new();
338    ///
339    /// let a = obj_pool.insert(1);
340    /// let b = obj_pool.insert(2);
341    /// assert!(a != b);
342    /// ```
343    pub fn insert(&mut self, object: T) -> ObjId {
344        self.len += 1;
345
346        if self.head == u32::MAX {
347            self.slots.push(Slot::Occupied(object));
348            Self::index_to_obj_id(self.len - 1)
349        } else {
350            let index = self.head;
351            match self.slots[index as usize] {
352                Slot::Vacant(next) => {
353                    self.head = next;
354                    self.slots[index as usize] = Slot::Occupied(object);
355                }
356                Slot::Occupied(_) => unreachable!(),
357            }
358            Self::index_to_obj_id(index)
359        }
360    }
361
362    /// Removes the object stored by `ObjId` from the object pool and returns it.
363    ///
364    /// `None` is returned in case the there is no object with such an `ObjId`.
365    ///
366    /// # Examples
367    ///
368    /// ```
369    /// use obj_pool::ObjPool;
370    ///
371    /// let mut obj_pool = ObjPool::new();
372    /// let a = obj_pool.insert("hello");
373    ///
374    /// assert_eq!(obj_pool.len(), 1);
375    /// assert_eq!(obj_pool.remove(a), Some("hello"));
376    ///
377    /// assert_eq!(obj_pool.len(), 0);
378    /// assert_eq!(obj_pool.remove(a), None);
379    /// ```
380    pub fn remove(&mut self, obj_id: ObjId) -> Option<T> {
381        let index = Self::obj_id_to_index(obj_id);
382        match self.slots.get_mut(index as usize) {
383            None => None,
384            Some(&mut Slot::Vacant(_)) => None,
385            Some(slot @ &mut Slot::Occupied(_)) => {
386                if let Slot::Occupied(object) = mem::replace(slot, Slot::Vacant(self.head)) {
387                    self.head = index;
388                    self.len -= 1;
389                    Some(object)
390                } else {
391                    unreachable!();
392                }
393            }
394        }
395    }
396
397    /// Clears the object pool, removing and dropping all objects it holds. Keeps the allocated memory
398    /// for reuse.
399    ///
400    /// # Examples
401    ///
402    /// ```
403    /// use obj_pool::ObjPool;
404    ///
405    /// let mut obj_pool = ObjPool::new();
406    /// for i in 0..10 {
407    ///     obj_pool.insert(i);
408    /// }
409    ///
410    /// assert_eq!(obj_pool.len(), 10);
411    /// obj_pool.clear();
412    /// assert_eq!(obj_pool.len(), 0);
413    /// ```
414    #[inline]
415    pub fn clear(&mut self) {
416        self.slots.clear();
417        self.len = 0;
418        self.head = u32::MAX;
419    }
420
421    /// Returns a reference to the object by its `ObjId`.
422    ///
423    /// If object is not found with given `obj_id`, `None` is returned.
424    ///
425    /// # Examples
426    ///
427    /// ```
428    /// use obj_pool::ObjPool;
429    ///
430    /// let mut obj_pool = ObjPool::new();
431    /// let obj_id = obj_pool.insert("hello");
432    ///
433    /// assert_eq!(obj_pool.get(obj_id), Some(&"hello"));
434    /// obj_pool.remove(obj_id);
435    /// assert_eq!(obj_pool.get(obj_id), None);
436    /// ```
437    pub fn get(&self, obj_id: ObjId) -> Option<&T> {
438        let index = Self::obj_id_to_index(obj_id) as usize;
439        match self.slots.get(index) {
440            None => None,
441            Some(&Slot::Vacant(_)) => None,
442            Some(Slot::Occupied(object)) => Some(object),
443        }
444    }
445
446    /// Returns a mutable reference to the object by its `ObjId`.
447    ///
448    /// If object can't be found, `None` is returned.
449    ///
450    /// # Examples
451    ///
452    /// ```
453    /// use obj_pool::ObjPool;
454    ///
455    /// let mut obj_pool = ObjPool::new();
456    /// let obj_id = obj_pool.insert(7);
457    ///
458    /// assert_eq!(obj_pool.get_mut(obj_id), Some(&mut 7));
459    /// *obj_pool.get_mut(obj_id).unwrap() *= 10;
460    /// assert_eq!(obj_pool.get_mut(obj_id), Some(&mut 70));
461    /// ```
462    #[inline]
463    pub fn get_mut(&mut self, obj_id: ObjId) -> Option<&mut T> {
464        let index = Self::obj_id_to_index(obj_id) as usize;
465        match self.slots.get_mut(index) {
466            None => None,
467            Some(&mut Slot::Vacant(_)) => None,
468            Some(&mut Slot::Occupied(ref mut object)) => Some(object),
469        }
470    }
471
472    /// Returns a reference to the object by its `ObjId`.
473    ///
474    /// # Safety
475    ///
476    /// Behavior is undefined if object can't be found.
477    ///
478    /// # Examples
479    ///
480    /// ```
481    /// use obj_pool::ObjPool;
482    ///
483    /// let mut obj_pool = ObjPool::new();
484    /// let obj_id = obj_pool.insert("hello");
485    ///
486    /// unsafe { assert_eq!(&*obj_pool.get_unchecked(obj_id), &"hello") }
487    /// ```
488    pub unsafe fn get_unchecked(&self, obj_id: ObjId) -> &T {
489        match self.slots.get(Self::obj_id_to_index(obj_id) as usize) {
490            None => unsafe { unreachable() },
491            Some(Slot::Vacant(_)) => unsafe { unreachable() },
492            Some(Slot::Occupied(object)) => object,
493        }
494    }
495
496    /// Returns a mutable reference to the object by its `ObjId`.
497    ///
498    /// # Safety
499    ///
500    /// Behavior is undefined if object can't be found.
501    ///
502    /// # Examples
503    ///
504    /// ```
505    /// use obj_pool::ObjPool;
506    ///
507    /// let mut obj_pool = ObjPool::new();
508    /// let obj_id = obj_pool.insert("hello");
509    ///
510    /// unsafe { assert_eq!(&*obj_pool.get_unchecked_mut(obj_id), &"hello") }
511    /// ```
512    pub unsafe fn get_unchecked_mut(&mut self, obj_id: ObjId) -> &mut T {
513        let index = Self::obj_id_to_index(obj_id) as usize;
514        match self.slots.get_mut(index) {
515            Some(&mut Slot::Vacant(_)) => unsafe { unreachable() },
516            Some(&mut Slot::Occupied(ref mut object)) => object,
517            _ => unsafe { unreachable() },
518        }
519    }
520
521    /// Swaps two objects in the object pool.
522    ///
523    /// The two `ObjId`s are `a` and `b`.
524    ///
525    /// # Panics
526    ///
527    /// Panics if any of the `ObjId`s is invalid.
528    ///
529    /// # Examples
530    ///
531    /// ```
532    /// use obj_pool::ObjPool;
533    ///
534    /// let mut obj_pool = ObjPool::new();
535    /// let a = obj_pool.insert(7);
536    /// let b = obj_pool.insert(8);
537    ///
538    /// obj_pool.swap(a, b);
539    /// assert_eq!(obj_pool.get(a), Some(&8));
540    /// assert_eq!(obj_pool.get(b), Some(&7));
541    /// ```
542    #[inline]
543    pub fn swap(&mut self, a: ObjId, b: ObjId) {
544        unsafe {
545            let fst = self.get_mut(a).unwrap() as *mut _;
546            let snd = self.get_mut(b).unwrap() as *mut _;
547            if a != b {
548                ptr::swap(fst, snd);
549            }
550        }
551    }
552
553    /// Reserves capacity for at least `additional` more objects to be inserted. The object pool may
554    /// reserve more space to avoid frequent reallocations.
555    ///
556    /// # Panics
557    ///
558    /// Panics if the new capacity overflows `u32`.
559    ///
560    /// # Examples
561    ///
562    /// ```
563    /// use obj_pool::ObjPool;
564    ///
565    /// let mut obj_pool = ObjPool::new();
566    /// obj_pool.insert("hello");
567    ///
568    /// obj_pool.reserve(10);
569    /// assert!(obj_pool.capacity() >= 11);
570    /// ```
571    pub fn reserve(&mut self, additional: u32) {
572        let vacant = self.slots.len() as u32 - self.len;
573        if additional > vacant {
574            self.slots.reserve((additional - vacant) as usize);
575        }
576    }
577
578    /// Reserves the minimum capacity for exactly `additional` more objects to be inserted.
579    ///
580    /// Note that the allocator may give the object pool more space than it requests.
581    ///
582    /// # Panics
583    ///
584    /// Panics if the new capacity overflows `u32`.
585    ///
586    /// # Examples
587    ///
588    /// ```
589    /// use obj_pool::ObjPool;
590    ///
591    /// let mut obj_pool = ObjPool::new();
592    /// obj_pool.insert("hello");
593    ///
594    /// obj_pool.reserve_exact(10);
595    /// assert!(obj_pool.capacity() >= 11);
596    /// ```
597    pub fn reserve_exact(&mut self, additional: u32) {
598        let vacant = self.slots.len() as u32 - self.len;
599        if additional > vacant {
600            self.slots.reserve_exact((additional - vacant) as usize);
601        }
602    }
603
604    /// Returns an iterator over occupied slots.
605    ///
606    /// # Examples
607    ///
608    /// ```
609    /// use obj_pool::ObjPool;
610    ///
611    /// let mut obj_pool = ObjPool::new();
612    /// obj_pool.insert(1);
613    /// obj_pool.insert(2);
614    /// obj_pool.insert(4);
615    ///
616    /// let mut iterator = obj_pool.iter();
617    /// assert_eq!(iterator.next(), Some((ObjPool::<usize>::index_to_obj_id(0), &1)));
618    /// assert_eq!(iterator.next(), Some((ObjPool::<usize>::index_to_obj_id(1), &2)));
619    /// assert_eq!(iterator.next(), Some((ObjPool::<usize>::index_to_obj_id(2), &4)));
620    /// ```
621    #[inline]
622    pub fn iter(&self) -> Iter<'_, T> {
623        Iter {
624            len: self.len as usize,
625            slots: self.slots.iter().enumerate(),
626        }
627    }
628
629    /// Returns an iterator that returns mutable references to objects.
630    ///
631    /// # Examples
632    ///
633    /// ```
634    /// use obj_pool::ObjPool;
635    ///
636    /// let mut obj_pool = ObjPool::new();
637    /// obj_pool.insert("zero".to_string());
638    /// obj_pool.insert("one".to_string());
639    /// obj_pool.insert("two".to_string());
640    ///
641    /// for (obj_id, object) in obj_pool.iter_mut() {
642    ///     *object = obj_id.into_index().to_string() + " " + object;
643    /// }
644    ///
645    /// let mut iterator = obj_pool.iter();
646    /// assert_eq!(iterator.next(), Some((ObjPool::<String>::index_to_obj_id(0), &"0 zero".to_string())));
647    /// assert_eq!(iterator.next(), Some((ObjPool::<String>::index_to_obj_id(1), &"1 one".to_string())));
648    /// assert_eq!(iterator.next(), Some((ObjPool::<String>::index_to_obj_id(2), &"2 two".to_string())));
649    /// ```
650    #[inline]
651    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
652        IterMut {
653            len: self.len as usize,
654            slots: self.slots.iter_mut().enumerate(),
655        }
656    }
657
658    /// Shrinks the capacity of the object pool as much as possible.
659    ///
660    /// It will drop down as close as possible to the length but the allocator may still inform
661    /// the object pool that there is space for a few more elements.
662    ///
663    /// # Examples
664    ///
665    /// ```
666    /// use obj_pool::ObjPool;
667    ///
668    /// let mut obj_pool = ObjPool::with_capacity(10);
669    /// obj_pool.insert("first".to_string());
670    /// obj_pool.insert("second".to_string());
671    /// obj_pool.insert("third".to_string());
672    /// assert_eq!(obj_pool.capacity(), 10);
673    /// obj_pool.shrink_to_fit();
674    /// assert!(obj_pool.capacity() >= 3);
675    /// ```
676    pub fn shrink_to_fit(&mut self) {
677        self.slots.shrink_to_fit();
678    }
679}
680
681impl<T> fmt::Debug for ObjPool<T> {
682    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
683        write!(f, "ObjPool {{ ... }}")
684    }
685}
686
687impl<T> Index<ObjId> for ObjPool<T> {
688    type Output = T;
689
690    #[inline]
691    fn index(&self, obj_id: ObjId) -> &T {
692        self.get(obj_id).expect("object not found")
693    }
694}
695
696impl<T> IndexMut<ObjId> for ObjPool<T> {
697    #[inline]
698    fn index_mut(&mut self, obj_id: ObjId) -> &mut T {
699        self.get_mut(obj_id).expect("object not found")
700    }
701}
702
703impl<T> Default for ObjPool<T> {
704    fn default() -> Self {
705        ObjPool::new()
706    }
707}
708
709impl<T: Clone> Clone for ObjPool<T> {
710    fn clone(&self) -> Self {
711        ObjPool {
712            slots: self.slots.clone(),
713            len: self.len,
714            head: self.head,
715        }
716    }
717}
718
719/// An iterator over the occupied slots in a `ObjPool`.
720pub struct IntoIter<T> {
721    slots: iter::Enumerate<vec::IntoIter<Slot<T>>>,
722    len: usize,
723}
724
725impl<T> IntoIter<T> {
726    #[inline]
727    pub const fn obj_id_to_index(obj_id: ObjId) -> u32 {
728        obj_id.into_index()
729    }
730
731    #[inline]
732    pub fn index_to_obj_id(index: u32) -> ObjId {
733        ObjId::from_index(index)
734    }
735}
736
737impl<T> Iterator for IntoIter<T> {
738    type Item = (ObjId, T);
739
740    #[inline]
741    fn next(&mut self) -> Option<Self::Item> {
742        for (index, slot) in self.slots.by_ref() {
743            if let Slot::Occupied(object) = slot {
744                self.len -= 1;
745                return Some((Self::index_to_obj_id(index as u32), object));
746            }
747        }
748        None
749    }
750
751    fn size_hint(&self) -> (usize, Option<usize>) {
752        (self.len, Some(self.len))
753    }
754}
755
756impl<T> ExactSizeIterator for IntoIter<T> {
757    fn len(&self) -> usize {
758        self.len
759    }
760}
761
762impl<T> iter::FusedIterator for IntoIter<T> {}
763
764impl<T> IntoIterator for ObjPool<T> {
765    type Item = (ObjId, T);
766    type IntoIter = IntoIter<T>;
767
768    #[inline]
769    fn into_iter(self) -> Self::IntoIter {
770        IntoIter {
771            len: self.len as usize,
772            slots: self.slots.into_iter().enumerate(),
773        }
774    }
775}
776
777impl<T> iter::FromIterator<T> for ObjPool<T> {
778    fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> ObjPool<T> {
779        let iter = iter.into_iter();
780        let mut obj_pool = ObjPool::with_capacity(iter.size_hint().0);
781        for i in iter {
782            obj_pool.insert(i);
783        }
784        obj_pool
785    }
786}
787
788impl<T> fmt::Debug for IntoIter<T> {
789    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
790        write!(f, "IntoIter {{ ... }}")
791    }
792}
793
794/// An iterator over references to the occupied slots in a `ObjPool`.
795pub struct Iter<'a, T: 'a> {
796    slots: iter::Enumerate<slice::Iter<'a, Slot<T>>>,
797    len: usize,
798}
799
800impl<'a, T: 'a> Iter<'a, T> {
801    #[inline]
802    pub fn index_to_obj_id(index: u32) -> ObjId {
803        ObjId::from_index(index)
804    }
805}
806
807impl<'a, T> Iterator for Iter<'a, T> {
808    type Item = (ObjId, &'a T);
809
810    #[inline]
811    fn next(&mut self) -> Option<Self::Item> {
812        for (index, slot) in self.slots.by_ref() {
813            if let Slot::Occupied(ref object) = *slot {
814                self.len -= 1;
815                return Some((Self::index_to_obj_id(index as u32), object));
816            }
817        }
818        None
819    }
820
821    fn size_hint(&self) -> (usize, Option<usize>) {
822        (self.len, Some(self.len))
823    }
824}
825
826impl<T> ExactSizeIterator for Iter<'_, T> {
827    fn len(&self) -> usize {
828        self.len
829    }
830}
831
832impl<T> iter::FusedIterator for Iter<'_, T> {}
833
834impl<'a, T> IntoIterator for &'a ObjPool<T> {
835    type Item = (ObjId, &'a T);
836    type IntoIter = Iter<'a, T>;
837
838    #[inline]
839    fn into_iter(self) -> Self::IntoIter {
840        self.iter()
841    }
842}
843
844impl<'a, T> fmt::Debug for Iter<'a, T> {
845    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
846        write!(f, "Iter {{ ... }}")
847    }
848}
849
850/// An iterator over mutable references to the occupied slots in a `Arena`.
851pub struct IterMut<'a, T: 'a> {
852    slots: iter::Enumerate<slice::IterMut<'a, Slot<T>>>,
853    len: usize,
854}
855
856impl<'a, T: 'a> IterMut<'a, T> {
857    #[inline]
858    pub const fn obj_id_to_index(obj_id: ObjId) -> u32 {
859        obj_id.into_index()
860    }
861
862    #[inline]
863    pub fn index_to_obj_id(index: u32) -> ObjId {
864        ObjId::from_index(index)
865    }
866}
867
868impl<'a, T> Iterator for IterMut<'a, T> {
869    type Item = (ObjId, &'a mut T);
870
871    #[inline]
872    fn next(&mut self) -> Option<Self::Item> {
873        for (index, slot) in self.slots.by_ref() {
874            if let Slot::Occupied(ref mut object) = *slot {
875                self.len -= 1;
876                return Some((Self::index_to_obj_id(index as u32), object));
877            }
878        }
879        None
880    }
881
882    fn size_hint(&self) -> (usize, Option<usize>) {
883        (self.len, Some(self.len))
884    }
885}
886
887impl<T> ExactSizeIterator for IterMut<'_, T> {
888    fn len(&self) -> usize {
889        self.len
890    }
891}
892
893impl<T> iter::FusedIterator for IterMut<'_, T> {}
894
895impl<'a, T> IntoIterator for &'a mut ObjPool<T> {
896    type Item = (ObjId, &'a mut T);
897    type IntoIter = IterMut<'a, T>;
898
899    #[inline]
900    fn into_iter(self) -> Self::IntoIter {
901        self.iter_mut()
902    }
903}
904
905impl<'a, T> fmt::Debug for IterMut<'a, T> {
906    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
907        write!(f, "IterMut {{ ... }}")
908    }
909}
910
911#[cfg(test)]
912mod tests {
913    use super::*;
914
915    #[test]
916    fn new() {
917        let obj_pool = ObjPool::<i32>::new();
918        assert!(obj_pool.is_empty());
919        assert_eq!(obj_pool.len(), 0);
920        assert_eq!(obj_pool.capacity(), 0);
921    }
922
923    #[test]
924    fn insert() {
925        let mut obj_pool = ObjPool::new();
926
927        for i in 0..10 {
928            let a = obj_pool.insert(i * 10);
929            assert_eq!(obj_pool[a], i * 10);
930        }
931        assert!(!obj_pool.is_empty());
932        assert_eq!(obj_pool.len(), 10);
933    }
934
935    #[test]
936    fn with_capacity() {
937        let mut obj_pool = ObjPool::with_capacity(10);
938        assert_eq!(obj_pool.capacity(), 10);
939
940        for _ in 0..10 {
941            obj_pool.insert(());
942        }
943        assert_eq!(obj_pool.len(), 10);
944        assert_eq!(obj_pool.capacity(), 10);
945
946        obj_pool.insert(());
947        assert_eq!(obj_pool.len(), 11);
948        assert!(obj_pool.capacity() > 10);
949    }
950
951    #[test]
952    fn remove() {
953        let mut obj_pool = ObjPool::new();
954
955        let a = obj_pool.insert(0);
956        let b = obj_pool.insert(10);
957        let c = obj_pool.insert(20);
958        obj_pool.insert(30);
959        assert_eq!(obj_pool.len(), 4);
960
961        assert_eq!(obj_pool.remove(b), Some(10));
962        assert_eq!(obj_pool.remove(c), Some(20));
963        assert_eq!(obj_pool.len(), 2);
964
965        obj_pool.insert(-1);
966        obj_pool.insert(-1);
967        assert_eq!(obj_pool.len(), 4);
968
969        assert_eq!(obj_pool.remove(a), Some(0));
970        obj_pool.insert(-1);
971        assert_eq!(obj_pool.len(), 4);
972
973        obj_pool.insert(400);
974        assert_eq!(obj_pool.len(), 5);
975    }
976
977    #[test]
978    fn clear() {
979        let mut obj_pool = ObjPool::new();
980        obj_pool.insert(10);
981        obj_pool.insert(20);
982
983        assert!(!obj_pool.is_empty());
984        assert_eq!(obj_pool.len(), 2);
985
986        let cap = obj_pool.capacity();
987        obj_pool.clear();
988
989        assert!(obj_pool.is_empty());
990        assert_eq!(obj_pool.len(), 0);
991        assert_eq!(obj_pool.capacity(), cap);
992    }
993
994    #[test]
995    fn indexing() {
996        let mut obj_pool = ObjPool::new();
997
998        let a = obj_pool.insert(10);
999        let b = obj_pool.insert(20);
1000        let c = obj_pool.insert(30);
1001
1002        obj_pool[b] += obj_pool[c];
1003        assert_eq!(obj_pool[a], 10);
1004        assert_eq!(obj_pool[b], 50);
1005        assert_eq!(obj_pool[c], 30);
1006    }
1007
1008    #[test]
1009    #[should_panic]
1010    fn indexing_vacant() {
1011        let mut obj_pool = ObjPool::new();
1012
1013        let _ = obj_pool.insert(10);
1014        let b = obj_pool.insert(20);
1015        let _ = obj_pool.insert(30);
1016
1017        obj_pool.remove(b);
1018        obj_pool[b];
1019    }
1020
1021    #[test]
1022    #[should_panic]
1023    fn invalid_indexing() {
1024        let mut obj_pool = ObjPool::new();
1025
1026        obj_pool.insert(10);
1027        obj_pool.insert(20);
1028        let a = obj_pool.insert(30);
1029        obj_pool.remove(a);
1030
1031        obj_pool[a];
1032    }
1033
1034    #[test]
1035    fn get() {
1036        let mut obj_pool = ObjPool::new();
1037
1038        let a = obj_pool.insert(10);
1039        let b = obj_pool.insert(20);
1040        let c = obj_pool.insert(30);
1041
1042        *obj_pool.get_mut(b).unwrap() += *obj_pool.get(c).unwrap();
1043        assert_eq!(obj_pool.get(a), Some(&10));
1044        assert_eq!(obj_pool.get(b), Some(&50));
1045        assert_eq!(obj_pool.get(c), Some(&30));
1046
1047        obj_pool.remove(b);
1048        assert_eq!(obj_pool.get(b), None);
1049        assert_eq!(obj_pool.get_mut(b), None);
1050    }
1051
1052    #[test]
1053    fn reserve() {
1054        let mut obj_pool = ObjPool::new();
1055        obj_pool.insert(1);
1056        obj_pool.insert(2);
1057
1058        obj_pool.reserve(10);
1059        assert!(obj_pool.capacity() >= 11);
1060    }
1061
1062    #[test]
1063    fn reserve_exact() {
1064        let mut obj_pool = ObjPool::new();
1065        obj_pool.insert(1);
1066        obj_pool.insert(2);
1067        obj_pool.reserve(10);
1068        assert!(obj_pool.capacity() >= 11);
1069    }
1070
1071    #[test]
1072    fn iter() {
1073        let mut arena = ObjPool::new();
1074        let a = arena.insert(10);
1075        let b = arena.insert(20);
1076        let c = arena.insert(30);
1077        let d = arena.insert(40);
1078
1079        arena.remove(b);
1080
1081        let mut it = arena.iter();
1082        assert_eq!(it.next(), Some((a, &10)));
1083        assert_eq!(it.next(), Some((c, &30)));
1084        assert_eq!(it.next(), Some((d, &40)));
1085        assert_eq!(it.next(), None);
1086    }
1087
1088    #[test]
1089    fn iter_mut() {
1090        let mut obj_pool = ObjPool::new();
1091        let a = obj_pool.insert(10);
1092        let b = obj_pool.insert(20);
1093        let c = obj_pool.insert(30);
1094        let d = obj_pool.insert(40);
1095
1096        obj_pool.remove(b);
1097
1098        {
1099            let mut it = obj_pool.iter_mut();
1100            assert_eq!(it.next(), Some((a, &mut 10)));
1101            assert_eq!(it.next(), Some((c, &mut 30)));
1102            assert_eq!(it.next(), Some((d, &mut 40)));
1103            assert_eq!(it.next(), None);
1104        }
1105
1106        for (obj_id, value) in &mut obj_pool {
1107            *value += obj_id.get();
1108        }
1109
1110        let mut it = obj_pool.iter_mut();
1111        assert_eq!(*it.next().unwrap().1, 10 + a.get());
1112        assert_eq!(*it.next().unwrap().1, 30 + c.get());
1113        assert_eq!(*it.next().unwrap().1, 40 + d.get());
1114        assert_eq!(it.next(), None);
1115    }
1116
1117    #[test]
1118    fn from_iter() {
1119        let obj_pool: ObjPool<usize> = [10, 20, 30, 40].iter().cloned().collect();
1120
1121        let mut it = obj_pool.iter();
1122        assert_eq!(it.next(), Some((ObjPool::<usize>::index_to_obj_id(0), &10)));
1123        assert_eq!(it.next(), Some((ObjPool::<usize>::index_to_obj_id(1), &20)));
1124        assert_eq!(it.next(), Some((ObjPool::<usize>::index_to_obj_id(2), &30)));
1125        assert_eq!(it.next(), Some((ObjPool::<usize>::index_to_obj_id(3), &40)));
1126        assert_eq!(it.next(), None);
1127    }
1128}