SliceRbRefMut

Struct SliceRbRefMut 

Source
pub struct SliceRbRefMut<'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 a mutable 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 mut stack_data = [0u32, 1, 2, 3];
let mut rb_ref = SliceRbRefMut::new(&mut stack_data);

rb_ref[-4] = 5;

let (s1, s2) = rb_ref.as_slices_len(2, 3);
assert_eq!(s1, &[2, 3]);
assert_eq!(s2, &[5]);

Implementations§

Source§

impl<'a, T> SliceRbRefMut<'a, T>

Source

pub const fn new(slice: &'a mut [T]) -> Self

Creates a new SliceRbRefMut with the given data.

§Example
let mut data = [1u32, 2, 3, 4];
let rb = SliceRbRefMut::new(&mut data[..]);

assert_eq!(rb.len(), 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 slice is 0 or is greater than isize::MAX.
Source

pub const unsafe fn new_unchecked(slice: &'a mut [T]) -> Self

Creates a new SliceRbRefMut 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 mut data = [1u32, 2, 3, 4];
let rb = unsafe { SliceRbRefMut::new_unchecked(&mut data[..]) };

assert_eq!(rb.len(), 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.

Source

pub fn len(&self) -> usize

Returns the length of the ring buffer.

§Example
let mut data = [0u32; 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

assert_eq!(rb.len(), 4);
Source

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 isize value.
§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 mut data = [0u32; 4];
let mut rb = SliceRbRefMut::new(&mut 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);
Source

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 mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut 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]);
Source

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 index
  • len - The length of data to read. If len is 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 mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut 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]);
Source

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 index
  • len - The length of data to read. 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.
§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 mut data = [1u32, 2, 3, 4];
let rb = SliceRbRefMut::new(&mut 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]);
Source

pub fn as_mut_slices(&mut self, start: isize) -> (&mut [T], &mut [T])

Returns two mutable 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 mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

let (s1, s2) = rb.as_mut_slices(-4);
assert_eq!(s1, &mut [1, 2, 3, 4]);
assert_eq!(s2, &mut []);

let (s1, s2) = rb.as_mut_slices(3);
assert_eq!(s1, &mut [4]);
assert_eq!(s2, &mut [1, 2, 3]);
Source

pub fn as_mut_slices_len( &mut self, start: isize, len: usize, ) -> (&mut [T], &mut [T])

Returns two mutable slices of data in the ring buffer starting at the index start and with length len.

  • start - The starting index
  • len - The length of data to read. If len is 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 mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

let (s1, s2) = rb.as_mut_slices_len(-4, 3);
assert_eq!(s1, &mut [1, 2, 3]);
assert_eq!(s2, &mut []);

let (s1, s2) = rb.as_mut_slices_len(3, 5);
assert_eq!(s1, &mut [4]);
assert_eq!(s2, &mut [1, 2, 3]);
Source

pub fn as_mut_slices_latest( &mut self, start: isize, len: usize, ) -> (&mut [T], &mut [T])

Returns two mutable 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 index
  • len - The length of data to read. 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.
§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 mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

let (s1, s2) = rb.as_mut_slices_latest(-4, 3);
assert_eq!(s1, &mut [1, 2, 3]);
assert_eq!(s2, &mut []);

let (s1, s2) = rb.as_mut_slices_latest(0, 5);
assert_eq!(s1, &mut [2, 3, 4]);
assert_eq!(s2, &mut [1]);
Source

pub fn raw_data(&self) -> &[T]

Returns all the data in the buffer. The starting index will always be 0.

§Example
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

let raw_data = rb.raw_data();
assert_eq!(raw_data, &[1u32, 2, 3, 4]);
Source

pub fn raw_data_mut(&mut self) -> &mut [T]

Returns all the data in the buffer as mutable. The starting index will always be 0.

§Example
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

let raw_data = rb.raw_data_mut();
assert_eq!(raw_data, &mut [1u32, 2, 3, 4]);
Source

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 mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

assert_eq!(*rb.get(-3), 2);
Source

pub fn get_mut(&mut self, i: isize) -> &mut T

Returns a mutable 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 mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

*rb.get_mut(-3) = 5;

assert_eq!(*rb.get(-3), 5);
Source

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 mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

let mut i = -3;
assert_eq!(*rb.constrain_and_get(&mut i), 2);
assert_eq!(i, 1);
Source

pub fn constrain_and_get_mut(&mut self, i: &mut isize) -> &mut T

Returns a mutable reference to the element at the index of type isize as mutable 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 mut data = [0u32; 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

let mut i = -3;
*rb.constrain_and_get_mut(&mut i) = 2;

assert_eq!(rb[1], 2);
assert_eq!(i, 1);
Source§

impl<'a, T: Clone + Copy> SliceRbRefMut<'a, T>

Source

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 mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRefMut::new(&mut 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]);
Source

pub fn write_latest(&mut self, slice: &[T], start: isize)

Copies data from the given slice into the ring buffer starting from the index start.

Earlier data will not be copied if it will be overwritten by newer data, avoiding unecessary memcpy’s. The correct placement of the newer data will still be preserved.

  • slice - This slice to copy data from.
  • 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 mut data = [0u32; 4];
let mut rb = SliceRbRefMut::new(&mut data[..]);

let input = [1u32, 2, 3];
rb.write_latest(&input[..], -3);
assert_eq!(rb[0], 0);
assert_eq!(rb[1], 1);
assert_eq!(rb[2], 2);
assert_eq!(rb[3], 3);

let input = [1u32, 2, 3, 4, 5, 6, 7, 8, 9];
rb.write_latest(&input[..], 2);
assert_eq!(rb[0], 7);
assert_eq!(rb[1], 8);
assert_eq!(rb[2], 9);
assert_eq!(rb[3], 6);
Source

pub fn write_latest_2(&mut self, first: &[T], second: &[T], start: isize)

Copies data from two given slices into the ring buffer starting from the index start. The first slice will be copied first then second will be copied next.

Earlier data will not be copied if it will be overwritten by newer data, avoiding unecessary memcpy’s. The correct placement of the newer data will still be preserved.

  • first - This first slice to copy data from.
  • second - This second slice to copy data from.
  • 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 mut input_rb = SliceRB::<u32>::new(NonZeroUsize::new(4).unwrap(), 0);
input_rb[0] = 1;
input_rb[1] = 2;
input_rb[2] = 3;
input_rb[3] = 4;

let mut output_data = [0u32; 4];
let mut output_rb = SliceRbRefMut::new(&mut output_data[..]);
// s1 == &[1, 2], s2 == &[]
let (s1, s2) = input_rb.as_slices_len(0, 2);
output_rb.write_latest_2(s1, s2, -3);
assert_eq!(output_rb[0], 0);
assert_eq!(output_rb[1], 1);
assert_eq!(output_rb[2], 2);
assert_eq!(output_rb[3], 0);

let mut output_data = [0u32; 2];
let mut output_rb = SliceRbRefMut::new(&mut output_data[..]);
// s1 == &[4],  s2 == &[1, 2, 3]
let (s1, s2) = input_rb.as_slices_len(3, 4);
// rb[1] = 4  ->  rb[0] = 1  ->  rb[1] = 2  ->  rb[0] = 3
output_rb.write_latest_2(s1, s2, 1);
assert_eq!(output_rb[0], 3);
assert_eq!(output_rb[1], 2);

Trait Implementations§

Source§

impl<'a, T: Debug> Debug for SliceRbRefMut<'a, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a, T> Index<isize> for SliceRbRefMut<'a, T>

Source§

type Output = T

The returned type after indexing.
Source§

fn index(&self, i: isize) -> &T

Performs the indexing (container[index]) operation. Read more
Source§

impl<'a, T> IndexMut<isize> for SliceRbRefMut<'a, T>

Source§

fn index_mut(&mut self, i: isize) -> &mut T

Performs the mutable indexing (container[index]) operation. Read more
Source§

impl<'a, T> Into<SliceRbRef<'a, T>> for SliceRbRefMut<'a, T>

Source§

fn into(self) -> SliceRbRef<'a, T>

Converts this type into the (usually inferred) input type.

Auto Trait Implementations§

§

impl<'a, T> Freeze for SliceRbRefMut<'a, T>

§

impl<'a, T> RefUnwindSafe for SliceRbRefMut<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> Send for SliceRbRefMut<'a, T>
where T: Send,

§

impl<'a, T> Sync for SliceRbRefMut<'a, T>
where T: Sync,

§

impl<'a, T> Unpin for SliceRbRefMut<'a, T>

§

impl<'a, T> !UnwindSafe for SliceRbRefMut<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.