use crate::implementations::ptr_utils::take;
use core::iter::FusedIterator;
pub struct ArrayIntoSeqIter<T, M> {
current: *const T,
last: *const T,
allocation_to_drop: Option<(*const T, usize)>,
_moved_into: M,
}
impl<T, M> ArrayIntoSeqIter<T, M> {
pub(crate) fn new(
first: *const T,
last: *const T,
allocation_to_drop: Option<(*const T, usize)>,
moved_into: M,
) -> Self {
Self {
current: first,
last,
allocation_to_drop,
_moved_into: moved_into,
}
}
fn remaining(&self) -> usize {
match self.current.is_null() {
true => 0,
false => unsafe { self.last.offset_from(self.current) as usize + 1 },
}
}
}
impl<T, M> Default for ArrayIntoSeqIter<T, M>
where
M: Default,
{
fn default() -> Self {
Self::new(core::ptr::null(), core::ptr::null(), None, M::default())
}
}
impl<T, M> Drop for ArrayIntoSeqIter<T, M> {
fn drop(&mut self) {
if core::mem::needs_drop::<T>() {
while !self.current.is_null() {
let p = self.current as *mut T;
unsafe { p.drop_in_place() };
let completed = self.current == self.last;
self.current = match completed {
true => core::ptr::null(),
false => unsafe { self.current.add(1) },
};
}
}
if let Some((ptr, capacity)) = &self.allocation_to_drop {
let _vec_to_drop =
unsafe { alloc::vec::Vec::from_raw_parts(*ptr as *mut T, 0, *capacity) };
}
}
}
impl<T, M> Iterator for ArrayIntoSeqIter<T, M> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
match self.current.is_null() {
false => {
let value = Some(unsafe { take(self.current as *mut T) });
let completed = self.current == self.last;
self.current = match completed {
true => core::ptr::null(),
false => unsafe { self.current.add(1) },
};
value
}
true => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.remaining();
(len, Some(len))
}
}
impl<T, M> ExactSizeIterator for ArrayIntoSeqIter<T, M> {
fn len(&self) -> usize {
self.remaining()
}
}
impl<T, M> FusedIterator for ArrayIntoSeqIter<T, M> {}