konst/slice/slice_as_chunks.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use crate::slice;
/// Const equivalent of
/// [`<[T]>::as_chunks`](https://doc.rust-lang.org/std/primitive.slice.html#method.as_chunks)
///
/// The equivalent std function is unstable as of Rust 1.83.0.
///
/// # Panics
///
/// Panics if `N == 0`.
///
/// # Example
///
/// ```rust
/// use konst::slice;
///
/// let (arrs, rem) = slice::as_chunks::<_, 3>(&[2u32, 3, 5, 8, 13, 21, 34, 55]);
///
/// assert_eq!(arrs, &[[2, 3, 5], [8, 13, 21]][..]);
/// assert_eq!(rem, &[34, 55][..])
///
/// ```
#[track_caller]
pub const fn as_chunks<'a, T, const N: usize>(this: &[T]) -> (&[[T; N]], &[T]) {
assert!(N != 0, "chunk size must be non-zero");
let arrs_len = this.len() / N;
let (arrs_in, rem) = slice::split_at(this, arrs_len * N);
// SAFETY: `arrs_in` is a `&[T]` that is `arrs_len * N` long,
// its layout is compatible with the `&[[T; N]]` that this produces.
let arrs: &[[T; N]] =
unsafe { core::slice::from_raw_parts(arrs_in.as_ptr() as *const [T; N], arrs_len) };
(arrs, rem)
}
/// Const equivalent of
/// [`<[T]>::as_rchunks`](https://doc.rust-lang.org/std/primitive.slice.html#method.as_rchunks)
///
/// The equivalent std function is unstable as of Rust 1.83.0.
///
/// # Panics
///
/// Panics if `N == 0`.
///
/// # Example
///
/// ```rust
/// use konst::slice;
///
/// let (rem, arrs) = slice::as_rchunks::<_, 2>(&[2u32, 3, 5, 8, 13, 21, 34]);
///
/// assert_eq!(rem, &[2][..]);
/// assert_eq!(arrs, &[[3, 5], [8, 13], [21, 34]][..]);
/// ```
#[track_caller]
pub const fn as_rchunks<'a, T, const N: usize>(this: &[T]) -> (&[T], &[[T; N]]) {
assert!(N != 0, "chunk size must be non-zero");
let arrs_len = this.len() / N;
let rem_len = this.len() % N;
let (rem, arrs_in) = slice::split_at(this, rem_len);
// SAFETY: `arrs_in` is a `&[T]` that is `arrs_len * N` long,
// its layout is compatible with the `&[[T; N]]` that this produces.
let arrs: &[[T; N]] =
unsafe { core::slice::from_raw_parts(arrs_in.as_ptr() as *const [T; N], arrs_len) };
(rem, arrs)
}