//! Arena adapted from the generational-arena crate.
//!
//! See https://github.com/fitzgen/generational-arena/blob/master/src/lib.rs.
//! This has been modified to have a fully deterministic deserialization (including for the order of
//! Index attribution after a deserialization of the arena.
use std::cmp;
use std::iter::{self, Extend, FromIterator, FusedIterator};
use std::mem;
use std::ops;
use std::slice;
use std::vec;
/// The `Arena` allows inserting and removing elements that are referred to by
/// `Index`.
///
/// [See the module-level documentation for example usage and motivation.](./index.html)
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct Arena<T> {
items: Vec<Entry<T>>,
generation: u64,
free_list_head: Option<usize>,
len: usize,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
enum Entry<T> {
Free { next_free: Option<usize> },
Occupied { generation: u64, value: T },
}
/// An index (and generation) into an `Arena`.
///
/// To get an `Index`, insert an element into an `Arena`, and the `Index` for
/// that element will be returned.
///
/// # Examples
///
/// ```ignore
/// use rapier::data::arena::Arena;
///
/// let mut arena = Arena::new();
/// let idx = arena.insert(123);
/// assert_eq!(arena[idx], 123);
/// ```
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct Index {
index: usize,
generation: u64,
}
impl Index {
/// Create a new `Index` from its raw parts.
///
/// The parts must have been returned from an earlier call to
/// `into_raw_parts`.
///
/// Providing arbitrary values will lead to malformed indices and ultimately
/// panics.
pub fn from_raw_parts(a: usize, b: u64) -> Index {
Index {
index: a,
generation: b,
}
}
/// Convert this `Index` into its raw parts.
///
/// This niche method is useful for converting an `Index` into another
/// identifier type. Usually, you should prefer a newtype wrapper around
/// `Index` like `pub struct MyIdentifier(Index);`. However, for external
/// types whose definition you can't customize, but which you can construct
/// instances of, this method can be useful.
pub fn into_raw_parts(self) -> (usize, u64) {
(self.index, self.generation)
}
}
const DEFAULT_CAPACITY: usize = 4;
impl<T> Default for Arena<T> {
fn default() -> Arena<T> {
Arena::new()
}
}
impl<T> Arena<T> {
/// Constructs a new, empty `Arena`.
///
/// # Examples
///
/// ```ignore
/// use rapier::data::arena::Arena;
///
/// let mut arena = Arena::<usize>::new();
/// # let _ = arena;
/// ```
pub fn new() -> Arena<T> {
Arena::with_capacity(DEFAULT_CAPACITY)
}
/// Constructs a new, empty `Arena<T>` with the specified capacity.
///
/// The `Arena<T>` will be able to hold `n` elements without further allocation.
///
/// # Examples
///
/// ```ignore
/// use rapier::data::arena::Arena;
///
/// let mut arena = Arena::with_capacity(10);
///
/// // These insertions will not require further allocation.
/// for i in 0..10 {
/// assert!(arena.try_insert(i).is_ok());
/// }
///
/// // But now we are at capacity, and there is no more room.
/// assert!(arena.try_insert(99).is_err());
/// ```
pub fn with_capacity(n: usize) -> Arena<T> {
let n = cmp::max(n, 1);
let mut arena = Arena {
items: Vec::new(),
generation: 0,
free_list_head: None,
len: 0,
};
arena.reserve(n);
arena
}
/// Clear all the items inside the arena, but keep its allocation.
///
/// # Examples
///
/// ```ignore
/// use rapier::data::arena::Arena;
///
/// let mut arena = Arena::with_capacity(1);
/// arena.insert(42);
/// arena.insert(43);
///
/// arena.clear();
///