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