pub struct SliceRbRef<'a, T> { /* private fields */ }Expand description
A ring buffer implementation optimized for working with slices. Note this pretty
much does the same thing as VecDeque, but with the added ability to index
using negative values, as well as working with buffers allocated on the stack.
This struct can be used without the standard library (#![no_std]).
This works the same as SliceRB except it uses an immutable reference as its
data source instead of an internal Vec.
This struct has no consumer/producer logic, and is meant to be used for DSP or as a base for other data structures.
This data type is optimized for manipulating data in chunks with slices. Indexing one element at a time is slow.
The length of this ring buffer cannot be 0.
§Example
let stack_data = [0u32, 1, 2, 3];
let rb_ref = SliceRbRef::new(&stack_data);
assert_eq!(rb_ref[-3], 1);
let (s1, s2) = rb_ref.as_slices_len(2, 3);
assert_eq!(s1, &[2, 3]);
assert_eq!(s2, &[0]);Implementations§
Source§impl<'a, T> SliceRbRef<'a, T>
impl<'a, T> SliceRbRef<'a, T>
Sourcepub const fn new(slice: &'a [T]) -> Self
pub const fn new(slice: &'a [T]) -> Self
Creates a new SliceRbRef with the given data.
§Example
let data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&data[..]);
assert_eq!(rb.len().get(), 4);
assert_eq!(rb[0], 1);
assert_eq!(rb[1], 2);
assert_eq!(rb[2], 3);
assert_eq!(rb[3], 4);§Panics
- This will panic if the length of
sliceis0or is greater thanisize::MAX.
Sourcepub const unsafe fn new_unchecked(slice: &'a [T]) -> Self
pub const unsafe fn new_unchecked(slice: &'a [T]) -> Self
Creates a new SliceRbRef with the given data without checking
that the length of the data is greater than 0 and less than or
equal to isize::MAX.
§Example
let data = [1u32, 2, 3, 4];
let rb = unsafe { SliceRbRef::new_unchecked(&data[..]) };
assert_eq!(rb.len().get(), 4);
assert_eq!(rb[0], 1);
assert_eq!(rb[1], 2);
assert_eq!(rb[2], 3);
assert_eq!(rb[3], 4);§Safety
The length of slice must be greater than 0 and less than or
equal to isize::MAX.
Sourcepub fn len(&self) -> NonZeroUsize
pub fn len(&self) -> NonZeroUsize
Returns the length of the ring buffer.
§Example
let data = [0u32; 4];
let rb = SliceRbRef::new(&data[..]);
assert_eq!(rb.len().get(), 4);Sourcepub fn constrain(&self, i: isize) -> isize
pub fn constrain(&self, i: isize) -> isize
Returns the actual index of the ring buffer from the given
i index.
- First, a bounds check will be performed. If it is within bounds, then it is simply returned.
- If it is not in bounds, then performance will
be limited by the modulo (remainder) operation on an
isizevalue.
§Performance
Prefer to manipulate data in bulk with methods that return slices. If you
need to index multiple elements one at a time, prefer to use
SliceRbRef::at(&mut i) over SliceRbRef[i] to reduce the number of
modulo operations to perform.
§Example
let data = [0u32; 4];
let rb = SliceRbRef::new(&data[..]);
assert_eq!(rb.constrain(2), 2);
assert_eq!(rb.constrain(4), 0);
assert_eq!(rb.constrain(-3), 1);
assert_eq!(rb.constrain(7), 3);Sourcepub fn as_slices(&self, start: isize) -> (&[T], &[T])
pub fn as_slices(&self, start: isize) -> (&[T], &[T])
Returns two slices that contain all the data in the ring buffer
starting at the index start.
§Returns
- The first slice is the starting chunk of data. This will never be empty.
- The second slice is the second contiguous chunk of data. This may or may not be empty depending if the buffer needed to wrap around to the beginning of its internal memory layout.
§Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
§Example
let data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&data[..]);
let (s1, s2) = rb.as_slices(-4);
assert_eq!(s1, &[1, 2, 3, 4]);
assert_eq!(s2, &[]);
let (s1, s2) = rb.as_slices(3);
assert_eq!(s1, &[4]);
assert_eq!(s2, &[1, 2, 3]);Sourcepub fn as_slices_len(&self, start: isize, len: usize) -> (&[T], &[T])
pub fn as_slices_len(&self, start: isize, len: usize) -> (&[T], &[T])
Returns two slices of data in the ring buffer
starting at the index start and with length len.
start- The starting indexlen- The length of data to read. Iflenis greater than the capacity of the ring buffer, then that capacity will be used instead.
§Returns
- The first slice is the starting chunk of data.
- The second slice is the second contiguous chunk of data. This may or may not be empty depending if the buffer needed to wrap around to the beginning of its internal memory layout.
§Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
§Example
let data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&data[..]);
let (s1, s2) = rb.as_slices_len(-4, 3);
assert_eq!(s1, &[1, 2, 3]);
assert_eq!(s2, &[]);
let (s1, s2) = rb.as_slices_len(3, 5);
assert_eq!(s1, &[4]);
assert_eq!(s2, &[1, 2, 3]);Sourcepub fn as_slices_latest(&self, start: isize, len: usize) -> (&[T], &[T])
pub fn as_slices_latest(&self, start: isize, len: usize) -> (&[T], &[T])
Returns two slices of data in the ring buffer
starting at the index start and with length len. If len is greater
than the length of the ring buffer, then the buffer’s length will be used
instead, while still preserving the position of the last element.
start- The starting indexlen- The length of data to read. Iflenis greater than the length of the ring buffer, then the buffer’s length will be used instead, while still preserving the position of the last element.
§Returns
- The first slice is the starting chunk of data.
- The second slice is the second contiguous chunk of data. This may or may not be empty depending if the buffer needed to wrap around to the beginning of its internal memory layout.
§Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
§Example
let data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&data[..]);
let (s1, s2) = rb.as_slices_latest(-4, 3);
assert_eq!(s1, &[1, 2, 3]);
assert_eq!(s2, &[]);
let (s1, s2) = rb.as_slices_latest(0, 5);
assert_eq!(s1, &[2, 3, 4]);
assert_eq!(s2, &[1]);Sourcepub fn raw_data(&self) -> &[T]
pub fn raw_data(&self) -> &[T]
Returns all the data in the buffer. The starting index will
always be 0.
§Example
let data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&data[..]);
let raw_data = rb.raw_data();
assert_eq!(raw_data, &[1u32, 2, 3, 4]);Sourcepub fn get(&self, i: isize) -> &T
pub fn get(&self, i: isize) -> &T
Returns an immutable reference the element at the index of type isize.
§Performance
Prefer to manipulate data in bulk with methods that return slices. If you
need to index multiple elements one at a time, prefer to use
this over SliceRbRef[i] to reduce the number of
modulo operations to perform.
§Example
let data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&data[..]);
assert_eq!(*rb.get(-3), 2);Sourcepub fn constrain_and_get(&self, i: &mut isize) -> &T
pub fn constrain_and_get(&self, i: &mut isize) -> &T
Returns an immutable reference to the element at the index of type isize
while also constraining the index i. This is more efficient than calling
both methods individually.
§Performance
Prefer to manipulate data in bulk with methods that return slices. If you
need to index multiple elements one at a time, prefer to use
this over SliceRbRef[i] to reduce the number of
modulo operations to perform.
§Example
let data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&data[..]);
let mut i = -3;
assert_eq!(*rb.constrain_and_get(&mut i), 2);
assert_eq!(i, 1);Source§impl<'a, T: Clone + Copy> SliceRbRef<'a, T>
impl<'a, T: Clone + Copy> SliceRbRef<'a, T>
Sourcepub fn read_into(&self, slice: &mut [T], start: isize)
pub fn read_into(&self, slice: &mut [T], start: isize)
Copies the data from the ring buffer starting from the index start
into the given slice. If the length of slice is larger than the
capacity of the ring buffer, then the data will be reapeated until
the given slice is filled.
slice- This slice to copy the data into.start- The index of the ring buffer to start copying from.
§Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
§Example
let data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&data[..]);
let mut read_buf = [0u32; 3];
rb.read_into(&mut read_buf[..], -3);
assert_eq!(read_buf, [2, 3, 4]);
let mut read_buf = [0u32; 9];
rb.read_into(&mut read_buf[..], 2);
assert_eq!(read_buf, [3, 4, 1, 2, 3, 4, 1, 2, 3]);