diff options
author | Wedson Almeida Filho <walmeida@microsoft.com> | 2024-03-27 22:35:57 -0300 |
---|---|---|
committer | Miguel Ojeda <ojeda@kernel.org> | 2024-04-16 22:05:00 +0200 |
commit | 9d0441bab775d2daa51370909b8648e27d0eb47d (patch) | |
tree | 131e5b6540f803266b39e543a383f5ab8714d9d4 /rust/alloc/vec | |
parent | 11795ae4cc430192fb9aee2c1142e313cbce3ec5 (diff) | |
download | linux-9d0441bab775d2daa51370909b8648e27d0eb47d.tar.gz linux-9d0441bab775d2daa51370909b8648e27d0eb47d.tar.bz2 linux-9d0441bab775d2daa51370909b8648e27d0eb47d.zip |
rust: alloc: remove our fork of the `alloc` crate
It is not used anymore as `VecExt` now provides the functionality we
depend on.
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
Link: https://lore.kernel.org/r/20240328013603.206764-5-wedsonaf@gmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/alloc/vec')
-rw-r--r-- | rust/alloc/vec/drain.rs | 255 | ||||
-rw-r--r-- | rust/alloc/vec/extract_if.rs | 115 | ||||
-rw-r--r-- | rust/alloc/vec/into_iter.rs | 484 | ||||
-rw-r--r-- | rust/alloc/vec/is_zero.rs | 204 | ||||
-rw-r--r-- | rust/alloc/vec/mod.rs | 3724 | ||||
-rw-r--r-- | rust/alloc/vec/partial_eq.rs | 49 | ||||
-rw-r--r-- | rust/alloc/vec/set_len_on_drop.rs | 35 | ||||
-rw-r--r-- | rust/alloc/vec/spec_extend.rs | 119 |
8 files changed, 0 insertions, 4985 deletions
diff --git a/rust/alloc/vec/drain.rs b/rust/alloc/vec/drain.rs deleted file mode 100644 index 78177a9e2ad0..000000000000 --- a/rust/alloc/vec/drain.rs +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR MIT - -use crate::alloc::{Allocator, Global}; -use core::fmt; -use core::iter::{FusedIterator, TrustedLen}; -use core::mem::{self, ManuallyDrop, SizedTypeProperties}; -use core::ptr::{self, NonNull}; -use core::slice::{self}; - -use super::Vec; - -/// A draining iterator for `Vec<T>`. -/// -/// This `struct` is created by [`Vec::drain`]. -/// See its documentation for more. -/// -/// # Example -/// -/// ``` -/// let mut v = vec![0, 1, 2]; -/// let iter: std::vec::Drain<'_, _> = v.drain(..); -/// ``` -#[stable(feature = "drain", since = "1.6.0")] -pub struct Drain< - 'a, - T: 'a, - #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global, -> { - /// Index of tail to preserve - pub(super) tail_start: usize, - /// Length of tail - pub(super) tail_len: usize, - /// Current remaining range to remove - pub(super) iter: slice::Iter<'a, T>, - pub(super) vec: NonNull<Vec<T, A>>, -} - -#[stable(feature = "collection_debug", since = "1.17.0")] -impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Drain").field(&self.iter.as_slice()).finish() - } -} - -impl<'a, T, A: Allocator> Drain<'a, T, A> { - /// Returns the remaining items of this iterator as a slice. - /// - /// # Examples - /// - /// ``` - /// let mut vec = vec!['a', 'b', 'c']; - /// let mut drain = vec.drain(..); - /// assert_eq!(drain.as_slice(), &['a', 'b', 'c']); - /// let _ = drain.next().unwrap(); - /// assert_eq!(drain.as_slice(), &['b', 'c']); - /// ``` - #[must_use] - #[stable(feature = "vec_drain_as_slice", since = "1.46.0")] - pub fn as_slice(&self) -> &[T] { - self.iter.as_slice() - } - - /// Returns a reference to the underlying allocator. - #[unstable(feature = "allocator_api", issue = "32838")] - #[must_use] - #[inline] - pub fn allocator(&self) -> &A { - unsafe { self.vec.as_ref().allocator() } - } - - /// Keep unyielded elements in the source `Vec`. - /// - /// # Examples - /// - /// ``` - /// #![feature(drain_keep_rest)] - /// - /// let mut vec = vec!['a', 'b', 'c']; - /// let mut drain = vec.drain(..); - /// - /// assert_eq!(drain.next().unwrap(), 'a'); - /// - /// // This call keeps 'b' and 'c' in the vec. - /// drain.keep_rest(); - /// - /// // If we wouldn't call `keep_rest()`, - /// // `vec` would be empty. - /// assert_eq!(vec, ['b', 'c']); - /// ``` - #[unstable(feature = "drain_keep_rest", issue = "101122")] - pub fn keep_rest(self) { - // At this moment layout looks like this: - // - // [head] [yielded by next] [unyielded] [yielded by next_back] [tail] - // ^-- start \_________/-- unyielded_len \____/-- self.tail_len - // ^-- unyielded_ptr ^-- tail - // - // Normally `Drop` impl would drop [unyielded] and then move [tail] to the `start`. - // Here we want to - // 1. Move [unyielded] to `start` - // 2. Move [tail] to a new start at `start + len(unyielded)` - // 3. Update length of the original vec to `len(head) + len(unyielded) + len(tail)` - // a. In case of ZST, this is the only thing we want to do - // 4. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do - let mut this = ManuallyDrop::new(self); - - unsafe { - let source_vec = this.vec.as_mut(); - - let start = source_vec.len(); - let tail = this.tail_start; - - let unyielded_len = this.iter.len(); - let unyielded_ptr = this.iter.as_slice().as_ptr(); - - // ZSTs have no identity, so we don't need to move them around. - if !T::IS_ZST { - let start_ptr = source_vec.as_mut_ptr().add(start); - - // memmove back unyielded elements - if unyielded_ptr != start_ptr { - let src = unyielded_ptr; - let dst = start_ptr; - - ptr::copy(src, dst, unyielded_len); - } - - // memmove back untouched tail - if tail != (start + unyielded_len) { - let src = source_vec.as_ptr().add(tail); - let dst = start_ptr.add(unyielded_len); - ptr::copy(src, dst, this.tail_len); - } - } - - source_vec.set_len(start + unyielded_len + this.tail_len); - } - } -} - -#[stable(feature = "vec_drain_as_slice", since = "1.46.0")] -impl<'a, T, A: Allocator> AsRef<[T]> for Drain<'a, T, A> { - fn as_ref(&self) -> &[T] { - self.as_slice() - } -} - -#[stable(feature = "drain", since = "1.6.0")] -unsafe impl<T: Sync, A: Sync + Allocator> Sync for Drain<'_, T, A> {} -#[stable(feature = "drain", since = "1.6.0")] -unsafe impl<T: Send, A: Send + Allocator> Send for Drain<'_, T, A> {} - -#[stable(feature = "drain", since = "1.6.0")] -impl<T, A: Allocator> Iterator for Drain<'_, T, A> { - type Item = T; - - #[inline] - fn next(&mut self) -> Option<T> { - self.iter.next().map(|elt| unsafe { ptr::read(elt as *const _) }) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - self.iter.size_hint() - } -} - -#[stable(feature = "drain", since = "1.6.0")] -impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> { - #[inline] - fn next_back(&mut self) -> Option<T> { - self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) }) - } -} - -#[stable(feature = "drain", since = "1.6.0")] -impl<T, A: Allocator> Drop for Drain<'_, T, A> { - fn drop(&mut self) { - /// Moves back the un-`Drain`ed elements to restore the original `Vec`. - struct DropGuard<'r, 'a, T, A: Allocator>(&'r mut Drain<'a, T, A>); - - impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> { - fn drop(&mut self) { - if self.0.tail_len > 0 { - unsafe { - let source_vec = self.0.vec.as_mut(); - // memmove back untouched tail, update to new length - let start = source_vec.len(); - let tail = self.0.tail_start; - if tail != start { - let src = source_vec.as_ptr().add(tail); - let dst = source_vec.as_mut_ptr().add(start); - ptr::copy(src, dst, self.0.tail_len); - } - source_vec.set_len(start + self.0.tail_len); - } - } - } - } - - let iter = mem::take(&mut self.iter); - let drop_len = iter.len(); - - let mut vec = self.vec; - - if T::IS_ZST { - // ZSTs have no identity, so we don't need to move them around, we only need to drop the correct amount. - // this can be achieved by manipulating the Vec length instead of moving values out from `iter`. - unsafe { - let vec = vec.as_mut(); - let old_len = vec.len(); - vec.set_len(old_len + drop_len + self.tail_len); - vec.truncate(old_len + self.tail_len); - } - - return; - } - - // ensure elements are moved back into their appropriate places, even when drop_in_place panics - let _guard = DropGuard(self); - - if drop_len == 0 { - return; - } - - // as_slice() must only be called when iter.len() is > 0 because - // it also gets touched by vec::Splice which may turn it into a dangling pointer - // which would make it and the vec pointer point to different allocations which would - // lead to invalid pointer arithmetic below. - let drop_ptr = iter.as_slice().as_ptr(); - - unsafe { - // drop_ptr comes from a slice::Iter which only gives us a &[T] but for drop_in_place - // a pointer with mutable provenance is necessary. Therefore we must reconstruct - // it from the original vec but also avoid creating a &mut to the front since that could - // invalidate raw pointers to it which some unsafe code might rely on. - let vec_ptr = vec.as_mut().as_mut_ptr(); - let drop_offset = drop_ptr.sub_ptr(vec_ptr); - let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len); - ptr::drop_in_place(to_drop); - } - } -} - -#[stable(feature = "drain", since = "1.6.0")] -impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> { - fn is_empty(&self) -> bool { - self.iter.is_empty() - } -} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<T, A: Allocator> TrustedLen for Drain<'_, T, A> {} - -#[stable(feature = "fused", since = "1.26.0")] -impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {} diff --git a/rust/alloc/vec/extract_if.rs b/rust/alloc/vec/extract_if.rs deleted file mode 100644 index f314a51d4d3d..000000000000 --- a/rust/alloc/vec/extract_if.rs +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR MIT - -use crate::alloc::{Allocator, Global}; -use core::ptr; -use core::slice; - -use super::Vec; - -/// An iterator which uses a closure to determine if an element should be removed. -/// -/// This struct is created by [`Vec::extract_if`]. -/// See its documentation for more. -/// -/// # Example -/// -/// ``` -/// #![feature(extract_if)] -/// -/// let mut v = vec![0, 1, 2]; -/// let iter: std::vec::ExtractIf<'_, _, _> = v.extract_if(|x| *x % 2 == 0); -/// ``` -#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -#[derive(Debug)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -pub struct ExtractIf< - 'a, - T, - F, - #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, -> where - F: FnMut(&mut T) -> bool, -{ - pub(super) vec: &'a mut Vec<T, A>, - /// The index of the item that will be inspected by the next call to `next`. - pub(super) idx: usize, - /// The number of items that have been drained (removed) thus far. - pub(super) del: usize, - /// The original length of `vec` prior to draining. - pub(super) old_len: usize, - /// The filter test predicate. - pub(super) pred: F, -} - -impl<T, F, A: Allocator> ExtractIf<'_, T, F, A> -where - F: FnMut(&mut T) -> bool, -{ - /// Returns a reference to the underlying allocator. - #[unstable(feature = "allocator_api", issue = "32838")] - #[inline] - pub fn allocator(&self) -> &A { - self.vec.allocator() - } -} - -#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -impl<T, F, A: Allocator> Iterator for ExtractIf<'_, T, F, A> -where - F: FnMut(&mut T) -> bool, -{ - type Item = T; - - fn next(&mut self) -> Option<T> { - unsafe { - while self.idx < self.old_len { - let i = self.idx; - let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); - let drained = (self.pred)(&mut v[i]); - // Update the index *after* the predicate is called. If the index - // is updated prior and the predicate panics, the element at this - // index would be leaked. - self.idx += 1; - if drained { - self.del += 1; - return Some(ptr::read(&v[i])); - } else if self.del > 0 { - let del = self.del; - let src: *const T = &v[i]; - let dst: *mut T = &mut v[i - del]; - ptr::copy_nonoverlapping(src, dst, 1); - } - } - None - } - } - - fn size_hint(&self) -> (usize, Option<usize>) { - (0, Some(self.old_len - self.idx)) - } -} - -#[unstable(feature = "extract_if", reason = "recently added", issue = "43244")] -impl<T, F, A: Allocator> Drop for ExtractIf<'_, T, F, A> -where - F: FnMut(&mut T) -> bool, -{ - fn drop(&mut self) { - unsafe { - if self.idx < self.old_len && self.del > 0 { - // This is a pretty messed up state, and there isn't really an - // obviously right thing to do. We don't want to keep trying - // to execute `pred`, so we just backshift all the unprocessed - // elements and tell the vec that they still exist. The backshift - // is required to prevent a double-drop of the last successfully - // drained item prior to a panic in the predicate. - let ptr = self.vec.as_mut_ptr(); - let src = ptr.add(self.idx); - let dst = src.sub(self.del); - let tail_len = self.old_len - self.idx; - src.copy_to(dst, tail_len); - } - self.vec.set_len(self.old_len - self.del); - } - } -} diff --git a/rust/alloc/vec/into_iter.rs b/rust/alloc/vec/into_iter.rs deleted file mode 100644 index 0f11744c44b3..000000000000 --- a/rust/alloc/vec/into_iter.rs +++ /dev/null @@ -1,484 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR MIT - -#[cfg(not(no_global_oom_handling))] -use super::AsVecIntoIter; -use crate::alloc::{Allocator, Global}; -#[cfg(not(no_global_oom_handling))] -use crate::collections::VecDeque; -use crate::raw_vec::RawVec; -use core::array; -use core::fmt; -use core::iter::{ - FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen, - TrustedRandomAccessNoCoerce, -}; -use core::marker::PhantomData; -use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; -use core::num::NonZeroUsize; -#[cfg(not(no_global_oom_handling))] -use core::ops::Deref; -use core::ptr::{self, NonNull}; -use core::slice::{self}; - -macro non_null { - (mut $place:expr, $t:ident) => {{ - #![allow(unused_unsafe)] // we're sometimes used within an unsafe block - unsafe { &mut *(ptr::addr_of_mut!($place) as *mut NonNull<$t>) } - }}, - ($place:expr, $t:ident) => {{ - #![allow(unused_unsafe)] // we're sometimes used within an unsafe block - unsafe { *(ptr::addr_of!($place) as *const NonNull<$t>) } - }}, -} - -/// An iterator that moves out of a vector. -/// -/// This `struct` is created by the `into_iter` method on [`Vec`](super::Vec) -/// (provided by the [`IntoIterator`] trait). -/// -/// # Example -/// -/// ``` -/// let v = vec![0, 1, 2]; -/// let iter: std::vec::IntoIter<_> = v.into_iter(); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_insignificant_dtor] -pub struct IntoIter< - T, - #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, -> { - pub(super) buf: NonNull<T>, - pub(super) phantom: PhantomData<T>, - pub(super) cap: usize, - // the drop impl reconstructs a RawVec from buf, cap and alloc - // to avoid dropping the allocator twice we need to wrap it into ManuallyDrop - pub(super) alloc: ManuallyDrop<A>, - pub(super) ptr: NonNull<T>, - /// If T is a ZST, this is actually ptr+len. This encoding is picked so that - /// ptr == end is a quick test for the Iterator being empty, that works - /// for both ZST and non-ZST. - /// For non-ZSTs the pointer is treated as `NonNull<T>` - pub(super) end: *const T, -} - -#[stable(feature = "vec_intoiter_debug", since = "1.13.0")] -impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("IntoIter").field(&self.as_slice()).finish() - } -} - -impl<T, A: Allocator> IntoIter<T, A> { - /// Returns the remaining items of this iterator as a slice. - /// - /// # Examples - /// - /// ``` - /// let vec = vec!['a', 'b', 'c']; - /// let mut into_iter = vec.into_iter(); - /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); - /// let _ = into_iter.next().unwrap(); - /// assert_eq!(into_iter.as_slice(), &['b', 'c']); - /// ``` - #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] - pub fn as_slice(&self) -> &[T] { - unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len()) } - } - - /// Returns the remaining items of this iterator as a mutable slice. - /// - /// # Examples - /// - /// ``` - /// let vec = vec!['a', 'b', 'c']; - /// let mut into_iter = vec.into_iter(); - /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); - /// into_iter.as_mut_slice()[2] = 'z'; - /// assert_eq!(into_iter.next().unwrap(), 'a'); - /// assert_eq!(into_iter.next().unwrap(), 'b'); - /// assert_eq!(into_iter.next().unwrap(), 'z'); - /// ``` - #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] - pub fn as_mut_slice(&mut self) -> &mut [T] { - unsafe { &mut *self.as_raw_mut_slice() } - } - - /// Returns a reference to the underlying allocator. - #[unstable(feature = "allocator_api", issue = "32838")] - #[inline] - pub fn allocator(&self) -> &A { - &self.alloc - } - - fn as_raw_mut_slice(&mut self) -> *mut [T] { - ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), self.len()) - } - - /// Drops remaining elements and relinquishes the backing allocation. - /// This method guarantees it won't panic before relinquishing - /// the backing allocation. - /// - /// This is roughly equivalent to the following, but more efficient - /// - /// ``` - /// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter(); - /// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter()); - /// (&mut into_iter).for_each(drop); - /// std::mem::forget(into_iter); - /// ``` - /// - /// This method is used by in-place iteration, refer to the vec::in_place_collect - /// documentation for an overview. - #[cfg(not(no_global_oom_handling))] - pub(super) fn forget_allocation_drop_remaining(&mut self) { - let remaining = self.as_raw_mut_slice(); - - // overwrite the individual fields instead of creating a new - // struct and then overwriting &mut self. - // this creates less assembly - self.cap = 0; - self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) }; - self.ptr = self.buf; - self.end = self.buf.as_ptr(); - - // Dropping the remaining elements can panic, so this needs to be - // done only after updating the other fields. - unsafe { - ptr::drop_in_place(remaining); - } - } - - /// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed. - pub(crate) fn forget_remaining_elements(&mut self) { - // For the ZST case, it is crucial that we mutate `end` here, not `ptr`. - // `ptr` must stay aligned, while `end` may be unaligned. - self.end = self.ptr.as_ptr(); - } - - #[cfg(not(no_global_oom_handling))] - #[inline] - pub(crate) fn into_vecdeque(self) -> VecDeque<T, A> { - // Keep our `Drop` impl from dropping the elements and the allocator - let mut this = ManuallyDrop::new(self); - - // SAFETY: This allocation originally came from a `Vec`, so it passes - // all those checks. We have `this.buf` ≤ `this.ptr` ≤ `this.end`, - // so the `sub_ptr`s below cannot wrap, and will produce a well-formed - // range. `end` ≤ `buf + cap`, so the range will be in-bounds. - // Taking `alloc` is ok because nothing else is going to look at it, - // since our `Drop` impl isn't going to run so there's no more code. - unsafe { - let buf = this.buf.as_ptr(); - let initialized = if T::IS_ZST { - // All the pointers are the same for ZSTs, so it's fine to - // say that they're all at the beginning of the "allocation". - 0..this.len() - } else { - this.ptr.sub_ptr(this.buf)..this.end.sub_ptr(buf) - }; - let cap = this.cap; - let alloc = ManuallyDrop::take(&mut this.alloc); - VecDeque::from_contiguous_raw_parts_in(buf, initialized, cap, alloc) - } - } -} - -#[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")] -impl<T, A: Allocator> AsRef<[T]> for IntoIter<T, A> { - fn as_ref(&self) -> &[T] { - self.as_slice() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<T: Send, A: Allocator + Send> Send for IntoIter<T, A> {} -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<T: Sync, A: Allocator + Sync> Sync for IntoIter<T, A> {} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T, A: Allocator> Iterator for IntoIter<T, A> { - type Item = T; - - #[inline] - fn next(&mut self) -> Option<T> { - if T::IS_ZST { - if self.ptr.as_ptr() == self.end as *mut _ { - None - } else { - // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by - // reducing the `end`. - self.end = self.end.wrapping_byte_sub(1); - - // Make up a value of this ZST. - Some(unsafe { mem::zeroed() }) - } - } else { - if self.ptr == non_null!(self.end, T) { - None - } else { - let old = self.ptr; - self.ptr = unsafe { old.add(1) }; - - Some(unsafe { ptr::read(old.as_ptr()) }) - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option<usize>) { - let exact = if T::IS_ZST { - self.end.addr().wrapping_sub(self.ptr.as_ptr().addr()) - } else { - unsafe { non_null!(self.end, T).sub_ptr(self.ptr) } - }; - (exact, Some(exact)) - } - - #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { - let step_size = self.len().min(n); - let to_drop = ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), step_size); - if T::IS_ZST { - // See `next` for why we sub `end` here. - self.end = self.end.wrapping_byte_sub(step_size); - } else { - // SAFETY: the min() above ensures that step_size is in bounds - self.ptr = unsafe { self.ptr.add(step_size) }; - } - // SAFETY: the min() above ensures that step_size is in bounds - unsafe { - ptr::drop_in_place(to_drop); - } - NonZeroUsize::new(n - step_size).map_or(Ok(()), Err) - } - - #[inline] - fn count(self) -> usize { - self.len() - } - - #[inline] - fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> { - let mut raw_ary = MaybeUninit::uninit_array(); - - let len = self.len(); - - if T::IS_ZST { - if len < N { - self.forget_remaining_elements(); - // Safety: ZSTs can be conjured ex nihilo, only the amount has to be correct - return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, 0..len) }); - } - - self.end = self.end.wrapping_byte_sub(N); - // Safety: ditto - return Ok(unsafe { raw_ary.transpose().assume_init() }); - } - - if len < N { - // Safety: `len` indicates that this many elements are available and we just checked that - // it fits into the array. - unsafe { - ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, len); - self.forget_remaining_elements(); - return Err(array::IntoIter::new_unchecked(raw_ary, 0..len)); - } - } - - // Safety: `len` is larger than the array size. Copy a fixed amount here to fully initialize - // the array. - return unsafe { - ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, N); - self.ptr = self.ptr.add(N); - Ok(raw_ary.transpose().assume_init()) - }; - } - - unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item - where - Self: TrustedRandomAccessNoCoerce, - { - // SAFETY: the caller must guarantee that `i` is in bounds of the - // `Vec<T>`, so `i` cannot overflow an `isize`, and the `self.ptr.add(i)` - // is guaranteed to pointer to an element of the `Vec<T>` and - // thus guaranteed to be valid to dereference. - // - // Also note the implementation of `Self: TrustedRandomAccess` requires - // that `T: Copy` so reading elements from the buffer doesn't invalidate - // them for `Drop`. - unsafe { if T::IS_ZST { mem::zeroed() } else { self.ptr.add(i).read() } } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> { - #[inline] - fn next_back(&mut self) -> Option<T> { - if T::IS_ZST { - if self.end as *mut _ == self.ptr.as_ptr() { - None - } else { - // See above for why 'ptr.offset' isn't used - self.end = self.end.wrapping_byte_sub(1); - - // Make up a value of this ZST. - Some(unsafe { mem::zeroed() }) - } - } else { - if non_null!(self.end, T) == self.ptr { - None - } else { - let new_end = unsafe { non_null!(self.end, T).sub(1) }; - *non_null!(mut self.end, T) = new_end; - - Some(unsafe { ptr::read(new_end.as_ptr()) }) - } - } - } - - #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { - let step_size = self.len().min(n); - if T::IS_ZST { - // SAFETY: same as for advance_by() - self.end = self.end.wrapping_byte_sub(step_size); - } else { - // SAFETY: same as for advance_by() - self.end = unsafe { self.end.sub(step_size) }; - } - let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size); - // SAFETY: same as for advance_by() - unsafe { - ptr::drop_in_place(to_drop); - } - NonZeroUsize::new(n - step_size).map_or(Ok(()), Err) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> { - fn is_empty(&self) -> bool { - if T::IS_ZST { - self.ptr.as_ptr() == self.end as *mut _ - } else { - self.ptr == non_null!(self.end, T) - } - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {} - -#[doc(hidden)] -#[unstable(issue = "none", feature = "trusted_fused")] -unsafe impl<T, A: Allocator> TrustedFused for IntoIter<T, A> {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {} - -#[stable(feature = "default_iters", since = "1.70.0")] -impl<T, A> Default for IntoIter<T, A> -where - A: Allocator + Default, -{ - /// Creates an empty `vec::IntoIter`. - /// - /// ``` - /// # use std::vec; - /// let iter: vec::IntoIter<u8> = Default::default(); - /// assert_eq!(iter.len(), 0); - /// assert_eq!(iter.as_slice(), &[]); - /// ``` - fn default() -> Self { - super::Vec::new_in(Default::default()).into_iter() - } -} - -#[doc(hidden)] -#[unstable(issue = "none", feature = "std_internals")] -#[rustc_unsafe_specialization_marker] -pub trait NonDrop {} - -// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr -// and thus we can't implement drop-handling -#[unstable(issue = "none", feature = "std_internals")] -impl<T: Copy> NonDrop for T {} - -#[doc(hidden)] -#[unstable(issue = "none", feature = "std_internals")] -// TrustedRandomAccess (without NoCoerce) must not be implemented because -// subtypes/supertypes of `T` might not be `NonDrop` -unsafe impl<T, A: Allocator> TrustedRandomAccessNoCoerce for IntoIter<T, A> -where - T: NonDrop, -{ - const MAY_HAVE_SIDE_EFFECT: bool = false; -} - -#[cfg(not(no_global_oom_handling))] -#[stable(feature = "vec_into_iter_clone", since = "1.8.0")] -impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> { - #[cfg(not(test))] - fn clone(&self) -> Self { - self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter() - } - #[cfg(test)] - fn clone(&self) -> Self { - crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> { - fn drop(&mut self) { - struct DropGuard<'a, T, A: Allocator>(&'a mut IntoIter<T, A>); - - impl<T, A: Allocator> Drop for DropGuard<'_, T, A> { - fn drop(&mut self) { - unsafe { - // `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec - let alloc = ManuallyDrop::take(&mut self.0.alloc); - // RawVec handles deallocation - let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc); - } - } - } - - let guard = DropGuard(self); - // destroy the remaining elements - unsafe { - ptr::drop_in_place(guard.0.as_raw_mut_slice()); - } - // now `guard` will be dropped and do the rest - } -} - -// In addition to the SAFETY invariants of the following three unsafe traits -// also refer to the vec::in_place_collect module documentation to get an overview -#[unstable(issue = "none", feature = "inplace_iteration")] -#[doc(hidden)] -unsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> { - const EXPAND_BY: Option<NonZeroUsize> = NonZeroUsize::new(1); - const MERGE_BY: Option<NonZeroUsize> = NonZeroUsize::new(1); -} - -#[unstable(issue = "none", feature = "inplace_iteration")] -#[doc(hidden)] -unsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> { - type Source = Self; - - #[inline] - unsafe fn as_inner(&mut self) -> &mut Self::Source { - self - } -} - -#[cfg(not(no_global_oom_handling))] -unsafe impl<T> AsVecIntoIter for IntoIter<T> { - type Item = T; - - fn as_into_iter(&mut self) -> &mut IntoIter<Self::Item> { - self - } -} diff --git a/rust/alloc/vec/is_zero.rs b/rust/alloc/vec/is_zero.rs deleted file mode 100644 index d928dcf90e80..000000000000 --- a/rust/alloc/vec/is_zero.rs +++ /dev/null @@ -1,204 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 OR MIT - -use core::num::{Saturating, Wrapping}; - -use crate::boxed::Box; - -#[rustc_specialization_trait] -pub(super) unsafe trait IsZero { - /// Whether this value's representation is all zeros, - /// or can be represented with all zeroes. - fn is_zero(&self) -> bool; -} - -macro_rules! impl_is_zero { - ($t:ty, $is_zero:expr) => { - unsafe impl IsZero for $t { - #[inline] - fn is_zero(&self) -> bool { - $is_zero(*self) - } - } - }; -} - -impl_is_zero!(i8, |x| x == 0); // It is needed to impl for arrays and tuples of i8. -impl_is_zero!(i16, |x| x == 0); -impl_is_zero!(i32, |x| x == 0); -impl_is_zero!(i64, |x| x == 0); -impl_is_zero!(i128, |x| x == 0); -impl_is_zero!(isize, |x| x == 0); - -impl_is_zero!(u8, |x| x == 0); // It is needed to impl for arrays and tuples of u8. -impl_is_zero!(u16, |x| x == 0); -impl_is_zero!(u32, |x| x == 0); -impl_is_zero!(u64, |x| x == 0); -impl_is_zero!(u128, |x| x == 0); -impl_is_zero!(usize, |x| x == 0); - -impl_is_zero!(bool, |x| x == false); -impl_is_zero!(char, |x| x == '\0'); - -impl_is_zero!(f32, |x: f32| x.to_bits() == 0); -impl_is_zero!(f64, |x: f64| x.to_bits() == 0); - -unsafe impl<T> IsZero for *const T { - #[inline] - fn is_zero(&self) -> bool { - (*self).is_null() - } -} - -unsafe impl<T> IsZero for *mut T { |