Immutable exact chunks

This commit is contained in:
Pascal Engélibert 2022-10-01 10:13:50 +02:00
parent 60841ec34c
commit c49db676ee
Signed by: tuxmain
GPG key ID: 3504BC6D362F7DCA
2 changed files with 33 additions and 1 deletions

View file

@ -6,7 +6,7 @@ Yet another Rust ring buffer implementation.
Features: Features:
* Checked/unchecked element/iterator safe push * Checked/unchecked element/iterator safe push
* Mutable exact chunk iterator (read contiguous slices) * Mutable/immutable exact chunk iterator (read contiguous slices)
## License ## License

View file

@ -64,6 +64,16 @@ impl<T> RingBuf<T> {
len len
} }
pub fn chunks_exact(&mut self, chunk_size: usize) -> ChunksExact<T> {
assert_eq!(self.read_index % chunk_size, 0);
assert_eq!(self.data.len() % chunk_size, 0);
ChunksExact {
ringbuf: self,
chunk_size,
}
}
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<T> { pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<T> {
assert_eq!(self.read_index % chunk_size, 0); assert_eq!(self.read_index % chunk_size, 0);
assert_eq!(self.data.len() % chunk_size, 0); assert_eq!(self.data.len() % chunk_size, 0);
@ -75,6 +85,28 @@ impl<T> RingBuf<T> {
} }
} }
pub struct ChunksExact<'a, T> {
ringbuf: &'a mut RingBuf<T>,
chunk_size: usize,
}
impl<'a, T> Iterator for ChunksExact<'a, T> {
type Item = &'a [T];
fn next(&mut self) -> Option<Self::Item> {
if self.ringbuf.available >= self.chunk_size {
let read_index = self.ringbuf.read_index;
self.ringbuf.read_index =
(self.ringbuf.read_index + self.chunk_size) % self.ringbuf.data.len();
self.ringbuf.available -= self.chunk_size;
let ret: &[T] = &self.ringbuf.data[read_index..read_index + self.chunk_size];
let ret: &'a [T] = unsafe { std::mem::transmute(ret) };
Some(ret)
} else {
None
}
}
}
pub struct ChunksExactMut<'a, T> { pub struct ChunksExactMut<'a, T> {
ringbuf: &'a mut RingBuf<T>, ringbuf: &'a mut RingBuf<T>,
chunk_size: usize, chunk_size: usize,