use crate::ParallelParam;
use core::{
iter::{DoubleEndedIterator, ExactSizeIterator},
marker::PhantomData,
};
pub struct Iter<'a, Param: ParallelParam> {
pub(crate) ptr: Param::Ptr,
pub(crate) remaining: usize,
pub(crate) _marker: PhantomData<&'a Param>,
}
impl<'a, Param: ParallelParam> Iterator for Iter<'a, Param> {
type Item = Param::Ref<'a>;
fn next(&mut self) -> Option<Param::Ref<'a>> {
unsafe {
if self.remaining == 0 {
return None;
}
let output = Param::as_ref(self.ptr);
self.ptr = Param::add(self.ptr, 1);
self.remaining -= 1;
Some(output)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<'a, Param: ParallelParam> ExactSizeIterator for Iter<'a, Param> {}
impl<'a, Param: ParallelParam> DoubleEndedIterator for Iter<'a, Param> {
fn next_back(&mut self) -> Option<Param::Ref<'a>> {
unsafe {
if self.remaining == 0 {
return None;
}
self.remaining -= 1;
let ptr = Param::add(self.ptr, self.remaining);
Some(Param::as_ref(ptr))
}
}
}
pub struct IterMut<'a, Param: ParallelParam> {
pub(crate) ptr: Param::Ptr,
pub(crate) remaining: usize,
pub(crate) _marker: PhantomData<&'a Param>,
}
impl<'a, Param: ParallelParam> Iterator for IterMut<'a, Param> {
type Item = Param::RefMut<'a>;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
if self.remaining == 0 {
return None;
}
let output = Param::as_mut(self.ptr);
self.ptr = Param::add(self.ptr, 1);
self.remaining -= 1;
Some(output)
}
}
}
impl<'a, Param: ParallelParam> ExactSizeIterator for IterMut<'a, Param> {}
impl<'a, Param: ParallelParam> DoubleEndedIterator for IterMut<'a, Param> {
fn next_back(&mut self) -> Option<Param::RefMut<'a>> {
unsafe {
if self.remaining == 0 {
return None;
}
self.remaining -= 1;
let ptr = Param::add(self.ptr, self.remaining);
Some(Param::as_mut(ptr))
}
}
}
#[repr(C)]
pub struct IntoIter<Param: ParallelParam> {
pub(crate) len: usize,
pub(crate) storage: Param::Storage,
pub(crate) capacity: usize,
pub(crate) idx: usize,
}
impl<Param: ParallelParam> Iterator for IntoIter<Param> {
type Item = Param;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
if self.idx >= self.len {
return None;
}
let ptr = Param::ptr_at(self.storage, self.idx);
let value = Param::read(ptr);
self.idx += 1;
Some(value)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.len - self.idx;
(remaining, Some(remaining))
}
}
impl<Param: ParallelParam> ExactSizeIterator for IntoIter<Param> {}
impl<Param: ParallelParam> DoubleEndedIterator for IntoIter<Param> {
fn next_back(&mut self) -> Option<Param> {
unsafe {
if self.len == 0 {
return None;
}
self.len -= 1;
let ptr = Param::ptr_at(self.storage, self.len);
Some(Param::read(ptr))
}
}
}
impl<Param: ParallelParam> Drop for IntoIter<Param> {
fn drop(&mut self) {
unsafe {
for idx in self.idx..self.len {
Param::drop(Param::ptr_at(self.storage, idx));
}
Param::dealloc(self.storage, self.capacity);
}
}
}