//! Iteration. #[allow(clippy::wildcard_imports)] use super::*; struct BaseIter { ptr: *const *mut T, ptr_back: *const *mut T, } impl BaseIter { fn new(vec: &Vec) -> 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<'a, T: ?Sized> IntoIterator for &'a Vec { 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 [`Vec`]. pub struct Iter<'a, T: ?Sized> { base: BaseIter, _phantom: PhantomData<&'a T> } impl<'a, T: ?Sized> Iter<'a, T> { /// Creates a new by-ref iterator over a [`Vec`]. usually seen as [`Vec::iter`]. pub fn new(vec: &'a Vec) -> Self { Self { base: BaseIter::new(vec), _phantom: PhantomData } } } impl<'a, T: ?Sized> Iterator for Iter<'a, T> { type Item = &'a T; fn next(&mut self) -> Option { unsafe { self.base.next().map(|v| &*v) } } } impl<'a, T: ?Sized> DoubleEndedIterator for Iter<'a, T> { fn next_back(&mut self) -> Option { unsafe { self.base.next_back().map(|v| &*v) } } } // By-mut iteration impl<'a, T: ?Sized> IntoIterator for &'a mut Vec { 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 [`Vec`]. #[allow(clippy::module_name_repetitions)] pub struct IterMut<'a, T: ?Sized> { base: BaseIter, _phantom: PhantomData<&'a mut T> } impl<'a, T: ?Sized> IterMut<'a, T> { /// Creates a new by-mut iterator over a [`Vec`]. usually seen as [`Vec::iter_mut`]. pub fn new(vec: &'a mut Vec) -> Self { Self { base: BaseIter::new(vec), _phantom: PhantomData } } } impl<'a, T: ?Sized> Iterator for IterMut<'a, T> { type Item = &'a mut T; fn next(&mut self) -> Option { unsafe { self.base.next().map(|v| &mut *v) } } } impl<'a, T: ?Sized> DoubleEndedIterator for IterMut<'a, T> { fn next_back(&mut self) -> Option { unsafe { self.base.next_back().map(|v| &mut *v) } } } // By-value iteration impl IntoIterator for Vec { type Item = Box; type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter::new(self) } } /// A by-value iterator over the elements of a [`Vec`]. #[allow(clippy::module_name_repetitions)] pub struct IntoIter { ptr: NonNull, capacity: usize, base: BaseIter } impl IntoIter { /// Creates a new by-value iterator over a [`Vec`]. usually seen as [`Vec::into_iter`]. pub fn new(vec: Vec) -> Self { let this = Self { ptr: vec.ptr, capacity: vec.capacity, base: BaseIter::new(&vec) }; mem::forget(vec); this } } impl Iterator for IntoIter { type Item = Box; fn next(&mut self) -> Option { let ptr = self.base.next()?; unsafe { let alloc = alloc(Layout::for_value_raw(ptr)); memcpy(ptr.cast(), alloc, size_of_val_raw(ptr)); Some(Box::from_raw(ptr::from_raw_parts_mut(alloc.cast(), metadata(ptr)))) } } } impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { let ptr = self.base.next_back()?; unsafe { let alloc = alloc(Layout::for_value_raw(ptr)); memcpy(ptr.cast(), alloc, size_of_val_raw(ptr)); Some(Box::from_raw(ptr::from_raw_parts_mut(alloc.cast(), metadata(ptr)))) } } } impl Drop for IntoIter { fn drop(&mut self) { drop(Vec:: { 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 Vec where for<'a> &'a U: CoerceUnsized<&'a T> { // fn from_iter>(iter: I) -> Self { // let mut vec = Vec::new(); // for item in iter.into_iter() { // vec.push_unsize(item); // } // vec // } // } impl FromIterator for Vec { fn from_iter>(iter: I) -> Self { let mut vec = Vec::new(); for item in iter { vec.push(item); } vec } }