use super::Array;
use core::{mem::ManuallyDrop, ptr, slice};
pub struct ArrayIter<T>
where
T: Array,
{
source: ManuallyDrop<T>,
index: usize,
}
impl<T> ArrayIter<T>
where
T: Array,
{
pub fn new(source: T) -> Self {
Self {
source: ManuallyDrop::new(source),
index: 0,
}
}
}
impl<T> Iterator for ArrayIter<T>
where
T: Array,
{
type Item = T::Item;
fn next(&mut self) -> Option<Self::Item> {
let source = self.source.as_slice();
let index = self.index;
if index < source.len() {
self.index = index + 1;
Some(unsafe { ptr::read(&source[index]) })
} else {
None
}
}
}
impl<T> Drop for ArrayIter<T>
where
T: Array,
{
fn drop(&mut self) {
let source = self.source.as_mut_slice();
let remaining_len = source.len() - self.index;
unsafe {
let start = source.as_mut_ptr().offset(self.index as isize);
let remaining = slice::from_raw_parts_mut(start, remaining_len);
ptr::drop_in_place(remaining);
}
}
}