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