[go: up one dir, main page]

slotmap/
hop.rs

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