Bump to 0.5.0, delete unsafe, use 2018 edition

This commit is contained in:
Stjepan Glavina 2020-07-07 09:35:12 +02:00
parent 095b9b5a6c
commit f533229a0a
6 changed files with 316 additions and 347 deletions

View File

@ -1,16 +1,11 @@
[package]
name = "vec-arena"
version = "0.4.2"
version = "0.5.0"
authors = ["Stjepan Glavina <stjepang@gmail.com>"]
edition = "2018"
description = "A simple object arena"
repository = "https://github.com/stjepang/vec-arena"
documentation = "https://docs.rs/vec-arena"
readme = "README.md"
license = "Apache-2.0/MIT"
license = "Apache-2.0 OR MIT"
categories = ["memory-management"]
[badges]
travis-ci = { repository = "stjepang/vec-arena" }
[dependencies]
unreachable = "0.1"

View File

@ -1,12 +1,10 @@
# vec-arena (deprecated)
# vec-arena
[![Build Status](https://travis-ci.org/stjepang/vec-arena.svg?branch=master)](https://travis-ci.org/stjepang/vec-arena)
[![License](https://img.shields.io/badge/license-Apache--2.0%2FMIT-blue.svg)](https://github.com/stjepang/vec-arena)
[![Cargo](https://img.shields.io/crates/v/vec-arena.svg)](https://crates.io/crates/vec-arena)
[![Documentation](https://docs.rs/vec-arena/badge.svg)](https://docs.rs/vec-arena)
**This crate is now deprecated in favor of [slab](https://github.com/carllerche/slab).**
#### What is this?
A simple object arena.

View File

@ -1,5 +1,3 @@
extern crate vec_arena;
use vec_arena::Arena;
/// The null index, akin to null pointers.
@ -49,8 +47,12 @@ impl<T> List<T> {
/// Links nodes `a` and `b` together, so that `a` comes before `b` in the list.
fn link(&mut self, a: usize, b: usize) {
if a != NULL { self.arena[a].next = b; }
if b != NULL { self.arena[b].prev = a; }
if a != NULL {
self.arena[a].next = b;
}
if b != NULL {
self.arena[b].prev = a;
}
}
/// Appends `value` to the back of the list.
@ -88,8 +90,12 @@ impl<T> List<T> {
let node = self.arena.remove(index).unwrap();
self.link(node.prev, node.next);
if self.head == index { self.head = node.next; }
if self.tail == index { self.tail = node.prev; }
if self.head == index {
self.head = node.next;
}
if self.tail == index {
self.tail = node.prev;
}
node.value
}

View File

@ -1,5 +1,3 @@
extern crate vec_arena;
use vec_arena::Arena;
/// The null index, akin to null pointers.
@ -39,7 +37,7 @@ struct Splay<T> {
root: usize,
}
impl<T> Splay<T> where T: Ord {
impl<T: Ord> Splay<T> {
/// Constructs a new, empty splay tree.
fn new() -> Splay<T> {
Splay {
@ -139,7 +137,11 @@ impl<T> Splay<T> where T: Ord {
let mut p = self.root;
loop {
// Decide whether to go left or right.
let dir = if self.arena[n].value < self.arena[p].value { 0 } else { 1 };
let dir = if self.arena[n].value < self.arena[p].value {
0
} else {
1
};
let c = self.arena[p].children[dir];
if c == NULL {
@ -153,7 +155,10 @@ impl<T> Splay<T> where T: Ord {
}
/// Pretty-prints the subtree rooted at `node`, indented by `indent` spaces.
fn print(&self, node: usize, indent: usize) where T: std::fmt::Display {
fn print(&self, node: usize, indent: usize)
where
T: std::fmt::Display,
{
if node != NULL {
// Print the left subtree.
self.print(self.arena[node].children[0], indent + 3);

View File

@ -2,7 +2,7 @@
//!
//! `Arena<T>` is basically just a `Vec<Option<T>>`, which allows you to:
//!
//! * Insert an object (reuse an existing `None` element, or append to the end).
//! * Insert an object (reuse an existing [`None`] element, or append to the end).
//! * Remove object at a specified index.
//! * Access object at a specified index.
//!
@ -13,18 +13,16 @@
//! * [Doubly linked list](https://github.com/stjepang/vec-arena/blob/master/examples/linked_list.rs)
//! * [Splay tree](https://github.com/stjepang/vec-arena/blob/master/examples/splay_tree.rs)
extern crate unreachable;
#![forbid(unsafe_code)]
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
use std::fmt;
use std::iter;
use std::mem;
use std::ops::{Index, IndexMut};
use std::ptr;
use std::slice;
use std::vec;
use unreachable::unreachable;
/// A slot, which is either vacant or occupied.
///
/// Vacant slots in arena are linked together into a singly linked list. This allows the arena to
@ -39,6 +37,16 @@ enum Slot<T> {
Occupied(T),
}
impl<T> Slot<T> {
/// Returns `true` if the slot is vacant.
fn is_occupied(&self) -> bool {
match self {
Slot::Vacant(_) => false,
Slot::Occupied(_) => true,
}
}
}
/// An object arena.
///
/// `Arena<T>` holds an array of slots for storing objects.
@ -73,7 +81,7 @@ enum Slot<T> {
///
/// # Indexing
///
/// You can also access objects in an arena by index, just like you would in a `Vec`.
/// You can also access objects in an arena by index, just like you would in a [`Vec`].
/// However, accessing a vacant slot by index or using an out-of-bounds index will result in panic.
///
/// ```
@ -90,7 +98,8 @@ enum Slot<T> {
/// assert_eq!(arena[a], 30);
/// ```
///
/// To access slots without fear of panicking, use `get` and `get_mut`, which return `Option`s.
/// To access slots without fear of panicking, use [`get()`][`Arena::get()`] and
/// [`get_mut()`][`Arena::get_mut()`], which return [`Option`]s.
pub struct Arena<T> {
/// Slots in which objects are stored.
slots: Vec<Slot<T>>,
@ -125,8 +134,8 @@ impl<T> Arena<T> {
/// Constructs a new, empty arena with the specified capacity (number of slots).
///
/// The arena will be able to hold exactly `capacity` objects without reallocating.
/// If `capacity` is 0, the arena will not allocate.
/// The arena will be able to hold exactly `cap` objects without reallocating.
/// If `cap` is 0, the arena will not allocate.
///
/// # Examples
///
@ -210,7 +219,7 @@ impl<T> Arena<T> {
self.len == 0
}
/// Returns the index of the slot that next `insert` will use if no other
/// Returns the index of the slot that next [`insert`][`Arena::insert()`] will use if no
/// mutating calls take place in between.
///
/// # Examples
@ -228,7 +237,7 @@ impl<T> Arena<T> {
/// assert_eq!(c, d);
/// ```
#[inline]
pub fn next_vacant(&mut self) -> usize {
pub fn next_vacant(&self) -> usize {
if self.head == !0 {
self.len
} else {
@ -237,6 +246,7 @@ impl<T> Arena<T> {
}
/// Inserts an object into the arena and returns the slot index it was stored in.
///
/// The arena will reallocate if it's full.
///
/// # Examples
@ -263,7 +273,7 @@ impl<T> Arena<T> {
Slot::Vacant(next) => {
self.head = next;
self.slots[index] = Slot::Occupied(object);
},
}
Slot::Occupied(_) => unreachable!(),
}
index
@ -272,7 +282,7 @@ impl<T> Arena<T> {
/// Removes the object stored at `index` from the arena and returns it.
///
/// `None` is returned in case the slot is vacant, or `index` is out of bounds.
/// If the slot is vacant or `index` is out of bounds, [`None`] will be returned.
///
/// # Examples
///
@ -305,8 +315,9 @@ impl<T> Arena<T> {
}
}
/// Clears the arena, removing and dropping all objects it holds. Keeps the allocated memory
/// for reuse.
/// Clears the arena, removing and dropping all objects it holds.
///
/// Keeps the allocated memory for reuse.
///
/// # Examples
///
@ -331,7 +342,7 @@ impl<T> Arena<T> {
/// Returns a reference to the object stored at `index`.
///
/// If `index` is out of bounds or the slot is vacant, `None` is returned.
/// If the slot is vacant or `index` is out of bounds, [`None`] will be returned.
///
/// # Examples
///
@ -356,7 +367,7 @@ impl<T> Arena<T> {
/// Returns a mutable reference to the object stored at `index`.
///
/// If `index` is out of bounds or the slot is vacant, `None` is returned.
/// If the slot is vacant or `index` is out of bounds, [`None`] will be returned.
///
/// # Examples
///
@ -379,56 +390,6 @@ impl<T> Arena<T> {
}
}
/// Returns a reference to the object stored at `index`.
///
/// # Safety
///
/// Behavior is undefined if `index` is out of bounds or the slot is vacant.
///
/// # Examples
///
/// ```
/// use vec_arena::Arena;
///
/// let mut arena = Arena::new();
/// let index = arena.insert("hello");
///
/// unsafe { assert_eq!(&*arena.get_unchecked(index), &"hello") }
/// ```
#[inline]
pub unsafe fn get_unchecked(&self, index: usize) -> &T {
match self.slots.get(index) {
None => unreachable(),
Some(&Slot::Vacant(_)) => unreachable(),
Some(&Slot::Occupied(ref object)) => object,
}
}
/// Returns a mutable reference to the object stored at `index`.
///
/// # Safety
///
/// Behavior is undefined if `index` is out of bounds or the slot is vacant.
///
/// # Examples
///
/// ```
/// use vec_arena::Arena;
///
/// let mut arena = Arena::new();
/// let index = arena.insert("hello");
///
/// unsafe { assert_eq!(&*arena.get_unchecked_mut(index), &"hello") }
/// ```
#[inline]
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
match self.slots.get_mut(index) {
None => unreachable(),
Some(&mut Slot::Vacant(_)) => unreachable(),
Some(&mut Slot::Occupied(ref mut object)) => object,
}
}
/// Swaps two objects in the arena.
///
/// The two indices are `a` and `b`.
@ -452,17 +413,19 @@ impl<T> Arena<T> {
/// ```
#[inline]
pub fn swap(&mut self, a: usize, b: usize) {
unsafe {
let fst = self.get_mut(a).unwrap() as *mut _;
let snd = self.get_mut(b).unwrap() as *mut _;
if a != b {
ptr::swap(fst, snd);
}
assert!(self.slots[a].is_occupied(), "invalid object ID");
assert!(self.slots[b].is_occupied(), "invalid object ID");
if a != b {
let (a, b) = (a.min(b), a.max(b));
let (l, r) = self.slots.split_at_mut(b);
mem::swap(&mut l[a], &mut r[0]);
}
}
/// Reserves capacity for at least `additional` more objects to be inserted. The arena may
/// reserve more space to avoid frequent reallocations.
/// Reserves capacity for at least `additional` more objects to be inserted.
///
/// The arena may reserve more space to avoid frequent reallocations.
///
/// # Panics
///
@ -530,8 +493,10 @@ impl<T> Arena<T> {
/// assert_eq!(iterator.next(), Some((2, &4)));
/// ```
#[inline]
pub fn iter(&self) -> Iter<T> {
Iter { slots: self.slots.iter().enumerate() }
pub fn iter(&self) -> Iter<'_, T> {
Iter {
slots: self.slots.iter().enumerate(),
}
}
/// Returns an iterator that returns mutable references to objects.
@ -556,8 +521,10 @@ impl<T> Arena<T> {
/// assert_eq!(iterator.next(), Some((2, &"2 two".to_string())));
/// ```
#[inline]
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut { slots: self.slots.iter_mut().enumerate() }
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut {
slots: self.slots.iter_mut().enumerate(),
}
}
/// Shrinks the capacity of the arena as much as possible.
@ -584,7 +551,7 @@ impl<T> Arena<T> {
}
impl<T> fmt::Debug for Arena<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Arena {{ ... }}")
}
}
@ -621,7 +588,7 @@ impl<T: Clone> Clone for Arena<T> {
}
}
/// An iterator over the occupied slots in a `Arena`.
/// An iterator over the occupied slots in an [`Arena`].
pub struct IntoIter<T> {
slots: iter::Enumerate<vec::IntoIter<Slot<T>>>,
}
@ -646,12 +613,14 @@ impl<T> IntoIterator for Arena<T> {
#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter { slots: self.slots.into_iter().enumerate() }
IntoIter {
slots: self.slots.into_iter().enumerate(),
}
}
}
impl<T> iter::FromIterator<T> for Arena<T> {
fn from_iter<U: IntoIterator<Item=T>>(iter: U) -> Arena<T> {
fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Arena<T> {
let iter = iter.into_iter();
let mut arena = Arena::with_capacity(iter.size_hint().0);
for i in iter {
@ -662,13 +631,13 @@ impl<T> iter::FromIterator<T> for Arena<T> {
}
impl<T> fmt::Debug for IntoIter<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "IntoIter {{ ... }}")
}
}
/// An iterator over references to the occupied slots in a `Arena`.
pub struct Iter<'a, T: 'a> {
/// An iterator over references to the occupied slots in an [`Arena`].
pub struct Iter<'a, T> {
slots: iter::Enumerate<slice::Iter<'a, Slot<T>>>,
}
@ -697,13 +666,13 @@ impl<'a, T> IntoIterator for &'a Arena<T> {
}
impl<'a, T> fmt::Debug for Iter<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Iter {{ ... }}")
}
}
/// An iterator over mutable references to the occupied slots in a `Arena`.
pub struct IterMut<'a, T: 'a> {
pub struct IterMut<'a, T> {
slots: iter::Enumerate<slice::IterMut<'a, Slot<T>>>,
}
@ -732,243 +701,7 @@ impl<'a, T> IntoIterator for &'a mut Arena<T> {
}
impl<'a, T> fmt::Debug for IterMut<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "IterMut {{ ... }}")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new() {
let arena = Arena::<i32>::new();
assert!(arena.is_empty());
assert_eq!(arena.len(), 0);
assert_eq!(arena.capacity(), 0);
}
#[test]
fn insert() {
let mut arena = Arena::new();
for i in 0..10 {
assert_eq!(arena.insert(i * 10), i);
assert_eq!(arena[i], i * 10);
}
assert!(!arena.is_empty());
assert_eq!(arena.len(), 10);
}
#[test]
fn with_capacity() {
let mut arena = Arena::with_capacity(10);
assert_eq!(arena.capacity(), 10);
for _ in 0..10 {
arena.insert(());
}
assert_eq!(arena.len(), 10);
assert_eq!(arena.capacity(), 10);
arena.insert(());
assert_eq!(arena.len(), 11);
assert!(arena.capacity() > 10);
}
#[test]
fn remove() {
let mut arena = Arena::new();
assert_eq!(arena.insert(0), 0);
assert_eq!(arena.insert(10), 1);
assert_eq!(arena.insert(20), 2);
assert_eq!(arena.insert(30), 3);
assert_eq!(arena.len(), 4);
assert_eq!(arena.remove(1), Some(10));
assert_eq!(arena.remove(2), Some(20));
assert_eq!(arena.len(), 2);
assert!(arena.insert(-1) < 4);
assert!(arena.insert(-1) < 4);
assert_eq!(arena.len(), 4);
assert_eq!(arena.remove(0), Some(0));
assert!(arena.insert(-1) < 4);
assert_eq!(arena.len(), 4);
assert_eq!(arena.insert(400), 4);
assert_eq!(arena.len(), 5);
}
#[test]
fn invalid_remove() {
let mut arena = Arena::new();
for i in 0..10 {
arena.insert(i.to_string());
}
assert_eq!(arena.remove(7), Some("7".to_string()));
assert_eq!(arena.remove(5), Some("5".to_string()));
assert_eq!(arena.remove(!0), None);
assert_eq!(arena.remove(10), None);
assert_eq!(arena.remove(11), None);
assert_eq!(arena.remove(5), None);
assert_eq!(arena.remove(7), None);
}
#[test]
fn clear() {
let mut arena = Arena::new();
arena.insert(10);
arena.insert(20);
assert!(!arena.is_empty());
assert_eq!(arena.len(), 2);
let cap = arena.capacity();
arena.clear();
assert!(arena.is_empty());
assert_eq!(arena.len(), 0);
assert_eq!(arena.capacity(), cap);
}
#[test]
fn indexing() {
let mut arena = Arena::new();
let a = arena.insert(10);
let b = arena.insert(20);
let c = arena.insert(30);
arena[b] += arena[c];
assert_eq!(arena[a], 10);
assert_eq!(arena[b], 50);
assert_eq!(arena[c], 30);
}
#[test]
#[should_panic]
fn indexing_vacant() {
let mut arena = Arena::new();
let _ = arena.insert(10);
let b = arena.insert(20);
let _ = arena.insert(30);
arena.remove(b);
arena[b];
}
#[test]
#[should_panic]
fn invalid_indexing() {
let mut arena = Arena::new();
arena.insert(10);
arena.insert(20);
arena.insert(30);
arena[100];
}
#[test]
fn get() {
let mut arena = Arena::new();
let a = arena.insert(10);
let b = arena.insert(20);
let c = arena.insert(30);
*arena.get_mut(b).unwrap() += *arena.get(c).unwrap();
assert_eq!(arena.get(a), Some(&10));
assert_eq!(arena.get(b), Some(&50));
assert_eq!(arena.get(c), Some(&30));
arena.remove(b);
assert_eq!(arena.get(b), None);
assert_eq!(arena.get_mut(b), None);
}
#[test]
fn reserve() {
let mut arena = Arena::new();
arena.insert(1);
arena.insert(2);
arena.reserve(10);
assert!(arena.capacity() >= 11);
}
#[test]
fn reserve_exact() {
let mut arena = Arena::new();
arena.insert(1);
arena.insert(2);
arena.reserve(10);
assert!(arena.capacity() >= 11);
}
#[test]
fn iter() {
let mut arena = Arena::new();
let a = arena.insert(10);
let b = arena.insert(20);
let c = arena.insert(30);
let d = arena.insert(40);
arena.remove(b);
let mut it = arena.iter();
assert_eq!(it.next(), Some((a, &10)));
assert_eq!(it.next(), Some((c, &30)));
assert_eq!(it.next(), Some((d, &40)));
assert_eq!(it.next(), None);
}
#[test]
fn iter_mut() {
let mut arena = Arena::new();
let a = arena.insert(10);
let b = arena.insert(20);
let c = arena.insert(30);
let d = arena.insert(40);
arena.remove(b);
{
let mut it = arena.iter_mut();
assert_eq!(it.next(), Some((a, &mut 10)));
assert_eq!(it.next(), Some((c, &mut 30)));
assert_eq!(it.next(), Some((d, &mut 40)));
assert_eq!(it.next(), None);
}
for (index, value) in &mut arena {
*value += index;
}
let mut it = arena.iter_mut();
assert_eq!(*it.next().unwrap().1, 10 + a);
assert_eq!(*it.next().unwrap().1, 30 + c);
assert_eq!(*it.next().unwrap().1, 40 + d);
assert_eq!(it.next(), None);
}
#[test]
fn from_iter() {
let arena: Arena<_> = [10, 20, 30, 40].iter().cloned().collect();
let mut it = arena.iter();
assert_eq!(it.next(), Some((0, &10)));
assert_eq!(it.next(), Some((1, &20)));
assert_eq!(it.next(), Some((2, &30)));
assert_eq!(it.next(), Some((3, &40)));
assert_eq!(it.next(), None);
}
}

232
tests/arena.rs Normal file
View File

@ -0,0 +1,232 @@
use vec_arena::Arena;
#[test]
fn new() {
let arena = Arena::<i32>::new();
assert!(arena.is_empty());
assert_eq!(arena.len(), 0);
assert_eq!(arena.capacity(), 0);
}
#[test]
fn insert() {
let mut arena = Arena::new();
for i in 0..10 {
assert_eq!(arena.insert(i * 10), i);
assert_eq!(arena[i], i * 10);
}
assert!(!arena.is_empty());
assert_eq!(arena.len(), 10);
}
#[test]
fn with_capacity() {
let mut arena = Arena::with_capacity(10);
assert_eq!(arena.capacity(), 10);
for _ in 0..10 {
arena.insert(());
}
assert_eq!(arena.len(), 10);
assert_eq!(arena.capacity(), 10);
arena.insert(());
assert_eq!(arena.len(), 11);
assert!(arena.capacity() > 10);
}
#[test]
fn remove() {
let mut arena = Arena::new();
assert_eq!(arena.insert(0), 0);
assert_eq!(arena.insert(10), 1);
assert_eq!(arena.insert(20), 2);
assert_eq!(arena.insert(30), 3);
assert_eq!(arena.len(), 4);
assert_eq!(arena.remove(1), Some(10));
assert_eq!(arena.remove(2), Some(20));
assert_eq!(arena.len(), 2);
assert!(arena.insert(-1) < 4);
assert!(arena.insert(-1) < 4);
assert_eq!(arena.len(), 4);
assert_eq!(arena.remove(0), Some(0));
assert!(arena.insert(-1) < 4);
assert_eq!(arena.len(), 4);
assert_eq!(arena.insert(400), 4);
assert_eq!(arena.len(), 5);
}
#[test]
fn invalid_remove() {
let mut arena = Arena::new();
for i in 0..10 {
arena.insert(i.to_string());
}
assert_eq!(arena.remove(7), Some("7".to_string()));
assert_eq!(arena.remove(5), Some("5".to_string()));
assert_eq!(arena.remove(!0), None);
assert_eq!(arena.remove(10), None);
assert_eq!(arena.remove(11), None);
assert_eq!(arena.remove(5), None);
assert_eq!(arena.remove(7), None);
}
#[test]
fn clear() {
let mut arena = Arena::new();
arena.insert(10);
arena.insert(20);
assert!(!arena.is_empty());
assert_eq!(arena.len(), 2);
let cap = arena.capacity();
arena.clear();
assert!(arena.is_empty());
assert_eq!(arena.len(), 0);
assert_eq!(arena.capacity(), cap);
}
#[test]
fn indexing() {
let mut arena = Arena::new();
let a = arena.insert(10);
let b = arena.insert(20);
let c = arena.insert(30);
arena[b] += arena[c];
assert_eq!(arena[a], 10);
assert_eq!(arena[b], 50);
assert_eq!(arena[c], 30);
}
#[test]
#[should_panic]
fn indexing_vacant() {
let mut arena = Arena::new();
let _ = arena.insert(10);
let b = arena.insert(20);
let _ = arena.insert(30);
arena.remove(b);
arena[b];
}
#[test]
#[should_panic]
fn invalid_indexing() {
let mut arena = Arena::new();
arena.insert(10);
arena.insert(20);
arena.insert(30);
arena[100];
}
#[test]
fn get() {
let mut arena = Arena::new();
let a = arena.insert(10);
let b = arena.insert(20);
let c = arena.insert(30);
*arena.get_mut(b).unwrap() += *arena.get(c).unwrap();
assert_eq!(arena.get(a), Some(&10));
assert_eq!(arena.get(b), Some(&50));
assert_eq!(arena.get(c), Some(&30));
arena.remove(b);
assert_eq!(arena.get(b), None);
assert_eq!(arena.get_mut(b), None);
}
#[test]
fn reserve() {
let mut arena = Arena::new();
arena.insert(1);
arena.insert(2);
arena.reserve(10);
assert!(arena.capacity() >= 11);
}
#[test]
fn reserve_exact() {
let mut arena = Arena::new();
arena.insert(1);
arena.insert(2);
arena.reserve(10);
assert!(arena.capacity() >= 11);
}
#[test]
fn iter() {
let mut arena = Arena::new();
let a = arena.insert(10);
let b = arena.insert(20);
let c = arena.insert(30);
let d = arena.insert(40);
arena.remove(b);
let mut it = arena.iter();
assert_eq!(it.next(), Some((a, &10)));
assert_eq!(it.next(), Some((c, &30)));
assert_eq!(it.next(), Some((d, &40)));
assert_eq!(it.next(), None);
}
#[test]
fn iter_mut() {
let mut arena = Arena::new();
let a = arena.insert(10);
let b = arena.insert(20);
let c = arena.insert(30);
let d = arena.insert(40);
arena.remove(b);
{
let mut it = arena.iter_mut();
assert_eq!(it.next(), Some((a, &mut 10)));
assert_eq!(it.next(), Some((c, &mut 30)));
assert_eq!(it.next(), Some((d, &mut 40)));
assert_eq!(it.next(), None);
}
for (index, value) in &mut arena {
*value += index;
}
let mut it = arena.iter_mut();
assert_eq!(*it.next().unwrap().1, 10 + a);
assert_eq!(*it.next().unwrap().1, 30 + c);
assert_eq!(*it.next().unwrap().1, 40 + d);
assert_eq!(it.next(), None);
}
#[test]
fn from_iter() {
let arena: Arena<_> = [10, 20, 30, 40].iter().cloned().collect();
let mut it = arena.iter();
assert_eq!(it.next(), Some((0, &10)));
assert_eq!(it.next(), Some((1, &20)));
assert_eq!(it.next(), Some((2, &30)));
assert_eq!(it.next(), Some((3, &40)));
assert_eq!(it.next(), None);
}