slotmap/
basic.rs

1//! Contains the slot map implementation.
2
3use alloc::collections::TryReserveError;
4use alloc::vec::Vec;
5use core::fmt;
6use core::iter::{Enumerate, FusedIterator};
7use core::marker::PhantomData;
8use core::mem::{ManuallyDrop, MaybeUninit};
9use core::ops::{Index, IndexMut};
10
11use crate::util::{Never, PanicOnDrop, UnwrapNever};
12use crate::{DefaultKey, Key, KeyData};
13
14// Storage inside a slot or metadata for the freelist when vacant.
15union SlotUnion<T> {
16    value: ManuallyDrop<T>,
17    next_free: u32,
18}
19
20// A slot, which represents storage for a value and a current version.
21// Can be occupied or vacant.
22struct Slot<T> {
23    u: SlotUnion<T>,
24    version: u32, // Even = vacant, odd = occupied.
25}
26
27// Safe API to read a slot.
28enum SlotContent<'a, T: 'a> {
29    Occupied(&'a T),
30    Vacant(&'a u32),
31}
32
33enum SlotContentMut<'a, T: 'a> {
34    OccupiedMut(&'a mut T),
35    VacantMut(&'a mut u32),
36}
37
38use self::SlotContent::{Occupied, Vacant};
39use self::SlotContentMut::{OccupiedMut, VacantMut};
40
41impl<T> Slot<T> {
42    // Is this slot occupied?
43    #[inline(always)]
44    pub fn occupied(&self) -> bool {
45        self.version % 2 > 0
46    }
47
48    pub fn get(&self) -> SlotContent<'_, T> {
49        unsafe {
50            if self.occupied() {
51                Occupied(&*self.u.value)
52            } else {
53                Vacant(&self.u.next_free)
54            }
55        }
56    }
57
58    pub fn get_mut(&mut self) -> SlotContentMut<'_, T> {
59        unsafe {
60            if self.occupied() {
61                OccupiedMut(&mut *self.u.value)
62            } else {
63                VacantMut(&mut self.u.next_free)
64            }
65        }
66    }
67}
68
69impl<T> Drop for Slot<T> {
70    fn drop(&mut self) {
71        if core::mem::needs_drop::<T>() && self.occupied() {
72            // This is safe because we checked that we're occupied.
73            unsafe {
74                ManuallyDrop::drop(&mut self.u.value);
75            }
76        }
77    }
78}
79
80impl<T: Clone> Clone for Slot<T> {
81    fn clone(&self) -> Self {
82        Self {
83            u: match self.get() {
84                Occupied(value) => SlotUnion {
85                    value: ManuallyDrop::new(value.clone()),
86                },
87                Vacant(&next_free) => SlotUnion { next_free },
88            },
89            version: self.version,
90        }
91    }
92
93    fn clone_from(&mut self, source: &Self) {
94        match (self.get_mut(), source.get()) {
95            (OccupiedMut(self_val), Occupied(source_val)) => self_val.clone_from(source_val),
96            (OccupiedMut(_), Vacant(&next_free)) => unsafe {
97                // SAFETY: we are occupied.
98                ManuallyDrop::drop(&mut self.u.value);
99                self.u = SlotUnion { next_free };
100            },
101            (VacantMut(self_next_free), Vacant(&source_next_free)) => {
102                *self_next_free = source_next_free
103            },
104            (VacantMut(_), Occupied(value)) => {
105                self.u = SlotUnion {
106                    value: ManuallyDrop::new(value.clone()),
107                }
108            },
109        }
110        self.version = source.version;
111    }
112}
113
114impl<T: fmt::Debug> fmt::Debug for Slot<T> {
115    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
116        let mut builder = fmt.debug_struct("Slot");
117        builder.field("version", &self.version);
118        match self.get() {
119            Occupied(value) => builder.field("value", value).finish(),
120            Vacant(next_free) => builder.field("next_free", next_free).finish(),
121        }
122    }
123}
124
125/// Slot map, storage with stable unique keys.
126///
127/// See [crate documentation](crate) for more details.
128#[derive(Debug)]
129pub struct SlotMap<K: Key, V> {
130    slots: Vec<Slot<V>>,
131    free_head: u32,
132    num_elems: u32,
133    _k: PhantomData<fn(K) -> K>,
134}
135
136impl<V> SlotMap<DefaultKey, V> {
137    /// Constructs a new, empty [`SlotMap`].
138    ///
139    /// # Examples
140    ///
141    /// ```
142    /// # use slotmap::*;
143    /// let mut sm: SlotMap<_, i32> = SlotMap::new();
144    /// ```
145    pub fn new() -> Self {
146        Self::with_capacity_and_key(0)
147    }
148
149    /// Creates an empty [`SlotMap`] with the given capacity.
150    ///
151    /// The slot map will not reallocate until it holds at least `capacity`
152    /// elements.
153    ///
154    /// # Examples
155    ///
156    /// ```
157    /// # use slotmap::*;
158    /// let mut sm: SlotMap<_, i32> = SlotMap::with_capacity(10);
159    /// ```
160    pub fn with_capacity(capacity: usize) -> Self {
161        Self::with_capacity_and_key(capacity)
162    }
163}
164
165impl<K: Key, V> SlotMap<K, V> {
166    /// Constructs a new, empty [`SlotMap`] with a custom key type.
167    ///
168    /// # Examples
169    ///
170    /// ```
171    /// # use slotmap::*;
172    /// new_key_type! {
173    ///     struct PositionKey;
174    /// }
175    /// let mut positions: SlotMap<PositionKey, i32> = SlotMap::with_key();
176    /// ```
177    pub fn with_key() -> Self {
178        Self::with_capacity_and_key(0)
179    }
180
181    /// Creates an empty [`SlotMap`] with the given capacity and a custom key
182    /// type.
183    ///
184    /// The slot map will not reallocate until it holds at least `capacity`
185    /// elements.
186    ///
187    /// # Examples
188    ///
189    /// ```
190    /// # use slotmap::*;
191    /// new_key_type! {
192    ///     struct MessageKey;
193    /// }
194    /// let mut messages = SlotMap::with_capacity_and_key(3);
195    /// let welcome: MessageKey = messages.insert("Welcome");
196    /// let good_day = messages.insert("Good day");
197    /// let hello = messages.insert("Hello");
198    /// ```
199    pub fn with_capacity_and_key(capacity: usize) -> Self {
200        // Create slots with a sentinel at index 0.
201        // We don't actually use the sentinel for anything currently, but
202        // HopSlotMap does, and if we want keys to remain valid through
203        // conversion we have to have one as well.
204        let mut slots = Vec::with_capacity(capacity + 1);
205        slots.push(Slot {
206            u: SlotUnion { next_free: 0 },
207            version: 0,
208        });
209
210        Self {
211            slots,
212            free_head: 1,
213            num_elems: 0,
214            _k: PhantomData,
215        }
216    }
217
218    /// Returns the number of elements in the slot map.
219    ///
220    /// # Examples
221    ///
222    /// ```
223    /// # use slotmap::*;
224    /// let mut sm = SlotMap::with_capacity(10);
225    /// sm.insert("len() counts actual elements, not capacity");
226    /// let key = sm.insert("removed elements don't count either");
227    /// sm.remove(key);
228    /// assert_eq!(sm.len(), 1);
229    /// ```
230    pub fn len(&self) -> usize {
231        self.num_elems as usize
232    }
233
234    /// Returns if the slot map is empty.
235    ///
236    /// # Examples
237    ///
238    /// ```
239    /// # use slotmap::*;
240    /// let mut sm = SlotMap::new();
241    /// let key = sm.insert("dummy");
242    /// assert_eq!(sm.is_empty(), false);
243    /// sm.remove(key);
244    /// assert_eq!(sm.is_empty(), true);
245    /// ```
246    pub fn is_empty(&self) -> bool {
247        self.num_elems == 0
248    }
249
250    /// Returns the number of elements the [`SlotMap`] can hold without
251    /// reallocating.
252    ///
253    /// # Examples
254    ///
255    /// ```
256    /// # use slotmap::*;
257    /// let sm: SlotMap<_, f64> = SlotMap::with_capacity(10);
258    /// assert_eq!(sm.capacity(), 10);
259    /// ```
260    pub fn capacity(&self) -> usize {
261        // One slot is reserved for the sentinel.
262        self.slots.capacity() - 1
263    }
264
265    /// Reserves capacity for at least `additional` more elements to be inserted
266    /// in the [`SlotMap`]. The collection may reserve more space to avoid
267    /// frequent reallocations.
268    ///
269    /// # Panics
270    ///
271    /// Panics if the new allocation size overflows [`usize`].
272    ///
273    /// # Examples
274    ///
275    /// ```
276    /// # use slotmap::*;
277    /// let mut sm = SlotMap::new();
278    /// sm.insert("foo");
279    /// sm.reserve(32);
280    /// assert!(sm.capacity() >= 33);
281    /// ```
282    pub fn reserve(&mut self, additional: usize) {
283        // One slot is reserved for the sentinel.
284        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);
285        self.slots.reserve(needed);
286    }
287
288    /// Tries to reserve capacity for at least `additional` more elements to be
289    /// inserted in the [`SlotMap`]. The collection may reserve more space to
290    /// avoid frequent reallocations.
291    ///
292    /// # Examples
293    ///
294    /// ```
295    /// # use slotmap::*;
296    /// let mut sm = SlotMap::new();
297    /// sm.insert("foo");
298    /// sm.try_reserve(32).unwrap();
299    /// assert!(sm.capacity() >= 33);
300    /// ```
301    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
302        // One slot is reserved for the sentinel.
303        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);
304        self.slots.try_reserve(needed)
305    }
306
307    /// Returns [`true`] if the slot map contains `key`.
308    ///
309    /// # Examples
310    ///
311    /// ```
312    /// # use slotmap::*;
313    /// let mut sm = SlotMap::new();
314    /// let key = sm.insert(42);
315    /// assert_eq!(sm.contains_key(key), true);
316    /// sm.remove(key);
317    /// assert_eq!(sm.contains_key(key), false);
318    /// ```
319    pub fn contains_key(&self, key: K) -> bool {
320        let kd = key.data();
321        self.slots
322            .get(kd.idx as usize)
323            .map_or(false, |slot| slot.version == kd.version.get())
324    }
325
326    /// Inserts a value into the slot map. Returns a unique key that can be used
327    /// to access this value.
328    ///
329    /// # Panics
330    ///
331    /// Panics if the slot map is full.
332    ///
333    /// # Examples
334    ///
335    /// ```
336    /// # use slotmap::*;
337    /// let mut sm = SlotMap::new();
338    /// let key = sm.insert(42);
339    /// assert_eq!(sm[key], 42);
340    /// ```
341    #[inline(always)]
342    pub fn insert(&mut self, value: V) -> K {
343        self.try_insert_with_key::<_, Never>(move |_| Ok(value))
344            .unwrap_never()
345    }
346
347    /// Inserts a value given by `f` into the slot map. The key where the
348    /// value will be stored is passed into `f`. This is useful to store values
349    /// that contain their own key.
350    ///
351    /// # Panics
352    ///
353    /// Panics if the slot map is full.
354    ///
355    /// # Examples
356    ///
357    /// ```
358    /// # use slotmap::*;
359    /// let mut sm = SlotMap::new();
360    /// let key = sm.insert_with_key(|k| (k, 20));
361    /// assert_eq!(sm[key], (key, 20));
362    /// ```
363    #[inline(always)]
364    pub fn insert_with_key<F>(&mut self, f: F) -> K
365    where
366        F: FnOnce(K) -> V,
367    {
368        self.try_insert_with_key::<_, Never>(move |k| Ok(f(k)))
369            .unwrap_never()
370    }
371
372    /// Inserts a value given by `f` into the slot map. The key where the
373    /// value will be stored is passed into `f`. This is useful to store values
374    /// that contain their own key.
375    ///
376    /// If `f` returns `Err`, this method returns the error. The slotmap is untouched.
377    ///
378    /// # Panics
379    ///
380    /// Panics if the slot map is full.
381    ///
382    /// # Examples
383    ///
384    /// ```
385    /// # use slotmap::*;
386    /// let mut sm = SlotMap::new();
387    /// let key = sm.try_insert_with_key::<_, ()>(|k| Ok((k, 20))).unwrap();
388    /// assert_eq!(sm[key], (key, 20));
389    ///
390    /// sm.try_insert_with_key::<_, ()>(|k| Err(())).unwrap_err();
391    /// ```
392    pub fn try_insert_with_key<F, E>(&mut self, f: F) -> Result<K, E>
393    where
394        F: FnOnce(K) -> Result<V, E>,
395    {
396        if let Some(slot) = self.slots.get_mut(self.free_head as usize) {
397            let occupied_version = slot.version | 1;
398            let kd = KeyData::new(self.free_head, occupied_version);
399
400            // Get value first in case f panics or returns an error.
401            let value = f(kd.into())?;
402
403            // Update.
404            unsafe {
405                self.free_head = slot.u.next_free;
406                slot.u.value = ManuallyDrop::new(value);
407                slot.version = occupied_version;
408            }
409            self.num_elems += 1;
410            return Ok(kd.into());
411        }
412
413        if self.slots.len() >= u32::MAX as usize {
414            panic!("SlotMap is full");
415        }
416
417        let version = 1;
418        let kd = KeyData::new(self.slots.len() as u32, version);
419
420        // Create new slot before adjusting freelist in case f or the allocation panics or errors.
421        self.slots.push(Slot {
422            u: SlotUnion {
423                value: ManuallyDrop::new(f(kd.into())?),
424            },
425            version,
426        });
427
428        self.free_head = kd.idx + 1;
429        self.num_elems += 1;
430        Ok(kd.into())
431    }
432
433    // Helper function to remove a value from a slot. Safe iff the slot is
434    // occupied. Returns the value removed.
435    #[inline(always)]
436    unsafe fn remove_from_slot(&mut self, idx: usize) -> V {
437        // Remove value from slot before overwriting union.
438        let slot = self.slots.get_unchecked_mut(idx);
439        let value = ManuallyDrop::take(&mut slot.u.value);
440
441        // Maintain freelist.
442        slot.u.next_free = self.free_head;
443        self.free_head = idx as u32;
444        self.num_elems -= 1;
445        slot.version = slot.version.wrapping_add(1);
446
447        value
448    }
449
450    /// Removes a key from the slot map, returning the value at the key if the
451    /// key was not previously removed.
452    ///
453    /// # Examples
454    ///
455    /// ```
456    /// # use slotmap::*;
457    /// let mut sm = SlotMap::new();
458    /// let key = sm.insert(42);
459    /// assert_eq!(sm.remove(key), Some(42));
460    /// assert_eq!(sm.remove(key), None);
461    /// ```
462    pub fn remove(&mut self, key: K) -> Option<V> {
463        let kd = key.data();
464        if self.contains_key(key) {
465            // This is safe because we know that the slot is occupied.
466            Some(unsafe { self.remove_from_slot(kd.idx as usize) })
467        } else {
468            None
469        }
470    }
471
472    /// Temporarily removes a key from the slot map, returning the value at the
473    /// key if the key was not previously removed.
474    ///
475    /// The key becomes invalid and cannot be used until
476    /// [`reattach`](Self::reattach) is called with that key and a new value.
477    ///
478    /// Unfortunately, detached keys become permanently removed in a
479    /// deserialized copy if the slot map is serialized while they are detached.
480    /// Preserving detached keys across serialization is a possible future
481    /// enhancement, you must not rely on this behavior.
482    ///
483    /// # Examples
484    ///
485    /// ```
486    /// # use slotmap::*;
487    /// let mut sm = SlotMap::new();
488    /// let key = sm.insert(42);
489    /// assert_eq!(sm.detach(key), Some(42));
490    /// assert_eq!(sm.get(key), None);
491    /// sm.reattach(key, 100);
492    /// assert_eq!(sm.get(key), Some(&100));
493    /// ```
494    pub fn detach(&mut self, key: K) -> Option<V> {
495        let kd = key.data();
496        if self.contains_key(key) {
497            unsafe {
498                // Remove value from slot before overwriting union.
499                let slot = self.slots.get_unchecked_mut(kd.idx as usize);
500                let value = ManuallyDrop::take(&mut slot.u.value);
501
502                // Don't add slot to freelist, mark it as detached.
503                slot.u.next_free = u32::MAX;
504                slot.version = slot.version.wrapping_add(1);
505                self.num_elems -= 1;
506                Some(value)
507            }
508        } else {
509            None
510        }
511    }
512
513    /// Reattaches a previously detached key with a new value. See
514    /// [`detach`](Self::detach) for details.
515    ///
516    /// # Panics
517    ///
518    /// Panics if the key is not detached.
519    ///
520    /// # Examples
521    /// ```
522    /// # use slotmap::*;
523    /// let mut sm = SlotMap::new();
524    /// let key = sm.insert(42);
525    /// assert_eq!(sm.detach(key), Some(42));
526    /// assert_eq!(sm.get(key), None);
527    /// sm.reattach(key, 100);
528    /// assert_eq!(sm.get(key), Some(&100));
529    /// ```
530    pub fn reattach(&mut self, detached_key: K, value: V) {
531        let kd = detached_key.data();
532        let slot = self
533            .slots
534            .get_mut(kd.idx as usize)
535            .filter(|slot| slot.version == kd.version.get().wrapping_add(1))
536            .filter(|slot| unsafe {
537                // SAFETY: we already implicitly checked just above that the
538                // version is even, meaning we are unoccupied.
539                slot.u.next_free == u32::MAX
540            })
541            .expect("key is not detached");
542
543        // Reattach the slot.
544        slot.u.value = ManuallyDrop::new(value);
545        slot.version = slot.version.wrapping_sub(1);
546        self.num_elems += 1;
547    }
548
549    /// Retains only the elements specified by the predicate.
550    ///
551    /// In other words, remove all key-value pairs `(k, v)` such that
552    /// `f(k, &mut v)` returns false. This method invalidates any removed keys.
553    ///
554    /// This function must iterate over all slots, empty or not. In the face of
555    /// many deleted elements it can be inefficient.
556    ///
557    /// # Examples
558    ///
559    /// ```
560    /// # use slotmap::*;
561    /// let mut sm = SlotMap::new();
562    ///
563    /// let k1 = sm.insert(0);
564    /// let k2 = sm.insert(1);
565    /// let k3 = sm.insert(2);
566    ///
567    /// sm.retain(|key, val| key == k1 || *val == 1);
568    ///
569    /// assert!(sm.contains_key(k1));
570    /// assert!(sm.contains_key(k2));
571    /// assert!(!sm.contains_key(k3));
572    ///
573    /// assert_eq!(2, sm.len());
574    /// ```
575    pub fn retain<F>(&mut self, mut f: F)
576    where
577        F: FnMut(K, &mut V) -> bool,
578    {
579        for i in 1..self.slots.len() {
580            // This is safe because removing elements does not shrink slots.
581            let slot = unsafe { self.slots.get_unchecked_mut(i) };
582            let version = slot.version;
583
584            let should_remove = if let OccupiedMut(value) = slot.get_mut() {
585                let key = KeyData::new(i as u32, version).into();
586                !f(key, value)
587            } else {
588                false
589            };
590
591            if should_remove {
592                // This is safe because we know that the slot was occupied.
593                unsafe { self.remove_from_slot(i) };
594            }
595        }
596    }
597
598    /// Clears the slot map. Keeps the allocated memory for reuse.
599    ///
600    /// This function must iterate over all slots, empty or not. In the face of
601    /// many deleted elements it can be inefficient.
602    ///
603    /// # Examples
604    ///
605    /// ```
606    /// # use slotmap::*;
607    /// let mut sm = SlotMap::new();
608    /// for i in 0..10 {
609    ///     sm.insert(i);
610    /// }
611    /// assert_eq!(sm.len(), 10);
612    /// sm.clear();
613    /// assert_eq!(sm.len(), 0);
614    /// ```
615    pub fn clear(&mut self) {
616        self.drain();
617    }
618
619    /// Clears the slot map, returning all key-value pairs in an arbitrary order
620    /// as an iterator. Keeps the allocated memory for reuse.
621    ///
622    /// When the iterator is dropped all elements in the slot map are removed,
623    /// even if the iterator was not fully consumed. If the iterator is not
624    /// dropped (using e.g. [`std::mem::forget`]), only the elements that were
625    /// iterated over are removed.
626    ///
627    /// This function must iterate over all slots, empty or not. In the face of
628    /// many deleted elements it can be inefficient.
629    ///
630    /// # Examples
631    ///
632    /// ```
633    /// # use slotmap::*;
634    /// let mut sm = SlotMap::new();
635    /// let k = sm.insert(0);
636    /// let v: Vec<_> = sm.drain().collect();
637    /// assert_eq!(sm.len(), 0);
638    /// assert_eq!(v, vec![(k, 0)]);
639    /// ```
640    pub fn drain(&mut self) -> Drain<'_, K, V> {
641        Drain { cur: 1, sm: self }
642    }
643
644    /// Returns a reference to the value corresponding to the key.
645    ///
646    /// # Examples
647    ///
648    /// ```
649    /// # use slotmap::*;
650    /// let mut sm = SlotMap::new();
651    /// let key = sm.insert("bar");
652    /// assert_eq!(sm.get(key), Some(&"bar"));
653    /// sm.remove(key);
654    /// assert_eq!(sm.get(key), None);
655    /// ```
656    pub fn get(&self, key: K) -> Option<&V> {
657        let kd = key.data();
658        self.slots
659            .get(kd.idx as usize)
660            .filter(|slot| slot.version == kd.version.get())
661            .map(|slot| unsafe { &*slot.u.value })
662    }
663
664    /// Returns a reference to the value corresponding to the key without
665    /// version or bounds checking.
666    ///
667    /// # Safety
668    ///
669    /// This should only be used if `contains_key(key)` is true. Otherwise it is
670    /// potentially unsafe.
671    ///
672    /// # Examples
673    ///
674    /// ```
675    /// # use slotmap::*;
676    /// let mut sm = SlotMap::new();
677    /// let key = sm.insert("bar");
678    /// assert_eq!(unsafe { sm.get_unchecked(key) }, &"bar");
679    /// sm.remove(key);
680    /// // sm.get_unchecked(key) is now dangerous!
681    /// ```
682    pub unsafe fn get_unchecked(&self, key: K) -> &V {
683        debug_assert!(self.contains_key(key));
684        &self.slots.get_unchecked(key.data().idx as usize).u.value
685    }
686
687    /// Returns a mutable reference to the value corresponding to the key.
688    ///
689    /// # Examples
690    ///
691    /// ```
692    /// # use slotmap::*;
693    /// let mut sm = SlotMap::new();
694    /// let key = sm.insert(3.5);
695    /// if let Some(x) = sm.get_mut(key) {
696    ///     *x += 3.0;
697    /// }
698    /// assert_eq!(sm[key], 6.5);
699    /// ```
700    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
701        let kd = key.data();
702        self.slots
703            .get_mut(kd.idx as usize)
704            .filter(|slot| slot.version == kd.version.get())
705            .map(|slot| unsafe { &mut *slot.u.value })
706    }
707
708    /// Returns a mutable reference to the value corresponding to the key
709    /// without version or bounds checking.
710    ///
711    /// # Safety
712    ///
713    /// This should only be used if `contains_key(key)` is true. Otherwise it is
714    /// potentially unsafe.
715    ///
716    /// # Examples
717    ///
718    /// ```
719    /// # use slotmap::*;
720    /// let mut sm = SlotMap::new();
721    /// let key = sm.insert("foo");
722    /// unsafe { *sm.get_unchecked_mut(key) = "bar" };
723    /// assert_eq!(sm[key], "bar");
724    /// sm.remove(key);
725    /// // sm.get_unchecked_mut(key) is now dangerous!
726    /// ```
727    pub unsafe fn get_unchecked_mut(&mut self, key: K) -> &mut V {
728        debug_assert!(self.contains_key(key));
729        &mut self
730            .slots
731            .get_unchecked_mut(key.data().idx as usize)
732            .u
733            .value
734    }
735
736    /// Returns mutable references to the values corresponding to the given
737    /// keys. All keys must be valid and disjoint, otherwise None is returned.
738    ///
739    /// Requires at least stable Rust version 1.51.
740    ///
741    /// # Examples
742    ///
743    /// ```
744    /// # use slotmap::*;
745    /// let mut sm = SlotMap::new();
746    /// let ka = sm.insert("butter");
747    /// let kb = sm.insert("apples");
748    /// let kc = sm.insert("charlie");
749    /// sm.remove(kc); // Make key c invalid.
750    /// assert_eq!(sm.get_disjoint_mut([ka, kb, kc]), None); // Has invalid key.
751    /// assert_eq!(sm.get_disjoint_mut([ka, ka]), None); // Not disjoint.
752    /// let [a, b] = sm.get_disjoint_mut([ka, kb]).unwrap();
753    /// std::mem::swap(a, b);
754    /// assert_eq!(sm[ka], "apples");
755    /// assert_eq!(sm[kb], "butter");
756    /// ```
757    pub fn get_disjoint_mut<const N: usize>(&mut self, keys: [K; N]) -> Option<[&mut V; N]> {
758        let mut ptrs: [MaybeUninit<*mut V>; N] = [(); N].map(|_| MaybeUninit::uninit());
759        let slots_ptr = self.slots.as_mut_ptr();
760
761        let mut i = 0;
762        while i < N {
763            let kd = keys[i].data();
764            if !self.contains_key(kd.into()) {
765                break;
766            }
767
768            // This key is valid, and thus the slot is occupied. Temporarily
769            // mark it as unoccupied so duplicate keys would show up as invalid.
770            // This gives us a linear time disjointness check.
771            unsafe {
772                let slot = &mut *slots_ptr.add(kd.idx as usize);
773                slot.version ^= 1;
774                ptrs[i] = MaybeUninit::new(&mut *slot.u.value);
775            }
776            i += 1;
777        }
778
779        // Undo temporary unoccupied markings.
780        for k in &keys[..i] {
781            let idx = k.data().idx as usize;
782            unsafe {
783                (*slots_ptr.add(idx)).version ^= 1;
784            }
785        }
786
787        if i == N {
788            // All were valid and disjoint.
789            Some(ptrs.map(|p| unsafe { &mut *p.assume_init() }))
790        } else {
791            None
792        }
793    }
794
795    /// Returns mutable references to the values corresponding to the given
796    /// keys. All keys must be valid and disjoint.
797    ///
798    /// Requires at least stable Rust version 1.51.
799    ///
800    /// # Safety
801    ///
802    /// This should only be used if `contains_key(key)` is true for every given
803    /// key and no two keys are equal. Otherwise it is potentially unsafe.
804    ///
805    /// # Examples
806    ///
807    /// ```
808    /// # use slotmap::*;
809    /// let mut sm = SlotMap::new();
810    /// let ka = sm.insert("butter");
811    /// let kb = sm.insert("apples");
812    /// let [a, b] = unsafe { sm.get_disjoint_unchecked_mut([ka, kb]) };
813    /// std::mem::swap(a, b);
814    /// assert_eq!(sm[ka], "apples");
815    /// assert_eq!(sm[kb], "butter");
816    /// ```
817    pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(
818        &mut self,
819        keys: [K; N],
820    ) -> [&mut V; N] {
821        let slots_ptr = self.slots.as_mut_ptr();
822        keys.map(|k| unsafe {
823            let slot = &mut *slots_ptr.add(k.data().idx as usize);
824            &mut *slot.u.value
825        })
826    }
827
828    /// An iterator visiting all key-value pairs in an arbitrary order. The
829    /// iterator element type is `(K, &'a V)`.
830    ///
831    /// This function must iterate over all slots, empty or not. In the face of
832    /// many deleted elements it can be inefficient.
833    ///
834    /// # Examples
835    ///
836    /// ```
837    /// # use slotmap::*;
838    /// let mut sm = SlotMap::new();
839    /// let k0 = sm.insert(0);
840    /// let k1 = sm.insert(1);
841    /// let k2 = sm.insert(2);
842    ///
843    /// for (k, v) in sm.iter() {
844    ///     println!("key: {:?}, val: {}", k, v);
845    /// }
846    /// ```
847    pub fn iter(&self) -> Iter<'_, K, V> {
848        let mut it = self.slots.iter().enumerate();
849        it.next(); // Skip sentinel.
850        Iter {
851            slots: it,
852            num_left: self.len(),
853            _k: PhantomData,
854        }
855    }
856
857    /// An iterator visiting all key-value pairs in an arbitrary order, with
858    /// mutable references to the values. The iterator element type is
859    /// `(K, &'a mut V)`.
860    ///
861    /// This function must iterate over all slots, empty or not. In the face of
862    /// many deleted elements it can be inefficient.
863    ///
864    /// # Examples
865    ///
866    /// ```
867    /// # use slotmap::*;
868    /// let mut sm = SlotMap::new();
869    /// let k0 = sm.insert(10);
870    /// let k1 = sm.insert(20);
871    /// let k2 = sm.insert(30);
872    ///
873    /// for (k, v) in sm.iter_mut() {
874    ///     if k != k1 {
875    ///         *v *= -1;
876    ///     }
877    /// }
878    ///
879    /// assert_eq!(sm[k0], -10);
880    /// assert_eq!(sm[k1], 20);
881    /// assert_eq!(sm[k2], -30);
882    /// ```
883    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
884        let len = self.len();
885        let mut it = self.slots.iter_mut().enumerate();
886        it.next(); // Skip sentinel.
887        IterMut {
888            num_left: len,
889            slots: it,
890            _k: PhantomData,
891        }
892    }
893
894    /// An iterator visiting all keys in an arbitrary order. The iterator
895    /// element type is `K`.
896    ///
897    /// This function must iterate over all slots, empty or not. In the face of
898    /// many deleted elements it can be inefficient.
899    ///
900    /// # Examples
901    ///
902    /// ```
903    /// # use slotmap::*;
904    /// # use std::collections::HashSet;
905    /// let mut sm = SlotMap::new();
906    /// let k0 = sm.insert(10);
907    /// let k1 = sm.insert(20);
908    /// let k2 = sm.insert(30);
909    /// let keys: HashSet<_> = sm.keys().collect();
910    /// let check: HashSet<_> = vec![k0, k1, k2].into_iter().collect();
911    /// assert_eq!(keys, check);
912    /// ```
913    pub fn keys(&self) -> Keys<'_, K, V> {
914        Keys { inner: self.iter() }
915    }
916
917    /// An iterator visiting all values in an arbitrary order. The iterator
918    /// element type is `&'a V`.
919    ///
920    /// This function must iterate over all slots, empty or not. In the face of
921    /// many deleted elements it can be inefficient.
922    ///
923    /// # Examples
924    ///
925    /// ```
926    /// # use slotmap::*;
927    /// # use std::collections::HashSet;
928    /// let mut sm = SlotMap::new();
929    /// let k0 = sm.insert(10);
930    /// let k1 = sm.insert(20);
931    /// let k2 = sm.insert(30);
932    /// let values: HashSet<_> = sm.values().collect();
933    /// let check: HashSet<_> = vec![&10, &20, &30].into_iter().collect();
934    /// assert_eq!(values, check);
935    /// ```
936    pub fn values(&self) -> Values<'_, K, V> {
937        Values { inner: self.iter() }
938    }
939
940    /// An iterator visiting all values mutably in an arbitrary order. The
941    /// iterator element type is `&'a mut V`.
942    ///
943    /// This function must iterate over all slots, empty or not. In the face of
944    /// many deleted elements it can be inefficient.
945    ///
946    /// # Examples
947    ///
948    /// ```
949    /// # use slotmap::*;
950    /// # use std::collections::HashSet;
951    /// let mut sm = SlotMap::new();
952    /// sm.insert(1);
953    /// sm.insert(2);
954    /// sm.insert(3);
955    /// sm.values_mut().for_each(|n| { *n *= 3 });
956    /// let values: HashSet<_> = sm.into_iter().map(|(_k, v)| v).collect();
957    /// let check: HashSet<_> = vec![3, 6, 9].into_iter().collect();
958    /// assert_eq!(values, check);
959    /// ```
960    pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
961        ValuesMut {
962            inner: self.iter_mut(),
963        }
964    }
965}
966
967impl<K: Key, V> Clone for SlotMap<K, V>
968where
969    V: Clone,
970{
971    fn clone(&self) -> Self {
972        Self {
973            slots: self.slots.clone(),
974            ..*self
975        }
976    }
977
978    fn clone_from(&mut self, source: &Self) {
979        // There is no way to recover from a botched clone of slots due to a
980        // panic. So we abort by double-panicking.
981        let guard = PanicOnDrop("abort - a panic during SlotMap::clone_from is unrecoverable");
982        self.slots.clone_from(&source.slots);
983        self.free_head = source.free_head;
984        self.num_elems = source.num_elems;
985        core::mem::forget(guard);
986    }
987}
988
989impl<K: Key, V> Default for SlotMap<K, V> {
990    fn default() -> Self {
991        Self::with_key()
992    }
993}
994
995impl<K: Key, V> Index<K> for SlotMap<K, V> {
996    type Output = V;
997
998    fn index(&self, key: K) -> &V {
999        match self.get(key) {
1000            Some(r) => r,
1001            None => panic!("invalid SlotMap key used"),
1002        }
1003    }
1004}
1005
1006impl<K: Key, V> IndexMut<K> for SlotMap<K, V> {
1007    fn index_mut(&mut self, key: K) -> &mut V {
1008        match self.get_mut(key) {
1009            Some(r) => r,
1010            None => panic!("invalid SlotMap key used"),
1011        }
1012    }
1013}
1014
1015// Iterators.
1016/// A draining iterator for [`SlotMap`].
1017///
1018/// This iterator is created by [`SlotMap::drain`].
1019#[derive(Debug)]
1020pub struct Drain<'a, K: 'a + Key, V: 'a> {
1021    sm: &'a mut SlotMap<K, V>,
1022    cur: usize,
1023}
1024
1025/// An iterator that moves key-value pairs out of a [`SlotMap`].
1026///
1027/// This iterator is created by calling the `into_iter` method on [`SlotMap`],
1028/// provided by the [`IntoIterator`] trait.
1029#[derive(Debug, Clone)]
1030pub struct IntoIter<K: Key, V> {
1031    num_left: usize,
1032    slots: Enumerate<alloc::vec::IntoIter<Slot<V>>>,
1033    _k: PhantomData<fn(K) -> K>,
1034}
1035
1036/// An iterator over the key-value pairs in a [`SlotMap`].
1037///
1038/// This iterator is created by [`SlotMap::iter`].
1039#[derive(Debug)]
1040pub struct Iter<'a, K: 'a + Key, V: 'a> {
1041    num_left: usize,
1042    slots: Enumerate<core::slice::Iter<'a, Slot<V>>>,
1043    _k: PhantomData<fn(K) -> K>,
1044}
1045
1046impl<'a, K: 'a + Key, V: 'a> Clone for Iter<'a, K, V> {
1047    fn clone(&self) -> Self {
1048        Iter {
1049            num_left: self.num_left,
1050            slots: self.slots.clone(),
1051            _k: self._k,
1052        }
1053    }
1054}
1055
1056/// A mutable iterator over the key-value pairs in a [`SlotMap`].
1057///
1058/// This iterator is created by [`SlotMap::iter_mut`].
1059#[derive(Debug)]
1060pub struct IterMut<'a, K: 'a + Key, V: 'a> {
1061    num_left: usize,
1062    slots: Enumerate<core::slice::IterMut<'a, Slot<V>>>,
1063    _k: PhantomData<fn(K) -> K>,
1064}
1065
1066/// An iterator over the keys in a [`SlotMap`].
1067///
1068/// This iterator is created by [`SlotMap::keys`].
1069#[derive(Debug)]
1070pub struct Keys<'a, K: 'a + Key, V: 'a> {
1071    inner: Iter<'a, K, V>,
1072}
1073
1074impl<'a, K: 'a + Key, V: 'a> Clone for Keys<'a, K, V> {
1075    fn clone(&self) -> Self {
1076        Keys {
1077            inner: self.inner.clone(),
1078        }
1079    }
1080}
1081
1082/// An iterator over the values in a [`SlotMap`].
1083///
1084/// This iterator is created by [`SlotMap::values`].
1085#[derive(Debug)]
1086pub struct Values<'a, K: 'a + Key, V: 'a> {
1087    inner: Iter<'a, K, V>,
1088}
1089
1090impl<'a, K: 'a + Key, V: 'a> Clone for Values<'a, K, V> {
1091    fn clone(&self) -> Self {
1092        Values {
1093            inner: self.inner.clone(),
1094        }
1095    }
1096}
1097
1098/// A mutable iterator over the values in a [`SlotMap`].
1099///
1100/// This iterator is created by [`SlotMap::values_mut`].
1101#[derive(Debug)]
1102pub struct ValuesMut<'a, K: 'a + Key, V: 'a> {
1103    inner: IterMut<'a, K, V>,
1104}
1105
1106impl<'a, K: Key, V> Iterator for Drain<'a, K, V> {
1107    type Item = (K, V);
1108
1109    fn next(&mut self) -> Option<(K, V)> {
1110        let len = self.sm.slots.len();
1111        while self.cur < len {
1112            let idx = self.cur;
1113            self.cur += 1;
1114
1115            // This is safe because removing doesn't shrink slots.
1116            unsafe {
1117                let slot = self.sm.slots.get_unchecked(idx);
1118                if slot.occupied() {
1119                    let kd = KeyData::new(idx as u32, slot.version);
1120                    return Some((kd.into(), self.sm.remove_from_slot(idx)));
1121                }
1122            }
1123        }
1124
1125        None
1126    }
1127
1128    fn size_hint(&self) -> (usize, Option<usize>) {
1129        (self.sm.len(), Some(self.sm.len()))
1130    }
1131}
1132
1133impl<'a, K: Key, V> Drop for Drain<'a, K, V> {
1134    fn drop(&mut self) {
1135        self.for_each(|_drop| {});
1136    }
1137}
1138
1139impl<K: Key, V> Iterator for IntoIter<K, V> {
1140    type Item = (K, V);
1141
1142    fn next(&mut self) -> Option<(K, V)> {
1143        while let Some((idx, mut slot)) = self.slots.next() {
1144            if slot.occupied() {
1145                let kd = KeyData::new(idx as u32, slot.version);
1146
1147                // Prevent dropping after extracting the value.
1148                slot.version = 0;
1149
1150                // This is safe because we know the slot was occupied.
1151                let value = unsafe { ManuallyDrop::take(&mut slot.u.value) };
1152
1153                self.num_left -= 1;
1154                return Some((kd.into(), value));
1155            }
1156        }
1157
1158        None
1159    }
1160
1161    fn size_hint(&self) -> (usize, Option<usize>) {
1162        (self.num_left, Some(self.num_left))
1163    }
1164}
1165
1166impl<'a, K: Key, V> Iterator for Iter<'a, K, V> {
1167    type Item = (K, &'a V);
1168
1169    fn next(&mut self) -> Option<(K, &'a V)> {
1170        while let Some((idx, slot)) = self.slots.next() {
1171            if let Occupied(value) = slot.get() {
1172                let kd = KeyData::new(idx as u32, slot.version);
1173                self.num_left -= 1;
1174                return Some((kd.into(), value));
1175            }
1176        }
1177
1178        None
1179    }
1180
1181    fn size_hint(&self) -> (usize, Option<usize>) {
1182        (self.num_left, Some(self.num_left))
1183    }
1184}
1185
1186impl<'a, K: Key, V> Iterator for IterMut<'a, K, V> {
1187    type Item = (K, &'a mut V);
1188
1189    fn next(&mut self) -> Option<(K, &'a mut V)> {
1190        for (idx, slot) in self.slots.by_ref() {
1191            let version = slot.version;
1192            if let OccupiedMut(value) = slot.get_mut() {
1193                let kd = KeyData::new(idx as u32, version);
1194                self.num_left -= 1;
1195                return Some((kd.into(), value));
1196            }
1197        }
1198
1199        None
1200    }
1201
1202    fn size_hint(&self) -> (usize, Option<usize>) {
1203        (self.num_left, Some(self.num_left))
1204    }
1205}
1206
1207impl<'a, K: Key, V> Iterator for Keys<'a, K, V> {
1208    type Item = K;
1209
1210    fn next(&mut self) -> Option<K> {
1211        self.inner.next().map(|(key, _)| key)
1212    }
1213
1214    fn size_hint(&self) -> (usize, Option<usize>) {
1215        self.inner.size_hint()
1216    }
1217}
1218
1219impl<'a, K: Key, V> Iterator for Values<'a, K, V> {
1220    type Item = &'a V;
1221
1222    fn next(&mut self) -> Option<&'a V> {
1223        self.inner.next().map(|(_, value)| value)
1224    }
1225
1226    fn size_hint(&self) -> (usize, Option<usize>) {
1227        self.inner.size_hint()
1228    }
1229}
1230
1231impl<'a, K: Key, V> Iterator for ValuesMut<'a, K, V> {
1232    type Item = &'a mut V;
1233
1234    fn next(&mut self) -> Option<&'a mut V> {
1235        self.inner.next().map(|(_, value)| value)
1236    }
1237
1238    fn size_hint(&self) -> (usize, Option<usize>) {
1239        self.inner.size_hint()
1240    }
1241}
1242
1243impl<'a, K: Key, V> IntoIterator for &'a SlotMap<K, V> {
1244    type Item = (K, &'a V);
1245    type IntoIter = Iter<'a, K, V>;
1246
1247    fn into_iter(self) -> Self::IntoIter {
1248        self.iter()
1249    }
1250}
1251
1252impl<'a, K: Key, V> IntoIterator for &'a mut SlotMap<K, V> {
1253    type Item = (K, &'a mut V);
1254    type IntoIter = IterMut<'a, K, V>;
1255
1256    fn into_iter(self) -> Self::IntoIter {
1257        self.iter_mut()
1258    }
1259}
1260
1261impl<K: Key, V> IntoIterator for SlotMap<K, V> {
1262    type Item = (K, V);
1263    type IntoIter = IntoIter<K, V>;
1264
1265    fn into_iter(self) -> Self::IntoIter {
1266        let len = self.len();
1267        let mut it = self.slots.into_iter().enumerate();
1268        it.next(); // Skip sentinel.
1269        IntoIter {
1270            num_left: len,
1271            slots: it,
1272            _k: PhantomData,
1273        }
1274    }
1275}
1276
1277impl<'a, K: Key, V> FusedIterator for Iter<'a, K, V> {}
1278impl<'a, K: Key, V> FusedIterator for IterMut<'a, K, V> {}
1279impl<'a, K: Key, V> FusedIterator for Keys<'a, K, V> {}
1280impl<'a, K: Key, V> FusedIterator for Values<'a, K, V> {}
1281impl<'a, K: Key, V> FusedIterator for ValuesMut<'a, K, V> {}
1282impl<'a, K: Key, V> FusedIterator for Drain<'a, K, V> {}
1283impl<K: Key, V> FusedIterator for IntoIter<K, V> {}
1284
1285impl<'a, K: Key, V> ExactSizeIterator for Iter<'a, K, V> {}
1286impl<'a, K: Key, V> ExactSizeIterator for IterMut<'a, K, V> {}
1287impl<'a, K: Key, V> ExactSizeIterator for Keys<'a, K, V> {}
1288impl<'a, K: Key, V> ExactSizeIterator for Values<'a, K, V> {}
1289impl<'a, K: Key, V> ExactSizeIterator for ValuesMut<'a, K, V> {}
1290impl<'a, K: Key, V> ExactSizeIterator for Drain<'a, K, V> {}
1291impl<K: Key, V> ExactSizeIterator for IntoIter<K, V> {}
1292
1293// Serialization with serde.
1294#[cfg(feature = "serde")]
1295mod serialize {
1296    use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
1297
1298    use super::*;
1299
1300    #[derive(Serialize, Deserialize)]
1301    struct SerdeSlot<T> {
1302        value: Option<T>,
1303        version: u32,
1304    }
1305
1306    impl<T: Serialize> Serialize for Slot<T> {
1307        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1308        where
1309            S: Serializer,
1310        {
1311            let serde_slot = SerdeSlot {
1312                version: self.version,
1313                value: match self.get() {
1314                    Occupied(value) => Some(value),
1315                    Vacant(_) => None,
1316                },
1317            };
1318            serde_slot.serialize(serializer)
1319        }
1320    }
1321
1322    impl<'de, T> Deserialize<'de> for Slot<T>
1323    where
1324        T: Deserialize<'de>,
1325    {
1326        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1327        where
1328            D: Deserializer<'de>,
1329        {
1330            let serde_slot: SerdeSlot<T> = Deserialize::deserialize(deserializer)?;
1331            let occupied = serde_slot.version % 2 == 1;
1332            if occupied ^ serde_slot.value.is_some() {
1333                return Err(de::Error::custom("inconsistent occupation in Slot"));
1334            }
1335
1336            Ok(Self {
1337                u: match serde_slot.value {
1338                    Some(value) => SlotUnion {
1339                        value: ManuallyDrop::new(value),
1340                    },
1341                    None => SlotUnion { next_free: 0 },
1342                },
1343                version: serde_slot.version,
1344            })
1345        }
1346    }
1347
1348    impl<K: Key, V: Serialize> Serialize for SlotMap<K, V> {
1349        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1350        where
1351            S: Serializer,
1352        {
1353            self.slots.serialize(serializer)
1354        }
1355    }
1356
1357    impl<'de, K, V> Deserialize<'de> for SlotMap<K, V>
1358    where
1359        K: Key,
1360        V: Deserialize<'de>,
1361    {
1362        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1363        where
1364            D: Deserializer<'de>,
1365        {
1366            let mut slots: Vec<Slot<V>> = Deserialize::deserialize(deserializer)?;
1367            if slots.len() >= u32::MAX as usize {
1368                return Err(de::Error::custom("too many slots"));
1369            }
1370
1371            // Ensure the first slot exists and is empty for the sentinel.
1372            if slots.first().map_or(true, |slot| slot.version % 2 == 1) {
1373                return Err(de::Error::custom("first slot not empty"));
1374            }
1375
1376            slots[0].version = 0;
1377            slots[0].u.next_free = 0;
1378
1379            // We have our slots, rebuild freelist.
1380            let mut num_elems = 0;
1381            let mut next_free = slots.len();
1382            for (i, slot) in slots[1..].iter_mut().enumerate() {
1383                if slot.occupied() {
1384                    num_elems += 1;
1385                } else {
1386                    slot.u.next_free = next_free as u32;
1387                    next_free = i + 1;
1388                }
1389            }
1390
1391            Ok(Self {
1392                num_elems,
1393                slots,
1394                free_head: next_free as u32,
1395                _k: PhantomData,
1396            })
1397        }
1398    }
1399}
1400
1401#[cfg(test)]
1402mod tests {
1403    use std::collections::{HashMap, HashSet};
1404
1405    use quickcheck::quickcheck;
1406
1407    use super::*;
1408
1409    #[derive(Clone)]
1410    struct CountDrop<'a>(&'a std::cell::RefCell<usize>);
1411
1412    impl<'a> Drop for CountDrop<'a> {
1413        fn drop(&mut self) {
1414            *self.0.borrow_mut() += 1;
1415        }
1416    }
1417
1418    #[test]
1419    fn check_drops() {
1420        let drops = std::cell::RefCell::new(0usize);
1421
1422        {
1423            let mut clone = {
1424                // Insert 1000 items.
1425                let mut sm = SlotMap::new();
1426                let mut sm_keys = Vec::new();
1427                for _ in 0..1000 {
1428                    sm_keys.push(sm.insert(CountDrop(&drops)));
1429                }
1430
1431                // Remove even keys.
1432                for i in (0..1000).filter(|i| i % 2 == 0) {
1433                    sm.remove(sm_keys[i]);
1434                }
1435
1436                // Should only have dropped 500 so far.
1437                assert_eq!(*drops.borrow(), 500);
1438
1439                // Let's clone ourselves and then die.
1440                sm.clone()
1441            };
1442
1443            // Now all original items should have been dropped exactly once.
1444            assert_eq!(*drops.borrow(), 1000);
1445
1446            // Reuse some empty slots.
1447            for _ in 0..250 {
1448                clone.insert(CountDrop(&drops));
1449            }
1450        }
1451
1452        // 1000 + 750 drops in total should have happened.
1453        assert_eq!(*drops.borrow(), 1750);
1454    }
1455
1456    #[test]
1457    fn disjoint() {
1458        // Intended to be run with miri to find any potential UB.
1459        let mut sm = SlotMap::new();
1460
1461        // Some churn.
1462        for i in 0..20usize {
1463            sm.insert(i);
1464        }
1465        sm.retain(|_, i| *i % 2 == 0);
1466
1467        let keys: Vec<_> = sm.keys().collect();
1468        for i in 0..keys.len() {
1469            for j in 0..keys.len() {
1470                if let Some([r0, r1]) = sm.get_disjoint_mut([keys[i], keys[j]]) {
1471                    *r0 ^= *r1;
1472                    *r1 = r1.wrapping_add(*r0);
1473                } else {
1474                    assert!(i == j);
1475                }
1476            }
1477        }
1478
1479        for i in 0..keys.len() {
1480            for j in 0..keys.len() {
1481                for k in 0..keys.len() {
1482                    if let Some([r0, r1, r2]) = sm.get_disjoint_mut([keys[i], keys[j], keys[k]]) {
1483                        *r0 ^= *r1;
1484                        *r0 = r0.wrapping_add(*r2);
1485                        *r1 ^= *r0;
1486                        *r1 = r1.wrapping_add(*r2);
1487                        *r2 ^= *r0;
1488                        *r2 = r2.wrapping_add(*r1);
1489                    } else {
1490                        assert!(i == j || j == k || i == k);
1491                    }
1492                }
1493            }
1494        }
1495    }
1496
1497    quickcheck! {
1498        fn qc_slotmap_equiv_hashmap(operations: Vec<(u8, u32)>) -> bool {
1499            let mut hm = HashMap::new();
1500            let mut hm_keys = Vec::new();
1501            let mut unique_key = 0u32;
1502            let mut sm = SlotMap::new();
1503            let mut sm_keys = Vec::new();
1504
1505            #[cfg(not(feature = "serde"))]
1506            let num_ops = 3;
1507            #[cfg(feature = "serde")]
1508            let num_ops = 4;
1509
1510            for (op, val) in operations {
1511                match op % num_ops {
1512                    // Insert.
1513                    0 => {
1514                        hm.insert(unique_key, val);
1515                        hm_keys.push(unique_key);
1516                        unique_key += 1;
1517
1518                        sm_keys.push(sm.insert(val));
1519                    }
1520
1521                    // Delete.
1522                    1 => {
1523                        // 10% of the time test clear.
1524                        if val % 10 == 0 {
1525                            let hmvals: HashSet<_> = hm.drain().map(|(_, v)| v).collect();
1526                            let smvals: HashSet<_> = sm.drain().map(|(_, v)| v).collect();
1527                            if hmvals != smvals {
1528                                return false;
1529                            }
1530                        }
1531                        if hm_keys.is_empty() { continue; }
1532
1533                        let idx = val as usize % hm_keys.len();
1534                        if hm.remove(&hm_keys[idx]) != sm.remove(sm_keys[idx]) {
1535                            return false;
1536                        }
1537                    }
1538
1539                    // Access.
1540                    2 => {
1541                        if hm_keys.is_empty() { continue; }
1542                        let idx = val as usize % hm_keys.len();
1543                        let (hm_key, sm_key) = (&hm_keys[idx], sm_keys[idx]);
1544
1545                        if hm.contains_key(hm_key) != sm.contains_key(sm_key) ||
1546                           hm.get(hm_key) != sm.get(sm_key) {
1547                            return false;
1548                        }
1549                    }
1550
1551                    // Serde round-trip.
1552                    #[cfg(feature = "serde")]
1553                    3 => {
1554                        let ser = serde_json::to_string(&sm).unwrap();
1555                        sm = serde_json::from_str(&ser).unwrap();
1556                    }
1557
1558                    _ => unreachable!(),
1559                }
1560            }
1561
1562            let mut smv: Vec<_> = sm.values().collect();
1563            let mut hmv: Vec<_> = hm.values().collect();
1564            smv.sort();
1565            hmv.sort();
1566            smv == hmv
1567        }
1568    }
1569
1570    #[cfg(feature = "serde")]
1571    #[test]
1572    fn slotmap_serde() {
1573        let mut sm = SlotMap::new();
1574        // Self-referential structure.
1575        let first = sm.insert_with_key(|k| (k, 23i32));
1576        let second = sm.insert((first, 42));
1577
1578        // Make some empty slots.
1579        let empties = vec![sm.insert((first, 0)), sm.insert((first, 0))];
1580        empties.iter().for_each(|k| {
1581            sm.remove(*k);
1582        });
1583
1584        let third = sm.insert((second, 0));
1585        sm[first].0 = third;
1586
1587        let ser = serde_json::to_string(&sm).unwrap();
1588        let de: SlotMap<DefaultKey, (DefaultKey, i32)> = serde_json::from_str(&ser).unwrap();
1589        assert_eq!(de.len(), sm.len());
1590
1591        let mut smkv: Vec<_> = sm.iter().collect();
1592        let mut dekv: Vec<_> = de.iter().collect();
1593        smkv.sort();
1594        dekv.sort();
1595        assert_eq!(smkv, dekv);
1596    }
1597
1598    #[cfg(feature = "serde")]
1599    #[test]
1600    fn slotmap_serde_freelist() {
1601        let mut sm = SlotMap::new();
1602        let k = sm.insert(5i32);
1603        sm.remove(k);
1604
1605        let ser = serde_json::to_string(&sm).unwrap();
1606        let mut de: SlotMap<DefaultKey, i32> = serde_json::from_str(&ser).unwrap();
1607
1608        de.insert(0);
1609        de.insert(1);
1610        de.insert(2);
1611        assert_eq!(de.len(), 3);
1612    }
1613}