1use core::iter::{FusedIterator, TrustedLen};
2use core::mem::{self, ManuallyDrop, SizedTypeProperties};
3use core::ptr::{self, NonNull};
4use core::{fmt, slice};
5
6use super::Vec;
7use crate::alloc::{Allocator, Global};
8
9#[stable(feature = "drain", since = "1.6.0")]
21pub struct Drain<
22 'a,
23 T: 'a,
24 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global,
25> {
26 pub(super) tail_start: usize,
28 pub(super) tail_len: usize,
30 pub(super) iter: slice::Iter<'a, T>,
32 pub(super) vec: NonNull<Vec<T, A>>,
33}
34
35#[stable(feature = "collection_debug", since = "1.17.0")]
36impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
39 }
40}
41
42impl<'a, T, A: Allocator> Drain<'a, T, A> {
43 #[must_use]
55 #[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
56 pub fn as_slice(&self) -> &[T] {
57 self.iter.as_slice()
58 }
59
60 #[unstable(feature = "allocator_api", issue = "32838")]
62 #[must_use]
63 #[inline]
64 pub fn allocator(&self) -> &A {
65 unsafe { self.vec.as_ref().allocator() }
66 }
67
68 #[unstable(feature = "drain_keep_rest", issue = "101122")]
88 pub fn keep_rest(self) {
89 let mut this = ManuallyDrop::new(self);
103
104 unsafe {
105 let source_vec = this.vec.as_mut();
106
107 let start = source_vec.len();
108 let tail = this.tail_start;
109
110 let unyielded_len = this.iter.len();
111 let unyielded_ptr = this.iter.as_slice().as_ptr();
112
113 if !T::IS_ZST {
115 let start_ptr = source_vec.as_mut_ptr().add(start);
116
117 if unyielded_ptr != start_ptr {
119 let src = unyielded_ptr;
120 let dst = start_ptr;
121
122 ptr::copy(src, dst, unyielded_len);
123 }
124
125 if tail != (start + unyielded_len) {
127 let src = source_vec.as_ptr().add(tail);
128 let dst = start_ptr.add(unyielded_len);
129 ptr::copy(src, dst, this.tail_len);
130 }
131 }
132
133 source_vec.set_len(start + unyielded_len + this.tail_len);
134 }
135 }
136}
137
138#[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
139impl<'a, T, A: Allocator> AsRef<[T]> for Drain<'a, T, A> {
140 fn as_ref(&self) -> &[T] {
141 self.as_slice()
142 }
143}
144
145#[stable(feature = "drain", since = "1.6.0")]
146unsafe impl<T: Sync, A: Sync + Allocator> Sync for Drain<'_, T, A> {}
147#[stable(feature = "drain", since = "1.6.0")]
148unsafe impl<T: Send, A: Send + Allocator> Send for Drain<'_, T, A> {}
149
150#[stable(feature = "drain", since = "1.6.0")]
151impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
152 type Item = T;
153
154 #[inline]
155 fn next(&mut self) -> Option<T> {
156 self.iter.next().map(|elt| unsafe { ptr::read(elt as *const _) })
157 }
158
159 fn size_hint(&self) -> (usize, Option<usize>) {
160 self.iter.size_hint()
161 }
162}
163
164#[stable(feature = "drain", since = "1.6.0")]
165impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
166 #[inline]
167 fn next_back(&mut self) -> Option<T> {
168 self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) })
169 }
170}
171
172#[stable(feature = "drain", since = "1.6.0")]
173impl<T, A: Allocator> Drop for Drain<'_, T, A> {
174 fn drop(&mut self) {
175 struct DropGuard<'r, 'a, T, A: Allocator>(&'r mut Drain<'a, T, A>);
177
178 impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> {
179 fn drop(&mut self) {
180 if self.0.tail_len > 0 {
181 unsafe {
182 let source_vec = self.0.vec.as_mut();
183 let start = source_vec.len();
185 let tail = self.0.tail_start;
186 if tail != start {
187 let src = source_vec.as_ptr().add(tail);
188 let dst = source_vec.as_mut_ptr().add(start);
189 ptr::copy(src, dst, self.0.tail_len);
190 }
191 source_vec.set_len(start + self.0.tail_len);
192 }
193 }
194 }
195 }
196
197 let iter = mem::take(&mut self.iter);
198 let drop_len = iter.len();
199
200 let mut vec = self.vec;
201
202 if T::IS_ZST {
203 unsafe {
206 let vec = vec.as_mut();
207 let old_len = vec.len();
208 vec.set_len(old_len + drop_len + self.tail_len);
209 vec.truncate(old_len + self.tail_len);
210 }
211
212 return;
213 }
214
215 let _guard = DropGuard(self);
217
218 if drop_len == 0 {
219 return;
220 }
221
222 let drop_ptr = iter.as_slice().as_ptr();
227
228 unsafe {
229 let vec_ptr = vec.as_mut().as_mut_ptr();
234 let drop_offset = drop_ptr.offset_from_unsigned(vec_ptr);
235 let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len);
236 ptr::drop_in_place(to_drop);
237 }
238 }
239}
240
241#[stable(feature = "drain", since = "1.6.0")]
242impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
243 fn is_empty(&self) -> bool {
244 self.iter.is_empty()
245 }
246}
247
248#[unstable(feature = "trusted_len", issue = "37572")]
249unsafe impl<T, A: Allocator> TrustedLen for Drain<'_, T, A> {}
250
251#[stable(feature = "fused", since = "1.26.0")]
252impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}