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