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}