Skip to main content

alloc/collections/vec_deque/
into_iter.rs

1use core::iter::{FusedIterator, TrustedLen};
2use core::mem::MaybeUninit;
3use core::num::NonZero;
4use core::ops::Try;
5use core::{array, fmt, ptr};
6
7use super::VecDeque;
8use super::index::WrappedIndex;
9use crate::alloc::{Allocator, Global};
10
11/// An owning iterator over the elements of a `VecDeque`.
12///
13/// This `struct` is created by the [`into_iter`] method on [`VecDeque`]
14/// (provided by the [`IntoIterator`] trait). See its documentation for more.
15///
16/// [`into_iter`]: VecDeque::into_iter
17#[derive(#[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ::core::clone::Clone, A: ::core::clone::Clone + Allocator>
    ::core::clone::Clone for IntoIter<T, A> {
    #[inline]
    fn clone(&self) -> IntoIter<T, A> {
        IntoIter { inner: ::core::clone::Clone::clone(&self.inner) }
    }
}Clone)]
18#[stable(feature = "rust1", since = "1.0.0")]
19pub struct IntoIter<
20    T,
21    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
22> {
23    inner: VecDeque<T, A>,
24}
25
26impl<T, A: Allocator> IntoIter<T, A> {
27    pub(super) fn new(inner: VecDeque<T, A>) -> Self {
28        IntoIter { inner }
29    }
30
31    pub(super) fn into_vecdeque(self) -> VecDeque<T, A> {
32        self.inner
33    }
34}
35
36#[stable(feature = "collection_debug", since = "1.17.0")]
37impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        f.debug_tuple("IntoIter").field(&self.inner).finish()
40    }
41}
42
43#[stable(feature = "rust1", since = "1.0.0")]
44impl<T, A: Allocator> Iterator for IntoIter<T, A> {
45    type Item = T;
46
47    #[inline]
48    fn next(&mut self) -> Option<T> {
49        self.inner.pop_front()
50    }
51
52    #[inline]
53    fn size_hint(&self) -> (usize, Option<usize>) {
54        let len = self.inner.len();
55        (len, Some(len))
56    }
57
58    #[inline]
59    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
60        let len = self.inner.len;
61        let rem = if len < n {
62            self.inner.clear();
63            n - len
64        } else {
65            self.inner.drain(..n);
66            0
67        };
68        NonZero::new(rem).map_or(Ok(()), Err)
69    }
70
71    #[inline]
72    fn count(self) -> usize {
73        self.inner.len
74    }
75
76    fn try_fold<B, F, R>(&mut self, mut init: B, mut f: F) -> R
77    where
78        F: FnMut(B, Self::Item) -> R,
79        R: Try<Output = B>,
80    {
81        struct Guard<'a, T, A: Allocator> {
82            deque: &'a mut VecDeque<T, A>,
83            // `consumed <= deque.len` always holds.
84            consumed: usize,
85        }
86
87        impl<'a, T, A: Allocator> Drop for Guard<'a, T, A> {
88            fn drop(&mut self) {
89                self.deque.len -= self.consumed;
90                self.deque.head = self.deque.to_wrapped_index(self.consumed);
91            }
92        }
93
94        let mut guard = Guard { deque: &mut self.inner, consumed: 0 };
95
96        let (head, tail) = guard.deque.as_slices();
97
98        init = head
99            .iter()
100            .map(|elem| {
101                guard.consumed += 1;
102                // SAFETY: Because we incremented `guard.consumed`, the
103                // deque effectively forgot the element, so we can take
104                // ownership
105                unsafe { ptr::read(elem) }
106            })
107            .try_fold(init, &mut f)?;
108
109        tail.iter()
110            .map(|elem| {
111                guard.consumed += 1;
112                // SAFETY: Same as above.
113                unsafe { ptr::read(elem) }
114            })
115            .try_fold(init, &mut f)
116    }
117
118    #[inline]
119    fn fold<B, F>(mut self, init: B, mut f: F) -> B
120    where
121        F: FnMut(B, Self::Item) -> B,
122    {
123        match self.try_fold(init, |b, item| Ok::<B, !>(f(b, item))) {
124            Ok(b) => b,
125        }
126    }
127
128    #[inline]
129    fn last(mut self) -> Option<Self::Item> {
130        self.inner.pop_back()
131    }
132
133    fn next_chunk<const N: usize>(
134        &mut self,
135    ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
136        let mut raw_arr = [const { MaybeUninit::uninit() }; N];
137        let raw_arr_ptr = raw_arr.as_mut_ptr().cast();
138        let (head, tail) = self.inner.as_slices();
139
140        if head.len() >= N {
141            // SAFETY: By manually adjusting the head and length of the deque, we effectively
142            // make it forget the first `N` elements, so taking ownership of them is safe.
143            unsafe { ptr::copy_nonoverlapping(head.as_ptr(), raw_arr_ptr, N) };
144            self.inner.head = self.inner.to_wrapped_index(N);
145            self.inner.len -= N;
146            // SAFETY: We initialized the entire array with items from `head`
147            return Ok(unsafe { raw_arr.transpose().assume_init() });
148        }
149
150        // SAFETY: Same argument as above.
151        unsafe { ptr::copy_nonoverlapping(head.as_ptr(), raw_arr_ptr, head.len()) };
152        let remaining = N - head.len();
153
154        if tail.len() >= remaining {
155            // SAFETY: Same argument as above.
156            unsafe {
157                ptr::copy_nonoverlapping(tail.as_ptr(), raw_arr_ptr.add(head.len()), remaining)
158            };
159            self.inner.head = self.inner.to_wrapped_index(N);
160            self.inner.len -= N;
161            // SAFETY: We initialized the entire array with items from `head` and `tail`
162            Ok(unsafe { raw_arr.transpose().assume_init() })
163        } else {
164            // SAFETY: Same argument as above.
165            unsafe {
166                ptr::copy_nonoverlapping(tail.as_ptr(), raw_arr_ptr.add(head.len()), tail.len())
167            };
168            let init = head.len() + tail.len();
169            // We completely drained all the deques elements.
170            self.inner.head = WrappedIndex::zero();
171            self.inner.len = 0;
172            // SAFETY: We copied all elements from both slices to the beginning of the array, so
173            // the given range is initialized.
174            Err(unsafe { array::IntoIter::new_unchecked(raw_arr, 0..init) })
175        }
176    }
177}
178
179#[stable(feature = "rust1", since = "1.0.0")]
180impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
181    #[inline]
182    fn next_back(&mut self) -> Option<T> {
183        self.inner.pop_back()
184    }
185
186    #[inline]
187    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
188        let len = self.inner.len;
189        let rem = if len < n {
190            self.inner.clear();
191            n - len
192        } else {
193            self.inner.truncate(len - n);
194            0
195        };
196        NonZero::new(rem).map_or(Ok(()), Err)
197    }
198
199    fn try_rfold<B, F, R>(&mut self, mut init: B, mut f: F) -> R
200    where
201        F: FnMut(B, Self::Item) -> R,
202        R: Try<Output = B>,
203    {
204        struct Guard<'a, T, A: Allocator> {
205            deque: &'a mut VecDeque<T, A>,
206            // `consumed <= deque.len` always holds.
207            consumed: usize,
208        }
209
210        impl<'a, T, A: Allocator> Drop for Guard<'a, T, A> {
211            fn drop(&mut self) {
212                self.deque.len -= self.consumed;
213            }
214        }
215
216        let mut guard = Guard { deque: &mut self.inner, consumed: 0 };
217
218        let (head, tail) = guard.deque.as_slices();
219
220        init = tail
221            .iter()
222            .map(|elem| {
223                guard.consumed += 1;
224                // SAFETY: See `try_fold`'s safety comment.
225                unsafe { ptr::read(elem) }
226            })
227            .try_rfold(init, &mut f)?;
228
229        head.iter()
230            .map(|elem| {
231                guard.consumed += 1;
232                // SAFETY: Same as above.
233                unsafe { ptr::read(elem) }
234            })
235            .try_rfold(init, &mut f)
236    }
237
238    #[inline]
239    fn rfold<B, F>(mut self, init: B, mut f: F) -> B
240    where
241        F: FnMut(B, Self::Item) -> B,
242    {
243        match self.try_rfold(init, |b, item| Ok::<B, !>(f(b, item))) {
244            Ok(b) => b,
245        }
246    }
247}
248
249#[stable(feature = "rust1", since = "1.0.0")]
250impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
251    #[inline]
252    fn is_empty(&self) -> bool {
253        self.inner.is_empty()
254    }
255}
256
257#[stable(feature = "fused", since = "1.26.0")]
258impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
259
260#[unstable(feature = "trusted_len", issue = "37572")]
261unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}