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