#![cfg_attr(all(test, feature = "nightly"), feature(test))]
#[cfg(all(test, feature = "nightly"))] extern crate test;
#[cfg(all(test, feature = "nightly"))] extern crate rand;
use std::cmp::Ordering;
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};
use std::iter::{self, IntoIterator};
use std::marker::PhantomData;
use std::{ptr, mem};
struct Node<T> {
prev: Raw<T>,
next: Link<T>,
elem: T,
}
impl<T> Node<T> {
#[inline]
fn new(elem: T) -> Node<T> {
Node {
prev: Raw::none(),
next: None,
elem: elem,
}
}
#[inline]
fn link(&mut self, mut next: Box<Node<T>>) {
next.prev = Raw::some(self);
self.next = Some(next);
}
#[inline]
fn splice_next(&mut self, mut next: Box<Node<T>>) {
let mut old_next = self.next.take();
old_next.as_mut().map(|node| node.prev = Raw::some(&mut *next));
next.prev = Raw::some(self);
next.next = old_next;
self.next = Some(next);
}
#[inline]
fn take_next(&mut self) -> Option<Box<Node<T>>> {
let mut next = self.next.take();
next.as_mut().map(|node| {
node.prev = Raw::none();
});
next
}
}
type Link<T> = Option<Box<Node<T>>>;
struct Raw<T> {
ptr: *mut Node<T>,
}
impl<T> Raw<T> {
#[inline]
fn none() -> Raw<T> {
Raw { ptr: ptr::null_mut() }
}
#[inline]
fn some(ptr: &mut Node<T>) -> Raw<T> {
Raw { ptr: ptr }
}
#[inline]
fn as_ref(&self) -> Option<& Node<T>> {
unsafe {
if self.ptr.is_null() {
None
} else {
Some(&*self.ptr)
}
}
}
#[inline]
fn as_mut(&mut self) -> Option<&mut Node<T>> {
unsafe {
if self.ptr.is_null() {
None
} else {
Some(&mut *self.ptr)
}
}
}
#[inline]
fn take(&mut self) -> Raw<T> {
mem::replace(self, Raw::none())
}
#[inline]
fn clone(&mut self) -> Raw<T> {
Raw { ptr: self.ptr }
}
}
pub struct LinkedList<T> {
len: usize,
head: Link<T>,
tail: Raw<T>,
}
impl<T> LinkedList<T> {
#[inline]
pub fn new() -> LinkedList<T> {
LinkedList { head: None, tail: Raw::none(), len: 0 }
}
pub fn push_back(&mut self, elem: T) {
self.len += 1;
let mut node = Box::new(Node::new(elem));
let mut old_tail = mem::replace(&mut self.tail, Raw::some(&mut *node));
match old_tail.as_mut() {
None => self.head = Some(node),
Some(tail) => tail.link(node),
}
}
pub fn push_front(&mut self, elem: T) {
self.len += 1;
let mut node = Box::new(Node::new(elem));
match self.head.take() {
None => self.tail = Raw::some(&mut *node),
Some(head) => node.link(head),
}
self.head = Some(node);
}
pub fn pop_back(&mut self) -> Option<T> {
self.tail.take().as_mut().and_then(|tail| {
self.len -= 1;
match tail.prev.take().as_mut() {
None => self.head.take().map(|node| node.elem),
Some(prev) => {
self.tail = Raw::some(prev);
prev.next.take().map(|node| node.elem)
}
}
})
}
pub fn pop_front(&mut self) -> Option<T> {
self.head.take().map(|mut head| {
self.len -= 1;
match head.take_next() {
None => self.tail = Raw::none(),
Some(next) => self.head = Some(next),
}
head.elem
})
}
#[inline]
pub fn front(&self) -> Option<&T> {
self.head.as_ref().map(|node| &node.elem)
}
#[inline]
pub fn back(&self) -> Option<&T> {
self.tail.as_ref().map(|node| &node.elem)
}
#[inline]
pub fn front_mut(&mut self) -> Option<&mut T> {
self.head.as_mut().map(|node| &mut node.elem)
}
#[inline]
pub fn back_mut(&mut self) -> Option<&mut T> {
self.tail.as_mut().map(|node| &mut node.elem)
}
#[inline]
pub fn insert(&mut self, index: usize, elem: T) {
assert!(index <= self.len(), "index out of bounds");
let mut cursor = self.cursor();
cursor.seek_forward(index);
cursor.insert(elem);
}
#[inline]
pub fn remove(&mut self, index: usize) -> Option<T> {
if index >= self.len() {
None
} else {
let mut cursor = self.cursor();
cursor.seek_forward(index);
cursor.remove()
}
}
pub fn split_at(&mut self, index: usize) -> LinkedList<T> {
if index >= self.len() {
LinkedList::new()
} else {
let mut cursor = self.cursor();
cursor.seek_forward(index);
cursor.split()
}
}
pub fn append(&mut self, other: &mut LinkedList<T>) {
let mut cursor = self.cursor();
cursor.prev();
cursor.splice(other);
}
pub fn splice(&mut self, index: usize, other: &mut LinkedList<T>) {
let mut cursor = self.cursor();
cursor.seek_forward(index);
cursor.splice(other);
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn clear(&mut self) {
while !self.is_empty() {
self.pop_front();
}
}
#[inline]
pub fn cursor(&mut self) -> Cursor<T> {
Cursor {
list: self,
prev: Raw::none(),
index: 0,
}
}
#[inline]
pub fn iter<'a>(&'a self) -> Iter<'a, T> {
Iter{nelem: self.len(), head: &self.head, tail: &self.tail}
}
#[inline]
pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
let head_raw = match self.head.as_mut() {
Some(head) => Raw::some(&mut **head),
None => Raw::none(),
};
IterMut{
nelem: self.len(),
head: head_raw,
tail: self.tail.clone(),
phantom: PhantomData,
}
}
#[inline]
pub fn into_iter(self) -> IntoIter<T> {
IntoIter{list: self}
}
}
pub struct Cursor<'a, T: 'a> {
list: &'a mut LinkedList<T>,
prev: Raw<T>,
index: usize,
}
impl<'a, T> Cursor<'a, T> {
#[inline]
pub fn reset(&mut self) {
self.prev = Raw::none();
self.index = 0;
}
pub fn next(&mut self) -> Option<&mut T> {
self.index += 1;
match self.prev.take().as_mut() {
None => match self.list.head.as_mut() {
None => {
self.index = 0;
None
}
Some(head) => {
self.prev = Raw::some(&mut **head);
Some(&mut head.elem)
}
},
Some(prev) => match prev.next.as_mut() {
None => {
self.index = 0;
self.prev = Raw::none();
None
}
Some(next) => {
self.prev = Raw::some(&mut **next);
unsafe {
Some(mem::transmute(&mut next.elem))
}
}
}
}
}
pub fn prev(&mut self) -> Option<&mut T> {
match self.prev.take().as_mut() {
None => {
self.prev = self.list.tail.clone();
self.index = self.list.len();
None
},
Some(prev) => {
self.index -= 1;
self.prev = prev.prev.clone();
unsafe {
Some(mem::transmute(&mut prev.elem))
}
}
}
}
pub fn peek_next(&mut self) -> Option<&mut T> {
let Cursor{ref mut list, ref mut prev, ..} = *self;
match prev.as_mut() {
None => list.front_mut(),
Some(prev) => prev.next.as_mut().map(|next| &mut next.elem),
}
}
pub fn peek_prev(&mut self) -> Option<&mut T> {
self.prev.as_mut().map(|prev| &mut prev.elem)
}
pub fn insert(&mut self, elem: T) {
let Cursor{ref mut list, ref mut prev, ..} = *self;
match prev.as_mut() {
None => list.push_front(elem),
Some(node) => if node.next.as_mut().is_none() {
list.push_back(elem);
} else {
list.len += 1;
node.splice_next(Box::new(Node::new(elem)));
}
}
}
pub fn remove(&mut self) -> Option<T> {
let Cursor{ref mut list, ref mut prev, ..} = *self;
match prev.as_mut() {
None => list.pop_front(),
Some(prev) => match prev.take_next() {
None => None,
Some(mut next) => {
list.len -= 1;
match next.next.take() {
None => list.tail = Raw::some(prev),
Some(next_next) => prev.link(next_next),
}
Some(next.elem)
}
}
}
}
pub fn split(&mut self) -> LinkedList<T> {
let Cursor{ref mut list, ref mut prev, index} = *self;
let new_tail = prev.clone();
let len = list.len();
match prev.as_mut() {
None => mem::replace(*list, LinkedList::new()),
Some(prev) => {
let next_tail = list.tail.clone();
list.len = index;
list.tail = new_tail; let next_head = prev.take_next();
LinkedList {
head: next_head,
tail: next_tail,
len: len - index
}
}
}
}
pub fn splice(&mut self, other: &mut LinkedList<T>) {
if other.is_empty() { return; }
let len = other.len;
other.len = 0;
let mut head = other.head.take();
let mut tail = other.tail.take();
let Cursor{ref mut list, ref mut prev, ..} = *self;
list.len += len;
match prev.as_mut() {
None => match list.head.take() {
None => {
list.head = head;
list.tail = tail;
},
Some(self_head) => {
list.head = head;
tail.as_mut().unwrap().link(self_head);
}
},
Some(prev) => match prev.take_next() {
None => {
prev.link(head.take().unwrap());
list.tail = tail;
}
Some(next) => {
prev.link(head.take().unwrap());
tail.as_mut().unwrap().link(next);
}
}
}
}
pub fn seek_forward(&mut self, by: usize) {
for _ in 0..by { self.next(); }
}
pub fn seek_backward(&mut self, by: usize) {
for _ in 0..by { self.prev(); }
}
}
#[derive(Clone)]
pub struct Iter<'a, T:'a> {
head: &'a Link<T>,
tail: &'a Raw<T>,
nelem: usize,
}
pub struct IterMut<'a, T:'a> {
head: Raw<T>,
tail: Raw<T>,
nelem: usize,
phantom: PhantomData<&'a mut T>,
}
#[derive(Clone)]
pub struct IntoIter<T> {
list: LinkedList<T>
}
impl<'a, A> Iterator for Iter<'a, A> {
type Item = &'a A;
#[inline]
fn next(&mut self) -> Option<&'a A> {
if self.nelem == 0 {
return None;
}
self.head.as_ref().map(|head| {
self.nelem -= 1;
self.head = &head.next;
&head.elem
})
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.nelem, Some(self.nelem))
}
}
impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
#[inline]
fn next_back(&mut self) -> Option<&'a A> {
if self.nelem == 0 {
return None;
}
self.tail.as_ref().map(|tail| {
self.nelem -= 1;
self.tail = &tail.prev;
&tail.elem
})
}
}
impl<'a, A> ExactSizeIterator for Iter<'a, A> {}
impl<'a, A> Iterator for IterMut<'a, A> {
type Item = &'a mut A;
#[inline]
fn next(&mut self) -> Option<&'a mut A> {
if self.nelem == 0 {
return None;
}
self.head.take().as_mut().map(|next| {
self.nelem -= 1;
self.head = match next.next {
Some(ref mut node) => Raw::some(&mut **node),
None => Raw::none(),
};
unsafe {
&mut *((&mut next.elem) as *mut _)
}
})
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.nelem, Some(self.nelem))
}
}
impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
#[inline]
fn next_back(&mut self) -> Option<&'a mut A> {
if self.nelem == 0 {
return None;
}
self.tail.take().as_mut().map(|prev| {
self.nelem -= 1;
self.tail = prev.prev.clone();
unsafe {
&mut *((&mut prev.elem) as *mut _)
}
})
}
}
impl<'a, A> ExactSizeIterator for IterMut<'a, A> {}
impl<A> Iterator for IntoIter<A> {
type Item = A;
#[inline]
fn next(&mut self) -> Option<A> { self.list.pop_front() }
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.list.len(), Some(self.list.len()))
}
}
impl<A> DoubleEndedIterator for IntoIter<A> {
#[inline]
fn next_back(&mut self) -> Option<A> { self.list.pop_back() }
}
impl<T> Drop for LinkedList<T> {
fn drop(&mut self) {
self.clear()
}
}
impl<A> iter::FromIterator<A> for LinkedList<A> {
fn from_iter<T: IntoIterator<Item=A>>(iter: T) -> LinkedList<A> {
let mut ret = LinkedList::new();
ret.extend(iter);
ret
}
}
impl<A> Extend<A> for LinkedList<A> {
fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T) {
for elt in iter { self.push_back(elt); }
}
}
impl<A: PartialEq> PartialEq for LinkedList<A> {
fn eq(&self, other: &Self) -> bool {
if self.len() == other.len() {
let mut a = self.iter();
let mut b = other.iter();
loop {
match (a.next(), b.next()) {
(Some(x), Some(y)) => if x != y {
return false;
},
(None, None) => return true,
_ => return false
}
}
} else {
false
}
}
}
impl<A: Eq> Eq for LinkedList<A> {}
impl<A: PartialOrd> PartialOrd for LinkedList<A> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let mut a = self.iter();
let mut b = other.iter();
loop {
match (a.next(), b.next()) {
(Some(x), Some(y)) => match x.partial_cmp(&y) {
Some(Ordering::Equal) => {}
otherwise => return otherwise,
},
(None, None) => return Some(Ordering::Equal),
(None, _) => return Some(Ordering::Less),
(_, None) => return Some(Ordering::Greater),
}
}
}
}
impl<A: Ord> Ord for LinkedList<A> {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
impl<A: fmt::Debug> fmt::Debug for LinkedList<A> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "["));
for (i, e) in self.iter().enumerate() {
if i != 0 { try!(write!(f, ", ")); }
try!(write!(f, "{:?}", *e));
}
write!(f, "]")
}
}
impl<A: Hash> Hash for LinkedList<A> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.len().hash(state);
for elt in self.iter() {
elt.hash(state);
}
}
}
impl<T: Clone> Clone for LinkedList<T> {
fn clone(&self) -> LinkedList<T> {
self.iter().cloned().collect()
}
}
impl<'a, T> IntoIterator for &'a LinkedList<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> { self.iter() }
}
impl<'a, T> IntoIterator for &'a mut LinkedList<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> IterMut<'a, T> { self.iter_mut() }
}
impl<T> IntoIterator for LinkedList<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> { self.into_iter() }
}
#[cfg(test)]
mod tests {
use super::LinkedList;
fn generate_test() -> LinkedList<i32> {
list_from(&[0,1,2,3,4,5,6])
}
fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
v.iter().map(|x| (*x).clone()).collect()
}
#[test]
fn test_basic() {
let mut m = LinkedList::new();
assert_eq!(m.pop_front(), None);
assert_eq!(m.pop_back(), None);
assert_eq!(m.pop_front(), None);
m.push_front(1);
assert_eq!(m.pop_front(), Some(1));
m.push_back(2);
m.push_back(3);
assert_eq!(m.len(), 2);
assert_eq!(m.pop_front(), Some(2));
assert_eq!(m.pop_front(), Some(3));
assert_eq!(m.len(), 0);
assert_eq!(m.pop_front(), None);
m.push_back(1);
m.push_back(3);
m.push_back(5);
m.push_back(7);
assert_eq!(m.pop_front(), Some(1));
let mut n = LinkedList::new();
n.push_front(2);
n.push_front(3);
{
assert_eq!(n.front().unwrap(), &3);
let x = n.front_mut().unwrap();
assert_eq!(*x, 3);
*x = 0;
}
{
assert_eq!(n.back().unwrap(), &2);
let y = n.back_mut().unwrap();
assert_eq!(*y, 2);
*y = 1;
}
assert_eq!(n.pop_front(), Some(0));
assert_eq!(n.pop_front(), Some(1));
}
#[test]
fn test_iterator() {
let m = generate_test();
for (i, elt) in m.iter().enumerate() {
assert_eq!(i as i32, *elt);
}
let mut n = LinkedList::new();
assert_eq!(n.iter().next(), None);
n.push_front(4);
let mut it = n.iter();
assert_eq!(it.size_hint(), (1, Some(1)));
assert_eq!(it.next().unwrap(), &4);
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next(), None);
}
#[test]
fn test_iterator_double_end() {
let mut n = LinkedList::new();
assert_eq!(n.iter().next(), None);
n.push_front(4);
n.push_front(5);
n.push_front(6);
let mut it = n.iter();
assert_eq!(it.size_hint(), (3, Some(3)));
assert_eq!(it.next().unwrap(), &6);
assert_eq!(it.size_hint(), (2, Some(2)));
assert_eq!(it.next_back().unwrap(), &4);
assert_eq!(it.size_hint(), (1, Some(1)));
assert_eq!(it.next_back().unwrap(), &5);
assert_eq!(it.next_back(), None);
assert_eq!(it.next(), None);
}
#[test]
fn test_rev_iter() {
let m = generate_test();
for (i, elt) in m.iter().rev().enumerate() {
assert_eq!(6 - i as i32, *elt);
}
let mut n = LinkedList::new();
assert_eq!(n.iter().rev().next(), None);
n.push_front(4);
let mut it = n.iter().rev();
assert_eq!(it.size_hint(), (1, Some(1)));
assert_eq!(it.next().unwrap(), &4);
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next(), None);
}
#[test]
fn test_mut_iter() {
let mut m = generate_test();
let mut len = m.len();
for (i, elt) in m.iter_mut().enumerate() {
assert_eq!(i as i32, *elt);
len -= 1;
}
assert_eq!(len, 0);
let mut n = LinkedList::new();
assert!(n.iter_mut().next().is_none());
n.push_front(4);
n.push_back(5);
let mut it = n.iter_mut();
assert_eq!(it.size_hint(), (2, Some(2)));
assert!(it.next().is_some());
assert!(it.next().is_some());
assert_eq!(it.size_hint(), (0, Some(0)));
assert!(it.next().is_none());
}
#[test]
fn test_iterator_mut_double_end() {
let mut n = LinkedList::new();
assert!(n.iter_mut().next_back().is_none());
n.push_front(4);
n.push_front(5);
n.push_front(6);
let mut it = n.iter_mut();
assert_eq!(it.size_hint(), (3, Some(3)));
assert_eq!(*it.next().unwrap(), 6);
assert_eq!(it.size_hint(), (2, Some(2)));
assert_eq!(*it.next_back().unwrap(), 4);
assert_eq!(it.size_hint(), (1, Some(1)));
assert_eq!(*it.next_back().unwrap(), 5);
assert!(it.next_back().is_none());
assert!(it.next().is_none());
}
#[test]
fn test_eq() {
let mut n: LinkedList<u8> = list_from(&[]);
let mut m = list_from(&[]);
assert!(n == m);
n.push_front(1);
assert!(n != m);
m.push_back(1);
assert!(n == m);
let n = list_from(&[2,3,4]);
let m = list_from(&[1,2,3]);
assert!(n != m);
}
#[test]
fn test_ord() {
let n = list_from(&[]);
let m = list_from(&[1,2,3]);
assert!(n < m);
assert!(m > n);
assert!(n <= n);
assert!(n >= n);
}
#[test]
fn test_ord_nan() {
let nan = 0.0f64/0.0;
let n = list_from(&[nan]);
let m = list_from(&[nan]);
assert!(!(n < m));
assert!(!(n > m));
assert!(!(n <= m));
assert!(!(n >= m));
let n = list_from(&[nan]);
let one = list_from(&[1.0f64]);
assert!(!(n < one));
assert!(!(n > one));
assert!(!(n <= one));
assert!(!(n >= one));
let u = list_from(&[1.0f64,2.0,nan]);
let v = list_from(&[1.0f64,2.0,3.0]);
assert!(!(u < v));
assert!(!(u > v));
assert!(!(u <= v));
assert!(!(u >= v));
let s = list_from(&[1.0f64,2.0,4.0,2.0]);
let t = list_from(&[1.0f64,2.0,3.0,2.0]);
assert!(!(s < t));
assert!(s > one);
assert!(!(s <= one));
assert!(s >= one);
}
#[test]
fn test_debug() {
let list: LinkedList<i32> = (0..10).collect();
assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
let list: LinkedList<&str> = vec!["just", "one", "test", "more"].iter()
.map(|&s| s)
.collect();
assert_eq!(format!("{:?}", list), r#"["just", "one", "test", "more"]"#);
}
#[test]
fn test_cursor_seek() {
let mut list = list_from(&[0,1,2,3,4]);
let mut curs = list.cursor();
assert_eq!(*curs.peek_next().unwrap(), 0);
assert_eq!(*curs.next().unwrap(), 0);
assert_eq!(*curs.peek_next().unwrap(), 1);
assert_eq!(*curs.next().unwrap(), 1);
assert_eq!(*curs.next().unwrap(), 2);
assert_eq!(*curs.next().unwrap(), 3);
assert_eq!(*curs.next().unwrap(), 4);
assert_eq!(curs.peek_next(), None);
assert_eq!(curs.next(), None);
assert_eq!(*curs.next().unwrap(), 0);
assert_eq!(*curs.peek_prev().unwrap(), 0);
assert_eq!(*curs.prev().unwrap(), 0);
assert_eq!(curs.peek_prev(), None);
assert_eq!(curs.prev(), None);
assert_eq!(*curs.peek_prev().unwrap(), 4);
assert_eq!(*curs.prev().unwrap(), 4);
assert_eq!(*curs.prev().unwrap(), 3);
assert_eq!(*curs.prev().unwrap(), 2);
assert_eq!(*curs.prev().unwrap(), 1);
assert_eq!(*curs.prev().unwrap(), 0);
assert_eq!(curs.prev(), None);
}
#[test]
fn test_cursor_insert() {
let mut list = list_from(&[0,1,2,3,4]);
{
let mut curs = list.cursor();
curs.prev();
curs.insert(6);
curs.insert(5);
assert_eq!(*curs.next().unwrap(), 5);
assert_eq!(*curs.next().unwrap(), 6);
assert_eq!(curs.next(), None);
curs.insert(-1);
curs.insert(-2);
assert_eq!(*curs.next().unwrap(), -2);
assert_eq!(*curs.next().unwrap(), -1);
assert_eq!(*curs.next().unwrap(), 0);
assert_eq!(*curs.prev().unwrap(), 0);
assert_eq!(*curs.prev().unwrap(), -1);
assert_eq!(*curs.prev().unwrap(), -2);
assert_eq!(curs.prev(), None);
assert_eq!(*curs.prev().unwrap(), 6);
assert_eq!(*curs.prev().unwrap(), 5);
assert_eq!(*curs.prev().unwrap(), 4);
assert_eq!(*curs.prev().unwrap(), 3);
curs.insert(275); curs.insert(250);
curs.insert(225);
assert_eq!(*curs.next().unwrap(), 225);
assert_eq!(*curs.next().unwrap(), 250);
assert_eq!(*curs.next().unwrap(), 275);
assert_eq!(*curs.next().unwrap(), 3);
assert_eq!(*curs.next().unwrap(), 4);
assert_eq!(*curs.prev().unwrap(), 4);
assert_eq!(*curs.prev().unwrap(), 3);
assert_eq!(*curs.prev().unwrap(), 275);
assert_eq!(*curs.prev().unwrap(), 250);
assert_eq!(*curs.prev().unwrap(), 225);
assert_eq!(*curs.prev().unwrap(), 2);
assert_eq!(*curs.prev().unwrap(), 1);
}
assert_eq!(list.len(), 12);
}
#[test]
fn test_cursor_remove() {
let mut list = list_from(&[0,1,2,3,4,5,6,7]);
{
let mut curs = list.cursor();
assert_eq!(curs.remove().unwrap(), 0);
assert_eq!(curs.remove().unwrap(), 1);
assert_eq!(*curs.next().unwrap(), 2);
assert_eq!(*curs.next().unwrap(), 3);
assert_eq!(*curs.prev().unwrap(), 3);
assert_eq!(*curs.prev().unwrap(), 2);
assert_eq!(curs.prev(), None);
assert_eq!(*curs.prev().unwrap(), 7);
assert_eq!(curs.remove().unwrap(), 7);
assert_eq!(curs.remove(), None); assert_eq!(*curs.prev().unwrap(), 6);
assert_eq!(curs.remove().unwrap(), 6);
assert_eq!(*curs.prev().unwrap(), 5);
assert_eq!(*curs.prev().unwrap(), 4);
assert_eq!(*curs.next().unwrap(), 4);
assert_eq!(*curs.next().unwrap(), 5);
assert_eq!(curs.next(), None);
assert_eq!(*curs.next().unwrap(), 2);
assert_eq!(curs.remove().unwrap(), 3);
assert_eq!(curs.remove().unwrap(), 4);
assert_eq!(*curs.next().unwrap(), 5);
assert_eq!(curs.next(), None);
assert_eq!(*curs.next().unwrap(), 2);
assert_eq!(*curs.next().unwrap(), 5);
assert_eq!(*curs.prev().unwrap(), 5);
assert_eq!(*curs.prev().unwrap(), 2);
assert_eq!(curs.prev(), None);
assert_eq!(*curs.prev().unwrap(), 5);
}
assert_eq!(list.len(), 2);
}
#[test]
fn test_append() {
let mut list1 = list_from(&[0,1,2,3]);
let mut list2 = list_from(&[4,5,6,7]);
list1.append(&mut list2);
assert_eq!(&list1, &list_from(&[0,1,2,3,4,5,6,7]));
assert_eq!(&list2, &LinkedList::new());
assert_eq!(list1.len(), 8);
assert_eq!(list2.len(), 0);
list2.append(&mut list1);
assert_eq!(&list2, &list_from(&[0,1,2,3,4,5,6,7]));
assert_eq!(&list1, &LinkedList::new());
assert_eq!(list2.len(), 8);
assert_eq!(list1.len(), 0);
list2.append(&mut list1);
assert_eq!(&list2, &list_from(&[0,1,2,3,4,5,6,7]));
assert_eq!(&list1, &LinkedList::new());
assert_eq!(list2.len(), 8);
assert_eq!(list1.len(), 0);
}
#[test]
fn test_split_at() {
let mut list2 = list_from(&[4,5,6,7]);
let mut list3 = list2.split_at(0);
assert_eq!(&list3, &list_from(&[4,5,6,7]));
assert_eq!(&list2, &LinkedList::new());
assert_eq!(list3.len(), 4);
assert_eq!(list2.len(), 0);
let list4 = list3.split_at(4);
assert_eq!(&list3, &list_from(&[4,5,6,7]));
assert_eq!(&list4, &LinkedList::new());
assert_eq!(list3.len(), 4);
assert_eq!(list4.len(), 0);
let list5 = list3.split_at(2);
assert_eq!(&list3, &list_from(&[4,5]));
assert_eq!(&list5, &list_from(&[6,7]));
assert_eq!(list3.len(), 2);
assert_eq!(list5.len(), 2);
}
#[test]
fn test_splice() {
let mut list1 = list_from(&[3,4,5]);
let mut list2 = list_from(&[1,2,6,7]);
let mut list3 = LinkedList::new();
list1.splice(2, &mut list3);
assert_eq!(&list1, &list_from(&[3,4,5]));
assert_eq!(&list3, &LinkedList::new());
assert_eq!(list1.len(), 3);
assert_eq!(list3.len(), 0);
list2.splice(2, &mut list1);
assert_eq!(&list2, &list_from(&[1,2,3,4,5,6,7]));
assert_eq!(&list1, &LinkedList::new());
assert_eq!(list2.len(), 7);
assert_eq!(list1.len(), 0);
}
}
#[cfg(all(test, feature = "nightly"))]
mod bench{
use super::LinkedList;
use test;
#[bench]
fn bench_collect_into(b: &mut test::Bencher) {
let v = &[0i32; 64];
b.iter(|| {
let _: LinkedList<i32> = v.iter().map(|x| *x).collect();
})
}
#[bench]
fn bench_push_front(b: &mut test::Bencher) {
let mut m: LinkedList<i32> = LinkedList::new();
b.iter(|| {
m.push_front(0);
})
}
#[bench]
fn bench_push_back(b: &mut test::Bencher) {
let mut m: LinkedList<i32> = LinkedList::new();
b.iter(|| {
m.push_back(0);
})
}
#[bench]
fn bench_push_back_pop_back(b: &mut test::Bencher) {
let mut m: LinkedList<i32> = LinkedList::new();
b.iter(|| {
m.push_back(0);
m.pop_back();
})
}
#[bench]
fn bench_push_front_pop_front(b: &mut test::Bencher) {
let mut m: LinkedList<i32> = LinkedList::new();
b.iter(|| {
m.push_front(0);
m.pop_front();
})
}
#[bench]
fn bench_iter(b: &mut test::Bencher) {
let v = &[0; 128];
let m: LinkedList<i32> = v.iter().map(|&x|x).collect();
b.iter(|| {
assert!(m.iter().count() == 128);
})
}
#[bench]
fn bench_iter_mut(b: &mut test::Bencher) {
let v = &[0; 128];
let mut m: LinkedList<i32> = v.iter().map(|&x|x).collect();
b.iter(|| {
assert!(m.iter_mut().count() == 128);
})
}
#[bench]
fn bench_iter_rev(b: &mut test::Bencher) {
let v = &[0; 128];
let m: LinkedList<i32> = v.iter().map(|&x|x).collect();
b.iter(|| {
assert!(m.iter().rev().count() == 128);
})
}
#[bench]
fn bench_iter_mut_rev(b: &mut test::Bencher) {
let v = &[0; 128];
let mut m: LinkedList<i32> = v.iter().map(|&x|x).collect();
b.iter(|| {
assert!(m.iter_mut().rev().count() == 128);
})
}
}