slotmap_map/
secondary.rs

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