slotmap_map/
basic.rs

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