use std::iter::FusedIterator;
use crate::{Chunk, ChunkedVec};
pub struct FullChunks<'a, T, const N: usize> {
pub(crate) inner: std::slice::Iter<'a, Chunk<T, N>>,
}
impl<T, const N: usize> ChunkedVec<T, N> {
pub fn iter_full_chunks(&self) -> FullChunks<'_, T, N> {
let full_chunk_count = self.full_chunk_count();
FullChunks {
inner: self.data[..full_chunk_count].iter(),
}
}
}
impl<'a, T, const N: usize> Iterator for FullChunks<'a, T, N> {
type Item = &'a [T; N];
fn next(&mut self) -> Option<Self::Item> {
let chunk = self.inner.next()?;
let ptr = chunk.as_ref() as *const _ as *const [T; N];
unsafe { Some(&*ptr) }
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.inner.len();
(remaining, Some(remaining))
}
}
impl<T, const N: usize> ExactSizeIterator for FullChunks<'_, T, N> {}
impl<T, const N: usize> FusedIterator for FullChunks<'_, T, N> {}
#[cfg(test)]
mod tests {
use crate::{ChunkedVec, ChunkedVecSized};
#[test]
fn test_iter_full_chunks() {
let mut vec: ChunkedVec<i32, 4> = ChunkedVecSized::new();
vec.extend(0..10);
let chunks: Vec<&[i32; 4]> = vec.iter_full_chunks().collect();
assert_eq!(chunks, vec![&[0, 1, 2, 3], &[4, 5, 6, 7]]);
}
#[test]
fn test_iter_full_chunks_empty() {
let vec: ChunkedVec<i32, 4> = ChunkedVecSized::new();
assert_eq!(vec.iter_full_chunks().next(), None);
}
#[test]
fn test_iter_full_chunks_short_vector() {
let mut vec: ChunkedVec<i32, 4> = ChunkedVecSized::new();
vec.extend(0..2);
assert_eq!(vec.iter_full_chunks().next(), None);
}
}