Skip to main content

polars_utils/
chunks.rs

1/// A copy of the [`std::slice::Chunks`] that exposes the inner `slice` and `chunk_size`.
2#[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}