1use core::{
2 fmt,
3 iter::FusedIterator,
4 mem::{self, size_of},
5 ptr::{self, NonNull},
6 slice,
7};
8
9use crate::len_type::LenType;
10
11use super::VecView;
12
13pub struct Drain<'a, T: 'a, LenT: LenType> {
18 pub(super) tail_start: LenT,
20 pub(super) tail_len: LenT,
22 pub(super) iter: slice::Iter<'a, T>,
24 pub(super) vec: NonNull<VecView<T, LenT>>,
25}
26
27impl<T: fmt::Debug, LenT: LenType> fmt::Debug for Drain<'_, T, LenT> {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
30 }
31}
32
33impl<T, LenT: LenType> Drain<'_, T, LenT> {
34 #[must_use]
48 pub fn as_slice(&self) -> &[T] {
49 self.iter.as_slice()
50 }
51}
52
53impl<T, LenT: LenType> AsRef<[T]> for Drain<'_, T, LenT> {
54 fn as_ref(&self) -> &[T] {
55 self.as_slice()
56 }
57}
58
59unsafe impl<T: Sync, LenT: LenType> Sync for Drain<'_, T, LenT> {}
60unsafe impl<T: Send, LenT: LenType> Send for Drain<'_, T, LenT> {}
61
62impl<T, LenT: LenType> Iterator for Drain<'_, T, LenT> {
63 type Item = T;
64
65 #[inline]
66 fn next(&mut self) -> Option<T> {
67 self.iter
68 .next()
69 .map(|elt| unsafe { ptr::read(core::ptr::from_ref(elt)) })
70 }
71
72 fn size_hint(&self) -> (usize, Option<usize>) {
73 self.iter.size_hint()
74 }
75}
76
77impl<T, LenT: LenType> DoubleEndedIterator for Drain<'_, T, LenT> {
78 #[inline]
79 fn next_back(&mut self) -> Option<T> {
80 self.iter
81 .next_back()
82 .map(|elt| unsafe { ptr::read(core::ptr::from_ref(elt)) })
83 }
84}
85
86impl<T, LenT: LenType> Drop for Drain<'_, T, LenT> {
87 fn drop(&mut self) {
88 struct DropGuard<'r, 'a, T, LenT: LenType>(&'r mut Drain<'a, T, LenT>);
90
91 impl<T, LenT: LenType> Drop for DropGuard<'_, '_, T, LenT> {
92 fn drop(&mut self) {
93 if self.0.tail_len > LenT::ZERO {
94 unsafe {
95 let source_vec = self.0.vec.as_mut();
96 let start = source_vec.len();
98 let tail = self.0.tail_start.into_usize();
99 let tail_len = self.0.tail_len.into_usize();
100 if tail != start {
101 let dst = source_vec.as_mut_ptr().add(start);
102 let src = source_vec.as_ptr().add(tail);
103 ptr::copy(src, dst, tail_len);
104 }
105 source_vec.set_len(start + tail_len);
106 }
107 }
108 }
109 }
110
111 let iter = mem::take(&mut self.iter);
112 let drop_len = iter.len();
113
114 let mut vec = self.vec;
115
116 if size_of::<T>() == 0 {
117 unsafe {
121 let vec = vec.as_mut();
122 let old_len = vec.len();
123 let tail_len = self.tail_len.into_usize();
124 vec.set_len(old_len + drop_len + tail_len);
125 vec.truncate(old_len + tail_len);
126 }
127
128 return;
129 }
130
131 let _guard = DropGuard(self);
134
135 if drop_len == 0 {
136 return;
137 }
138
139 let drop_ptr = iter.as_slice().as_ptr();
144
145 unsafe {
146 let vec_ptr = vec.as_mut().as_mut_ptr();
151 let drop_offset = (drop_ptr as usize - vec_ptr as usize) / size_of::<T>();
153 let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len);
154 ptr::drop_in_place(to_drop);
155 }
156 }
157}
158
159impl<T, LenT: LenType> ExactSizeIterator for Drain<'_, T, LenT> {}
160
161impl<T, LenT: LenType> FusedIterator for Drain<'_, T, LenT> {}
162
163#[cfg(test)]
164mod tests {
165 use super::super::Vec;
166
167 #[test]
168 fn drain_front() {
169 let mut vec = Vec::<_, 8>::from_array([1, 2, 3, 4]);
170 let mut it = vec.drain(..1);
171 assert_eq!(it.next(), Some(1));
172 drop(it);
173 assert_eq!(vec, &[2, 3, 4]);
174 }
175
176 #[test]
177 fn drain_middle() {
178 let mut vec = Vec::<_, 8>::from_array([1, 2, 3, 4]);
179 let mut it = vec.drain(1..3);
180 assert_eq!(it.next(), Some(2));
181 assert_eq!(it.next(), Some(3));
182 drop(it);
183 assert_eq!(vec, &[1, 4]);
184 }
185
186 #[test]
187 fn drain_end() {
188 let mut vec = Vec::<_, 8>::from_array([1, 2, 3, 4]);
189 let mut it = vec.drain(3..);
190 assert_eq!(it.next(), Some(4));
191 drop(it);
192 assert_eq!(vec, &[1, 2, 3]);
193 }
194
195 #[test]
196 fn drain_drop_rest() {
197 droppable!();
198
199 let mut vec = Vec::<_, 8>::from_array([
200 Droppable::new(),
201 Droppable::new(),
202 Droppable::new(),
203 Droppable::new(),
204 ]);
205 assert_eq!(Droppable::count(), 4);
206
207 let mut iter = vec.drain(2..);
208 assert_eq!(iter.next().unwrap().0, 3);
209 drop(iter);
210 assert_eq!(Droppable::count(), 2);
211
212 assert_eq!(vec.len(), 2);
213 assert_eq!(vec.remove(0).0, 1);
214 assert_eq!(Droppable::count(), 1);
215
216 drop(vec);
217 assert_eq!(Droppable::count(), 0);
218 }
219}