use std::iter::IntoIterator;
use std::iter::FromIterator;
type Ix = usize;
const END: usize = std::usize::MAX;
#[derive(Clone, Debug)]
pub struct Node<T> {
link: [usize; 2],
pub value: T,
}
impl<T> Node<T> {
fn new(value: T, prev: Ix, next: Ix) -> Self
{
Node {
value: value,
link: [prev, next],
}
}
fn prev(&self) -> Ix { self.link[0] }
fn next(&self) -> Ix { self.link[1] }
fn set_prev(&mut self, index: Ix) { self.link[0] = index; }
fn set_next(&mut self, index: Ix) { self.link[1] = index; }
}
#[derive(Clone, Debug)]
pub struct List<T> {
link: [usize; 2],
nodes: Vec<Node<T>>,
}
#[derive(Copy, Clone, PartialEq, Debug)]
enum Terminal {
Head = 0,
Tail = 1,
}
impl Terminal
{
#[inline]
pub fn opposite(&self) -> Self
{
match *self {
Terminal::Head => Terminal::Tail,
Terminal::Tail => Terminal::Head,
}
}
#[inline]
pub fn index(&self) -> usize { *self as usize }
}
#[derive(Copy, Clone, Debug)]
pub struct Iter<'a, T: 'a>
{
link: [usize; 2],
nodes: &'a [Node<T>],
taken: usize,
}
#[derive(Debug)]
pub struct IterMut<'a, T: 'a>
{
link: [usize; 2],
nodes: &'a mut [Node<T>],
taken: usize,
}
#[derive(Debug)]
pub struct Cursor<'a, T: 'a>
{
pos: usize,
list: &'a mut List<T>,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub enum Seek {
Forward(usize),
Backward(usize),
Head,
Tail,
}
impl<T> List<T>
{
pub fn new() -> Self { List::with_capacity(0) }
pub fn with_capacity(cap: usize) -> Self
{
List{
link: [END; 2], nodes: Vec::with_capacity(cap),
}
}
fn head(&self) -> usize { self.link[0] }
fn tail(&self) -> usize { self.link[1] }
pub fn len(&self) -> usize
{
self.nodes.len()
}
pub fn iter(&self) -> Iter<T>
{
Iter {
link: self.link,
nodes: &*self.nodes,
taken: 0,
}
}
pub fn iter_mut(&mut self) -> IterMut<T>
{
IterMut {
link: self.link,
nodes: &mut *self.nodes,
taken: 0,
}
}
pub fn cursor(&mut self) -> Cursor<T>
{
Cursor {
pos: self.head(),
list: self,
}
}
fn push_terminal(&mut self, value: T, term: Terminal)
{
let t = term as usize;
let index = self.nodes.len();
let mut node = Node::new(value, END, END);
node.link[1 - t] = self.link[t];
match self.nodes.get_mut(self.link[t]) {
None => self.link[1 - t] = index, Some(n) => n.link[t] = index,
}
self.link[t] = index;
self.nodes.push(node);
}
pub fn push_front(&mut self, value: T) {
self.push_terminal(value, Terminal::Head)
}
pub fn push_back(&mut self, value: T) {
self.push_terminal(value, Terminal::Tail)
}
fn prepare_remove(&mut self, idx: usize)
{
let prev = self.nodes[idx].prev();
let next = self.nodes[idx].next();
match self.nodes.get_mut(prev) {
None => {}
Some(n) => n.set_next(next),
}
match self.nodes.get_mut(next) {
None => {}
Some(n) => n.set_prev(prev),
}
}
fn prepare_move(&mut self, idx: usize, to_index: usize)
{
let prev = self.nodes[idx].prev();
let next = self.nodes[idx].next();
match self.nodes.get_mut(prev) {
None => {}
Some(n) => n.set_next(to_index),
}
match self.nodes.get_mut(next) {
None => {}
Some(n) => n.set_prev(to_index),
}
}
fn prepare_swap(&mut self, free_spot: usize, moved_index: usize)
{
if free_spot == moved_index {
return
}
self.prepare_move(moved_index, free_spot);
if self.head() == moved_index {
self.link[0] = free_spot;
}
if self.tail() == moved_index {
self.link[1] = free_spot;
}
}
fn pop_terminal(&mut self, term: Terminal) -> Option<T>
{
let t = term as usize;
if self.link[t] == END {
return None
}
let h = self.link[t];
let new_terminal = self.nodes[h].link[1 - t];
self.prepare_remove(h);
self.link[t] = new_terminal;
if self.link[t] == END {
self.link[1 - t] = END;
} else {
let moved_index = self.nodes.len() - 1; self.prepare_swap(h, moved_index);
}
let removed_node = self.nodes.swap_remove(h);
Some(removed_node.value)
}
pub fn pop_front(&mut self) -> Option<T>
{
self.pop_terminal(Terminal::Head)
}
pub fn pop_back(&mut self) -> Option<T>
{
self.pop_terminal(Terminal::Tail)
}
pub fn linearize(&mut self)
{
if self.len() == 0 {
return;
}
let mut head = self.head();
let mut index = 0;
while let Some(n) = self.nodes.get_mut(head) {
index += 1;
head = n.next();
n.set_next(index);
}
self.nodes.sort_unstable_by_key(Node::next);
for (index, node) in self.nodes[1..].iter_mut().enumerate() {
node.set_prev(index);
}
self.link[0] = 0;
self.link[1] = self.len() - 1;
self.nodes[self.link[0]].set_prev(END);
self.nodes[self.link[1]].set_next(END);
}
}
impl<'a, T> FromIterator<T> for List<T>
{
fn from_iter<I>(iter: I) -> Self
where I: IntoIterator<Item=T>
{
let mut result = List::new();
result.extend(iter);
result
}
}
impl<'a, T> Extend<T> for List<T>
{
fn extend<I>(&mut self, iter: I) where I: IntoIterator<Item=T>
{
let mut iter = iter.into_iter();
let (low, _) = iter.size_hint();
self.nodes.reserve(low);
let tail = self.tail();
let index = self.nodes.len();
for elt in iter.by_ref() {
let node = Node::new(elt, tail, index + 1);
self.nodes.push(node);
break;
}
for (i, elt) in iter.enumerate() {
let node = Node::new(elt, index + i, index + i + 2);
self.nodes.push(node);
}
if self.nodes.len() == 0 {
return;
}
match self.nodes.get_mut(self.link[1]) {
None => self.link[0] = index, Some(tailn) => tailn.set_next(index),
}
self.link[1] = self.nodes.len() - 1;
self.nodes[self.link[1]].set_next(END);
}
}
impl<'a, T: 'a> Iter<'a, T>
{
fn next_terminal(&mut self, term: Terminal) -> Option<&'a T>
{
let h = term.index();
let t = term.opposite().index();
match self.nodes.get(self.link[h]) {
None => None,
Some(n) => {
let elt = Some(&n.value);
self.taken += 1;
if self.link[h] == self.link[t] {
self.link[0] = END;
self.link[1] = END;
} else {
self.link[h] = n.link[t];
}
elt
}
}
}
}
impl<'a, T: 'a> Iterator for Iter<'a, T>
{
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<&'a T> { self.next_terminal(Terminal::Head) }
fn size_hint(&self) -> (usize, Option<usize>)
{
let len = self.nodes.len() - self.taken;
(len, Some(len))
}
}
impl<'a, T: 'a> DoubleEndedIterator for Iter<'a, T>
{
#[inline]
fn next_back(&mut self) -> Option<&'a T> { self.next_terminal(Terminal::Tail) }
}
impl<'a, T: 'a> IterMut<'a, T>
{
fn next_terminal(&mut self, term: Terminal) -> Option<&'a mut T>
{
let h = term.index();
let t = term.opposite().index();
match self.nodes.get_mut(self.link[h]) {
None => None,
Some(n) => {
let long_life_value = unsafe {
&mut *(&mut n.value as *mut _)
};
let elt = Some(long_life_value);
self.taken += 1;
if self.link[h] == self.link[t] {
self.link = [END, END];
} else {
self.link[h] = n.link[t];
}
elt
}
}
}
}
impl<'a, T: 'a> Iterator for IterMut<'a, T>
{
type Item = &'a mut T;
#[inline]
fn next(&mut self) -> Option<&'a mut T> { self.next_terminal(Terminal::Head) }
fn size_hint(&self) -> (usize, Option<usize>)
{
let len = self.nodes.len() - self.taken;
(len, Some(len))
}
}
impl<'a, T: 'a> DoubleEndedIterator for IterMut<'a, T>
{
#[inline]
fn next_back(&mut self) -> Option<&'a mut T> { self.next_terminal(Terminal::Tail) }
}
impl<'a, T: 'a> Cursor<'a, T>
{
pub fn next(&mut self) -> Option<&mut T>
{
match self.list.nodes.get_mut(self.pos) {
None => {
self.pos = self.list.link[0];
None
}
Some(n) => {
self.pos = n.next();
Some(&mut n.value)
}
}
}
pub fn prev(&mut self) -> Option<&mut T>
{
if self.pos == self.list.head() {
self.pos = END;
return None;
}
let prev =
match self.list.nodes.get(self.pos) {
None => self.list.tail(),
Some(n) => n.prev(),
};
match self.list.nodes.get_mut(prev) {
None => None,
Some(n) => {
self.pos = prev;
Some(&mut n.value)
}
}
}
pub fn insert(&mut self, value: T)
{
let index = self.list.len();
if self.pos == END {
self.list.push_back(value);
self.pos = index;
} else if self.pos == self.list.head() {
self.list.push_front(value);
self.pos = index;
} else {
let prev = self.list.nodes[self.pos].prev();
let node = Node::new(value, prev, self.pos);
match self.list.nodes.get_mut(prev) {
None => self.list.link[0] = index, Some(n) => n.set_next(index),
}
self.list.nodes[self.pos].set_prev(index);
self.list.nodes.push(node);
self.pos = index;
}
}
pub fn seek(&mut self, offset: Seek)
{
match offset {
Seek::Head => self.pos = self.list.head(),
Seek::Tail => self.pos = END,
Seek::Forward(n) => for _ in 0..n { if self.pos == END { break; } self.next(); },
Seek::Backward(n) => for _ in 0..n { if self.pos == self.list.head() { break; } self.prev(); }
}
}
}