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}