162306a36Sopenharmony_ci// SPDX-License-Identifier: Apache-2.0 OR MIT 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 462306a36Sopenharmony_ciuse super::AsVecIntoIter; 562306a36Sopenharmony_ciuse crate::alloc::{Allocator, Global}; 662306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 762306a36Sopenharmony_ciuse crate::collections::VecDeque; 862306a36Sopenharmony_ciuse crate::raw_vec::RawVec; 962306a36Sopenharmony_ciuse core::array; 1062306a36Sopenharmony_ciuse core::fmt; 1162306a36Sopenharmony_ciuse core::iter::{ 1262306a36Sopenharmony_ci FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce, 1362306a36Sopenharmony_ci}; 1462306a36Sopenharmony_ciuse core::marker::PhantomData; 1562306a36Sopenharmony_ciuse core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; 1662306a36Sopenharmony_ciuse core::num::NonZeroUsize; 1762306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 1862306a36Sopenharmony_ciuse core::ops::Deref; 1962306a36Sopenharmony_ciuse core::ptr::{self, NonNull}; 2062306a36Sopenharmony_ciuse core::slice::{self}; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/// An iterator that moves out of a vector. 2362306a36Sopenharmony_ci/// 2462306a36Sopenharmony_ci/// This `struct` is created by the `into_iter` method on [`Vec`](super::Vec) 2562306a36Sopenharmony_ci/// (provided by the [`IntoIterator`] trait). 2662306a36Sopenharmony_ci/// 2762306a36Sopenharmony_ci/// # Example 2862306a36Sopenharmony_ci/// 2962306a36Sopenharmony_ci/// ``` 3062306a36Sopenharmony_ci/// let v = vec![0, 1, 2]; 3162306a36Sopenharmony_ci/// let iter: std::vec::IntoIter<_> = v.into_iter(); 3262306a36Sopenharmony_ci/// ``` 3362306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 3462306a36Sopenharmony_ci#[rustc_insignificant_dtor] 3562306a36Sopenharmony_cipub struct IntoIter< 3662306a36Sopenharmony_ci T, 3762306a36Sopenharmony_ci #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, 3862306a36Sopenharmony_ci> { 3962306a36Sopenharmony_ci pub(super) buf: NonNull<T>, 4062306a36Sopenharmony_ci pub(super) phantom: PhantomData<T>, 4162306a36Sopenharmony_ci pub(super) cap: usize, 4262306a36Sopenharmony_ci // the drop impl reconstructs a RawVec from buf, cap and alloc 4362306a36Sopenharmony_ci // to avoid dropping the allocator twice we need to wrap it into ManuallyDrop 4462306a36Sopenharmony_ci pub(super) alloc: ManuallyDrop<A>, 4562306a36Sopenharmony_ci pub(super) ptr: *const T, 4662306a36Sopenharmony_ci pub(super) end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that 4762306a36Sopenharmony_ci // ptr == end is a quick test for the Iterator being empty, that works 4862306a36Sopenharmony_ci // for both ZST and non-ZST. 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#[stable(feature = "vec_intoiter_debug", since = "1.13.0")] 5262306a36Sopenharmony_ciimpl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> { 5362306a36Sopenharmony_ci fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 5462306a36Sopenharmony_ci f.debug_tuple("IntoIter").field(&self.as_slice()).finish() 5562306a36Sopenharmony_ci } 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ciimpl<T, A: Allocator> IntoIter<T, A> { 5962306a36Sopenharmony_ci /// Returns the remaining items of this iterator as a slice. 6062306a36Sopenharmony_ci /// 6162306a36Sopenharmony_ci /// # Examples 6262306a36Sopenharmony_ci /// 6362306a36Sopenharmony_ci /// ``` 6462306a36Sopenharmony_ci /// let vec = vec!['a', 'b', 'c']; 6562306a36Sopenharmony_ci /// let mut into_iter = vec.into_iter(); 6662306a36Sopenharmony_ci /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); 6762306a36Sopenharmony_ci /// let _ = into_iter.next().unwrap(); 6862306a36Sopenharmony_ci /// assert_eq!(into_iter.as_slice(), &['b', 'c']); 6962306a36Sopenharmony_ci /// ``` 7062306a36Sopenharmony_ci #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] 7162306a36Sopenharmony_ci pub fn as_slice(&self) -> &[T] { 7262306a36Sopenharmony_ci unsafe { slice::from_raw_parts(self.ptr, self.len()) } 7362306a36Sopenharmony_ci } 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci /// Returns the remaining items of this iterator as a mutable slice. 7662306a36Sopenharmony_ci /// 7762306a36Sopenharmony_ci /// # Examples 7862306a36Sopenharmony_ci /// 7962306a36Sopenharmony_ci /// ``` 8062306a36Sopenharmony_ci /// let vec = vec!['a', 'b', 'c']; 8162306a36Sopenharmony_ci /// let mut into_iter = vec.into_iter(); 8262306a36Sopenharmony_ci /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); 8362306a36Sopenharmony_ci /// into_iter.as_mut_slice()[2] = 'z'; 8462306a36Sopenharmony_ci /// assert_eq!(into_iter.next().unwrap(), 'a'); 8562306a36Sopenharmony_ci /// assert_eq!(into_iter.next().unwrap(), 'b'); 8662306a36Sopenharmony_ci /// assert_eq!(into_iter.next().unwrap(), 'z'); 8762306a36Sopenharmony_ci /// ``` 8862306a36Sopenharmony_ci #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] 8962306a36Sopenharmony_ci pub fn as_mut_slice(&mut self) -> &mut [T] { 9062306a36Sopenharmony_ci unsafe { &mut *self.as_raw_mut_slice() } 9162306a36Sopenharmony_ci } 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci /// Returns a reference to the underlying allocator. 9462306a36Sopenharmony_ci #[unstable(feature = "allocator_api", issue = "32838")] 9562306a36Sopenharmony_ci #[inline] 9662306a36Sopenharmony_ci pub fn allocator(&self) -> &A { 9762306a36Sopenharmony_ci &self.alloc 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci fn as_raw_mut_slice(&mut self) -> *mut [T] { 10162306a36Sopenharmony_ci ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len()) 10262306a36Sopenharmony_ci } 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci /// Drops remaining elements and relinquishes the backing allocation. 10562306a36Sopenharmony_ci /// This method guarantees it won't panic before relinquishing 10662306a36Sopenharmony_ci /// the backing allocation. 10762306a36Sopenharmony_ci /// 10862306a36Sopenharmony_ci /// This is roughly equivalent to the following, but more efficient 10962306a36Sopenharmony_ci /// 11062306a36Sopenharmony_ci /// ``` 11162306a36Sopenharmony_ci /// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter(); 11262306a36Sopenharmony_ci /// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter()); 11362306a36Sopenharmony_ci /// (&mut into_iter).for_each(drop); 11462306a36Sopenharmony_ci /// std::mem::forget(into_iter); 11562306a36Sopenharmony_ci /// ``` 11662306a36Sopenharmony_ci /// 11762306a36Sopenharmony_ci /// This method is used by in-place iteration, refer to the vec::in_place_collect 11862306a36Sopenharmony_ci /// documentation for an overview. 11962306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 12062306a36Sopenharmony_ci pub(super) fn forget_allocation_drop_remaining(&mut self) { 12162306a36Sopenharmony_ci let remaining = self.as_raw_mut_slice(); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci // overwrite the individual fields instead of creating a new 12462306a36Sopenharmony_ci // struct and then overwriting &mut self. 12562306a36Sopenharmony_ci // this creates less assembly 12662306a36Sopenharmony_ci self.cap = 0; 12762306a36Sopenharmony_ci self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) }; 12862306a36Sopenharmony_ci self.ptr = self.buf.as_ptr(); 12962306a36Sopenharmony_ci self.end = self.buf.as_ptr(); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci // Dropping the remaining elements can panic, so this needs to be 13262306a36Sopenharmony_ci // done only after updating the other fields. 13362306a36Sopenharmony_ci unsafe { 13462306a36Sopenharmony_ci ptr::drop_in_place(remaining); 13562306a36Sopenharmony_ci } 13662306a36Sopenharmony_ci } 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci /// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed. 13962306a36Sopenharmony_ci pub(crate) fn forget_remaining_elements(&mut self) { 14062306a36Sopenharmony_ci // For th ZST case, it is crucial that we mutate `end` here, not `ptr`. 14162306a36Sopenharmony_ci // `ptr` must stay aligned, while `end` may be unaligned. 14262306a36Sopenharmony_ci self.end = self.ptr; 14362306a36Sopenharmony_ci } 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci #[cfg(not(no_global_oom_handling))] 14662306a36Sopenharmony_ci #[inline] 14762306a36Sopenharmony_ci pub(crate) fn into_vecdeque(self) -> VecDeque<T, A> { 14862306a36Sopenharmony_ci // Keep our `Drop` impl from dropping the elements and the allocator 14962306a36Sopenharmony_ci let mut this = ManuallyDrop::new(self); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci // SAFETY: This allocation originally came from a `Vec`, so it passes 15262306a36Sopenharmony_ci // all those checks. We have `this.buf` ≤ `this.ptr` ≤ `this.end`, 15362306a36Sopenharmony_ci // so the `sub_ptr`s below cannot wrap, and will produce a well-formed 15462306a36Sopenharmony_ci // range. `end` ≤ `buf + cap`, so the range will be in-bounds. 15562306a36Sopenharmony_ci // Taking `alloc` is ok because nothing else is going to look at it, 15662306a36Sopenharmony_ci // since our `Drop` impl isn't going to run so there's no more code. 15762306a36Sopenharmony_ci unsafe { 15862306a36Sopenharmony_ci let buf = this.buf.as_ptr(); 15962306a36Sopenharmony_ci let initialized = if T::IS_ZST { 16062306a36Sopenharmony_ci // All the pointers are the same for ZSTs, so it's fine to 16162306a36Sopenharmony_ci // say that they're all at the beginning of the "allocation". 16262306a36Sopenharmony_ci 0..this.len() 16362306a36Sopenharmony_ci } else { 16462306a36Sopenharmony_ci this.ptr.sub_ptr(buf)..this.end.sub_ptr(buf) 16562306a36Sopenharmony_ci }; 16662306a36Sopenharmony_ci let cap = this.cap; 16762306a36Sopenharmony_ci let alloc = ManuallyDrop::take(&mut this.alloc); 16862306a36Sopenharmony_ci VecDeque::from_contiguous_raw_parts_in(buf, initialized, cap, alloc) 16962306a36Sopenharmony_ci } 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci#[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")] 17462306a36Sopenharmony_ciimpl<T, A: Allocator> AsRef<[T]> for IntoIter<T, A> { 17562306a36Sopenharmony_ci fn as_ref(&self) -> &[T] { 17662306a36Sopenharmony_ci self.as_slice() 17762306a36Sopenharmony_ci } 17862306a36Sopenharmony_ci} 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 18162306a36Sopenharmony_ciunsafe impl<T: Send, A: Allocator + Send> Send for IntoIter<T, A> {} 18262306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 18362306a36Sopenharmony_ciunsafe impl<T: Sync, A: Allocator + Sync> Sync for IntoIter<T, A> {} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 18662306a36Sopenharmony_ciimpl<T, A: Allocator> Iterator for IntoIter<T, A> { 18762306a36Sopenharmony_ci type Item = T; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci #[inline] 19062306a36Sopenharmony_ci fn next(&mut self) -> Option<T> { 19162306a36Sopenharmony_ci if self.ptr == self.end { 19262306a36Sopenharmony_ci None 19362306a36Sopenharmony_ci } else if T::IS_ZST { 19462306a36Sopenharmony_ci // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by 19562306a36Sopenharmony_ci // reducing the `end`. 19662306a36Sopenharmony_ci self.end = self.end.wrapping_byte_sub(1); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci // Make up a value of this ZST. 19962306a36Sopenharmony_ci Some(unsafe { mem::zeroed() }) 20062306a36Sopenharmony_ci } else { 20162306a36Sopenharmony_ci let old = self.ptr; 20262306a36Sopenharmony_ci self.ptr = unsafe { self.ptr.add(1) }; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci Some(unsafe { ptr::read(old) }) 20562306a36Sopenharmony_ci } 20662306a36Sopenharmony_ci } 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci #[inline] 20962306a36Sopenharmony_ci fn size_hint(&self) -> (usize, Option<usize>) { 21062306a36Sopenharmony_ci let exact = if T::IS_ZST { 21162306a36Sopenharmony_ci self.end.addr().wrapping_sub(self.ptr.addr()) 21262306a36Sopenharmony_ci } else { 21362306a36Sopenharmony_ci unsafe { self.end.sub_ptr(self.ptr) } 21462306a36Sopenharmony_ci }; 21562306a36Sopenharmony_ci (exact, Some(exact)) 21662306a36Sopenharmony_ci } 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci #[inline] 21962306a36Sopenharmony_ci fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { 22062306a36Sopenharmony_ci let step_size = self.len().min(n); 22162306a36Sopenharmony_ci let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size); 22262306a36Sopenharmony_ci if T::IS_ZST { 22362306a36Sopenharmony_ci // See `next` for why we sub `end` here. 22462306a36Sopenharmony_ci self.end = self.end.wrapping_byte_sub(step_size); 22562306a36Sopenharmony_ci } else { 22662306a36Sopenharmony_ci // SAFETY: the min() above ensures that step_size is in bounds 22762306a36Sopenharmony_ci self.ptr = unsafe { self.ptr.add(step_size) }; 22862306a36Sopenharmony_ci } 22962306a36Sopenharmony_ci // SAFETY: the min() above ensures that step_size is in bounds 23062306a36Sopenharmony_ci unsafe { 23162306a36Sopenharmony_ci ptr::drop_in_place(to_drop); 23262306a36Sopenharmony_ci } 23362306a36Sopenharmony_ci NonZeroUsize::new(n - step_size).map_or(Ok(()), Err) 23462306a36Sopenharmony_ci } 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci #[inline] 23762306a36Sopenharmony_ci fn count(self) -> usize { 23862306a36Sopenharmony_ci self.len() 23962306a36Sopenharmony_ci } 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci #[inline] 24262306a36Sopenharmony_ci fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> { 24362306a36Sopenharmony_ci let mut raw_ary = MaybeUninit::uninit_array(); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci let len = self.len(); 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci if T::IS_ZST { 24862306a36Sopenharmony_ci if len < N { 24962306a36Sopenharmony_ci self.forget_remaining_elements(); 25062306a36Sopenharmony_ci // Safety: ZSTs can be conjured ex nihilo, only the amount has to be correct 25162306a36Sopenharmony_ci return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, 0..len) }); 25262306a36Sopenharmony_ci } 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci self.end = self.end.wrapping_byte_sub(N); 25562306a36Sopenharmony_ci // Safety: ditto 25662306a36Sopenharmony_ci return Ok(unsafe { raw_ary.transpose().assume_init() }); 25762306a36Sopenharmony_ci } 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci if len < N { 26062306a36Sopenharmony_ci // Safety: `len` indicates that this many elements are available and we just checked that 26162306a36Sopenharmony_ci // it fits into the array. 26262306a36Sopenharmony_ci unsafe { 26362306a36Sopenharmony_ci ptr::copy_nonoverlapping(self.ptr, raw_ary.as_mut_ptr() as *mut T, len); 26462306a36Sopenharmony_ci self.forget_remaining_elements(); 26562306a36Sopenharmony_ci return Err(array::IntoIter::new_unchecked(raw_ary, 0..len)); 26662306a36Sopenharmony_ci } 26762306a36Sopenharmony_ci } 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci // Safety: `len` is larger than the array size. Copy a fixed amount here to fully initialize 27062306a36Sopenharmony_ci // the array. 27162306a36Sopenharmony_ci return unsafe { 27262306a36Sopenharmony_ci ptr::copy_nonoverlapping(self.ptr, raw_ary.as_mut_ptr() as *mut T, N); 27362306a36Sopenharmony_ci self.ptr = self.ptr.add(N); 27462306a36Sopenharmony_ci Ok(raw_ary.transpose().assume_init()) 27562306a36Sopenharmony_ci }; 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item 27962306a36Sopenharmony_ci where 28062306a36Sopenharmony_ci Self: TrustedRandomAccessNoCoerce, 28162306a36Sopenharmony_ci { 28262306a36Sopenharmony_ci // SAFETY: the caller must guarantee that `i` is in bounds of the 28362306a36Sopenharmony_ci // `Vec<T>`, so `i` cannot overflow an `isize`, and the `self.ptr.add(i)` 28462306a36Sopenharmony_ci // is guaranteed to pointer to an element of the `Vec<T>` and 28562306a36Sopenharmony_ci // thus guaranteed to be valid to dereference. 28662306a36Sopenharmony_ci // 28762306a36Sopenharmony_ci // Also note the implementation of `Self: TrustedRandomAccess` requires 28862306a36Sopenharmony_ci // that `T: Copy` so reading elements from the buffer doesn't invalidate 28962306a36Sopenharmony_ci // them for `Drop`. 29062306a36Sopenharmony_ci unsafe { 29162306a36Sopenharmony_ci if T::IS_ZST { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } 29262306a36Sopenharmony_ci } 29362306a36Sopenharmony_ci } 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 29762306a36Sopenharmony_ciimpl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> { 29862306a36Sopenharmony_ci #[inline] 29962306a36Sopenharmony_ci fn next_back(&mut self) -> Option<T> { 30062306a36Sopenharmony_ci if self.end == self.ptr { 30162306a36Sopenharmony_ci None 30262306a36Sopenharmony_ci } else if T::IS_ZST { 30362306a36Sopenharmony_ci // See above for why 'ptr.offset' isn't used 30462306a36Sopenharmony_ci self.end = self.end.wrapping_byte_sub(1); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci // Make up a value of this ZST. 30762306a36Sopenharmony_ci Some(unsafe { mem::zeroed() }) 30862306a36Sopenharmony_ci } else { 30962306a36Sopenharmony_ci self.end = unsafe { self.end.sub(1) }; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci Some(unsafe { ptr::read(self.end) }) 31262306a36Sopenharmony_ci } 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci #[inline] 31662306a36Sopenharmony_ci fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { 31762306a36Sopenharmony_ci let step_size = self.len().min(n); 31862306a36Sopenharmony_ci if T::IS_ZST { 31962306a36Sopenharmony_ci // SAFETY: same as for advance_by() 32062306a36Sopenharmony_ci self.end = self.end.wrapping_byte_sub(step_size); 32162306a36Sopenharmony_ci } else { 32262306a36Sopenharmony_ci // SAFETY: same as for advance_by() 32362306a36Sopenharmony_ci self.end = unsafe { self.end.sub(step_size) }; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size); 32662306a36Sopenharmony_ci // SAFETY: same as for advance_by() 32762306a36Sopenharmony_ci unsafe { 32862306a36Sopenharmony_ci ptr::drop_in_place(to_drop); 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci NonZeroUsize::new(n - step_size).map_or(Ok(()), Err) 33162306a36Sopenharmony_ci } 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 33562306a36Sopenharmony_ciimpl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> { 33662306a36Sopenharmony_ci fn is_empty(&self) -> bool { 33762306a36Sopenharmony_ci self.ptr == self.end 33862306a36Sopenharmony_ci } 33962306a36Sopenharmony_ci} 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci#[stable(feature = "fused", since = "1.26.0")] 34262306a36Sopenharmony_ciimpl<T, A: Allocator> FusedIterator for IntoIter<T, A> {} 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci#[unstable(feature = "trusted_len", issue = "37572")] 34562306a36Sopenharmony_ciunsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {} 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci#[stable(feature = "default_iters", since = "1.70.0")] 34862306a36Sopenharmony_ciimpl<T, A> Default for IntoIter<T, A> 34962306a36Sopenharmony_ciwhere 35062306a36Sopenharmony_ci A: Allocator + Default, 35162306a36Sopenharmony_ci{ 35262306a36Sopenharmony_ci /// Creates an empty `vec::IntoIter`. 35362306a36Sopenharmony_ci /// 35462306a36Sopenharmony_ci /// ``` 35562306a36Sopenharmony_ci /// # use std::vec; 35662306a36Sopenharmony_ci /// let iter: vec::IntoIter<u8> = Default::default(); 35762306a36Sopenharmony_ci /// assert_eq!(iter.len(), 0); 35862306a36Sopenharmony_ci /// assert_eq!(iter.as_slice(), &[]); 35962306a36Sopenharmony_ci /// ``` 36062306a36Sopenharmony_ci fn default() -> Self { 36162306a36Sopenharmony_ci super::Vec::new_in(Default::default()).into_iter() 36262306a36Sopenharmony_ci } 36362306a36Sopenharmony_ci} 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci#[doc(hidden)] 36662306a36Sopenharmony_ci#[unstable(issue = "none", feature = "std_internals")] 36762306a36Sopenharmony_ci#[rustc_unsafe_specialization_marker] 36862306a36Sopenharmony_cipub trait NonDrop {} 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr 37162306a36Sopenharmony_ci// and thus we can't implement drop-handling 37262306a36Sopenharmony_ci#[unstable(issue = "none", feature = "std_internals")] 37362306a36Sopenharmony_ciimpl<T: Copy> NonDrop for T {} 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci#[doc(hidden)] 37662306a36Sopenharmony_ci#[unstable(issue = "none", feature = "std_internals")] 37762306a36Sopenharmony_ci// TrustedRandomAccess (without NoCoerce) must not be implemented because 37862306a36Sopenharmony_ci// subtypes/supertypes of `T` might not be `NonDrop` 37962306a36Sopenharmony_ciunsafe impl<T, A: Allocator> TrustedRandomAccessNoCoerce for IntoIter<T, A> 38062306a36Sopenharmony_ciwhere 38162306a36Sopenharmony_ci T: NonDrop, 38262306a36Sopenharmony_ci{ 38362306a36Sopenharmony_ci const MAY_HAVE_SIDE_EFFECT: bool = false; 38462306a36Sopenharmony_ci} 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 38762306a36Sopenharmony_ci#[stable(feature = "vec_into_iter_clone", since = "1.8.0")] 38862306a36Sopenharmony_ciimpl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> { 38962306a36Sopenharmony_ci #[cfg(not(test))] 39062306a36Sopenharmony_ci fn clone(&self) -> Self { 39162306a36Sopenharmony_ci self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter() 39262306a36Sopenharmony_ci } 39362306a36Sopenharmony_ci #[cfg(test)] 39462306a36Sopenharmony_ci fn clone(&self) -> Self { 39562306a36Sopenharmony_ci crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter() 39662306a36Sopenharmony_ci } 39762306a36Sopenharmony_ci} 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci#[stable(feature = "rust1", since = "1.0.0")] 40062306a36Sopenharmony_ciunsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> { 40162306a36Sopenharmony_ci fn drop(&mut self) { 40262306a36Sopenharmony_ci struct DropGuard<'a, T, A: Allocator>(&'a mut IntoIter<T, A>); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci impl<T, A: Allocator> Drop for DropGuard<'_, T, A> { 40562306a36Sopenharmony_ci fn drop(&mut self) { 40662306a36Sopenharmony_ci unsafe { 40762306a36Sopenharmony_ci // `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec 40862306a36Sopenharmony_ci let alloc = ManuallyDrop::take(&mut self.0.alloc); 40962306a36Sopenharmony_ci // RawVec handles deallocation 41062306a36Sopenharmony_ci let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc); 41162306a36Sopenharmony_ci } 41262306a36Sopenharmony_ci } 41362306a36Sopenharmony_ci } 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci let guard = DropGuard(self); 41662306a36Sopenharmony_ci // destroy the remaining elements 41762306a36Sopenharmony_ci unsafe { 41862306a36Sopenharmony_ci ptr::drop_in_place(guard.0.as_raw_mut_slice()); 41962306a36Sopenharmony_ci } 42062306a36Sopenharmony_ci // now `guard` will be dropped and do the rest 42162306a36Sopenharmony_ci } 42262306a36Sopenharmony_ci} 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci// In addition to the SAFETY invariants of the following three unsafe traits 42562306a36Sopenharmony_ci// also refer to the vec::in_place_collect module documentation to get an overview 42662306a36Sopenharmony_ci#[unstable(issue = "none", feature = "inplace_iteration")] 42762306a36Sopenharmony_ci#[doc(hidden)] 42862306a36Sopenharmony_ciunsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> {} 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci#[unstable(issue = "none", feature = "inplace_iteration")] 43162306a36Sopenharmony_ci#[doc(hidden)] 43262306a36Sopenharmony_ciunsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> { 43362306a36Sopenharmony_ci type Source = Self; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci #[inline] 43662306a36Sopenharmony_ci unsafe fn as_inner(&mut self) -> &mut Self::Source { 43762306a36Sopenharmony_ci self 43862306a36Sopenharmony_ci } 43962306a36Sopenharmony_ci} 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci#[cfg(not(no_global_oom_handling))] 44262306a36Sopenharmony_ciunsafe impl<T> AsVecIntoIter for IntoIter<T> { 44362306a36Sopenharmony_ci type Item = T; 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci fn as_into_iter(&mut self) -> &mut IntoIter<Self::Item> { 44662306a36Sopenharmony_ci self 44762306a36Sopenharmony_ci } 44862306a36Sopenharmony_ci} 449