alloc/collections/vec_deque/
into_iter.rs1use 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#[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: 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 unsafe { ptr::read(elem) }
106 })
107 .try_fold(init, &mut f)?;
108
109 tail.iter()
110 .map(|elem| {
111 guard.consumed += 1;
112 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 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 return Ok(unsafe { raw_arr.transpose().assume_init() });
148 }
149
150 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 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 Ok(unsafe { raw_arr.transpose().assume_init() })
163 } else {
164 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 self.inner.head = WrappedIndex::zero();
171 self.inner.len = 0;
172 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: 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 unsafe { ptr::read(elem) }
226 })
227 .try_rfold(init, &mut f)?;
228
229 head.iter()
230 .map(|elem| {
231 guard.consumed += 1;
232 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> {}