abi_stable/std_types/vec/iters.rs
1use super::*;
2
3use crate::utils::distance_from;
4
5use std::slice;
6
7pub(super) struct RawValIter<T> {
8 pub(super) start: *const T,
9 pub(super) end: *const T,
10}
11
12unsafe impl<T: Send> Send for RawValIter<T> {}
13unsafe impl<T: Sync> Sync for RawValIter<T> {}
14
15impl<T> RawValIter<T> {
16 /// # Safety
17 ///
18 /// Must remember to keep the underlying allocation alive.
19 pub(super) unsafe fn new(start: *mut T, len: usize) -> Self {
20 RawValIter {
21 start,
22 end: if mem::size_of::<T>() == 0 {
23 (start as usize + len) as *const _
24 } else if len == 0 {
25 start
26 } else {
27 unsafe { start.add(len) }
28 },
29 }
30 }
31
32 fn calculate_length(&self) -> usize {
33 let elem_size = mem::size_of::<T>();
34 let distance = self.end as usize - self.start as usize;
35 let stride_size = if elem_size == 0 { 1 } else { elem_size };
36 distance / stride_size
37 }
38
39 fn as_slice(&self) -> &[T] {
40 let len = self.calculate_length();
41 unsafe { ::std::slice::from_raw_parts(self.start, len) }
42 }
43
44 fn as_mut_slice(&mut self) -> &mut [T] {
45 let len = self.calculate_length();
46 unsafe { ::std::slice::from_raw_parts_mut(self.start as *mut T, len) }
47 }
48}
49
50impl<T> Iterator for RawValIter<T> {
51 type Item = T;
52 fn next(&mut self) -> Option<T> {
53 if self.start == self.end {
54 None
55 } else {
56 unsafe {
57 let result = ptr::read(self.start);
58 self.start = if mem::size_of::<T>() == 0 {
59 (self.start as usize + 1) as *const _
60 } else {
61 self.start.offset(1)
62 };
63 Some(result)
64 }
65 }
66 }
67
68 fn size_hint(&self) -> (usize, Option<usize>) {
69 let len = self.calculate_length();
70 (len, Some(len))
71 }
72}
73
74impl<T> DoubleEndedIterator for RawValIter<T> {
75 fn next_back(&mut self) -> Option<T> {
76 if self.start == self.end {
77 None
78 } else {
79 unsafe {
80 self.end = if mem::size_of::<T>() == 0 {
81 (self.end as usize - 1) as *const _
82 } else {
83 self.end.offset(-1)
84 };
85 Some(ptr::read(self.end))
86 }
87 }
88 }
89}
90
91///////////////////////////////////////////////////
92
93/// An Iterator returned by `<RVec<T> as IntoIterator>::into_iter`,
94/// which yields all the elements from the `RVec<T>`,
95/// consuming it in the process.
96pub struct IntoIter<T> {
97 pub(super) _buf: ManuallyDrop<RVec<T>>,
98 pub(super) iter: RawValIter<T>,
99}
100
101impl<T> IntoIter<T> {
102 /// Returns a slice over the remainder of the `Vec<T>` that is being iterated over.
103 ///
104 /// # Example
105 ///
106 /// ```
107 /// use abi_stable::std_types::RVec;
108 ///
109 /// let mut iter = RVec::from(vec![0, 1, 2, 3]).into_iter();
110 ///
111 /// assert_eq!(iter.as_slice(), &[0, 1, 2, 3]);
112 ///
113 /// assert_eq!(iter.next(), Some(0));
114 /// assert_eq!(iter.as_slice(), &[1, 2, 3]);
115 ///
116 /// assert_eq!(iter.next_back(), Some(3));
117 /// assert_eq!(iter.as_slice(), &[1, 2]);
118 ///
119 /// ```
120 pub fn as_slice(&self) -> &[T] {
121 self.iter.as_slice()
122 }
123
124 /// Returns a mutable slice over the remainder of the `Vec<T>` that is being iterated over.
125 ///
126 /// # Example
127 ///
128 /// ```
129 /// use abi_stable::std_types::RVec;
130 ///
131 /// let mut iter = RVec::from(vec![0, 1, 2, 3]).into_iter();
132 ///
133 /// assert_eq!(iter.as_mut_slice(), &mut [0, 1, 2, 3]);
134 ///
135 /// assert_eq!(iter.next(), Some(0));
136 /// assert_eq!(iter.as_mut_slice(), &mut [1, 2, 3]);
137 ///
138 /// assert_eq!(iter.next_back(), Some(3));
139 /// assert_eq!(iter.as_mut_slice(), &mut [1, 2]);
140 ///
141 /// ```
142 pub fn as_mut_slice(&mut self) -> &mut [T] {
143 self.iter.as_mut_slice()
144 }
145}
146
147impl<T> Iterator for IntoIter<T> {
148 type Item = T;
149 fn next(&mut self) -> Option<T> {
150 self.iter.next()
151 }
152 fn size_hint(&self) -> (usize, Option<usize>) {
153 self.iter.size_hint()
154 }
155}
156
157impl<T> DoubleEndedIterator for IntoIter<T> {
158 fn next_back(&mut self) -> Option<T> {
159 self.iter.next_back()
160 }
161}
162
163impl<T> Drop for IntoIter<T> {
164 fn drop(&mut self) {
165 self.by_ref().for_each(drop);
166 self._buf.length = 0;
167 unsafe { ManuallyDrop::drop(&mut self._buf) }
168 }
169}
170
171///////////////////////////////////////////////////
172
173/// An Iterator returned by `RVec::drain` ,
174/// which removes and yields all the elements in a range from the `RVec<T>`.
175#[repr(C)]
176pub struct Drain<'a, T> {
177 // pub(super) vec: &'a mut RVec<T>,
178 pub(super) allocation_start: *mut T,
179 pub(super) vec_len: &'a mut usize,
180 pub(super) iter: RawValIter<T>,
181 pub(super) len: usize,
182 pub(super) removed_start: *mut T,
183 pub(super) slice_len: usize,
184}
185
186impl<'a, T> Drain<'a, T> {
187 /// Returns a slice over the remainder of the `Vec<T>` that is being drained.
188 ///
189 /// # Example
190 ///
191 /// ```
192 /// use abi_stable::std_types::RVec;
193 ///
194 /// let mut list = (0..8).collect::<RVec<u8>>();
195 /// let mut iter = list.drain(3..7);
196 ///
197 /// assert_eq!(iter.as_slice(), &[3, 4, 5, 6]);
198 ///
199 /// assert_eq!(iter.next(), Some(3));
200 /// assert_eq!(iter.as_slice(), &[4, 5, 6]);
201 ///
202 /// assert_eq!(iter.next(), Some(4));
203 /// assert_eq!(iter.as_slice(), &[5, 6]);
204 ///
205 /// drop(iter);
206 ///
207 /// assert_eq!(list.as_slice(), &[0, 1, 2, 7]);
208 ///
209 /// ```
210 pub fn as_slice(&self) -> &[T] {
211 self.iter.as_slice()
212 }
213
214 /// Returns a mutable slice over the remainder of the `Vec<T>` that is being drained.
215 ///
216 /// # Example
217 ///
218 /// ```
219 /// use abi_stable::std_types::RVec;
220 ///
221 /// let mut list = (0..8).collect::<RVec<u8>>();
222 /// let mut iter = list.drain(3..7);
223 ///
224 /// assert_eq!(iter.as_mut_slice(), &mut [3, 4, 5, 6]);
225 ///
226 /// assert_eq!(iter.next(), Some(3));
227 /// assert_eq!(iter.as_mut_slice(), &mut [4, 5, 6]);
228 ///
229 /// assert_eq!(iter.next(), Some(4));
230 /// assert_eq!(iter.as_mut_slice(), &mut [5, 6]);
231 ///
232 /// drop(iter);
233 ///
234 /// assert_eq!(list.as_slice(), &[0, 1, 2, 7]);
235 ///
236 /// ```
237 pub fn as_mut_slice(&mut self) -> &mut [T] {
238 self.iter.as_mut_slice()
239 }
240}
241
242impl<'a, T> Iterator for Drain<'a, T> {
243 type Item = T;
244 fn next(&mut self) -> Option<T> {
245 self.iter.next()
246 }
247 fn size_hint(&self) -> (usize, Option<usize>) {
248 self.iter.size_hint()
249 }
250}
251
252impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
253 fn next_back(&mut self) -> Option<T> {
254 self.iter.next_back()
255 }
256}
257
258impl<'a, T> Drop for Drain<'a, T> {
259 fn drop(&mut self) {
260 self.iter.by_ref().for_each(drop);
261 unsafe {
262 let removed_start = self.removed_start;
263 let removed_end = self.removed_start.offset(self.slice_len as isize);
264 let end_index =
265 distance_from(self.allocation_start, removed_start).unwrap_or(0) + self.slice_len;
266 ptr::copy(removed_end, removed_start, self.len - end_index);
267 *self.vec_len = self.len - self.slice_len;
268 }
269 }
270}
271
272///////////////////////////////////////////////////
273
274// copy of the std library DrainFilter, without the allocator parameter.
275// (from rustc 1.50.0-nightly (eb4fc71dc 2020-12-17))
276#[derive(Debug)]
277pub(crate) struct DrainFilter<'a, T, F>
278where
279 F: FnMut(&mut T) -> bool,
280{
281 // pub(super) vec: &'a mut RVec<T>,
282 pub(super) allocation_start: *mut T,
283 pub(super) vec_len: &'a mut usize,
284 pub(super) idx: usize,
285 pub(super) del: usize,
286 pub(super) old_len: usize,
287 pub(super) pred: F,
288 pub(super) panic_flag: bool,
289}
290
291// copy of the std library DrainFilter impl, without the allocator parameter.
292// (from rustc 1.50.0-nightly (eb4fc71dc 2020-12-17))
293impl<T, F> Iterator for DrainFilter<'_, T, F>
294where
295 F: FnMut(&mut T) -> bool,
296{
297 type Item = T;
298
299 fn next(&mut self) -> Option<T> {
300 unsafe {
301 while self.idx < self.old_len {
302 let i = self.idx;
303 let v = slice::from_raw_parts_mut(self.allocation_start, self.old_len);
304 self.panic_flag = true;
305 let drained = (self.pred)(&mut v[i]);
306 self.panic_flag = false;
307 // Update the index *after* the predicate is called. If the index
308 // is updated prior and the predicate panics, the element at this
309 // index would be leaked.
310 self.idx += 1;
311 if drained {
312 self.del += 1;
313 return Some(ptr::read(&v[i]));
314 } else if self.del > 0 {
315 let del = self.del;
316 let src: *const T = &v[i];
317 let dst: *mut T = &mut v[i - del];
318 ptr::copy_nonoverlapping(src, dst, 1);
319 }
320 }
321 None
322 }
323 }
324
325 fn size_hint(&self) -> (usize, Option<usize>) {
326 (0, Some(self.old_len - self.idx))
327 }
328}
329
330// copy of the std library DrainFilter impl, without the allocator parameter.
331// (from rustc 1.50.0-nightly (eb4fc71dc 2020-12-17))
332impl<T, F> Drop for DrainFilter<'_, T, F>
333where
334 F: FnMut(&mut T) -> bool,
335{
336 fn drop(&mut self) {
337 struct BackshiftOnDrop<'a, 'b, T, F>
338 where
339 F: FnMut(&mut T) -> bool,
340 {
341 drain: &'b mut DrainFilter<'a, T, F>,
342 }
343
344 impl<'a, 'b, T, F> Drop for BackshiftOnDrop<'a, 'b, T, F>
345 where
346 F: FnMut(&mut T) -> bool,
347 {
348 fn drop(&mut self) {
349 unsafe {
350 if self.drain.idx < self.drain.old_len && self.drain.del > 0 {
351 // This is a pretty messed up state, and there isn't really an
352 // obviously right thing to do. We don't want to keep trying
353 // to execute `pred`, so we just backshift all the unprocessed
354 // elements and tell the vec that they still exist. The backshift
355 // is required to prevent a double-drop of the last successfully
356 // drained item prior to a panic in the predicate.
357 let ptr = self.drain.allocation_start;
358 let src = ptr.add(self.drain.idx);
359 let dst = src.sub(self.drain.del);
360 let tail_len = self.drain.old_len - self.drain.idx;
361 src.copy_to(dst, tail_len);
362 }
363 *self.drain.vec_len = self.drain.old_len - self.drain.del;
364 }
365 }
366 }
367
368 let backshift = BackshiftOnDrop { drain: self };
369
370 // Attempt to consume any remaining elements if the filter predicate
371 // has not yet panicked. We'll backshift any remaining elements
372 // whether we've already panicked or if the consumption here panics.
373 if !backshift.drain.panic_flag {
374 backshift.drain.for_each(drop);
375 }
376 }
377}