refactor: moved IntoIter into into_iter.rs
This commit is contained in:
parent
2580822b91
commit
93613901d0
270
library/alloc/src/vec/into_iter.rs
Normal file
270
library/alloc/src/vec/into_iter.rs
Normal file
@ -0,0 +1,270 @@
|
||||
use crate::alloc::{Allocator, Global};
|
||||
use crate::raw_vec::RawVec;
|
||||
use core::marker::PhantomData;
|
||||
use core::intrinsics::{arith_offset};
|
||||
use core::mem::{self};
|
||||
use core::fmt;
|
||||
use core::ptr::{self, NonNull};
|
||||
use core::slice::{self};
|
||||
use core::iter::{
|
||||
FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccess,
|
||||
};
|
||||
|
||||
/// An iterator that moves out of a vector.
|
||||
///
|
||||
/// This `struct` is created by the `into_iter` method on [`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")]
|
||||
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,
|
||||
pub(super) alloc: A,
|
||||
pub(super) ptr: *const 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, 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 *mut T, self.len())
|
||||
}
|
||||
|
||||
pub(super) fn drop_remaining(&mut self) {
|
||||
unsafe {
|
||||
ptr::drop_in_place(self.as_mut_slice());
|
||||
}
|
||||
self.ptr = self.end;
|
||||
}
|
||||
|
||||
/// Relinquishes the backing allocation, equivalent to
|
||||
/// `ptr::write(&mut self, Vec::new().into_iter())`
|
||||
pub(super) fn forget_allocation(&mut self) {
|
||||
self.cap = 0;
|
||||
self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
|
||||
self.ptr = self.buf.as_ptr();
|
||||
self.end = self.buf.as_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
#[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 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 self.ptr as *const _ == self.end {
|
||||
None
|
||||
} else if mem::size_of::<T>() == 0 {
|
||||
// purposefully don't use 'ptr.offset' because for
|
||||
// vectors with 0-size elements this would return the
|
||||
// same pointer.
|
||||
self.ptr = unsafe { arith_offset(self.ptr as *const i8, 1) as *mut T };
|
||||
|
||||
// Make up a value of this ZST.
|
||||
Some(unsafe { mem::zeroed() })
|
||||
} else {
|
||||
let old = self.ptr;
|
||||
self.ptr = unsafe { self.ptr.offset(1) };
|
||||
|
||||
Some(unsafe { ptr::read(old) })
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let exact = if mem::size_of::<T>() == 0 {
|
||||
(self.end as usize).wrapping_sub(self.ptr as usize)
|
||||
} else {
|
||||
unsafe { self.end.offset_from(self.ptr) as usize }
|
||||
};
|
||||
(exact, Some(exact))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn count(self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
|
||||
where
|
||||
Self: TrustedRandomAccess,
|
||||
{
|
||||
// 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 mem::size_of::<T>() == 0 { mem::zeroed() } else { ptr::read(self.ptr.add(i)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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 self.end == self.ptr {
|
||||
None
|
||||
} else if mem::size_of::<T>() == 0 {
|
||||
// See above for why 'ptr.offset' isn't used
|
||||
self.end = unsafe { arith_offset(self.end as *const i8, -1) as *mut T };
|
||||
|
||||
// Make up a value of this ZST.
|
||||
Some(unsafe { mem::zeroed() })
|
||||
} else {
|
||||
self.end = unsafe { self.end.offset(-1) };
|
||||
|
||||
Some(unsafe { ptr::read(self.end) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.ptr == self.end
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(issue = "none", feature = "std_internals")]
|
||||
// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr
|
||||
// and thus we can't implement drop-handling
|
||||
unsafe impl<T, A: Allocator> TrustedRandomAccess for IntoIter<T, A>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
fn may_have_side_effect() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[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.clone()).into_iter()
|
||||
}
|
||||
#[cfg(test)]
|
||||
fn clone(&self) -> Self {
|
||||
crate::slice::to_vec(self.as_slice(), self.alloc.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
|
||||
let alloc = ptr::read(&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
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> {}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> {
|
||||
type Source = Self;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut Self::Source {
|
||||
self
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ use core::fmt;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::intrinsics::{arith_offset, assume};
|
||||
use core::iter::{
|
||||
FromIterator, FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccess,
|
||||
FromIterator, InPlaceIterable, SourceIter, TrustedLen,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
use core::mem::{self, ManuallyDrop, MaybeUninit};
|
||||
@ -91,6 +91,11 @@ mod drain;
|
||||
|
||||
mod cow;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::into_iter::IntoIter;
|
||||
|
||||
mod into_iter;
|
||||
|
||||
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
|
||||
///
|
||||
/// # Examples
|
||||
@ -3015,269 +3020,6 @@ impl<T, A: Allocator, const N: usize> TryFrom<Vec<T, A>> for [T; N] {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// An iterator that moves out of a vector.
|
||||
///
|
||||
/// This `struct` is created by the `into_iter` method on [`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")]
|
||||
pub struct IntoIter<
|
||||
T,
|
||||
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
|
||||
> {
|
||||
buf: NonNull<T>,
|
||||
phantom: PhantomData<T>,
|
||||
cap: usize,
|
||||
alloc: A,
|
||||
ptr: *const T,
|
||||
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, 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 *mut T, self.len())
|
||||
}
|
||||
|
||||
fn drop_remaining(&mut self) {
|
||||
unsafe {
|
||||
ptr::drop_in_place(self.as_mut_slice());
|
||||
}
|
||||
self.ptr = self.end;
|
||||
}
|
||||
|
||||
/// Relinquishes the backing allocation, equivalent to
|
||||
/// `ptr::write(&mut self, Vec::new().into_iter())`
|
||||
fn forget_allocation(&mut self) {
|
||||
self.cap = 0;
|
||||
self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
|
||||
self.ptr = self.buf.as_ptr();
|
||||
self.end = self.buf.as_ptr();
|
||||
}
|
||||
}
|
||||
|
||||
#[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 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 self.ptr as *const _ == self.end {
|
||||
None
|
||||
} else if mem::size_of::<T>() == 0 {
|
||||
// purposefully don't use 'ptr.offset' because for
|
||||
// vectors with 0-size elements this would return the
|
||||
// same pointer.
|
||||
self.ptr = unsafe { arith_offset(self.ptr as *const i8, 1) as *mut T };
|
||||
|
||||
// Make up a value of this ZST.
|
||||
Some(unsafe { mem::zeroed() })
|
||||
} else {
|
||||
let old = self.ptr;
|
||||
self.ptr = unsafe { self.ptr.offset(1) };
|
||||
|
||||
Some(unsafe { ptr::read(old) })
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let exact = if mem::size_of::<T>() == 0 {
|
||||
(self.end as usize).wrapping_sub(self.ptr as usize)
|
||||
} else {
|
||||
unsafe { self.end.offset_from(self.ptr) as usize }
|
||||
};
|
||||
(exact, Some(exact))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn count(self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
|
||||
where
|
||||
Self: TrustedRandomAccess,
|
||||
{
|
||||
// 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 mem::size_of::<T>() == 0 { mem::zeroed() } else { ptr::read(self.ptr.add(i)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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 self.end == self.ptr {
|
||||
None
|
||||
} else if mem::size_of::<T>() == 0 {
|
||||
// See above for why 'ptr.offset' isn't used
|
||||
self.end = unsafe { arith_offset(self.end as *const i8, -1) as *mut T };
|
||||
|
||||
// Make up a value of this ZST.
|
||||
Some(unsafe { mem::zeroed() })
|
||||
} else {
|
||||
self.end = unsafe { self.end.offset(-1) };
|
||||
|
||||
Some(unsafe { ptr::read(self.end) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.ptr == self.end
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(issue = "none", feature = "std_internals")]
|
||||
// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr
|
||||
// and thus we can't implement drop-handling
|
||||
unsafe impl<T, A: Allocator> TrustedRandomAccess for IntoIter<T, A>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
fn may_have_side_effect() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[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.clone()).into_iter()
|
||||
}
|
||||
#[cfg(test)]
|
||||
fn clone(&self) -> Self {
|
||||
crate::slice::to_vec(self.as_slice(), self.alloc.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
|
||||
let alloc = ptr::read(&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
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> {}
|
||||
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
unsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> {
|
||||
type Source = Self;
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_inner(&mut self) -> &mut Self::Source {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// internal helper trait for in-place iteration specialization.
|
||||
#[rustc_specialization_trait]
|
||||
pub(crate) trait AsIntoIter {
|
||||
|
Loading…
Reference in New Issue
Block a user