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