1 use std::convert::TryInto;
2 use std::mem::replace;
3 use std::ops;
4 
5 use crate::drain::Drain;
6 use crate::free_pointer::FreePointer;
7 use crate::generation::Generation;
8 use crate::into_iter::IntoIter;
9 use crate::iter::Iter;
10 use crate::iter_mut::IterMut;
11 
12 /// Container that can have elements inserted into it and removed from it.
13 ///
14 /// Indices use the [`Index`] type, created by inserting values with [`Arena::insert`].
15 #[derive(Debug, Clone)]
16 pub struct Arena<T> {
17     storage: Vec<Entry<T>>,
18     len: u32,
19     first_free: Option<FreePointer>,
20 }
21 
22 /// Index type for [`Arena`] that has a generation attached to it.
23 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
24 pub struct Index {
25     pub(crate) slot: u32,
26     pub(crate) generation: Generation,
27 }
28 
29 impl Index {
30     /// Convert this `Index` to an equivalent `u64` representation. Mostly
31     /// useful for passing to code outside of Rust.
32     #[allow(clippy::integer_arithmetic)]
to_bits(self) -> u6433     pub fn to_bits(self) -> u64 {
34         // This is safe because a `u32` bit-shifted by 32 will still fit in a `u64`.
35         ((self.generation.to_u32() as u64) << 32) | (self.slot as u64)
36     }
37 
38     /// Convert back from a value generated with `Index::to_bits`. Don't call
39     /// this with arbitrary inputs; you'll almost certainly just get invalid
40     /// and/or malformed indices.
41     ///
42     /// If fed an index which was not generated by thunderdome or even just run
43     /// `Index::from_bits(0)`, this function may panic!
44     #[allow(clippy::integer_arithmetic)]
from_bits(bits: u64) -> Self45     pub fn from_bits(bits: u64) -> Self {
46         // By bit-shifting right by 32, we're undoing the left-shift in `to_bits`
47         // thus this is okay by the same rationale.
48         let generation = Generation::from_u32((bits >> 32) as u32);
49         let slot = bits as u32;
50 
51         Self { generation, slot }
52     }
53 
54     /// Convert this `Index` into a slot, discarding its generation. Slots describe a
55     /// location in an [`Arena`] and are reused when entries are removed.
slot(self) -> u3256     pub fn slot(self) -> u32 {
57         self.slot
58     }
59 }
60 
61 #[derive(Debug, Clone)]
62 pub(crate) enum Entry<T> {
63     Occupied(OccupiedEntry<T>),
64     Empty(EmptyEntry),
65 }
66 
67 impl<T> Entry<T> {
68     /// Consume the entry, and if it's occupied, return the value.
into_value(self) -> Option<T>69     fn into_value(self) -> Option<T> {
70         match self {
71             Entry::Occupied(occupied) => Some(occupied.value),
72             Entry::Empty(_) => None,
73         }
74     }
75 
76     /// If the entry is empty, return a copy of the emptiness data.
get_empty(&self) -> Option<EmptyEntry>77     fn get_empty(&self) -> Option<EmptyEntry> {
78         match self {
79             Entry::Empty(empty) => Some(*empty),
80             Entry::Occupied(_) => None,
81         }
82     }
83 }
84 
85 #[derive(Debug, Clone)]
86 pub(crate) struct OccupiedEntry<T> {
87     pub(crate) generation: Generation,
88     pub(crate) value: T,
89 }
90 
91 #[derive(Debug, Clone, Copy)]
92 pub(crate) struct EmptyEntry {
93     pub(crate) generation: Generation,
94     pub(crate) next_free: Option<FreePointer>,
95 }
96 
97 impl<T> Arena<T> {
98     /// Construct an empty arena.
new() -> Self99     pub fn new() -> Self {
100         Self {
101             storage: Vec::new(),
102             len: 0,
103             first_free: None,
104         }
105     }
106 
107     /// Construct an empty arena with space to hold exactly `capacity` elements
108     /// without reallocating.
with_capacity(capacity: usize) -> Self109     pub fn with_capacity(capacity: usize) -> Self {
110         Self {
111             storage: Vec::with_capacity(capacity),
112             len: 0,
113             first_free: None,
114         }
115     }
116 
117     /// Return the number of elements contained in the arena.
len(&self) -> usize118     pub fn len(&self) -> usize {
119         self.len as usize
120     }
121 
122     /// Return the number of elements the arena can hold without allocating,
123     /// including the elements currently in the arena.
capacity(&self) -> usize124     pub fn capacity(&self) -> usize {
125         self.storage.capacity()
126     }
127 
128     /// Returns whether the arena is empty.
is_empty(&self) -> bool129     pub fn is_empty(&self) -> bool {
130         self.len == 0
131     }
132 
133     /// Insert a new value into the arena, returning an index that can be used
134     /// to later retrieve the value.
insert(&mut self, value: T) -> Index135     pub fn insert(&mut self, value: T) -> Index {
136         // This value will definitely be inserted, so we can update length now.
137         self.len = self
138             .len
139             .checked_add(1)
140             .unwrap_or_else(|| panic!("Cannot insert more than u32::MAX elements into Arena"));
141 
142         // If there was a previously free entry, we can re-use its slot as long
143         // as we increment its generation.
144         if let Some(free_pointer) = self.first_free {
145             let slot = free_pointer.slot();
146             let entry = self.storage.get_mut(slot as usize).unwrap_or_else(|| {
147                 unreachable!("first_free pointed past the end of the arena's storage")
148             });
149 
150             let empty = entry
151                 .get_empty()
152                 .unwrap_or_else(|| unreachable!("first_free pointed to an occupied entry"));
153 
154             // If there is another empty entry after this one, we'll update the
155             // arena to point to it to use it on the next insertion.
156             self.first_free = empty.next_free;
157 
158             // Overwrite the entry directly using our mutable reference instead
159             // of indexing into our storage again. This should avoid an
160             // additional bounds check.
161             let generation = empty.generation.next();
162             *entry = Entry::Occupied(OccupiedEntry { generation, value });
163 
164             Index { slot, generation }
165         } else {
166             // There were no more empty entries left in our free list, so we'll
167             // create a new first-generation entry and push it into storage.
168 
169             let generation = Generation::first();
170             let slot: u32 = self.storage.len().try_into().unwrap_or_else(|_| {
171                 unreachable!("Arena storage exceeded what can be represented by a u32")
172             });
173 
174             self.storage
175                 .push(Entry::Occupied(OccupiedEntry { generation, value }));
176 
177             Index { slot, generation }
178         }
179     }
180 
181     /// Returns true if the given index is valid for the arena.
contains(&self, index: Index) -> bool182     pub fn contains(&self, index: Index) -> bool {
183         match self.storage.get(index.slot as usize) {
184             Some(Entry::Occupied(occupied)) if occupied.generation == index.generation => true,
185             _ => false,
186         }
187     }
188 
189     /// Checks to see whether a slot is occupied in the arena, and if it is,
190     /// returns `Some` with the true `Index` of that slot (slot plus generation.)
191     /// Otherwise, returns `None`.
contains_slot(&self, slot: u32) -> Option<Index>192     pub fn contains_slot(&self, slot: u32) -> Option<Index> {
193         match self.storage.get(slot as usize) {
194             Some(Entry::Occupied(occupied)) => Some(Index {
195                 slot,
196                 generation: occupied.generation,
197             }),
198             _ => None,
199         }
200     }
201 
202     /// Get an immutable reference to a value inside the arena by
203     /// [`Index`], returning `None` if the index is not contained in the arena.
get(&self, index: Index) -> Option<&T>204     pub fn get(&self, index: Index) -> Option<&T> {
205         match self.storage.get(index.slot as usize) {
206             Some(Entry::Occupied(occupied)) if occupied.generation == index.generation => {
207                 Some(&occupied.value)
208             }
209             _ => None,
210         }
211     }
212 
213     /// Get a mutable reference to a value inside the arena by [`Index`],
214     /// returning `None` if the index is not contained in the arena.
get_mut(&mut self, index: Index) -> Option<&mut T>215     pub fn get_mut(&mut self, index: Index) -> Option<&mut T> {
216         match self.storage.get_mut(index.slot as usize) {
217             Some(Entry::Occupied(occupied)) if occupied.generation == index.generation => {
218                 Some(&mut occupied.value)
219             }
220             _ => None,
221         }
222     }
223 
224     /// Get mutable references of two values inside this arena at once by
225     /// [`Index`], returning `None` if the corresponding `index` is not
226     /// contained in this arena.
227     ///
228     /// # Panics
229     ///
230     /// This function panics when the two indices are equal (having the same
231     /// slot number and generation).
get2_mut(&mut self, index1: Index, index2: Index) -> (Option<&mut T>, Option<&mut T>)232     pub fn get2_mut(&mut self, index1: Index, index2: Index) -> (Option<&mut T>, Option<&mut T>) {
233         if index1 == index2 {
234             panic!("Arena::get2_mut is called with two identical indices");
235         }
236 
237         // SAFETY NOTES:
238         //
239         // - If `index1` and `index2` have different slot number, `item1` and
240         //   `item2` would point to different elements.
241         // - If `index1` and `index2` have the same slot number, only one could
242         //   be valid because there is only one valid generation number.
243         // - If `index1` and `index2` have the same slot number and the same
244         //   generation, this function will panic.
245         //
246         // Since `Vec::get_mut` will not reallocate, we can safely cast
247         // a mutable reference to an element to a pointer and back and remain
248         // valid.
249 
250         // Hold the first value in a pointer to sidestep the borrow checker
251         let item1_ptr = self.get_mut(index1).map(|x| x as *mut T);
252 
253         let item2 = self.get_mut(index2);
254         let item1 = unsafe { item1_ptr.map(|x| &mut *x) };
255 
256         (item1, item2)
257     }
258 
259     /// Remove the value contained at the given index from the arena, returning
260     /// it if it was present.
remove(&mut self, index: Index) -> Option<T>261     pub fn remove(&mut self, index: Index) -> Option<T> {
262         let entry = self.storage.get_mut(index.slot as usize)?;
263 
264         match entry {
265             Entry::Occupied(occupied) if occupied.generation == index.generation => {
266                 // We can replace an occupied entry with an empty entry with the
267                 // same generation. On next insertion, this generation will
268                 // increment.
269                 let new_entry = Entry::Empty(EmptyEntry {
270                     generation: occupied.generation,
271                     next_free: self.first_free,
272                 });
273 
274                 // Swap our new entry into our storage and take ownership of the
275                 // old entry. We'll consume it for its value so we can give that
276                 // back to our caller.
277                 let old_entry = replace(entry, new_entry);
278                 let value = old_entry.into_value().unwrap_or_else(|| unreachable!());
279 
280                 // The next time we insert, we can re-use the empty entry we
281                 // just created. If another removal happens before then, that
282                 // entry will be used before this one (FILO).
283                 self.first_free = Some(FreePointer::from_slot(index.slot));
284 
285                 self.len = self.len.checked_sub(1).unwrap_or_else(|| unreachable!());
286 
287                 Some(value)
288             }
289             _ => None,
290         }
291     }
292 
293     /// Invalidate the given index and return a new index to the same value. This
294     /// is roughly equivalent to `remove` followed by `insert`, but much faster.
295     /// If the old index is already invalid, this method returns `None`.
invalidate(&mut self, index: Index) -> Option<Index>296     pub fn invalidate(&mut self, index: Index) -> Option<Index> {
297         let entry = self.storage.get_mut(index.slot as usize)?;
298 
299         match entry {
300             Entry::Occupied(occupied) if occupied.generation == index.generation => {
301                 occupied.generation = occupied.generation.next();
302 
303                 Some(Index {
304                     generation: occupied.generation,
305                     ..index
306                 })
307             }
308             _ => None,
309         }
310     }
311 
312     /// Attempt to look up the given slot in the arena, disregarding any generational
313     /// information, and retrieve an immutable reference to it. Returns `None` if the
314     /// slot is empty.
get_by_slot(&self, slot: u32) -> Option<(Index, &T)>315     pub fn get_by_slot(&self, slot: u32) -> Option<(Index, &T)> {
316         match self.storage.get(slot as usize) {
317             Some(Entry::Occupied(occupied)) => {
318                 let index = Index {
319                     slot,
320                     generation: occupied.generation,
321                 };
322                 Some((index, &occupied.value))
323             }
324             _ => None,
325         }
326     }
327 
328     /// Attempt to look up the given slot in the arena, disregarding any generational
329     /// information, and retrieve a mutable reference to it. Returns `None` if the
330     /// slot is empty.
get_by_slot_mut(&mut self, slot: u32) -> Option<(Index, &mut T)>331     pub fn get_by_slot_mut(&mut self, slot: u32) -> Option<(Index, &mut T)> {
332         match self.storage.get_mut(slot as usize) {
333             Some(Entry::Occupied(occupied)) => {
334                 let index = Index {
335                     slot,
336                     generation: occupied.generation,
337                 };
338                 Some((index, &mut occupied.value))
339             }
340             _ => None,
341         }
342     }
343 
344     /// Remove an entry in the arena by its slot, disregarding any generational info.
345     /// Returns `None` if the slot was already empty.
remove_by_slot(&mut self, slot: u32) -> Option<(Index, T)>346     pub fn remove_by_slot(&mut self, slot: u32) -> Option<(Index, T)> {
347         let entry = self.storage.get_mut(slot as usize)?;
348 
349         match entry {
350             Entry::Occupied(occupied) => {
351                 // Construct the index that would be used to access this entry.
352                 let index = Index {
353                     generation: occupied.generation,
354                     slot,
355                 };
356 
357                 // This occupied entry will be replaced with an empty one of the
358                 // same generation. Generation will be incremented on the next
359                 // insert.
360                 let next_entry = Entry::Empty(EmptyEntry {
361                     generation: occupied.generation,
362                     next_free: self.first_free,
363                 });
364 
365                 // Swap new entry into place and consume the old one.
366                 let old_entry = replace(entry, next_entry);
367                 let value = old_entry.into_value().unwrap_or_else(|| unreachable!());
368 
369                 // Set this entry as the next one that should be inserted into,
370                 // should an insertion happen.
371                 self.first_free = Some(FreePointer::from_slot(slot));
372 
373                 self.len = self.len.checked_sub(1).unwrap_or_else(|| unreachable!());
374 
375                 Some((index, value))
376             }
377             _ => None,
378         }
379     }
380 
381     /// Clear the arena and drop all elements.
clear(&mut self)382     pub fn clear(&mut self) {
383         self.drain().for_each(drop);
384     }
385 
386     /// Iterate over all of the indexes and values contained in the arena.
387     ///
388     /// Iteration order is not defined.
iter(&self) -> Iter<'_, T>389     pub fn iter(&self) -> Iter<'_, T> {
390         Iter {
391             inner: self.storage.iter().enumerate(),
392             len: self.len,
393         }
394     }
395 
396     /// Iterate over all of the indexes and values contained in the arena, with
397     /// mutable access to each value.
398     ///
399     /// Iteration order is not defined.
iter_mut(&mut self) -> IterMut<'_, T>400     pub fn iter_mut(&mut self) -> IterMut<'_, T> {
401         IterMut {
402             inner: self.storage.iter_mut().enumerate(),
403             len: self.len,
404         }
405     }
406 
407     /// Returns an iterator that removes each element from the arena.
408     ///
409     /// Iteration order is not defined.
410     ///
411     /// If the iterator is dropped before it is fully consumed, any uniterated
412     /// items will be dropped from the arena, and the arena will be empty.
413     /// The arena's capacity will not be changed.
drain(&mut self) -> Drain<'_, T>414     pub fn drain(&mut self) -> Drain<'_, T> {
415         Drain {
416             arena: self,
417             slot: 0,
418         }
419     }
420 
421     /// Remove all entries in the `Arena` which don't satisfy the provided predicate.
retain<F: FnMut(Index, &mut T) -> bool>(&mut self, mut f: F)422     pub fn retain<F: FnMut(Index, &mut T) -> bool>(&mut self, mut f: F) {
423         for (i, entry) in self.storage.iter_mut().enumerate() {
424             if let Entry::Occupied(occupied) = entry {
425                 let index = Index {
426                     slot: i as u32,
427                     generation: occupied.generation,
428                 };
429 
430                 if !f(index, &mut occupied.value) {
431                     // We can replace an occupied entry with an empty entry with the
432                     // same generation. On next insertion, this generation will
433                     // increment.
434                     *entry = Entry::Empty(EmptyEntry {
435                         generation: occupied.generation,
436                         next_free: self.first_free,
437                     });
438 
439                     // The next time we insert, we can re-use the empty entry we
440                     // just created. If another removal happens before then, that
441                     // entry will be used before this one (FILO).
442                     self.first_free = Some(FreePointer::from_slot(index.slot));
443 
444                     // We just verified that this entry is (was) occupied, so there's
445                     // trivially no way for this `checked_sub` to fail.
446                     self.len = self.len.checked_sub(1).unwrap_or_else(|| unreachable!());
447                 }
448             }
449         }
450     }
451 }
452 
453 impl<T> Default for Arena<T> {
default() -> Self454     fn default() -> Self {
455         Arena::new()
456     }
457 }
458 
459 impl<T> IntoIterator for Arena<T> {
460     type Item = (Index, T);
461     type IntoIter = IntoIter<T>;
462 
into_iter(self) -> Self::IntoIter463     fn into_iter(self) -> Self::IntoIter {
464         IntoIter {
465             arena: self,
466             slot: 0,
467         }
468     }
469 }
470 
471 impl<'a, T> IntoIterator for &'a Arena<T> {
472     type Item = (Index, &'a T);
473     type IntoIter = Iter<'a, T>;
474 
into_iter(self) -> Self::IntoIter475     fn into_iter(self) -> Self::IntoIter {
476         self.iter()
477     }
478 }
479 
480 impl<'a, T> IntoIterator for &'a mut Arena<T> {
481     type Item = (Index, &'a mut T);
482     type IntoIter = IterMut<'a, T>;
483 
into_iter(self) -> Self::IntoIter484     fn into_iter(self) -> Self::IntoIter {
485         self.iter_mut()
486     }
487 }
488 
489 impl<T> ops::Index<Index> for Arena<T> {
490     type Output = T;
491 
index(&self, index: Index) -> &Self::Output492     fn index(&self, index: Index) -> &Self::Output {
493         self.get(index)
494             .unwrap_or_else(|| panic!("No entry at index {:?}", index))
495     }
496 }
497 
498 impl<T> ops::IndexMut<Index> for Arena<T> {
index_mut(&mut self, index: Index) -> &mut Self::Output499     fn index_mut(&mut self, index: Index) -> &mut Self::Output {
500         self.get_mut(index)
501             .unwrap_or_else(|| panic!("No entry at index {:?}", index))
502     }
503 }
504 
505 #[cfg(test)]
506 mod test {
507     use super::{Arena, Index};
508 
509     use std::mem::size_of;
510 
511     #[test]
size_of_index()512     fn size_of_index() {
513         assert_eq!(size_of::<Index>(), 8);
514         assert_eq!(size_of::<Option<Index>>(), 8);
515     }
516 
517     #[test]
new()518     fn new() {
519         let arena: Arena<u32> = Arena::new();
520         assert_eq!(arena.len(), 0);
521         assert_eq!(arena.capacity(), 0);
522     }
523 
524     #[test]
with_capacity()525     fn with_capacity() {
526         let arena: Arena<u32> = Arena::with_capacity(8);
527         assert_eq!(arena.len(), 0);
528         assert_eq!(arena.capacity(), 8);
529     }
530 
531     #[test]
insert_and_get()532     fn insert_and_get() {
533         let mut arena = Arena::new();
534 
535         let one = arena.insert(1);
536         assert_eq!(arena.len(), 1);
537         assert_eq!(arena.get(one), Some(&1));
538 
539         let two = arena.insert(2);
540         assert_eq!(arena.len(), 2);
541         assert_eq!(arena.get(one), Some(&1));
542         assert_eq!(arena.get(two), Some(&2));
543     }
544 
545     #[test]
insert_remove_get()546     fn insert_remove_get() {
547         let mut arena = Arena::new();
548         let one = arena.insert(1);
549 
550         let two = arena.insert(2);
551         assert_eq!(arena.len(), 2);
552         assert!(arena.contains(two));
553         assert_eq!(arena.remove(two), Some(2));
554         assert!(!arena.contains(two));
555 
556         let three = arena.insert(3);
557         assert_eq!(arena.len(), 2);
558         assert_eq!(arena.get(one), Some(&1));
559         assert_eq!(arena.get(three), Some(&3));
560         assert_eq!(arena.get(two), None);
561     }
562 
563     #[test]
insert_remove_get_by_slot()564     fn insert_remove_get_by_slot() {
565         let mut arena = Arena::new();
566         let one = arena.insert(1);
567 
568         let two = arena.insert(2);
569         assert_eq!(arena.len(), 2);
570         assert!(arena.contains(two));
571         assert_eq!(arena.remove_by_slot(two.slot()), Some((two, 2)));
572         assert!(!arena.contains(two));
573         assert_eq!(arena.get_by_slot(two.slot()), None);
574 
575         let three = arena.insert(3);
576         assert_eq!(arena.len(), 2);
577         assert_eq!(arena.get(one), Some(&1));
578         assert_eq!(arena.get(three), Some(&3));
579         assert_eq!(arena.get(two), None);
580         assert_eq!(arena.get_by_slot(two.slot()), Some((three, &3)));
581     }
582 
583     #[test]
get_mut()584     fn get_mut() {
585         let mut arena = Arena::new();
586         let foo = arena.insert(5);
587 
588         let handle = arena.get_mut(foo).unwrap();
589         *handle = 6;
590 
591         assert_eq!(arena.get(foo), Some(&6));
592     }
593 
594     #[test]
get2_mut()595     fn get2_mut() {
596         let mut arena = Arena::new();
597         let foo = arena.insert(100);
598         let bar = arena.insert(500);
599 
600         let (foo_handle, bar_handle) = arena.get2_mut(foo, bar);
601         let foo_handle = foo_handle.unwrap();
602         let bar_handle = bar_handle.unwrap();
603         *foo_handle = 105;
604         *bar_handle = 505;
605 
606         assert_eq!(arena.get(foo), Some(&105));
607         assert_eq!(arena.get(bar), Some(&505));
608     }
609 
610     #[test]
get2_mut_reversed_order()611     fn get2_mut_reversed_order() {
612         let mut arena = Arena::new();
613         let foo = arena.insert(100);
614         let bar = arena.insert(500);
615 
616         let (bar_handle, foo_handle) = arena.get2_mut(bar, foo);
617         let foo_handle = foo_handle.unwrap();
618         let bar_handle = bar_handle.unwrap();
619         *foo_handle = 105;
620         *bar_handle = 505;
621 
622         assert_eq!(arena.get(foo), Some(&105));
623         assert_eq!(arena.get(bar), Some(&505));
624     }
625 
626     #[test]
get2_mut_non_exist_handle()627     fn get2_mut_non_exist_handle() {
628         let mut arena = Arena::new();
629         let foo = arena.insert(100);
630         let bar = arena.insert(500);
631         arena.remove(bar);
632 
633         let (bar_handle, foo_handle) = arena.get2_mut(bar, foo);
634         let foo_handle = foo_handle.unwrap();
635         assert!(bar_handle.is_none());
636         *foo_handle = 105;
637 
638         assert_eq!(arena.get(foo), Some(&105));
639     }
640 
641     #[test]
get2_mut_same_slot_different_generation()642     fn get2_mut_same_slot_different_generation() {
643         let mut arena = Arena::new();
644         let foo = arena.insert(100);
645         let mut foo1 = foo;
646         foo1.generation = foo1.generation.next();
647 
648         let (foo_handle, foo1_handle) = arena.get2_mut(foo, foo1);
649         assert!(foo_handle.is_some());
650         assert!(foo1_handle.is_none());
651     }
652 
653     #[test]
654     #[should_panic]
get2_mut_panics()655     fn get2_mut_panics() {
656         let mut arena = Arena::new();
657         let foo = arena.insert(100);
658 
659         arena.get2_mut(foo, foo);
660     }
661 
662     #[test]
insert_remove_insert_capacity()663     fn insert_remove_insert_capacity() {
664         let mut arena = Arena::with_capacity(2);
665         assert_eq!(arena.capacity(), 2);
666 
667         let a = arena.insert("a");
668         let b = arena.insert("b");
669         assert_eq!(arena.len(), 2);
670         assert_eq!(arena.capacity(), 2);
671 
672         arena.remove(a);
673         arena.remove(b);
674         assert_eq!(arena.len(), 0);
675         assert_eq!(arena.capacity(), 2);
676 
677         let _a2 = arena.insert("a2");
678         let _b2 = arena.insert("b2");
679         assert_eq!(arena.len(), 2);
680         assert_eq!(arena.capacity(), 2);
681     }
682 
683     #[test]
invalidate()684     fn invalidate() {
685         let mut arena = Arena::new();
686 
687         let a = arena.insert("a");
688         assert_eq!(arena.get(a), Some(&"a"));
689 
690         let new_a = arena.invalidate(a).unwrap();
691         assert_eq!(arena.get(a), None);
692         assert_eq!(arena.get(new_a), Some(&"a"));
693     }
694 
695     #[test]
retain()696     fn retain() {
697         let mut arena = Arena::new();
698 
699         for i in 0..100 {
700             arena.insert(i);
701         }
702 
703         arena.retain(|_, &mut i| i % 2 == 1);
704 
705         for (_, i) in arena.iter() {
706             assert_eq!(i % 2, 1);
707         }
708 
709         assert_eq!(arena.len(), 50);
710     }
711 
712     #[test]
index_bits_roundtrip()713     fn index_bits_roundtrip() {
714         let index = Index::from_bits(0x1BADCAFE_DEADBEEF);
715         assert_eq!(index.to_bits(), 0x1BADCAFE_DEADBEEF);
716     }
717 
718     #[test]
719     #[should_panic]
index_bits_panic_on_zero_generation()720     fn index_bits_panic_on_zero_generation() {
721         Index::from_bits(0x00000000_DEADBEEF);
722     }
723 }
724