1#[derive(Clone, Debug)]
3pub struct Chunks<'a, T> {
4 slice: &'a [T],
5 chunk_size: usize,
6}
7
8impl<'a, T> Iterator for Chunks<'a, T> {
9 type Item = &'a [T];
10
11 #[inline]
12 fn next(&mut self) -> Option<Self::Item> {
13 if self.slice.is_empty() {
14 return None;
15 }
16
17 let item;
18 (item, self.slice) = self.slice.split_at(self.chunk_size.min(self.slice.len()));
19
20 Some(item)
21 }
22
23 fn size_hint(&self) -> (usize, Option<usize>) {
24 let len = self.slice.len().div_ceil(self.chunk_size);
25 (len, Some(len))
26 }
27}
28
29impl<T> DoubleEndedIterator for Chunks<'_, T> {
30 fn next_back(&mut self) -> Option<Self::Item> {
31 if self.slice.is_empty() {
32 return None;
33 }
34
35 let rem = self.slice.len() % self.chunk_size;
36 let offset = if rem == 0 { self.chunk_size } else { rem };
37
38 let item;
39 (self.slice, item) = self.slice.split_at(self.slice.len() - offset);
40
41 Some(item)
42 }
43}
44
45impl<T> ExactSizeIterator for Chunks<'_, T> {}
46
47impl<'a, T> Chunks<'a, T> {
48 #[inline(always)]
49 pub const fn new(slice: &'a [T], chunk_size: usize) -> Self {
50 Self { slice, chunk_size }
51 }
52
53 #[inline(always)]
54 pub const fn as_slice(&self) -> &'a [T] {
55 self.slice
56 }
57
58 #[inline(always)]
59 pub const fn chunk_size(&self) -> usize {
60 self.chunk_size
61 }
62
63 pub fn skip_in_place(&mut self, n: usize) {
64 let n = n * self.chunk_size;
65 self.slice = &self.slice[n.min(self.slice.len())..];
66 }
67}