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