#![no_std]
#![deny(missing_docs)]
extern crate alloc;
mod iter;
pub use iter::{IntoValues, Values, ValuesMut};
use alloc::vec::Vec;
use core::{
mem,
ops::{Index, IndexMut},
};
mod id {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Id(usize);
impl Default for Id {
fn default() -> Self {
Self(usize::MAX)
}
}
impl Id {
#[inline(always)]
pub fn new(i: usize) -> Self {
Self(i)
}
#[inline(always)]
pub fn is_empty(self) -> bool {
self.0 == usize::MAX
}
#[inline(always)]
pub fn index(self) -> Option<usize> {
if self.is_empty() { None } else { Some(self.0) }
}
#[inline(always)]
pub fn valid_index(self) -> usize {
self.0
}
}
}
use id::Id;
#[derive(Copy, Clone, Debug)]
struct LinkedListNode<T> {
next_index: Id,
prev_index: Id,
data: Option<T>,
}
impl<T> LinkedListNode<T> {
fn new(prev_index: Id, next_index: Id, data: T) -> Self {
Self {
next_index,
prev_index,
data: Some(data),
}
}
fn front(first_index: Id, data: T) -> Self {
Self {
next_index: first_index,
prev_index: Id::default(),
data: Some(data),
}
}
fn back(last_index: Id, data: T) -> Self {
Self {
next_index: Id::default(),
prev_index: last_index,
data: Some(data),
}
}
fn deleted(free_index: Id) -> Self {
Self {
next_index: free_index,
prev_index: Id::default(),
data: None,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct ArrayLinkedList<T> {
count: usize,
first_index: Id,
last_index: Id,
free_index: Id,
end_index: Id,
elements: Vec<LinkedListNode<T>>,
}
impl<T> ArrayLinkedList<T> {
pub fn new() -> Self {
Self {
count: 0,
first_index: Id::default(),
last_index: Id::default(),
free_index: Id::default(),
end_index: Id::default(),
elements: Vec::new(),
}
}
#[inline]
fn fill_elements(&mut self, capacity: usize) {
if capacity == 0 {
return;
}
for i in 1..capacity {
self.elements.push(LinkedListNode::deleted(Id::new(i)))
}
self.elements.push(LinkedListNode::deleted(Id::default()));
self.free_index = Id::new(0);
self.end_index = Id::new(capacity - 1);
}
pub fn get(&self, index: usize) -> Option<&T> {
self.elements.get(index)?.data.as_ref()
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
self.elements.get_mut(index)?.data.as_mut()
}
pub fn with_capacity(capacity: usize) -> Self {
let mut result = Self::new();
result.elements = Vec::with_capacity(capacity);
result.fill_elements(capacity);
result
}
pub fn reserve(&mut self, additional: usize) {
self.elements.reserve(additional);
}
pub fn shrink_to_fit(&mut self) {
self.elements.shrink_to_fit();
}
fn insert_free_element(&mut self, element: LinkedListNode<T>) -> Id {
Id::new(if let Some(free_index) = self.free_index.index() {
let recycle_element = &mut self.elements[free_index];
self.free_index = recycle_element.next_index;
*recycle_element = element;
free_index
} else {
let index = self.elements.len();
self.elements.push(element);
index
})
}
pub fn push_front(&mut self, value: T) -> usize {
let element = LinkedListNode::front(self.first_index, value);
let next_index = self.insert_free_element(element);
*self.prev_of_next(self.first_index, true) = next_index;
self.first_index = next_index;
self.count += 1;
next_index.valid_index()
}
pub fn push_back(&mut self, value: T) -> usize {
let element = LinkedListNode::back(self.last_index, value);
let prev_index = self.insert_free_element(element);
*self.next_of_prev(self.last_index, true) = prev_index;
self.last_index = prev_index;
self.count += 1;
prev_index.valid_index()
}
fn insert_between(&mut self, prev_index: Id, next_index: Id, value: T) -> usize {
let element = LinkedListNode::new(prev_index, next_index, value);
let index = self.insert_free_element(element);
*self.next_of_prev(prev_index, true) = index;
*self.prev_of_next(next_index, true) = index;
self.count += 1;
index.valid_index()
}
pub fn insert_after(&mut self, prev_index: usize, value: T) -> Option<usize> {
let LinkedListNode {
next_index, data, ..
} = &self.elements[prev_index];
if data.is_some() {
let next_index = *next_index;
Some(self.insert_between(Id::new(prev_index), next_index, value))
} else {
None
}
}
pub fn insert_before(&mut self, next_index: usize, value: T) -> Option<usize> {
let LinkedListNode {
prev_index, data, ..
} = &self.elements[next_index];
if data.is_some() {
let prev_index = *prev_index;
Some(self.insert_between(prev_index, Id::new(next_index), value))
} else {
None
}
}
#[inline]
fn prev_of_next(&mut self, index: Id, active: bool) -> &mut Id {
if let Some(index) = index.index() {
&mut self.elements[index].prev_index
} else if active {
&mut self.last_index
} else {
&mut self.end_index
}
}
#[inline]
fn next_of_prev(&mut self, index: Id, active: bool) -> &mut Id {
if let Some(index) = index.index() {
&mut self.elements[index].next_index
} else if active {
&mut self.first_index
} else {
&mut self.free_index
}
}
fn connect_indices(&mut self, prev_index: Id, next_index: Id, active: bool) {
*self.prev_of_next(next_index, active) = prev_index;
*self.next_of_prev(prev_index, active) = next_index;
}
pub fn remove(&mut self, index: usize) -> Option<T> {
let LinkedListNode {
next_index,
prev_index,
data,
} = mem::replace(
&mut self.elements[index],
LinkedListNode::deleted(self.free_index),
);
let removed = data.is_some();
self.connect_indices(prev_index, next_index, removed);
if removed {
self.count -= 1;
}
if let Some(free_index) = self.free_index.index() {
self.elements[free_index].prev_index = Id::new(index);
}
self.free_index = Id::new(index);
data
}
pub fn replace_front(&mut self, index: usize, value: T) -> Option<T> {
let LinkedListNode {
next_index,
prev_index,
data,
} = mem::replace(
&mut self.elements[index],
LinkedListNode::front(self.first_index, value),
);
let removed = data.is_some();
self.connect_indices(prev_index, next_index, removed);
if !removed {
self.count += 1;
}
if let Some(first_index) = self.first_index.index() {
self.elements[first_index].prev_index = Id::new(index);
}
self.first_index = Id::new(index);
data
}
pub fn replace_back(&mut self, index: usize, value: T) -> Option<T> {
let LinkedListNode {
next_index,
prev_index,
data,
} = mem::replace(
&mut self.elements[index],
LinkedListNode::back(self.last_index, value),
);
let removed = data.is_some();
self.connect_indices(prev_index, next_index, removed);
if !removed {
self.count += 1;
}
if let Some(last_index) = self.last_index.index() {
self.elements[last_index].next_index = Id::new(index);
}
self.last_index = Id::new(index);
data
}
pub fn pop_front(&mut self) -> Option<T> {
let index = self.first_index.index()?;
let LinkedListNode {
next_index, data, ..
} = mem::replace(
&mut self.elements[index],
LinkedListNode::deleted(self.free_index),
);
*self.prev_of_next(next_index, true) = Id::default();
self.first_index = next_index;
self.count -= 1;
if let Some(free_index) = self.free_index.index() {
self.elements[free_index].prev_index = Id::new(index);
}
self.free_index = Id::new(index);
Some(unsafe { data.unwrap_unchecked() })
}
pub fn pop_back(&mut self) -> Option<T> {
let index = self.last_index.index()?;
let LinkedListNode {
prev_index, data, ..
} = mem::replace(
&mut self.elements[index],
LinkedListNode::deleted(self.free_index),
);
self.last_index = prev_index;
*self.next_of_prev(prev_index, true) = Id::default();
self.count -= 1;
if let Some(free_index) = self.free_index.index() {
self.elements[free_index].prev_index = Id::new(index);
}
self.free_index = Id::new(index);
Some(unsafe { data.unwrap_unchecked() })
}
pub fn front_index(&self) -> Option<usize> {
self.first_index.index()
}
pub fn back_index(&self) -> Option<usize> {
self.last_index.index()
}
pub fn front(&self) -> Option<&T> {
let index = self.first_index.index()?;
Some(unsafe { self.elements[index].data.as_ref().unwrap_unchecked() })
}
pub fn back(&self) -> Option<&T> {
let index = self.last_index.index()?;
Some(unsafe { self.elements[index].data.as_ref().unwrap_unchecked() })
}
pub fn front_mut(&mut self) -> Option<&mut T> {
let index = self.first_index.index()?;
Some(unsafe { self.elements[index].data.as_mut().unwrap_unchecked() })
}
pub fn back_mut(&mut self) -> Option<&mut T> {
let index = self.last_index.index()?;
Some(unsafe { self.elements[index].data.as_mut().unwrap_unchecked() })
}
pub fn is_empty(&self) -> bool {
self.count == 0
}
pub fn clear(&mut self) {
self.count = 0;
self.first_index = Id::default();
self.last_index = Id::default();
self.free_index = Id::default();
self.end_index = Id::default();
let capacity = self.elements.len();
self.elements.clear();
self.fill_elements(capacity);
}
pub fn len(&self) -> usize {
self.count
}
pub fn capacity(&self) -> usize {
self.elements.len()
}
}
impl<T> Index<usize> for ArrayLinkedList<T> {
type Output = Option<T>;
fn index(&self, index: usize) -> &Option<T> {
&self.elements[index].data
}
}
impl<T> IndexMut<usize> for ArrayLinkedList<T> {
fn index_mut(&mut self, index: usize) -> &mut Option<T> {
&mut self.elements[index].data
}
}
impl<T> Extend<T> for ArrayLinkedList<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
let iter = iter.into_iter();
self.elements.reserve(iter.size_hint().0);
for value in iter {
self.push_back(value);
}
}
}
impl<T> FromIterator<T> for ArrayLinkedList<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut result = Self::new();
result.extend(iter);
result
}
}