Index access for cycled buffer

This commit is contained in:
Andrew Golovashevich 2026-03-10 20:04:44 +03:00
parent ff64f16bde
commit 9bf4b22cb1

View File

@ -1,5 +1,5 @@
use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut, IndexMut};
use std::ops::{Deref, DerefMut, Index, IndexMut};
use std::ptr::NonNull;
pub(crate) struct CycledBuffer<T> {
@ -78,6 +78,58 @@ impl<T> CycledBuffer<T> {
}
}
impl<T> Index<usize> for CycledBuffer<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
match self.pos {
BufferState::Filling { .. } => {
if index < self.data.len() {
&self.data[self.data.len() - 1 - index]
} else {
panic!("Index out of range")
}
}
BufferState::Cycle { next_write_pos } => {
if index < next_write_pos {
return &self.data[next_write_pos - 1 - index];
} else {
if index >= self.data.len() {
panic!("Index out of range");
}
return &self.data[self.data.len() - 1 - (index - next_write_pos)];
}
}
BufferState::Empty => panic!("Index out of range"),
}
}
}
impl<T> IndexMut<usize> for CycledBuffer<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
let data_len = self.data.len();
match self.pos {
BufferState::Filling { .. } => {
if index < self.data.len() {
&mut self.data[data_len - 1 - index]
} else {
panic!("Index out of range")
}
}
BufferState::Cycle { next_write_pos } => {
if index < next_write_pos {
return &mut self.data[next_write_pos - 1 - index];
} else {
if index >= self.data.len() {
panic!("Index out of range");
}
return &mut self.data[data_len - 1 - (index - next_write_pos)];
}
}
BufferState::Empty => panic!("Index out of range"),
}
}
}
/*
impl<T> Drop for CycledBuffer<T> {
@ -182,7 +234,7 @@ impl<C: Len, E, G: Fn(&mut C, usize) -> E> Iterator for CycledIterator<C, E, G>
} else {
self.state = IteratorState::Done;
}
return Some(e)
return Some(e);
}
}
}
@ -202,6 +254,9 @@ mod _tests {
assert_eq!(it.next(), Some(&9));
assert_eq!(it.next(), Some(&6));
assert_eq!(it.next(), None);
assert_eq!(b[0], 9);
assert_eq!(b[1], 6);
}
#[test]
fn test2() {
@ -214,5 +269,8 @@ mod _tests {
assert_eq!(it.next(), Some(&2));
assert_eq!(it.next(), Some(&5));
assert_eq!(it.next(), None);
assert_eq!(b[0], 2);
assert_eq!(b[1], 5);
}
}