1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
use std::collections::VecDeque;
use std::ops::{Index, IndexMut};
/// A view onto a finite range of an infinitely long sequence of T.
///
/// The Ts are indexed 0..infinity. A RingBuffer begins as a view of elements
/// 0..0 (i.e. nothing). The user of the RingBuffer advances its left and right
/// position independently, although only in the positive direction, and only
/// with left <= right at all times.
///
/// Holding a RingBuffer whose view is elements left..right gives the ability to
/// use Index and IndexMut to access elements i in the infinitely long queue for
/// which left <= i < right.
pub struct RingBuffer<T> {
data: VecDeque<T>,
// Abstract index of data[0] in the infinitely sized queue.
offset: usize,
}
impl<T> RingBuffer<T> {
pub fn new() -> Self {
RingBuffer { data: VecDeque::new(), offset: 0 }
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn push(&mut self, value: T) -> usize {
let index = self.offset + self.data.len();
self.data.push_back(value);
index
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn index_of_first(&self) -> usize {
self.offset
}
pub fn first(&self) -> Option<&T> {
self.data.front()
}
pub fn first_mut(&mut self) -> Option<&mut T> {
self.data.front_mut()
}
pub fn pop_first(&mut self) -> Option<T> {
let first = self.data.pop_front()?;
self.offset += 1;
Some(first)
}
pub fn last(&self) -> Option<&T> {
self.data.back()
}
pub fn last_mut(&mut self) -> Option<&mut T> {
self.data.back_mut()
}
}
impl<T> Index<usize> for RingBuffer<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.data[index.checked_sub(self.offset).unwrap()]
}
}
impl<T> IndexMut<usize> for RingBuffer<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.data[index.checked_sub(self.offset).unwrap()]
}
}