slotmap_map/
sparse_secondary.rs

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