Skip to content

Commit

Permalink
Refactor Array::slice_as_chunks(_mut) (#31)
Browse files Browse the repository at this point in the history
Moves them from being free functions to inherent methods on `Array`.

This avoids having to import them separately.
  • Loading branch information
tarcieri authored Jan 29, 2024
1 parent 914480c commit f68ed30
Showing 1 changed file with 46 additions and 46 deletions.
92 changes: 46 additions & 46 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,52 @@ where
(head, tail)
}
}

/// Splits the shared slice into a slice of `U`-element arrays, starting at the beginning
/// of the slice, and a remainder slice with length strictly less than `U`.
///
/// # Panics
/// Panics if `U` is 0.
#[allow(clippy::arithmetic_side_effects)]
#[inline]
pub fn slice_as_chunks(buf: &[T]) -> (&[Self], &[T]) {
assert_ne!(U::USIZE, 0, "chunk size must be non-zero");
// Arithmetic safety: we have checked that `N::USIZE` is not zero, thus
// division always returns correct result. `tail_pos` can not be bigger than `buf.len()`,
// thus overflow on multiplication and underflow on substraction are impossible.
let chunks_len = buf.len() / U::USIZE;
let tail_pos = U::USIZE * chunks_len;
let tail_len = buf.len() - tail_pos;
unsafe {
let ptr = buf.as_ptr();
let chunks = slice::from_raw_parts(ptr.cast(), chunks_len);
let tail = slice::from_raw_parts(ptr.add(tail_pos), tail_len);
(chunks, tail)
}
}

/// Splits the exclusive slice into a slice of `U`-element arrays, starting at the beginning
/// of the slice, and a remainder slice with length strictly less than `U`.
///
/// # Panics
/// Panics if `U` is 0.
#[allow(clippy::arithmetic_side_effects)]
#[inline]
pub fn slice_as_chunks_mut(buf: &mut [T]) -> (&mut [Self], &mut [T]) {
assert_ne!(U::USIZE, 0, "chunk size must be non-zero");
// Arithmetic safety: we have checked that `N::USIZE` is not zero, thus
// division always returns correct result. `tail_pos` can not be bigger than `buf.len()`,
// thus overflow on multiplication and underflow on substraction are impossible.
let chunks_len = buf.len() / U::USIZE;
let tail_pos = U::USIZE * chunks_len;
let tail_len = buf.len() - tail_pos;
unsafe {
let ptr = buf.as_mut_ptr();
let chunks = slice::from_raw_parts_mut(ptr.cast(), chunks_len);
let tail = slice::from_raw_parts_mut(ptr.add(tail_pos), tail_len);
(chunks, tail)
}
}
}

// Impls which depend on the inner array type being `[T; N]`.
Expand Down Expand Up @@ -731,49 +777,3 @@ fn check_slice_length<T, U: ArraySize>(slice: &[T]) -> Result<(), TryFromSliceEr

Ok(())
}

/// Splits the shared slice into a slice of `N`-element arrays, starting at the beginning
/// of the slice, and a remainder slice with length strictly less than `N`.
///
/// # Panics
/// Panics if `N` is 0.
#[allow(clippy::arithmetic_side_effects)]
#[inline]
pub fn slice_as_chunks<T, N: ArraySize>(buf: &[T]) -> (&[Array<T, N>], &[T]) {
assert_ne!(N::USIZE, 0, "chunk size must be non-zero");
// Arithmetic safety: we have checked that `N::USIZE` is not zero, thus
// division always returns correct result. `tail_pos` can not be bigger than `buf.len()`,
// thus overflow on multiplication and underflow on substraction are impossible.
let chunks_len = buf.len() / N::USIZE;
let tail_pos = N::USIZE * chunks_len;
let tail_len = buf.len() - tail_pos;
unsafe {
let ptr = buf.as_ptr();
let chunks = slice::from_raw_parts(ptr.cast(), chunks_len);
let tail = slice::from_raw_parts(ptr.add(tail_pos), tail_len);
(chunks, tail)
}
}

/// Splits the exclusive slice into a slice of `N`-element arrays, starting at the beginning
/// of the slice, and a remainder slice with length strictly less than `N`.
///
/// # Panics
/// Panics if `N` is 0.
#[allow(clippy::arithmetic_side_effects)]
#[inline]
pub fn slice_as_chunks_mut<T, N: ArraySize>(buf: &mut [T]) -> (&mut [Array<T, N>], &mut [T]) {
assert_ne!(N::USIZE, 0, "chunk size must be non-zero");
// Arithmetic safety: we have checked that `N::USIZE` is not zero, thus
// division always returns correct result. `tail_pos` can not be bigger than `buf.len()`,
// thus overflow on multiplication and underflow on substraction are impossible.
let chunks_len = buf.len() / N::USIZE;
let tail_pos = N::USIZE * chunks_len;
let tail_len = buf.len() - tail_pos;
unsafe {
let ptr = buf.as_mut_ptr();
let chunks = slice::from_raw_parts_mut(ptr.cast(), chunks_len);
let tail = slice::from_raw_parts_mut(ptr.add(tail_pos), tail_len);
(chunks, tail)
}
}

0 comments on commit f68ed30

Please sign in to comment.