Compare commits
2 commits
e8d81a91fd
...
992f351597
Author | SHA1 | Date | |
---|---|---|---|
missing | 992f351597 | ||
missing | 715b8bb93c |
65
src/impls.rs
Normal file
65
src/impls.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
//! Implements `Debug`, and `PartialEq` for various list-like types.
|
||||
|
||||
use super::*;
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
impl<T: ?Sized + Debug> Debug for Vec<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_list().entries(self.iter()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
// Vec<T> == Vec<U>
|
||||
impl<T: ?Sized + PartialEq<U>, U: ?Sized> PartialEq<Vec<U>> for Vec<T> {
|
||||
fn eq(&self, other: &Vec<U>) -> bool {
|
||||
if self.len != other.len { return false }
|
||||
for (el, el2) in self.iter().zip(other.iter()) {
|
||||
if el != el2 { return false }
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Eq> Eq for Vec<T> {}
|
||||
|
||||
// Vec<T> == &[U]
|
||||
impl<T: PartialEq<U>, U> PartialEq<&[U]> for Vec<T> {
|
||||
fn eq(&self, other: &&[U]) -> bool {
|
||||
if self.len != other.len() { return false }
|
||||
for (el, el2) in self.iter().zip(other.iter()) {
|
||||
if el != el2 { return false }
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// &[U] == Vec<T>
|
||||
impl<T: PartialEq<U>, U> PartialEq<Vec<T>> for &[U] {
|
||||
fn eq(&self, other: &Vec<T>) -> bool {
|
||||
other == self
|
||||
}
|
||||
}
|
||||
|
||||
// Vec<T> == [U; N]
|
||||
impl<T: PartialEq<U>, U, const N: usize> PartialEq<[U; N]> for Vec<T> {
|
||||
fn eq(&self, other: &[U; N]) -> bool {
|
||||
*self == &other[..]
|
||||
}
|
||||
}
|
||||
|
||||
// [U; N] == Vec<T>
|
||||
impl<T: PartialEq<U>, U, const N: usize> PartialEq<Vec<T>> for [U; N] {
|
||||
fn eq(&self, other: &Vec<T>) -> bool {
|
||||
other == self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, U: ?Sized> Extend<Box<U>> for Vec<T> where Box<U>: CoerceUnsized<Box<T>> {
|
||||
fn extend<I: IntoIterator<Item = Box<U>>>(&mut self, iter: I) {
|
||||
for item in iter {
|
||||
// TODO: optmize
|
||||
self.push_box(item);
|
||||
}
|
||||
}
|
||||
}
|
214
src/iter.rs
Normal file
214
src/iter.rs
Normal file
|
@ -0,0 +1,214 @@
|
|||
//! Iteration.
|
||||
|
||||
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> {
|
||||
unsafe { self.base.next().map(|v| &*v) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> DoubleEndedIterator for Iter<'a, T> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
unsafe { self.base.next_back().map(|v| &*v) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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`].
|
||||
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> {
|
||||
unsafe { self.base.next().map(|v| &mut *v) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> DoubleEndedIterator for IterMut<'a, T> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
unsafe { self.base.next_back().map(|v| &mut *v) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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`].
|
||||
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> {
|
||||
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<T: ?Sized> DoubleEndedIterator for IntoIter<T> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
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<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();
|
||||
|
||||
for item in iter.into_iter() {
|
||||
vec.push(item);
|
||||
}
|
||||
|
||||
vec
|
||||
}
|
||||
}
|
|
@ -432,6 +432,15 @@ impl<T: ?Sized> Vec<T> {
|
|||
dealloc(self.ptr.as_ptr(), Layout::from_size_align_unchecked(self.capacity, 8));
|
||||
}
|
||||
}
|
||||
|
||||
/// Extends this vector with an iterator.
|
||||
///
|
||||
/// Similar to [`Extend::extend`], but seperate to prevent conflicting implementations.
|
||||
pub fn extend_unsize<U, I: IntoIterator<Item = U>>(&mut self, iter: I) where for<'a> &'a U: CoerceUnsized<&'a T> {
|
||||
for item in iter {
|
||||
self.push_unsize(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Vec<[T]> {
|
||||
|
|
Loading…
Reference in a new issue