mirror of https://github.com/smol-rs/vec-arena
Bump to 0.5.0, delete unsafe, use 2018 edition
This commit is contained in:
parent
095b9b5a6c
commit
f533229a0a
11
Cargo.toml
11
Cargo.toml
|
@ -1,16 +1,11 @@
|
||||||
[package]
|
[package]
|
||||||
name = "vec-arena"
|
name = "vec-arena"
|
||||||
version = "0.4.2"
|
version = "0.5.0"
|
||||||
authors = ["Stjepan Glavina <stjepang@gmail.com>"]
|
authors = ["Stjepan Glavina <stjepang@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
description = "A simple object arena"
|
description = "A simple object arena"
|
||||||
repository = "https://github.com/stjepang/vec-arena"
|
repository = "https://github.com/stjepang/vec-arena"
|
||||||
documentation = "https://docs.rs/vec-arena"
|
documentation = "https://docs.rs/vec-arena"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "Apache-2.0/MIT"
|
license = "Apache-2.0 OR MIT"
|
||||||
categories = ["memory-management"]
|
categories = ["memory-management"]
|
||||||
|
|
||||||
[badges]
|
|
||||||
travis-ci = { repository = "stjepang/vec-arena" }
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
unreachable = "0.1"
|
|
||||||
|
|
|
@ -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)
|
[![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)
|
[![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)
|
[![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)
|
[![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?
|
#### What is this?
|
||||||
|
|
||||||
A simple object arena.
|
A simple object arena.
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
extern crate vec_arena;
|
|
||||||
|
|
||||||
use vec_arena::Arena;
|
use vec_arena::Arena;
|
||||||
|
|
||||||
/// The null index, akin to null pointers.
|
/// 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.
|
/// Links nodes `a` and `b` together, so that `a` comes before `b` in the list.
|
||||||
fn link(&mut self, a: usize, b: usize) {
|
fn link(&mut self, a: usize, b: usize) {
|
||||||
if a != NULL { self.arena[a].next = b; }
|
if a != NULL {
|
||||||
if b != NULL { self.arena[b].prev = a; }
|
self.arena[a].next = b;
|
||||||
|
}
|
||||||
|
if b != NULL {
|
||||||
|
self.arena[b].prev = a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends `value` to the back of the list.
|
/// Appends `value` to the back of the list.
|
||||||
|
@ -88,8 +90,12 @@ impl<T> List<T> {
|
||||||
let node = self.arena.remove(index).unwrap();
|
let node = self.arena.remove(index).unwrap();
|
||||||
|
|
||||||
self.link(node.prev, node.next);
|
self.link(node.prev, node.next);
|
||||||
if self.head == index { self.head = node.next; }
|
if self.head == index {
|
||||||
if self.tail == index { self.tail = node.prev; }
|
self.head = node.next;
|
||||||
|
}
|
||||||
|
if self.tail == index {
|
||||||
|
self.tail = node.prev;
|
||||||
|
}
|
||||||
|
|
||||||
node.value
|
node.value
|
||||||
}
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
extern crate vec_arena;
|
|
||||||
|
|
||||||
use vec_arena::Arena;
|
use vec_arena::Arena;
|
||||||
|
|
||||||
/// The null index, akin to null pointers.
|
/// The null index, akin to null pointers.
|
||||||
|
@ -39,7 +37,7 @@ struct Splay<T> {
|
||||||
root: usize,
|
root: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Splay<T> where T: Ord {
|
impl<T: Ord> Splay<T> {
|
||||||
/// Constructs a new, empty splay tree.
|
/// Constructs a new, empty splay tree.
|
||||||
fn new() -> Splay<T> {
|
fn new() -> Splay<T> {
|
||||||
Splay {
|
Splay {
|
||||||
|
@ -139,7 +137,11 @@ impl<T> Splay<T> where T: Ord {
|
||||||
let mut p = self.root;
|
let mut p = self.root;
|
||||||
loop {
|
loop {
|
||||||
// Decide whether to go left or right.
|
// 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];
|
let c = self.arena[p].children[dir];
|
||||||
|
|
||||||
if c == NULL {
|
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.
|
/// 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 {
|
if node != NULL {
|
||||||
// Print the left subtree.
|
// Print the left subtree.
|
||||||
self.print(self.arena[node].children[0], indent + 3);
|
self.print(self.arena[node].children[0], indent + 3);
|
383
src/lib.rs
383
src/lib.rs
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! `Arena<T>` is basically just a `Vec<Option<T>>`, which allows you to:
|
//! `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.
|
//! * Remove object at a specified index.
|
||||||
//! * Access 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)
|
//! * [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)
|
//! * [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::fmt;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
use std::ptr;
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
use unreachable::unreachable;
|
|
||||||
|
|
||||||
/// A slot, which is either vacant or occupied.
|
/// 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
|
/// 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),
|
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.
|
/// An object arena.
|
||||||
///
|
///
|
||||||
/// `Arena<T>` holds an array of slots for storing objects.
|
/// `Arena<T>` holds an array of slots for storing objects.
|
||||||
|
@ -73,7 +81,7 @@ enum Slot<T> {
|
||||||
///
|
///
|
||||||
/// # Indexing
|
/// # 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.
|
/// 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);
|
/// 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> {
|
pub struct Arena<T> {
|
||||||
/// Slots in which objects are stored.
|
/// Slots in which objects are stored.
|
||||||
slots: Vec<Slot<T>>,
|
slots: Vec<Slot<T>>,
|
||||||
|
@ -125,8 +134,8 @@ impl<T> Arena<T> {
|
||||||
|
|
||||||
/// Constructs a new, empty arena with the specified capacity (number of slots).
|
/// Constructs a new, empty arena with the specified capacity (number of slots).
|
||||||
///
|
///
|
||||||
/// The arena will be able to hold exactly `capacity` objects without reallocating.
|
/// The arena will be able to hold exactly `cap` objects without reallocating.
|
||||||
/// If `capacity` is 0, the arena will not allocate.
|
/// If `cap` is 0, the arena will not allocate.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -210,7 +219,7 @@ impl<T> Arena<T> {
|
||||||
self.len == 0
|
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.
|
/// mutating calls take place in between.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -228,7 +237,7 @@ impl<T> Arena<T> {
|
||||||
/// assert_eq!(c, d);
|
/// assert_eq!(c, d);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn next_vacant(&mut self) -> usize {
|
pub fn next_vacant(&self) -> usize {
|
||||||
if self.head == !0 {
|
if self.head == !0 {
|
||||||
self.len
|
self.len
|
||||||
} else {
|
} else {
|
||||||
|
@ -237,6 +246,7 @@ impl<T> Arena<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts an object into the arena and returns the slot index it was stored in.
|
/// Inserts an object into the arena and returns the slot index it was stored in.
|
||||||
|
///
|
||||||
/// The arena will reallocate if it's full.
|
/// The arena will reallocate if it's full.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -263,7 +273,7 @@ impl<T> Arena<T> {
|
||||||
Slot::Vacant(next) => {
|
Slot::Vacant(next) => {
|
||||||
self.head = next;
|
self.head = next;
|
||||||
self.slots[index] = Slot::Occupied(object);
|
self.slots[index] = Slot::Occupied(object);
|
||||||
},
|
}
|
||||||
Slot::Occupied(_) => unreachable!(),
|
Slot::Occupied(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
index
|
index
|
||||||
|
@ -272,7 +282,7 @@ impl<T> Arena<T> {
|
||||||
|
|
||||||
/// Removes the object stored at `index` from the arena and returns it.
|
/// 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
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -305,8 +315,9 @@ impl<T> Arena<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the arena, removing and dropping all objects it holds. Keeps the allocated memory
|
/// Clears the arena, removing and dropping all objects it holds.
|
||||||
/// for reuse.
|
///
|
||||||
|
/// Keeps the allocated memory for reuse.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -331,7 +342,7 @@ impl<T> Arena<T> {
|
||||||
|
|
||||||
/// Returns a reference to the object stored at `index`.
|
/// 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
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -356,7 +367,7 @@ impl<T> Arena<T> {
|
||||||
|
|
||||||
/// Returns a mutable reference to the object stored at `index`.
|
/// 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
|
/// # 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.
|
/// Swaps two objects in the arena.
|
||||||
///
|
///
|
||||||
/// The two indices are `a` and `b`.
|
/// The two indices are `a` and `b`.
|
||||||
|
@ -452,17 +413,19 @@ impl<T> Arena<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn swap(&mut self, a: usize, b: usize) {
|
pub fn swap(&mut self, a: usize, b: usize) {
|
||||||
unsafe {
|
assert!(self.slots[a].is_occupied(), "invalid object ID");
|
||||||
let fst = self.get_mut(a).unwrap() as *mut _;
|
assert!(self.slots[b].is_occupied(), "invalid object ID");
|
||||||
let snd = self.get_mut(b).unwrap() as *mut _;
|
|
||||||
if a != b {
|
if a != b {
|
||||||
ptr::swap(fst, snd);
|
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
|
/// Reserves capacity for at least `additional` more objects to be inserted.
|
||||||
/// reserve more space to avoid frequent reallocations.
|
///
|
||||||
|
/// The arena may reserve more space to avoid frequent reallocations.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
|
@ -530,8 +493,10 @@ impl<T> Arena<T> {
|
||||||
/// assert_eq!(iterator.next(), Some((2, &4)));
|
/// assert_eq!(iterator.next(), Some((2, &4)));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter(&self) -> Iter<T> {
|
pub fn iter(&self) -> Iter<'_, T> {
|
||||||
Iter { slots: self.slots.iter().enumerate() }
|
Iter {
|
||||||
|
slots: self.slots.iter().enumerate(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator that returns mutable references to objects.
|
/// 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())));
|
/// assert_eq!(iterator.next(), Some((2, &"2 two".to_string())));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter_mut(&mut self) -> IterMut<T> {
|
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
|
||||||
IterMut { slots: self.slots.iter_mut().enumerate() }
|
IterMut {
|
||||||
|
slots: self.slots.iter_mut().enumerate(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shrinks the capacity of the arena as much as possible.
|
/// 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> {
|
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 {{ ... }}")
|
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> {
|
pub struct IntoIter<T> {
|
||||||
slots: iter::Enumerate<vec::IntoIter<Slot<T>>>,
|
slots: iter::Enumerate<vec::IntoIter<Slot<T>>>,
|
||||||
}
|
}
|
||||||
|
@ -646,12 +613,14 @@ impl<T> IntoIterator for Arena<T> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
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> {
|
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 iter = iter.into_iter();
|
||||||
let mut arena = Arena::with_capacity(iter.size_hint().0);
|
let mut arena = Arena::with_capacity(iter.size_hint().0);
|
||||||
for i in iter {
|
for i in iter {
|
||||||
|
@ -662,13 +631,13 @@ impl<T> iter::FromIterator<T> for Arena<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> fmt::Debug for IntoIter<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 {{ ... }}")
|
write!(f, "IntoIter {{ ... }}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over references to the occupied slots in a `Arena`.
|
/// An iterator over references to the occupied slots in an [`Arena`].
|
||||||
pub struct Iter<'a, T: 'a> {
|
pub struct Iter<'a, T> {
|
||||||
slots: iter::Enumerate<slice::Iter<'a, Slot<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> {
|
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 {{ ... }}")
|
write!(f, "Iter {{ ... }}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over mutable references to the occupied slots in a `Arena`.
|
/// 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>>>,
|
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> {
|
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 {{ ... }}")
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue