use std::collections::VecDeque;
use std::iter::{IntoIterator, FromIterator};
use std::cmp::Ordering;
use std::fmt;
use std::ops::{Index, IndexMut};
#[derive(Clone,Default)]
pub struct GapBuffer<T> {
offset: usize,
buf: VecDeque<T>,
}
impl<T> GapBuffer<T> {
pub fn new() -> GapBuffer<T> {
GapBuffer {
buf: VecDeque::new(),
offset: 0,
}
}
pub fn with_capacity(n: usize) -> GapBuffer<T> {
GapBuffer {
buf: VecDeque::with_capacity(n),
offset: 0,
}
}
fn get_idx(&self, i: usize) -> usize {
if i < self.offset {
(self.len() - self.offset) + i
} else if i < self.len() {
i - self.offset
} else {
i
}
}
fn shift(&mut self, i: usize) {
match i.cmp(&self.offset) {
Ordering::Equal => return,
Ordering::Less => {
let mut last = self.buf.pop_back().unwrap();
self.offset -= 1;
while i < self.offset {
self.buf.push_front(last);
last = self.buf.pop_back().unwrap();
self.offset -= 1;
}
self.buf.push_front(last);
},
Ordering::Greater => {
let mut first = self.buf.pop_front().unwrap();
self.offset += 1;
while i > self.offset {
self.buf.push_back(first);
first = self.buf.pop_front().unwrap();
self.offset += 1;
}
self.buf.push_back(first);
}
}
}
pub fn get(&self, i: usize) -> Option<&T> {
let i = self.get_idx(i);
self.buf.get(i)
}
pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
let i = self.get_idx(i);
self.buf.get_mut(i)
}
pub fn swap(&mut self, i: usize, j: usize) {
let i = self.get_idx(i);
let j = self.get_idx(j);
self.buf.swap(i, j);
}
#[inline]
pub fn capacity(&self) -> usize { self.buf.capacity() }
pub fn reserve(&mut self, additional: usize) {
self.buf.reserve(additional)
}
pub fn iter(&self) -> Items<T> {
Items {
buff: self,
idx: 0,
}
}
pub fn len(&self) -> usize { self.buf.len() }
pub fn is_empty(&self) -> bool { self.len() == 0 }
pub fn clear(&mut self) {
self.offset = 0;
self.buf.clear();
}
pub fn insert(&mut self, i: usize, t: T) {
assert!(i <= self.len(), "index out of bounds");
self.shift(i);
self.offset += 1;
self.buf.push_back(t);
}
pub fn remove(&mut self, i: usize) -> Option<T> {
if self.len() <= i {
return None;
}
self.shift(i); self.buf.pop_front()
}
}
impl <A, B> PartialEq<GapBuffer<B>> for GapBuffer<A> where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &GapBuffer<B>) -> bool {
if self.len() != other.len() { return false }
self.iter().zip(other.iter()).all( |(x, y)| x == y )
}
}
impl<A> Eq for GapBuffer<A> where A: Eq {}
impl<A> PartialOrd for GapBuffer<A> where A: PartialOrd {
#[inline]
fn partial_cmp(&self, other: &GapBuffer<A>) -> Option<Ordering> {
match self.len().cmp(&other.len()) {
Ordering::Equal => {
for (x, y) in self.iter().zip(other.iter()) {
match x.partial_cmp(y) {
Some(Ordering::Equal) => continue,
cmp => return cmp,
}
}
Some(Ordering::Equal)
}
cmp => Some(cmp),
}
}
}
impl<A> Ord for GapBuffer<A> where A: Ord {
#[inline]
fn cmp(&self, other: &GapBuffer<A>) -> Ordering {
match self.len().cmp(&other.len()) {
Ordering::Equal => {
for (x, y) in self.iter().zip(other.iter()) {
match x.cmp(y) {
Ordering::Equal => continue,
cmp => return cmp,
}
}
Ordering::Equal
}
cmp => cmp,
}
}
}
impl<A> FromIterator<A> for GapBuffer<A> {
fn from_iter<I: IntoIterator<Item=A>>(iterator: I) -> GapBuffer<A> {
let buf = iterator.into_iter().collect();
GapBuffer {
buf: buf,
offset: 0,
}
}
}
impl<A> Extend<A> for GapBuffer<A> {
fn extend<T: IntoIterator<Item=A>>(&mut self, iterator: T) {
let len = self.len();
self.shift(len);
self.buf.extend(iterator);
}
}
impl<T> fmt::Debug for GapBuffer<T> where T: fmt::Debug {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "["));
let mut iter = self.iter();
if let Some(fst) = iter.next() {
try!(write!(f, "{:?}", fst));
for e in iter {
try!(write!(f, ",{:?}", e));
}
}
write!(f, "]")
}
}
impl<T> Index<usize> for GapBuffer<T> {
type Output = T;
#[inline]
fn index<'a>(&'a self, index: usize) -> &'a T {
let index = self.get_idx(index);
&self.buf[index]
}
}
impl<T> IndexMut<usize> for GapBuffer<T> {
#[inline]
fn index_mut<'a>(&'a mut self, index: usize) -> &'a mut T {
let index = self.get_idx(index);
&mut self.buf[index]
}
}
#[derive(Clone)]
pub struct Items<'a, T: 'a> {
buff: &'a GapBuffer<T>,
idx: usize,
}
impl<'a, T> Iterator for Items<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<&'a T> {
let next = self.buff.get(self.idx);
if next.is_some() {
self.idx += 1;
}
next
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.buff.len();
(len, Some(len))
}
}
#[cfg(test)]
mod tests {
use GapBuffer;
#[test]
fn test_init() {
let test: GapBuffer<usize> = GapBuffer::with_capacity(100);
assert!(test.capacity() >= 100, "buffer initialized to {} capacity", test.capacity());
assert!(test.len() == 0, "Buffer initialized to {} length", test.len());
}
#[test]
fn test_insert() {
let mut test: GapBuffer<usize> = GapBuffer::new();
for x in range(0, 100) {
if x % 2 == 0 { test.insert(x/2, x); }
}
assert!(test.len() == 50, "After even insertions, buffer length is {}", test.len());
for x in range(0, 100) {
if x % 2 == 1 { test.insert(x, x); }
}
assert!(test.len() == 100, "After odd insertions, buffer length is {}", test.len());
}
#[test]
fn test_iter() {
let mut test: GapBuffer<usize> = GapBuffer::new();
for x in range(0, 100) {
test.insert(x,x);
}
let mut iterator = test.iter();
let mut index = range(0,100);
loop {
match (iterator.next(), index.next()) {
(Some(&x), Some(y)) => {
assert!(x == y, "Element at index {} is {}", y, x);
}
(None, _) | (_, None) => { break }
}
}
}
#[test]
fn test_index() {
let mut test: GapBuffer<usize> = GapBuffer::new();
for x in range(0, 100) {
test.insert(x,x);
}
for x in range(0,100) {
assert!(test[x] == x, "Index {} failed", x);
}
}
#[test]
fn test_remove() {
let mut test1: GapBuffer<usize> = GapBuffer::new();
let mut test2: GapBuffer<usize> = GapBuffer::new();
for x in range(0, 10) {
test1.insert(x,x);
}
for x in range(0,10) {
assert!(test1.remove(0) == Some(x), "Remove failed at {} (forward)", x);
}
test2.extend(0..5);
test2.remove(0);
for (i, &x) in test2.iter().enumerate() {
assert!(x == i + 1, "Remove test2 failed. Index {} is {}", x, i);
}
}
}