ring/polyfill/slice/
as_chunks.rs1use super::AsChunksMut;
16use core::ops;
17
18#[inline(always)]
19pub fn as_chunks<T, const N: usize>(slice: &[T]) -> (AsChunks<T, N>, &[T]) {
20 assert!(N != 0, "chunk size must be non-zero");
21 let len = slice.len() / N;
22 let (multiple_of_n, remainder) = slice.split_at(len * N);
23 (AsChunks(multiple_of_n), remainder)
24}
25
26#[derive(Clone, Copy)]
27pub struct AsChunks<'a, T, const N: usize>(&'a [T]);
28
29impl<'a, T, const N: usize> AsChunks<'a, T, N> {
30 #[inline(always)]
31 pub fn from_ref(value: &'a [T; N]) -> Self {
32 Self(value)
33 }
34
35 #[inline(always)]
36 pub fn as_flattened(&self) -> &[T] {
37 self.0
38 }
39
40 #[cfg(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64"))]
41 #[inline(always)]
42 pub fn as_ptr(&self) -> *const [T; N] {
43 self.0.as_ptr().cast()
44 }
45
46 #[inline(always)]
47 pub fn is_empty(&self) -> bool {
48 self.0.is_empty()
49 }
50
51 #[inline(always)]
52 pub fn len(&self) -> usize {
53 self.0.len() / N
54 }
55}
56
57impl<T, const N: usize> ops::Index<usize> for AsChunks<'_, T, N>
58where
59 [T]: ops::Index<ops::Range<usize>, Output = [T]>,
60{
61 type Output = [T; N];
62
63 #[inline(always)]
64 fn index(&self, index: usize) -> &Self::Output {
65 let start = N * index;
66 let slice = &self.0[start..(start + N)];
67 slice.try_into().unwrap()
68 }
69}
70
71impl<'a, T, const N: usize> IntoIterator for AsChunks<'a, T, N> {
72 type IntoIter = AsChunksIter<'a, T, N>;
73 type Item = &'a [T; N];
74
75 #[inline(always)]
76 fn into_iter(self) -> Self::IntoIter {
77 AsChunksIter(self.0.chunks_exact(N))
78 }
79}
80
81pub struct AsChunksIter<'a, T, const N: usize>(core::slice::ChunksExact<'a, T>);
82
83impl<'a, T, const N: usize> Iterator for AsChunksIter<'a, T, N> {
84 type Item = &'a [T; N];
85
86 #[inline(always)]
87 fn next(&mut self) -> Option<Self::Item> {
88 self.0.next().map(|x| x.try_into().unwrap())
89 }
90}
91
92impl<'a, T, const N: usize> From<&'a AsChunksMut<'_, T, N>> for AsChunks<'a, T, N> {
95 #[inline(always)]
96 fn from(as_mut: &'a AsChunksMut<'_, T, N>) -> Self {
97 Self(as_mut.as_flattened())
98 }
99}
100
101impl<'a, T, const N: usize> From<&'a [T; N]> for AsChunks<'a, T, N> {
102 #[inline(always)]
103 fn from(array: &'a [T; N]) -> Self {
104 Self(array)
105 }
106}
107
108impl<'a, T> From<AsChunks<'a, T, 8>> for AsChunks<'a, T, 4> {
110 #[inline(always)]
111 fn from(as_2x: AsChunks<'a, T, 8>) -> Self {
112 Self(as_2x.0)
113 }
114}