cl_generic_vec/iter/
into_iter.rs

1use crate::{SimpleVec, Storage};
2#[cfg(feature = "nightly")]
3use core::iter::TrustedLen;
4use core::{
5    iter::{ExactSizeIterator, FusedIterator},
6    mem::ManuallyDrop,
7    ptr,
8};
9
10/// This struct is created by [`GenericVec::into_iter`](crate::GenericVec::into_iter).
11/// See its documentation for more.
12pub struct IntoIter<S: ?Sized + Storage> {
13    index: usize,
14    vec: ManuallyDrop<SimpleVec<S>>,
15}
16
17impl<S: ?Sized + Storage> Drop for IntoIter<S> {
18    fn drop(&mut self) {
19        unsafe {
20            struct DropAlloc<'a, S: ?Sized>(&'a mut S);
21
22            impl<S: ?Sized> Drop for DropAlloc<'_, S> {
23                fn drop(&mut self) {
24                    unsafe {
25                        core::ptr::drop_in_place(self.0);
26                    }
27                }
28            }
29
30            let len = self.vec.len();
31            let index = self.index;
32
33            let drop_alloc = DropAlloc(&mut self.vec.storage);
34            let data = drop_alloc.0.as_mut().as_mut_ptr().add(index);
35            core::ptr::slice_from_raw_parts_mut(data, len.wrapping_sub(index)).drop_in_place();
36        }
37    }
38}
39
40impl<S: Storage> IntoIterator for SimpleVec<S> {
41    type IntoIter = IntoIter<S>;
42    type Item = S::Item;
43
44    fn into_iter(self) -> Self::IntoIter {
45        IntoIter {
46            index: 0,
47            vec: ManuallyDrop::new(self),
48        }
49    }
50}
51
52impl<'a, S: ?Sized + Storage> IntoIterator for &'a mut SimpleVec<S> {
53    type IntoIter = core::slice::IterMut<'a, S::Item>;
54    type Item = &'a mut S::Item;
55
56    fn into_iter(self) -> Self::IntoIter { self.iter_mut() }
57}
58
59impl<'a, S: ?Sized + Storage> IntoIterator for &'a SimpleVec<S> {
60    type IntoIter = core::slice::Iter<'a, S::Item>;
61    type Item = &'a S::Item;
62
63    fn into_iter(self) -> Self::IntoIter { self.iter() }
64}
65
66impl<S: ?Sized + Storage> FusedIterator for IntoIter<S> {}
67impl<S: ?Sized + Storage> ExactSizeIterator for IntoIter<S> {
68    #[cfg(feature = "nightly")]
69    fn is_empty(&self) -> bool { self.index == self.vec.len() }
70}
71
72#[cfg(feature = "nightly")]
73unsafe impl<S: ?Sized + Storage> TrustedLen for IntoIter<S> {}
74
75impl<S: ?Sized + Storage> IntoIter<S> {
76    /// Get a slice to the remaining elements in the iterator
77    pub fn as_slice(&self) -> &[S::Item] {
78        let index = self.index;
79        let len = self.vec.len();
80        let ptr = self.vec.as_ptr();
81        unsafe { core::slice::from_raw_parts(ptr.add(index), len.wrapping_sub(index)) }
82    }
83
84    /// Get a mutable slice to the remaining elements in the iterator
85    pub fn as_mut_slice(&mut self) -> &mut [S::Item] {
86        let index = self.index;
87        let len = self.vec.len();
88        let ptr = self.vec.as_mut_ptr();
89        unsafe { core::slice::from_raw_parts_mut(ptr.add(index), len.wrapping_sub(index)) }
90    }
91}
92
93impl<S: ?Sized + Storage> Iterator for IntoIter<S> {
94    type Item = S::Item;
95
96    fn next(&mut self) -> Option<Self::Item> {
97        if self.index == self.vec.len() {
98            None
99        } else {
100            unsafe {
101                let value = self.vec.get_unchecked(self.index);
102                self.index += 1;
103                Some(ptr::read(value))
104            }
105        }
106    }
107
108    fn size_hint(&self) -> (usize, Option<usize>) {
109        let len = self.vec.len().wrapping_sub(self.index);
110        (len, Some(len))
111    }
112
113    fn nth(&mut self, n: usize) -> Option<Self::Item> {
114        let n = self.len().min(n);
115        let old_index = self.index;
116        self.index += n;
117
118        unsafe {
119            ptr::drop_in_place(self.vec.get_unchecked_mut(old_index..self.index));
120        }
121
122        self.next()
123    }
124
125    fn count(self) -> usize
126    where
127        Self: Sized,
128    {
129        self.len()
130    }
131}
132
133impl<S: ?Sized + Storage> DoubleEndedIterator for IntoIter<S> {
134    fn next_back(&mut self) -> Option<Self::Item> {
135        if self.index == self.vec.len() {
136            None
137        } else {
138            unsafe { Some(self.vec.pop_unchecked()) }
139        }
140    }
141}