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