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 {
120 let vec = vec.as_mut();
121 let old_len = vec.len();
122 let tail_len = self.tail_len.into_usize();
123 vec.set_len(old_len + drop_len + tail_len);
124 vec.truncate(old_len + tail_len);
125 }
126
127 return;
128 }
129
130 let _guard = DropGuard(self);
132
133 if drop_len == 0 {
134 return;
135 }
136
137 let drop_ptr = iter.as_slice().as_ptr();
142
143 unsafe {
144 let vec_ptr = vec.as_mut().as_mut_ptr();
149 let drop_offset = (drop_ptr as usize - vec_ptr as usize) / size_of::<T>();
151 let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len);
152 ptr::drop_in_place(to_drop);
153 }
154 }
155}
156
157impl<T, LenT: LenType> ExactSizeIterator for Drain<'_, T, LenT> {}
158
159impl<T, LenT: LenType> FusedIterator for Drain<'_, T, LenT> {}
160
161#[cfg(test)]
162mod tests {
163 use super::super::Vec;
164
165 #[test]
166 fn drain_front() {
167 let mut vec = Vec::<_, 8>::from_array([1, 2, 3, 4]);
168 let mut it = vec.drain(..1);
169 assert_eq!(it.next(), Some(1));
170 drop(it);
171 assert_eq!(vec, &[2, 3, 4]);
172 }
173
174 #[test]
175 fn drain_middle() {
176 let mut vec = Vec::<_, 8>::from_array([1, 2, 3, 4]);
177 let mut it = vec.drain(1..3);
178 assert_eq!(it.next(), Some(2));
179 assert_eq!(it.next(), Some(3));
180 drop(it);
181 assert_eq!(vec, &[1, 4]);
182 }
183
184 #[test]
185 fn drain_end() {
186 let mut vec = Vec::<_, 8>::from_array([1, 2, 3, 4]);
187 let mut it = vec.drain(3..);
188 assert_eq!(it.next(), Some(4));
189 drop(it);
190 assert_eq!(vec, &[1, 2, 3]);
191 }
192
193 #[test]
194 fn drain_drop_rest() {
195 droppable!();
196
197 let mut vec = Vec::<_, 8>::from_array([
198 Droppable::new(),
199 Droppable::new(),
200 Droppable::new(),
201 Droppable::new(),
202 ]);
203 assert_eq!(Droppable::count(), 4);
204
205 let mut iter = vec.drain(2..);
206 assert_eq!(iter.next().unwrap().0, 3);
207 drop(iter);
208 assert_eq!(Droppable::count(), 2);
209
210 assert_eq!(vec.len(), 2);
211 assert_eq!(vec.remove(0).0, 1);
212 assert_eq!(Droppable::count(), 1);
213
214 drop(vec);
215 assert_eq!(Droppable::count(), 0);
216 }
217}