#[derive(Copy, Clone)]
struct Item<T> {
val: Option<T>,
prev: usize,
next: usize,
}
impl<T> Item<T> {
fn reverse(&mut self) {
let prev = self.prev;
self.prev = self.next;
self.next = prev;
}
}
#[macro_export]
macro_rules! ring {
() => ( $crate::Ring::new() );
($($x:expr),*) => (
{
let s: Box<[_]> = Box::new([$($x),*]);
let mut x = s.into_vec();
let mut r = Ring::new();
for i in x.drain(..) {
r.push(i);
}
r
}
);
($($x:expr,)*) => (ring![$($x),*])
}
pub struct Ring<T> {
cur: Option<usize>,
items: Vec<Item<T>>,
gaps: Vec<usize>,
}
impl<T> Ring<T>
where
T: Sized,
{
pub fn new() -> Ring<T> {
Ring {
items: Vec::new(),
cur: None,
gaps: Vec::new(),
}
}
pub fn with_capacity(capacity: usize) -> Ring<T> {
Ring {
items: Vec::with_capacity(capacity),
cur: None,
gaps: Vec::new(),
}
}
pub fn pop_left(&mut self) -> Option<T> {
let mut val = None;
self.cur = self.cur.and_then(|c| {
let mut item = Item {
val: None,
next: 0,
prev: 0,
};
std::mem::swap(&mut item, &mut self.items[c]);
val = item.val;
self.gaps.push(c);
if item.next == c {
None
} else {
self.items[item.prev].next = item.next;
self.items[item.next].prev = item.prev;
Some(item.next)
}
});
val
}
pub fn pop(&mut self) -> Option<T> {
match self.cur {
Some(c) => {
let head = self.items[c].prev;
let mut tail = Item {
val: None,
next: 0,
prev: 0,
};
std::mem::swap(&mut tail, &mut self.items[head]);
let val = tail.val;
tail.val = None;
self.gaps.push(head);
if tail.next != head {
self.items[tail.prev].next = tail.next;
self.items[tail.next].prev = tail.prev;
}
val
}
None => None,
}
}
#[inline]
fn push_item(&mut self, value: T) -> usize {
let (head, prev) = self.cur.map(|c| (c, self.items[c].prev)).unwrap_or((0, 0));
let item = Item {
val: Some(value),
next: head,
prev: prev,
};
let curr = if self.gaps.len() > 0 {
let idx = self.gaps.pop().unwrap();
self.items[idx] = item;
idx
} else {
self.items.push(item);
self.items.len() - 1
};
self.items[prev].next = curr;
self.items[head].prev = curr;
curr
}
pub fn push(&mut self, value: T) {
let idx = self.push_item(value);
self.cur = self.cur.or(Some(idx));
}
pub fn push_left(&mut self, value: T) {
let curr = self.push_item(value);
self.cur = Some(curr);
}
#[inline]
fn rotate_left(&mut self, n: isize) {
self.cur = self.cur.map(|c| {
let mut cur = c;
for _ in n..0 {
cur = self.items[cur].next;
}
cur
});
}
#[inline]
fn rotate_right(&mut self, n: isize) {
self.cur = self.cur.map(|c| {
let mut cur = c;
for _ in 0..n {
cur = self.items[cur].prev;
}
cur
});
}
pub fn rotate(&mut self, n: isize) -> &mut Self {
if n > 0 {
self.rotate_right(n);
} else if n < 0 {
self.rotate_left(n);
}
self
}
#[inline]
fn peek_left(&self, cur: usize, n: isize) -> Option<&T> {
let mut c = cur;
for _ in n..0 {
c = self.items[c].prev;
}
self.items[c].val.as_ref()
}
#[inline]
fn peek_right(&self, cur: usize, n: isize) -> Option<&T> {
let mut c = cur;
for _ in 0..n {
c = self.items[c].next;
}
self.items[c].val.as_ref()
}
pub fn peek(&self, n: isize) -> Option<&T> {
match self.cur {
Some(cur) => {
if n < 0 {
self.peek_left(cur, n)
} else {
self.peek_right(cur, n)
}
}
None => None,
}
}
pub fn len(&self) -> usize {
self.items.len() - self.gaps.len()
}
pub fn capacity(&self) -> usize {
self.items.capacity()
}
pub fn clear(&mut self) {
self.cur = None;
self.gaps.clear();
self.items.clear();
}
pub fn append(&mut self, other: &mut Ring<T>) {
for item in other.into_iter() {
self.push(item);
}
}
pub fn append_left(&mut self, other: &mut Ring<T>) {
for item in other.into_iter() {
self.push_left(item);
}
}
pub fn reverse(&mut self) {
self.cur = self.cur.map(|cur| {
let mut c = cur;
let tail = self.items[c].prev;
loop {
let next = self.items[c].next;
self.items[c].reverse();
if next == cur {
break;
}
c = next;
}
tail
});
}
pub fn is_empty(&self) -> bool {
self.cur.is_none()
}
pub fn collect_vec(&self) -> Vec<T>
where
T: Copy,
{
let mut v = Vec::with_capacity(self.len());
match self.cur {
Some(cur) => {
let mut c = cur;
loop {
let item = self.items[c];
v.push(item.val.unwrap());
c = item.next;
if c == cur {
break;
}
}
}
None => (),
}
v
}
}
impl<'a, T> std::iter::IntoIterator for &'a Ring<T> where T: Copy {
type Item = T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
Iter {
items: &self.items,
head: self.cur.clone(),
pos: self.cur.clone(),
}
}
}
impl<'a, T> std::iter::IntoIterator for &'a mut Ring<T> {
type Item = T;
type IntoIter = IterMut<T>;
fn into_iter(self) -> Self::IntoIter {
let mut items = Vec::new();
let mut cur = None;
std::mem::swap(&mut items, &mut self.items);
std::mem::swap(&mut cur, &mut self.cur);
self.items.clear();
IterMut {
items: items,
head: cur,
pos: cur,
}
}
}
impl<T> Clone for Ring<T>
where
T: std::clone::Clone,
{
fn clone(&self) -> Self {
Ring {
cur: self.cur,
items: self.items.clone(),
gaps: self.gaps.clone(),
}
}
}
pub struct Iter<'a, T: Copy> {
items: &'a Vec<Item<T>>,
head: Option<usize>,
pos: Option<usize>,
}
impl<'a, T: Copy> Iterator for Iter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let mut val = None;
self.pos = self.pos.and_then(|pos| {
let item = self.items[pos];
val = item.val;
if item.next == self.head.unwrap() {
None
} else {
Some(item.next)
}
});
val
}
}
pub struct IterMut<T> {
items: Vec<Item<T>>,
head: Option<usize>,
pos: Option<usize>,
}
impl<T> Iterator for IterMut<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let mut val = None;
self.pos = self.pos.and_then(|pos| {
let mut item = Item {
val: None,
next: 0,
prev: 0,
};
std::mem::swap(&mut item, &mut self.items[pos]);
val = item.val;
if item.next == self.head.unwrap() {
None
} else {
Some(item.next)
}
});
val
}
}
impl<T> std::iter::FromIterator<T> for Ring<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut ring = Ring::new();
for item in iter {
ring.push(item);
}
ring
}
}
use std::fmt;
impl<T: fmt::Debug + Copy> fmt::Debug for Ring<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("[")?;
match self.cur {
Some(cur) => {
let mut next = cur;
loop {
f.write_fmt(format_args!("{:?}", self.items[next].val.unwrap()))?;
next = self.items[next].next;
if next == cur {
break;
} else {
f.write_str(", ")?;
}
}
}
None => (),
}
f.write_str("]")
}
}
impl<T> std::ops::Index<isize> for Ring<T> {
type Output = T;
fn index(&self, idx: isize) -> &T {
match self.peek(idx) {
Some(r) => r,
None => panic!("tried to access index {} of empty ring", idx),
}
}
}
impl<T: PartialEq> PartialEq for Ring<T> {
fn eq(&self, other: &Ring<T>) -> bool {
if self.len() != other.len() {
return false;
}
let cur = self.cur.unwrap();
let cur2 = other.cur.unwrap();
let mut next = cur;
let mut next2 = cur2;
loop {
let v = &self.items[next].val;
let v2 = &other.items[next2].val;
if v != v2 {
return false;
}
if next == cur && next2 == cur2 {
break;
} else if next == cur || next2 == cur2 {
return false;
}
next = self.items[next].next;
next2 = other.items[next2].next;
}
true
}
}
impl<T: Eq> Eq for Ring<T> {}
#[cfg(test)]
mod tests {
use super::*;
use std::iter::FromIterator;
#[test]
fn test_push() {
let mut r = ring![1, 2];
r.push(3);
assert_eq!(r.collect_vec(), vec![1, 2, 3]);
r.push_left(0);
assert_eq!(r.collect_vec(), vec![0, 1, 2, 3]);
}
#[test]
fn test_debug() {
let r = ring![1, 2, 3];
assert_eq!("[1, 2, 3]", format!("{:?}", r));
}
#[test]
fn test_iter_copyable() {
let r = ring![1, 2, 3];
let mut iter = r.into_iter();
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(3));
assert_eq!(iter.next(), None);
assert_eq!(r.len(), 3);
}
#[test]
fn test_iter_nocopyable() {
let mut r = ring![vec![1, 2], vec![3, 4]];
let mut iter = r.into_iter();
assert_eq!(iter.next(), Some(vec![1, 2]));
assert_eq!(iter.next(), Some(vec![3, 4]));
assert_eq!(iter.next(), None);
assert_eq!(r.is_empty(), true);
}
#[test]
fn test_collect() {
let r = ring![1, 2, 3];
assert_eq!(vec![1, 2, 3], r.collect_vec());
}
#[test]
fn test_from_iter() {
let r = Ring::from_iter(vec![1, 2, 3]);
assert_eq!(vec![1, 2, 3], r.collect_vec());
}
#[test]
fn test_peek() {
let r = ring![1, 2, 3, 4];
assert_eq!(r.peek(0), Some(&1));
assert_eq!(r.peek(1), Some(&2));
assert_eq!(r.peek(4), Some(&1));
assert_eq!(r.peek(-1), Some(&4));
assert_eq!(r.peek(-1), Some(&4));
assert_eq!(r.peek(-6), Some(&3));
}
#[test]
fn test_rotate() {
let mut r1 = ring![1, 2, 3, 4];
assert_eq!(r1.rotate(1).collect_vec(), vec![4, 1, 2, 3]);
let mut r2 = ring![1, 2, 3, 4];
assert_eq!(r2.rotate(0).collect_vec(), vec![1, 2, 3, 4]);
let mut r3 = ring![1, 2, 3, 4];
assert_eq!(r3.rotate(-1).collect_vec(), vec![2, 3, 4, 1]);
}
#[test]
fn test_pop() {
let mut r = ring![1, 2, 3, 4];
assert_eq!(r.pop(), Some(4));
assert_eq!(r.pop_left(), Some(1));
assert_eq!(r.collect_vec(), vec![2, 3]);
}
#[test]
fn test_len() {
let r = ring![1, 2, 3, 4];
assert_eq!(r.len(), 4);
}
#[test]
fn test_capacity() {
let r: Ring<i32> = Ring::with_capacity(6);
assert_eq!(r.capacity(), 6);
assert_eq!(r.len(), 0);
}
#[test]
fn test_clear() {
let mut r = Ring::with_capacity(5);
r.push(1);
r.push(2);
r.push(3);
assert_eq!(r.len(), 3);
assert_eq!(r.capacity(), 5);
r.clear();
assert_eq!(r.len(), 0);
assert_eq!(r.capacity(), 5);
}
#[test]
fn test_push_with_gaps() {
let mut r = ring![1, 2, 3, 4, 5];
assert_eq!(r.rotate(-1).pop_left(), Some(2));
assert_eq!(r.gaps.len(), 1);
r.push(6);
assert_eq!(r.gaps.len(), 0);
assert_eq!(r.items[1].val, Some(6));
r.push_left(7);
assert_eq!(r.collect_vec(), vec![7, 3, 4, 5, 1, 6]);
}
#[test]
fn test_append() {
let mut r = ring![1, 2, 3];
r.append(&mut ring![4, 5, 6]);
assert_eq!(r.collect_vec(), vec![1, 2, 3, 4, 5, 6]);
r.append_left(&mut ring![7, 8, 9]);
assert_eq!(r.collect_vec(), vec![9, 8, 7, 1, 2, 3, 4, 5, 6]);
}
#[test]
fn test_reverse() {
let mut r = ring![1, 2, 3];
r.reverse();
assert_eq!(r.collect_vec(), vec![3, 2, 1]);
}
#[test]
fn test_is_empty() {
let mut r = Ring::new();
assert_eq!(r.is_empty(), true);
r.push(1);
assert_eq!(r.is_empty(), false);
r.clear();
assert_eq!(r.is_empty(), true);
}
#[test]
fn test_macro_nocopy() {
let r = ring![vec![1, 2, 3]];
assert_eq!(r.is_empty(), false);
}
#[test]
fn test_eq() {
let r = ring![1, 2, 3];
assert_eq!(r == ring![1, 2], false);
assert_eq!(r == ring![1, 2, 3], true);
assert_eq!(r == ring![], false);
assert_eq!(r != ring![1, 2], true);
assert_eq!(r != ring![1, 2, 3], false);
assert_eq!(r != ring![], true);
}
#[test]
fn test_index() {
let r = ring![1, 2, 3];
assert_eq!(r[0], 1);
assert_eq!(r[1], 2);
assert_eq!(r[-1], 3);
}
}