Skip to content

Commit

Permalink
Add and implement get_range.
Browse files Browse the repository at this point in the history
  • Loading branch information
Julia Dijkstra (JUD) committed Sep 19, 2024
1 parent 75fe4f1 commit 708ff3d
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 4 deletions.
7 changes: 6 additions & 1 deletion src/ringbuffer_trait.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::ops::{Index, IndexMut};
use core::ops::{Index, IndexMut, Range};

#[cfg(feature = "alloc")]
extern crate alloc;
Expand Down Expand Up @@ -170,6 +170,11 @@ pub unsafe trait RingBuffer<T>:
unsafe { Self::ptr_get_mut(self, index).map(|i| &mut *i) }
}

/// Gets values relative to the current index. 0 is the next index to be written to with push.
fn get_range<'a>(&'a self, range: Range<usize>) -> impl Iterator<Item = &'a T>
where
T: 'a;

/// same as [`get_mut`](RingBuffer::get_mut) but on raw pointers.
///
/// # Safety
Expand Down
19 changes: 18 additions & 1 deletion src/with_alloc/alloc_ringbuffer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::ops::{Index, IndexMut};
use alloc::slice;
use core::ops::{Index, IndexMut, Range};

use crate::ringbuffer_trait::{
RingBuffer, RingBufferIntoIterator, RingBufferIterator, RingBufferMutIterator,
Expand Down Expand Up @@ -292,6 +293,22 @@ unsafe impl<T> RingBuffer<T> for AllocRingBuffer<T> {
unsafe { ptr::write(get_unchecked_mut(self, i), f()) };
}
}

#[inline]
fn get_range<'a>(&'a self, range: Range<usize>) -> impl Iterator<Item = &'a T>
where
T: 'a,
{
let normalized_index = self.readptr + range.start.rem_euclid(self.len());
let index = normalized_index % self.buffer_size();
let buf = unsafe { slice::from_raw_parts(self.buf, self.buffer_size()) };
buf[index..]
.iter()
.chain(buf[..index].iter())
.take(self.len())
.cycle()
.take(range.len())
}
}

impl<T> AllocRingBuffer<T> {
Expand Down
14 changes: 13 additions & 1 deletion src/with_alloc/vecdeque.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::ringbuffer_trait::{RingBufferIntoIterator, RingBufferIterator, RingBufferMutIterator};
use crate::{AllocRingBuffer, RingBuffer};
use alloc::collections::VecDeque;
use core::ops::{Deref, DerefMut, Index, IndexMut};
use core::ops::{Deref, DerefMut, Index, IndexMut, Range};

/// A growable ringbuffer. Once capacity is reached, the size is doubled.
/// Wrapper of the built-in [`VecDeque`] struct.
Expand Down Expand Up @@ -255,6 +255,18 @@ unsafe impl<T> RingBuffer<T> for GrowableAllocRingBuffer<T> {
}
.map(|i| i as *mut T)
}

/// Gets values relative to the current index. 0 is the next index to be written to with push.
///
/// # Panics
/// Panics if the starting point is greater than the end point
/// or if the end point is greater than the length of the deque.
fn get_range<'a>(&'a self, range: Range<usize>) -> impl Iterator<Item = &'a T>
where
T: 'a,
{
self.0.range(range)
}
}

impl<T> Extend<T> for GrowableAllocRingBuffer<T> {
Expand Down
18 changes: 17 additions & 1 deletion src/with_const_generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::RingBuffer;
use core::iter::FromIterator;
use core::mem;
use core::mem::MaybeUninit;
use core::ops::{Index, IndexMut};
use core::ops::{Index, IndexMut, Range};

/// The `ConstGenericRingBuffer` struct is a `RingBuffer` implementation which does not require `alloc` but
/// uses const generics instead.
Expand Down Expand Up @@ -321,6 +321,22 @@ unsafe impl<T, const CAP: usize> RingBuffer<T> for ConstGenericRingBuffer<T, CAP
self.writeptr = CAP;
self.buf.fill_with(|| MaybeUninit::new(f()));
}

#[inline]
fn get_range<'a>(&'a self, range: Range<usize>) -> impl Iterator<Item = &'a T>
where
T: 'a,
{
let normalized_index = self.readptr + range.start.rem_euclid(self.len());
let index = normalized_index % self.buffer_size();
self.buf[index..]
.iter()
.chain(self.buf[..index].iter())
.take(self.len())
.map(|x| unsafe { x.assume_init_ref() })
.cycle()
.take(range.len())
}
}

impl<T, const CAP: usize> Default for ConstGenericRingBuffer<T, CAP> {
Expand Down

0 comments on commit 708ff3d

Please sign in to comment.