use std::collections::{dlist, ring_buf, DList, RingBuf};
use std::iter;
use std::fmt;
use std::mem;
use std::hash::{Hash, Writer};
use std::num::Int;
use traverse::Traversal;
#[deriving(Clone)]
pub struct BList<T> {
list: DList<RingBuf<T>>,
b: uint,
len: uint,
}
impl<T> BList<T> {
pub fn new() -> BList<T> {
BList::with_b(6)
}
pub fn with_b(b: uint) -> BList<T> {
assert!(b > 1, "B must be > 1");
BList {
list: DList::new(),
b: b,
len: 0,
}
}
}
impl<T> BList<T> {
pub fn push_back(&mut self, elem: T) {
self.len = self.len.checked_add(1).expect("capacity overflow");
let b = self.b;
let max = block_max(b);
if let Some(block) = self.list.back_mut() {
if block.len() < max {
block.push_back(elem);
return;
}
}
let mut new_block = make_block(b);
new_block.push_back(elem);
self.list.push_back(new_block);
}
pub fn push_front(&mut self, elem: T) {
self.len = self.len.checked_add(1).expect("capacity overflow");
let b = self.b;
let max = block_max(b);
if let Some(block) = self.list.front_mut() {
if block.len() < max {
block.push_front(elem);
return;
}
}
let mut new_block = make_block(b);
new_block.push_front(elem);
self.list.push_front(new_block);
}
pub fn pop_back(&mut self) -> Option<T> {
let (result, should_pop) = match self.list.back_mut() {
None => (None, false),
Some(block) => (block.pop_back(), block.is_empty()),
};
if should_pop {
self.list.pop_back();
}
if result.is_some() {
self.len -= 1;
}
result
}
pub fn pop_front(&mut self) -> Option<T> {
let (result, should_pop) = match self.list.front_mut() {
None => (None, false),
Some(block) => (block.pop_front(), block.is_empty()),
};
if should_pop {
self.list.pop_front();
}
if result.is_some() {
self.len -= 1;
}
result
}
pub fn front(&self) -> Option<&T> {
self.list.front().and_then(|block| block.front())
}
pub fn back(&self) -> Option<&T> {
self.list.back().and_then(|block| block.back())
}
pub fn front_mut(&mut self) -> Option<&mut T> {
self.list.front_mut().and_then(|block| block.front_mut())
}
pub fn back_mut(&mut self) -> Option<&mut T> {
self.list.back_mut().and_then(|block| block.back_mut())
}
pub fn len(&self) -> uint {
self.len
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn clear(&mut self) {
self.list.clear();
}
pub fn iter(&self) -> Items<T> {
let len = self.len();
Items { iter: AbsItems {
list_iter: self.list.iter(),
right_block_iter: None,
left_block_iter: None,
len: len,
} }
}
pub fn iter_mut(&mut self) -> MutItems<T> {
let len = self.len();
MutItems { iter: AbsItems {
list_iter: self.list.iter_mut(),
right_block_iter: None,
left_block_iter: None,
len: len,
} }
}
pub fn traversal(&self) -> Trav<T> {
Trav { list: self }
}
pub fn traversal_mut(&mut self) -> MutTrav<T> {
MutTrav { list: self }
}
pub fn into_traversal(self) -> MoveTrav<T> {
MoveTrav { list: self }
}
pub fn append_lazy(&mut self, other: &mut BList<T>) {
let list = mem::replace(&mut other.list, DList::new());
self.list.append(list);
}
}
fn make_block<T>(b: uint) -> RingBuf<T> {
RingBuf::with_capacity(block_max(b))
}
fn block_max(b: uint) -> uint {
b + 1
}
#[allow(unused)]
fn block_min(b: uint) -> uint {
b - 1
}
trait Traverse<I> {
fn traverse(self) -> I;
}
impl<'a, T> Traverse<ring_buf::Items<'a, T>> for &'a RingBuf<T> {
fn traverse(self) -> ring_buf::Items<'a, T> { self.iter() }
}
impl<'a, T> Traverse<ring_buf::MutItems<'a, T>> for &'a mut RingBuf<T> {
fn traverse(self) -> ring_buf::MutItems<'a, T> { self.iter_mut() }
}
pub struct Items<'a, T: 'a> {
iter: AbsItems<dlist::Items<'a, RingBuf<T>>, ring_buf::Items<'a, T>>,
}
pub struct MutItems<'a, T: 'a> {
iter: AbsItems<dlist::MutItems<'a, RingBuf<T>>, ring_buf::MutItems<'a, T>>,
}
struct AbsItems<DListIter, RingBufIter> {
list_iter: DListIter,
left_block_iter: Option<RingBufIter>,
right_block_iter: Option<RingBufIter>,
len: uint,
}
impl<A,
RingBufIter: Iterator<A>,
DListIter: Iterator<T>,
T: Traverse<RingBufIter>> Iterator<A> for AbsItems<DListIter, RingBufIter> {
fn next(&mut self) -> Option<A> {
if self.len > 0 { self.len -= 1; }
loop {
let (ret, iter) = match self.left_block_iter.as_mut() {
None => match self.list_iter.next() {
None => match self.right_block_iter.as_mut() {
None => return None,
Some(iter) => return iter.next(),
},
Some(block) => {
let mut next_iter = block.traverse();
let next = next_iter.next();
(next, Some(next_iter))
},
},
Some(iter) => match iter.next() {
None => (None, None),
Some(next) => return Some(next),
},
};
self.left_block_iter = iter;
if ret.is_some() {
return ret;
}
}
}
fn size_hint(&self) -> (uint, Option<uint>) {
(self.len, Some(self.len))
}
}
impl<A,
RingBufIter: DoubleEndedIterator<A>,
DListIter: DoubleEndedIterator<T>,
T: Traverse<RingBufIter>> DoubleEndedIterator<A> for AbsItems<DListIter, RingBufIter> {
fn next_back(&mut self) -> Option<A> {
if self.len > 0 { self.len -= 1; }
loop {
let (ret, iter) = match self.right_block_iter.as_mut() {
None => match self.list_iter.next_back() {
None => match self.left_block_iter.as_mut() {
None => return None,
Some(iter) => return iter.next_back(),
},
Some(block) => {
let mut next_iter = block.traverse();
let next = next_iter.next_back();
(next, Some(next_iter))
},
},
Some(iter) => match iter.next_back() {
None => (None, None),
Some(next) => return Some(next),
},
};
self.right_block_iter = iter;
if ret.is_some() {
return ret;
}
}
}
}
impl<'a, T> Iterator<&'a T> for Items<'a, T> {
fn next(&mut self) -> Option<&'a T> { self.iter.next() }
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
}
impl<'a, T> DoubleEndedIterator<&'a T> for Items<'a, T> {
fn next_back(&mut self) -> Option<&'a T> { self.iter.next_back() }
}
impl<'a, T> ExactSizeIterator<&'a T> for Items<'a, T> {}
impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
fn next(&mut self) -> Option<&'a mut T> { self.iter.next() }
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
}
impl<'a, T> DoubleEndedIterator<&'a mut T> for MutItems<'a, T> {
fn next_back(&mut self) -> Option<&'a mut T> { self.iter.next_back() }
}
impl<'a, T> ExactSizeIterator<&'a mut T> for MutItems<'a, T> {}
pub struct Trav<'a, T: 'a> {
list: &'a BList<T>,
}
pub struct MutTrav<'a, T: 'a> {
list: &'a mut BList<T>,
}
pub struct MoveTrav<T> {
list: BList<T>,
}
impl<'a, T> Traversal<&'a T> for Trav<'a, T> {
fn foreach<F: FnMut(&'a T) -> bool>(self, mut f: F) {
for node in self.list.list.iter() {
for elem in node.iter() {
if f(elem) { return; }
}
}
}
}
impl<'a, T> Traversal<&'a mut T> for MutTrav<'a, T> {
fn foreach<F: FnMut(&'a mut T) -> bool>(self, mut f: F) {
for node in self.list.list.iter_mut() {
for elem in node.iter_mut() {
if f(elem) { return; }
}
}
}
}
impl<T> Traversal<T> for MoveTrav<T> {
fn foreach<F: FnMut(T) -> bool>(self, mut f: F) {
for node in self.list.list.into_iter() {
for elem in node.into_iter() {
if f(elem) { return; }
}
}
}
}
impl<A> FromIterator<A> for BList<A> {
fn from_iter<T: Iterator<A>>(iterator: T) -> BList<A> {
let mut ret = BList::new();
ret.extend(iterator);
ret
}
}
impl<A> Extend<A> for BList<A> {
fn extend<T: Iterator<A>>(&mut self, mut iterator: T) {
for elt in iterator { self.push_back(elt); }
}
}
impl<A: PartialEq> PartialEq for BList<A> {
fn eq(&self, other: &BList<A>) -> bool {
self.len() == other.len() &&
iter::order::eq(self.iter(), other.iter())
}
fn ne(&self, other: &BList<A>) -> bool {
self.len() != other.len() ||
iter::order::ne(self.iter(), other.iter())
}
}
impl<A: Eq> Eq for BList<A> {}
impl<A: PartialOrd> PartialOrd for BList<A> {
fn partial_cmp(&self, other: &BList<A>) -> Option<Ordering> {
iter::order::partial_cmp(self.iter(), other.iter())
}
}
impl<A: Ord> Ord for BList<A> {
#[inline]
fn cmp(&self, other: &BList<A>) -> Ordering {
iter::order::cmp(self.iter(), other.iter())
}
}
impl<A: fmt::Show> fmt::Show for BList<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<S: Writer, A: Hash<S>> Hash<S> for BList<A> {
fn hash(&self, state: &mut S) {
self.len().hash(state);
for elt in self.iter() {
elt.hash(state);
}
}
}
#[cfg(test)]
mod test {
use super::BList;
use std::hash;
fn generate_test() -> BList<int> {
list_from(&[0i,1,2,3,4,5,6])
}
fn list_from<T: Clone>(v: &[T]) -> BList<T> {
v.iter().map(|x| (*x).clone()).collect()
}
#[test]
fn test_basic() {
let mut m: BList<Box<int>> = BList::new();
assert_eq!(m.pop_front(), None);
assert_eq!(m.pop_back(), None);
assert_eq!(m.pop_front(), None);
m.push_front(box 1);
assert_eq!(m.pop_front(), Some(box 1));
m.push_back(box 2);
m.push_back(box 3);
assert_eq!(m.len(), 2);
assert_eq!(m.pop_front(), Some(box 2));
assert_eq!(m.pop_front(), Some(box 3));
assert_eq!(m.len(), 0);
assert_eq!(m.pop_front(), None);
m.push_back(box 1);
m.push_back(box 3);
m.push_back(box 5);
m.push_back(box 7);
assert_eq!(m.pop_front(), Some(box 1));
let mut n = BList::new();
n.push_front(2i);
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 int, *elt);
}
let mut n = BList::new();
assert_eq!(n.iter().next(), None);
n.push_front(4i);
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 = BList::new();
assert_eq!(n.iter().next(), None);
n.push_front(4i);
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 int, *elt);
}
let mut n = BList::new();
assert_eq!(n.iter().rev().next(), None);
n.push_front(4i);
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 int, *elt);
len -= 1;
}
assert_eq!(len, 0);
let mut n = BList::new();
assert!(n.iter_mut().next().is_none());
n.push_front(4i);
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 = BList::new();
assert!(n.iter_mut().next_back().is_none());
n.push_front(4i);
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: BList<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(&[2i,3,4]);
let m = list_from(&[1i,2,3]);
assert!(n != m);
}
#[test]
fn test_hash() {
let mut x = BList::new();
let mut y = BList::new();
assert!(hash::hash(&x) == hash::hash(&y));
x.push_back(1i);
x.push_back(2);
x.push_back(3);
y.push_front(3i);
y.push_front(2);
y.push_front(1);
assert!(hash::hash(&x) == hash::hash(&y));
}
#[test]
fn test_ord() {
let n: BList<int> = list_from(&[]);
let m = list_from(&[1i,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_show() {
let list: BList<int> = range(0i, 10).collect();
assert!(list.to_string().as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
let list: BList<&str> = vec!["just", "one", "test", "more"].iter()
.map(|&s| s)
.collect();
assert!(list.to_string().as_slice() == "[just, one, test, more]");
}
}
#[cfg(test)]
mod bench{
use super::BList;
use test;
use traverse::Traversal;
#[bench]
fn bench_collect_into(b: &mut test::Bencher) {
let v = &[0i, ..64];
b.iter(|| {
let _: BList<int> = v.iter().map(|x| *x).collect();
})
}
#[bench]
fn bench_push_front(b: &mut test::Bencher) {
let mut m: BList<int> = BList::new();
b.iter(|| {
m.push_front(0);
})
}
#[bench]
fn bench_push_back(b: &mut test::Bencher) {
let mut m: BList<int> = BList::new();
b.iter(|| {
m.push_back(0);
})
}
#[bench]
fn bench_push_back_pop_back(b: &mut test::Bencher) {
let mut m: BList<int> = BList::new();
b.iter(|| {
m.push_back(0);
m.pop_back();
})
}
#[bench]
fn bench_push_front_pop_front(b: &mut test::Bencher) {
let mut m: BList<int> = BList::new();
b.iter(|| {
m.push_front(0);
m.pop_front();
})
}
#[bench]
fn bench_iter(b: &mut test::Bencher) {
let v = &[0i, ..128];
let m: BList<int> = v.iter().map(|&x|x).collect();
b.iter(|| {
assert!(m.iter().count() == 128);
})
}
#[bench]
fn bench_iter_mut(b: &mut test::Bencher) {
let v = &[0i, ..128];
let mut m: BList<int> = 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 = &[0i, ..128];
let m: BList<int> = 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 = &[0i, ..128];
let mut m: BList<int> = v.iter().map(|&x|x).collect();
b.iter(|| {
assert!(m.iter_mut().rev().count() == 128);
})
}
#[bench]
fn bench_trav(b: &mut test::Bencher) {
let v = &[0i, ..128];
let m: BList<int> = v.iter().map(|&x|x).collect();
b.iter(|| {
assert!(m.traversal().count() == 128);
})
}
}