//! Iteration. use std::{marker::PhantomData, mem::ManuallyDrop, ptr::NonNull}; use crate::{ptr_ext::PtrExt, DynVec}; struct BaseIter { ptr: *const *mut T, ptr_back: *const *mut T, } unsafe impl Send for BaseIter {} unsafe impl Sync for BaseIter {} impl BaseIter { pub(crate) fn new(vec: &DynVec) -> Self { Self { ptr: vec.get_ptr_to_extra(vec.len).cast(), ptr_back: vec.get_ptr_to_extra(0).cast(), } } } impl Iterator for BaseIter { type Item = *mut T; fn next(&mut self) -> Option { if self.ptr == self.ptr_back { return None; } self.ptr_back = self.ptr_back.wrapping_sub(1); Some(unsafe { self.ptr_back.read() }) } } impl DoubleEndedIterator for BaseIter { fn next_back(&mut self) -> Option { if self.ptr == self.ptr_back { return None; } let el = unsafe { self.ptr.read() }; self.ptr = self.ptr.wrapping_add(1); Some(el) } } // By-ref iteration impl DynVec { /// Iterates over the vector by-ref. pub fn iter(&self) -> Iter { Iter { base: BaseIter::new(self), _phantom: PhantomData, } } } impl<'a, T: ?Sized> IntoIterator for &'a DynVec { type Item = &'a T; type IntoIter = Iter<'a, T>; fn into_iter(self) -> Self::IntoIter { self.iter() } } /// A by-ref iterator over the elements of a [`DynVec`]. pub struct Iter<'a, T: ?Sized> { base: BaseIter, _phantom: PhantomData<&'a T>, } unsafe impl<'a, T: Send> Send for Iter<'a, T> {} unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {} impl<'a, T: ?Sized> Iterator for Iter<'a, T> { type Item = &'a T; fn next(&mut self) -> Option { self.base.next().map(|v| unsafe { &*v }) } } impl<'a, T: ?Sized> DoubleEndedIterator for Iter<'a, T> { fn next_back(&mut self) -> Option { self.base.next_back().map(|v| unsafe { &*v }) } } // By-mut iteration impl DynVec { /// Iterates over the vector by-mut. pub fn iter_mut(&mut self) -> IterMut { IterMut { base: BaseIter::new(self), _phantom: PhantomData, } } } impl<'a, T: ?Sized> IntoIterator for &'a mut DynVec { type Item = &'a mut T; type IntoIter = IterMut<'a, T>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() } } /// A by-mut iterator over the elements of a [`DynVec`]. #[allow(clippy::module_name_repetitions)] pub struct IterMut<'a, T: ?Sized> { base: BaseIter, _phantom: PhantomData<&'a mut T>, } unsafe impl<'a, T: Send> Send for IterMut<'a, T> {} unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {} impl<'a, T: ?Sized> Iterator for IterMut<'a, T> { type Item = &'a mut T; fn next(&mut self) -> Option { self.base.next().map(|v| unsafe { &mut *v }) } } impl<'a, T: ?Sized> DoubleEndedIterator for IterMut<'a, T> { fn next_back(&mut self) -> Option { self.base.next_back().map(|v| unsafe { &mut *v }) } } // By-value iteration impl IntoIterator for DynVec { type Item = Box; type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { let this = ManuallyDrop::new(self); IntoIter { ptr: this.ptr, capacity: this.capacity, base: BaseIter::new(&this), } } } /// A by-value iterator over the elements of a [`DynVec`]. #[allow(clippy::module_name_repetitions)] pub struct IntoIter { ptr: NonNull, capacity: usize, base: BaseIter, } unsafe impl Send for IntoIter {} unsafe impl Sync for IntoIter {} impl Iterator for IntoIter { type Item = Box; fn next(&mut self) -> Option { Some(unsafe { self.base.next()?.read_to_box() }) } } impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { Some(unsafe { self.base.next_back()?.read_to_box() }) } } impl Drop for IntoIter { fn drop(&mut self) { drop(DynVec:: { ptr: self.ptr, len: 0, capacity: self.capacity, end_ptr: self.ptr, _phantom: PhantomData, }); } } // // this implementation will collect *while unsizing*, and would conflict with the other // impl FromIterator for DynVec where for<'a> &'a U: CoerceUnsized<&'a T> { // fn from_iter>(iter: I) -> Self { // let mut vec = DynVec::new(); // for item in iter.into_iter() { // vec.push_unsize(item); // } // vec // } // } impl FromIterator for DynVec { fn from_iter>(iter: I) -> Self { let mut vec = Self::new(); for item in iter { vec.push(item); } vec } }