1use core::iter::{
2 FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen,
3 TrustedRandomAccessNoCoerce,
4};
5use core::marker::PhantomData;
6use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties};
7use core::num::NonZero;
8#[cfg(not(no_global_oom_handling))]
9use core::ops::Deref;
10use core::panic::UnwindSafe;
11use core::ptr::{self, NonNull};
12use core::{array, fmt, slice};
13
14#[cfg(not(no_global_oom_handling))]
15use super::AsVecIntoIter;
16use crate::alloc::{Allocator, Global};
17#[cfg(not(no_global_oom_handling))]
18use crate::collections::VecDeque;
19use crate::raw_vec::RawVec;
20
21macro non_null {
22 (mut $place:expr, $t:ident) => {{
23 #![allow(unused_unsafe)] unsafe { &mut *((&raw mut $place) as *mut NonNull<$t>) }
26 }},
27 ($place:expr, $t:ident) => {{
28 #![allow(unused_unsafe)] unsafe { *((&raw const $place) as *const NonNull<$t>) }
31 }},
32}
33
34#[stable(feature = "rust1", since = "1.0.0")]
46#[rustc_insignificant_dtor]
47pub struct IntoIter<
48 T,
49 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
50> {
51 pub(super) buf: NonNull<T>,
52 pub(super) phantom: PhantomData<T>,
53 pub(super) cap: usize,
54 pub(super) alloc: ManuallyDrop<A>,
57 pub(super) ptr: NonNull<T>,
58 pub(super) end: *const T,
63}
64
65#[stable(feature = "catch_unwind", since = "1.9.0")]
68impl<T: UnwindSafe, A: Allocator + UnwindSafe> UnwindSafe for IntoIter<T, A> {}
69
70#[stable(feature = "vec_intoiter_debug", since = "1.13.0")]
71impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
74 }
75}
76
77impl<T, A: Allocator> IntoIter<T, A> {
78 #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")]
90 pub fn as_slice(&self) -> &[T] {
91 unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len()) }
93 }
94
95 #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")]
109 pub fn as_mut_slice(&mut self) -> &mut [T] {
110 unsafe { &mut *self.as_raw_mut_slice() }
112 }
113
114 #[unstable(feature = "allocator_api", issue = "32838")]
116 #[inline]
117 pub fn allocator(&self) -> &A {
118 &self.alloc
119 }
120
121 fn as_raw_mut_slice(&mut self) -> *mut [T] {
122 self.ptr.as_ptr().cast_slice(self.len())
123 }
124
125 #[cfg(not(no_global_oom_handling))]
147 pub(super) fn forget_allocation_drop_remaining(&mut self) {
148 let remaining = self.as_raw_mut_slice();
149
150 self.cap = 0;
154 self.buf = RawVec::new().non_null();
155 self.ptr = self.buf;
156 self.end = self.buf.as_ptr();
157
158 unsafe {
162 ptr::drop_in_place(remaining);
163 }
164 }
165
166 pub(crate) fn forget_remaining_elements(&mut self) {
172 self.end = self.ptr.as_ptr();
175 }
176
177 #[inline]
183 pub(crate) fn forget_remaining_elements_and_dealloc(self) {
184 let mut this = ManuallyDrop::new(self);
185 unsafe {
187 this.dealloc_only();
188 }
189 }
190
191 #[inline]
203 unsafe fn dealloc_only(&mut self) {
204 let alloc = unsafe { ManuallyDrop::take(&mut self.alloc) };
206 let _ = unsafe { RawVec::from_nonnull_in(self.buf, self.cap, alloc) };
208 }
209
210 #[cfg(not(no_global_oom_handling))]
211 #[inline]
212 pub(crate) fn into_vecdeque(self) -> VecDeque<T, A> {
213 let mut this = ManuallyDrop::new(self);
215
216 unsafe {
223 let buf = this.buf.as_ptr();
224 let initialized = if T::IS_ZST {
225 0..this.len()
228 } else {
229 this.ptr.offset_from_unsigned(this.buf)..this.end.offset_from_unsigned(buf)
230 };
231 let cap = this.cap;
232 let alloc = ManuallyDrop::take(&mut this.alloc);
233 VecDeque::from_contiguous_raw_parts_in(buf, initialized, cap, alloc)
234 }
235 }
236}
237
238#[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")]
239impl<T, A: Allocator> AsRef<[T]> for IntoIter<T, A> {
240 fn as_ref(&self) -> &[T] {
241 self.as_slice()
242 }
243}
244
245#[stable(feature = "rust1", since = "1.0.0")]
246unsafe impl<T: Send, A: Allocator + Send> Send for IntoIter<T, A> {}
247#[stable(feature = "rust1", since = "1.0.0")]
248unsafe impl<T: Sync, A: Allocator + Sync> Sync for IntoIter<T, A> {}
249
250#[stable(feature = "rust1", since = "1.0.0")]
251impl<T, A: Allocator> Iterator for IntoIter<T, A> {
252 type Item = T;
253
254 #[inline]
255 fn next(&mut self) -> Option<T> {
256 let ptr = if T::IS_ZST {
257 if self.ptr.as_ptr() == self.end as *mut T {
258 return None;
259 }
260 self.end = self.end.wrapping_byte_sub(1);
263 self.ptr
264 } else {
265 if self.ptr == non_null!(self.end, T) {
266 return None;
267 }
268 let old = self.ptr;
269 self.ptr = unsafe { old.add(1) };
271 old
272 };
273 Some(unsafe { ptr.read() })
275 }
276
277 #[inline]
278 fn size_hint(&self) -> (usize, Option<usize>) {
279 let exact = if T::IS_ZST {
280 self.end.addr().wrapping_sub(self.ptr.as_ptr().addr())
281 } else {
282 unsafe { non_null!(self.end, T).offset_from_unsigned(self.ptr) }
284 };
285 (exact, Some(exact))
286 }
287
288 #[inline]
289 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
290 let step_size = self.len().min(n);
291 let to_drop = self.ptr.as_ptr().cast_slice(step_size);
292 if T::IS_ZST {
293 self.end = self.end.wrapping_byte_sub(step_size);
295 } else {
296 self.ptr = unsafe { self.ptr.add(step_size) };
298 }
299 unsafe {
301 ptr::drop_in_place(to_drop);
302 }
303 NonZero::new(n - step_size).map_or(Ok(()), Err)
304 }
305
306 #[inline]
307 fn count(self) -> usize {
308 self.len()
309 }
310
311 #[inline]
312 fn last(mut self) -> Option<T> {
313 self.next_back()
314 }
315
316 #[inline]
317 fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> {
318 let mut raw_ary = [const { MaybeUninit::uninit() }; N];
319
320 let len = self.len();
321
322 if T::IS_ZST {
323 if len < N {
324 self.forget_remaining_elements();
325 return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, 0..len) });
327 }
328
329 self.end = self.end.wrapping_byte_sub(N);
330 return Ok(unsafe { raw_ary.transpose().assume_init() });
332 }
333
334 if len < N {
335 unsafe {
338 ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, len);
339 self.forget_remaining_elements();
340 return Err(array::IntoIter::new_unchecked(raw_ary, 0..len));
341 }
342 }
343
344 unsafe {
347 ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, N);
348 self.ptr = self.ptr.add(N);
349 Ok(raw_ary.transpose().assume_init())
350 }
351 }
352
353 fn fold<B, F>(mut self, mut accum: B, mut f: F) -> B
354 where
355 F: FnMut(B, Self::Item) -> B,
356 {
357 if T::IS_ZST {
358 while self.ptr.as_ptr() != self.end.cast_mut() {
359 let tmp = unsafe { self.ptr.read() };
361 self.end = self.end.wrapping_byte_sub(1);
363 accum = f(accum, tmp);
364 }
365 } else {
366 while self.ptr != non_null!(self.end, T) {
368 let tmp = unsafe { self.ptr.read() };
370 self.ptr = unsafe { self.ptr.add(1) };
373 accum = f(accum, tmp);
374 }
375 }
376
377 self.forget_remaining_elements_and_dealloc();
381
382 accum
383 }
384
385 fn try_fold<B, F, R>(&mut self, mut accum: B, mut f: F) -> R
386 where
387 Self: Sized,
388 F: FnMut(B, Self::Item) -> R,
389 R: core::ops::Try<Output = B>,
390 {
391 if T::IS_ZST {
392 while self.ptr.as_ptr() != self.end.cast_mut() {
393 let tmp = unsafe { self.ptr.read() };
395 self.end = self.end.wrapping_byte_sub(1);
397 accum = f(accum, tmp)?;
398 }
399 } else {
400 while self.ptr != non_null!(self.end, T) {
402 let tmp = unsafe { self.ptr.read() };
404 self.ptr = unsafe { self.ptr.add(1) };
407 accum = f(accum, tmp)?;
408 }
409 }
410 R::from_output(accum)
411 }
412
413 unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
414 where
415 Self: TrustedRandomAccessNoCoerce,
416 {
417 unsafe { self.ptr.add(i).read() }
426 }
427}
428
429#[stable(feature = "rust1", since = "1.0.0")]
430impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
431 #[inline]
432 fn next_back(&mut self) -> Option<T> {
433 if T::IS_ZST {
434 if self.ptr.as_ptr() == self.end as *mut _ {
435 return None;
436 }
437 self.end = self.end.wrapping_byte_sub(1);
439 Some(unsafe { ptr::read(self.ptr.as_ptr()) })
444 } else {
445 if self.ptr == non_null!(self.end, T) {
446 return None;
447 }
448 unsafe {
450 self.end = self.end.sub(1);
451 Some(ptr::read(self.end))
452 }
453 }
454 }
455
456 #[inline]
457 fn next_chunk_back<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> {
458 let mut raw_ary = [const { MaybeUninit::uninit() }; N];
459
460 let len = self.len();
461
462 if T::IS_ZST {
463 if len < N {
464 self.forget_remaining_elements();
465 return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, N - len..N) });
467 }
468
469 self.end = self.end.wrapping_byte_sub(N);
470 return Ok(unsafe { MaybeUninit::array_assume_init(raw_ary) });
472 }
473
474 if len < N {
475 unsafe {
478 ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, len);
479 self.forget_remaining_elements();
480 return Err(array::IntoIter::new_unchecked(raw_ary, 0..len));
481 }
482 }
483
484 unsafe {
487 ptr::copy_nonoverlapping(
488 self.ptr.add(len - N).as_ptr(),
489 raw_ary.as_mut_ptr() as *mut T,
490 N,
491 );
492 self.end = self.end.sub(N);
493 Ok(MaybeUninit::array_assume_init(raw_ary))
494 }
495 }
496
497 #[inline]
498 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
499 let step_size = self.len().min(n);
500 if T::IS_ZST {
501 self.end = self.end.wrapping_byte_sub(step_size);
503 } else {
504 self.end = unsafe { self.end.sub(step_size) };
506 }
507 let to_drop = if T::IS_ZST {
508 ptr::NonNull::<T>::dangling().as_ptr().cast_slice(step_size)
510 } else {
511 self.end.cast::<T>().cast_mut().cast_slice(step_size)
512 };
513 unsafe {
515 ptr::drop_in_place(to_drop);
516 }
517 NonZero::new(n - step_size).map_or(Ok(()), Err)
518 }
519}
520
521#[stable(feature = "rust1", since = "1.0.0")]
522impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
523 fn is_empty(&self) -> bool {
524 if T::IS_ZST {
525 self.ptr.as_ptr() == self.end as *mut _
526 } else {
527 self.ptr == non_null!(self.end, T)
528 }
529 }
530}
531
532#[stable(feature = "fused", since = "1.26.0")]
533impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
534
535#[doc(hidden)]
536#[unstable(issue = "none", feature = "trusted_fused")]
537unsafe impl<T, A: Allocator> TrustedFused for IntoIter<T, A> {}
538
539#[unstable(feature = "trusted_len", issue = "37572")]
540unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}
541
542#[stable(feature = "default_iters", since = "1.70.0")]
543impl<T, A> Default for IntoIter<T, A>
544where
545 A: Allocator + Default,
546{
547 fn default() -> Self {
556 super::Vec::new_in(Default::default()).into_iter()
557 }
558}
559
560#[doc(hidden)]
561#[unstable(issue = "none", feature = "std_internals")]
562#[unsafe(rustc_allow_lifetime_dependent_specialization)]
563trait NonDrop {}
564
565#[unstable(issue = "none", feature = "std_internals")]
568impl<T: Copy> NonDrop for T {}
569
570#[doc(hidden)]
571#[unstable(issue = "none", feature = "std_internals")]
572unsafe impl<T, A: Allocator> TrustedRandomAccessNoCoerce for IntoIter<T, A>
575where
576 T: NonDrop,
577{
578 const MAY_HAVE_SIDE_EFFECT: bool = false;
579}
580
581#[cfg(not(no_global_oom_handling))]
582#[stable(feature = "vec_into_iter_clone", since = "1.8.0")]
583impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {
584 fn clone(&self) -> Self {
585 self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter()
586 }
587}
588
589#[stable(feature = "rust1", since = "1.0.0")]
590unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> {
591 fn drop(&mut self) {
592 struct DropGuard<'a, T, A: Allocator>(&'a mut IntoIter<T, A>);
593
594 impl<T, A: Allocator> Drop for DropGuard<'_, T, A> {
595 fn drop(&mut self) {
596 unsafe {
598 self.0.dealloc_only();
599 }
600 }
601 }
602
603 let guard = DropGuard(self);
604 unsafe {
607 ptr::drop_in_place(guard.0.as_raw_mut_slice());
608 }
609 }
611}
612
613#[unstable(issue = "none", feature = "inplace_iteration")]
616#[doc(hidden)]
617unsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> {
618 const EXPAND_BY: Option<NonZero<usize>> = NonZero::new(1);
619 const MERGE_BY: Option<NonZero<usize>> = NonZero::new(1);
620}
621
622#[unstable(issue = "none", feature = "inplace_iteration")]
623#[doc(hidden)]
624unsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> {
625 type Source = Self;
626
627 #[inline]
628 unsafe fn as_inner(&mut self) -> &mut Self::Source {
629 self
630 }
631}
632
633#[cfg(not(no_global_oom_handling))]
634unsafe impl<T> AsVecIntoIter for IntoIter<T> {
635 type Item = T;
636
637 fn as_into_iter(&mut self) -> &mut IntoIter<Self::Item> {
638 self
639 }
640}