1 use crate::alloc
::{Allocator, Global}
;
3 use core
::iter
::{FusedIterator, TrustedLen}
;
5 use core
::ptr
::{self, NonNull}
;
6 use core
::slice
::{self}
;
10 /// A draining iterator for `Vec<T>`.
12 /// This `struct` is created by [`Vec::drain`].
13 /// See its documentation for more.
18 /// let mut v = vec![0, 1, 2];
19 /// let iter: std::vec::Drain<_> = v.drain(..);
21 #[stable(feature = "drain", since = "1.6.0")]
25 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global,
27 /// Index of tail to preserve
28 pub(super) tail_start
: usize,
30 pub(super) tail_len
: usize,
31 /// Current remaining range to remove
32 pub(super) iter
: slice
::Iter
<'a
, T
>,
33 pub(super) vec
: NonNull
<Vec
<T
, A
>>,
36 #[stable(feature = "collection_debug", since = "1.17.0")]
37 impl<T
: fmt
::Debug
, A
: Allocator
> fmt
::Debug
for Drain
<'_
, T
, A
> {
38 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
39 f
.debug_tuple("Drain").field(&self.iter
.as_slice()).finish()
43 impl<'a
, T
, A
: Allocator
> Drain
<'a
, T
, A
> {
44 /// Returns the remaining items of this iterator as a slice.
49 /// let mut vec = vec!['a', 'b', 'c'];
50 /// let mut drain = vec.drain(..);
51 /// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
52 /// let _ = drain.next().unwrap();
53 /// assert_eq!(drain.as_slice(), &['b', 'c']);
56 #[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
57 pub fn as_slice(&self) -> &[T
] {
61 /// Returns a reference to the underlying allocator.
62 #[unstable(feature = "allocator_api", issue = "32838")]
64 pub fn allocator(&self) -> &A
{
65 unsafe { self.vec.as_ref().allocator() }
69 #[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
70 impl<'a
, T
, A
: Allocator
> AsRef
<[T
]> for Drain
<'a
, T
, A
> {
71 fn as_ref(&self) -> &[T
] {
76 #[stable(feature = "drain", since = "1.6.0")]
77 unsafe impl<T
: Sync
, A
: Sync
+ Allocator
> Sync
for Drain
<'_
, T
, A
> {}
78 #[stable(feature = "drain", since = "1.6.0")]
79 unsafe impl<T
: Send
, A
: Send
+ Allocator
> Send
for Drain
<'_
, T
, A
> {}
81 #[stable(feature = "drain", since = "1.6.0")]
82 impl<T
, A
: Allocator
> Iterator
for Drain
<'_
, T
, A
> {
86 fn next(&mut self) -> Option
<T
> {
87 self.iter
.next().map(|elt
| unsafe { ptr::read(elt as *const _) }
)
90 fn size_hint(&self) -> (usize, Option
<usize>) {
95 #[stable(feature = "drain", since = "1.6.0")]
96 impl<T
, A
: Allocator
> DoubleEndedIterator
for Drain
<'_
, T
, A
> {
98 fn next_back(&mut self) -> Option
<T
> {
99 self.iter
.next_back().map(|elt
| unsafe { ptr::read(elt as *const _) }
)
103 #[stable(feature = "drain", since = "1.6.0")]
104 impl<T
, A
: Allocator
> Drop
for Drain
<'_
, T
, A
> {
106 /// Continues dropping the remaining elements in the `Drain`, then moves back the
107 /// un-`Drain`ed elements to restore the original `Vec`.
108 struct DropGuard
<'r
, 'a
, T
, A
: Allocator
>(&'r
mut Drain
<'a
, T
, A
>);
110 impl<'r
, 'a
, T
, A
: Allocator
> Drop
for DropGuard
<'r
, 'a
, T
, A
> {
112 // Continue the same loop we have below. If the loop already finished, this does
114 self.0.for_each
(drop
);
116 if self.0.tail_len
> 0 {
118 let source_vec
= self.0.vec
.as_mut();
119 // memmove back untouched tail, update to new length
120 let start
= source_vec
.len();
121 let tail
= self.0.tail_start
;
123 let src
= source_vec
.as_ptr().add(tail
);
124 let dst
= source_vec
.as_mut_ptr().add(start
);
125 ptr
::copy(src
, dst
, self.0.tail_len
);
127 source_vec
.set_len(start
+ self.0.tail_len
);
133 // exhaust self first
134 while let Some(item
) = self.next() {
135 let guard
= DropGuard(self);
140 // Drop a `DropGuard` to move back the non-drained tail of `self`.
145 #[stable(feature = "drain", since = "1.6.0")]
146 impl<T
, A
: Allocator
> ExactSizeIterator
for Drain
<'_
, T
, A
> {
147 fn is_empty(&self) -> bool
{
152 #[unstable(feature = "trusted_len", issue = "37572")]
153 unsafe impl<T
, A
: Allocator
> TrustedLen
for Drain
<'_
, T
, A
> {}
155 #[stable(feature = "fused", since = "1.26.0")]
156 impl<T
, A
: Allocator
> FusedIterator
for Drain
<'_
, T
, A
> {}