#![deny(missing_docs)]
use std::{
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
}
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.first_index.is_empty() && self.last_index.is_empty()
}
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()
}
pub fn iter(&self) -> impl DoubleEndedIterator<Item = &T> {
Values(Indexed::new(self))
}
pub fn indexed(&self) -> impl DoubleEndedIterator<Item = (usize, &T)> {
Indexed::new(self)
}
pub fn indices(&self) -> impl DoubleEndedIterator<Item = usize> + '_ {
Indices(Indexed::new(self))
}
pub fn iter_after(&self, index: usize) -> impl DoubleEndedIterator<Item = &T> {
Values(Indexed::after(self, index))
}
pub fn indexed_after(&self, index: usize) -> impl DoubleEndedIterator<Item = (usize, &T)> {
Indexed::after(self, index)
}
pub fn indices_after(&self, index: usize) -> impl DoubleEndedIterator<Item = usize> + '_ {
Indices(Indexed::after(self, index))
}
pub fn iter_before(&self, index: usize) -> impl DoubleEndedIterator<Item = &T> {
Values(Indexed::before(self, index))
}
pub fn indexed_before(&self, index: usize) -> impl DoubleEndedIterator<Item = (usize, &T)> {
Indexed::before(self, index)
}
pub fn indices_before(&self, index: usize) -> impl DoubleEndedIterator<Item = usize> + '_ {
Indices(Indexed::before(self, index))
}
pub fn into_indexed(self) -> impl DoubleEndedIterator<Item = (usize, T)> {
IntoIndexed(self)
}
pub fn into_indices(self) -> impl DoubleEndedIterator<Item = usize> {
IntoIndices(IntoIndexed(self))
}
}
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
}
}
struct Indexed<'a, T> {
front_index: Id,
back_index: Id,
array: &'a ArrayLinkedList<T>,
}
impl<'a, T> Indexed<'a, T> {
fn empty(array: &'a ArrayLinkedList<T>) -> Self {
Self {
front_index: Id::default(),
back_index: Id::default(),
array,
}
}
fn new(array: &'a ArrayLinkedList<T>) -> Self {
Self {
front_index: array.first_index,
back_index: array.last_index,
array,
}
}
fn after(array: &'a ArrayLinkedList<T>, prev_index: usize) -> Self {
let element = &array.elements[prev_index];
if element.data.is_some() {
Self {
front_index: element.next_index,
back_index: array.last_index,
array,
}
} else {
Self::empty(array)
}
}
fn before(array: &'a ArrayLinkedList<T>, next_index: usize) -> Self {
let element = &array.elements[next_index];
if element.data.is_some() {
Self {
front_index: array.first_index,
back_index: element.prev_index,
array,
}
} else {
Self::empty(array)
}
}
}
struct Indices<'a, T>(Indexed<'a, T>);
pub struct Values<'a, T>(Indexed<'a, T>);
impl<'a, T> Iterator for Indexed<'a, T> {
type Item = (usize, &'a T);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let index = self.front_index.index()?;
let element = &self.array.elements[index];
if self.front_index == self.back_index {
self.front_index = Id::default();
self.back_index = Id::default();
} else {
self.front_index = element.next_index;
}
Some((index, unsafe { element.data.as_ref().unwrap_unchecked() }))
}
}
impl<T> DoubleEndedIterator for Indexed<'_, T> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let index = self.back_index.index()?;
let element = &self.array.elements[index];
if self.front_index == self.back_index {
self.front_index = Id::default();
self.back_index = Id::default();
} else {
self.back_index = element.prev_index;
}
Some((index, unsafe { element.data.as_ref().unwrap_unchecked() }))
}
}
impl<T> Iterator for Indices<'_, T> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(index, _)| index)
}
}
impl<T> DoubleEndedIterator for Indices<'_, T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|(index, _)| index)
}
}
impl<'a, T> Iterator for Values<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(_, value)| value)
}
}
impl<T> DoubleEndedIterator for Values<'_, T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|(_, value)| value)
}
}
impl<'a, T> IntoIterator for &'a ArrayLinkedList<T> {
type Item = &'a T;
type IntoIter = Values<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Values(Indexed::new(self))
}
}
struct IntoIndexed<T>(ArrayLinkedList<T>);
struct IntoIndices<T>(IntoIndexed<T>);
pub struct IntoValues<T>(IntoIndexed<T>);
impl<T> Iterator for IntoIndexed<T> {
type Item = (usize, T);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let index = self.0.first_index.index()?;
let element = &mut self.0.elements[index];
if self.0.first_index == self.0.last_index {
self.0.first_index = Id::default();
self.0.last_index = Id::default();
} else {
self.0.first_index = element.next_index;
}
Some((index, unsafe { element.data.take().unwrap_unchecked() }))
}
}
impl<T> DoubleEndedIterator for IntoIndexed<T> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let index = self.0.last_index.index()?;
let element = &mut self.0.elements[index];
if self.0.first_index == self.0.last_index {
self.0.first_index = Id::default();
self.0.last_index = Id::default();
} else {
self.0.last_index = element.prev_index;
}
Some((index, unsafe { element.data.take().unwrap_unchecked() }))
}
}
impl<T> Iterator for IntoIndices<T> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(index, _)| index)
}
}
impl<T> DoubleEndedIterator for IntoIndices<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|(index, _)| index)
}
}
impl<T> Iterator for IntoValues<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(_, value)| value)
}
}
impl<T> DoubleEndedIterator for IntoValues<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|(_, value)| value)
}
}
impl<T> IntoIterator for ArrayLinkedList<T> {
type Item = T;
type IntoIter = IntoValues<T>;
fn into_iter(self) -> Self::IntoIter {
IntoValues(IntoIndexed(self))
}
}