2022-05-13 14:27:14 -05:00
|
|
|
//! Iteration.
|
|
|
|
|
2022-05-16 09:42:00 -05:00
|
|
|
#[allow(clippy::wildcard_imports)]
|
2022-05-13 14:27:14 -05:00
|
|
|
use super::*;
|
|
|
|
|
|
|
|
struct BaseIter<T: ?Sized> {
|
|
|
|
ptr: *const *mut T,
|
|
|
|
ptr_back: *const *mut T,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ?Sized> BaseIter<T> {
|
|
|
|
fn new(vec: &Vec<T>) -> Self {
|
|
|
|
Self {
|
|
|
|
ptr: vec.get_ptr_to_extra(vec.len).cast(),
|
|
|
|
ptr_back: vec.get_ptr_to_extra(0).cast(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ?Sized> Iterator for BaseIter<T> {
|
|
|
|
type Item = *mut T;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
if self.ptr == self.ptr_back {
|
|
|
|
return None
|
|
|
|
}
|
|
|
|
|
|
|
|
self.ptr_back = self.ptr_back.wrapping_sub(1);
|
|
|
|
Some(unsafe { self.ptr_back.read() })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ?Sized> DoubleEndedIterator for BaseIter<T> {
|
|
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
|
|
|
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<T> {
|
|
|
|
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<T>,
|
|
|
|
_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<T>) -> 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<Self::Item> {
|
2022-05-17 09:47:54 -05:00
|
|
|
self.base.next().map(|v| unsafe { &*v })
|
2022-05-13 14:27:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T: ?Sized> DoubleEndedIterator for Iter<'a, T> {
|
|
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
2022-05-17 09:47:54 -05:00
|
|
|
self.base.next_back().map(|v| unsafe { &*v })
|
2022-05-13 14:27:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// By-mut iteration
|
|
|
|
impl<'a, T: ?Sized> IntoIterator for &'a mut Vec<T> {
|
|
|
|
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`].
|
2022-05-16 09:42:00 -05:00
|
|
|
#[allow(clippy::module_name_repetitions)]
|
2022-05-13 14:27:14 -05:00
|
|
|
pub struct IterMut<'a, T: ?Sized> {
|
|
|
|
base: BaseIter<T>,
|
|
|
|
_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<T>) -> 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<Self::Item> {
|
2022-05-17 09:47:54 -05:00
|
|
|
self.base.next().map(|v| unsafe { &mut *v })
|
2022-05-13 14:27:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T: ?Sized> DoubleEndedIterator for IterMut<'a, T> {
|
|
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
2022-05-17 09:47:54 -05:00
|
|
|
self.base.next_back().map(|v| unsafe { &mut *v })
|
2022-05-13 14:27:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// By-value iteration
|
|
|
|
impl<T: ?Sized> IntoIterator for Vec<T> {
|
|
|
|
type Item = Box<T>;
|
|
|
|
|
|
|
|
type IntoIter = IntoIter<T>;
|
|
|
|
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
|
|
IntoIter::new(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A by-value iterator over the elements of a [`Vec`].
|
2022-05-16 09:42:00 -05:00
|
|
|
#[allow(clippy::module_name_repetitions)]
|
2022-05-13 14:27:14 -05:00
|
|
|
pub struct IntoIter<T: ?Sized> {
|
|
|
|
ptr: NonNull<u8>,
|
|
|
|
capacity: usize,
|
|
|
|
base: BaseIter<T>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ?Sized> IntoIter<T> {
|
|
|
|
/// Creates a new by-value iterator over a [`Vec`]. usually seen as [`Vec::into_iter`].
|
|
|
|
pub fn new(vec: Vec<T>) -> Self {
|
|
|
|
let this = Self {
|
|
|
|
ptr: vec.ptr,
|
|
|
|
capacity: vec.capacity,
|
|
|
|
base: BaseIter::new(&vec)
|
|
|
|
};
|
|
|
|
mem::forget(vec);
|
|
|
|
this
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ?Sized> Iterator for IntoIter<T> {
|
|
|
|
type Item = Box<T>;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
2022-05-17 09:47:54 -05:00
|
|
|
Some(unsafe { self.base.next()?.read_to_box() })
|
2022-05-13 14:27:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ?Sized> DoubleEndedIterator for IntoIter<T> {
|
|
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
2022-05-17 09:47:54 -05:00
|
|
|
Some(unsafe { self.base.next_back()?.read_to_box() })
|
2022-05-13 14:27:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ?Sized> Drop for IntoIter<T> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
drop(Vec::<T> {
|
|
|
|
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<T: ?Sized, U> FromIterator<U> for Vec<T> where for<'a> &'a U: CoerceUnsized<&'a T> {
|
|
|
|
// fn from_iter<I: IntoIterator<Item = U>>(iter: I) -> Self {
|
|
|
|
// let mut vec = Vec::new();
|
|
|
|
|
|
|
|
// for item in iter.into_iter() {
|
|
|
|
// vec.push_unsize(item);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// vec
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
impl<T> FromIterator<T> for Vec<T> {
|
|
|
|
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
|
|
|
let mut vec = Vec::new();
|
|
|
|
|
2022-05-16 09:42:00 -05:00
|
|
|
for item in iter {
|
2022-05-13 14:27:14 -05:00
|
|
|
vec.push(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
vec
|
|
|
|
}
|
|
|
|
}
|