aboutsummaryrefslogtreecommitdiff
path: root/src/ring.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ring.rs')
-rw-r--r--src/ring.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/ring.rs b/src/ring.rs
new file mode 100644
index 0000000..aff9258
--- /dev/null
+++ b/src/ring.rs
@@ -0,0 +1,81 @@
+use std::collections::VecDeque;
+use std::ops::{Index, IndexMut};
+
+pub struct RingBuffer<T> {
+ data: VecDeque<T>,
+ // Abstract index of data[0] in 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 len(&self) -> usize {
+ self.data.len()
+ }
+
+ 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) -> &T {
+ &self.data[0]
+ }
+
+ pub fn first_mut(&mut self) -> &mut T {
+ &mut self.data[0]
+ }
+
+ pub fn pop_first(&mut self) -> T {
+ self.offset += 1;
+ self.data.pop_front().unwrap()
+ }
+
+ pub fn last(&self) -> &T {
+ self.data.back().unwrap()
+ }
+
+ pub fn last_mut(&mut self) -> &mut T {
+ self.data.back_mut().unwrap()
+ }
+
+ pub fn second_last(&self) -> &T {
+ &self.data[self.data.len() - 2]
+ }
+
+ pub fn pop_last(&mut self) {
+ self.data.pop_back().unwrap();
+ }
+}
+
+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()]
+ }
+}