1 | use crate::iter::adapters::zip::try_get_unchecked; |
2 | use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce}; |
3 | use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen}; |
4 | use crate::num::NonZero; |
5 | use crate::ops::Try; |
6 | |
7 | /// An iterator that yields the current count and the element during iteration. |
8 | /// |
9 | /// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its |
10 | /// documentation for more. |
11 | /// |
12 | /// [`enumerate`]: Iterator::enumerate |
13 | /// [`Iterator`]: trait.Iterator.html |
14 | #[derive (Clone, Debug)] |
15 | #[must_use = "iterators are lazy and do nothing unless consumed" ] |
16 | #[stable (feature = "rust1" , since = "1.0.0" )] |
17 | #[rustc_diagnostic_item = "Enumerate" ] |
18 | pub struct Enumerate<I> { |
19 | iter: I, |
20 | count: usize, |
21 | } |
22 | impl<I> Enumerate<I> { |
23 | pub(in crate::iter) fn new(iter: I) -> Enumerate<I> { |
24 | Enumerate { iter, count: 0 } |
25 | } |
26 | |
27 | /// Retrieve the current position of the iterator. |
28 | /// |
29 | /// If the iterator has not advanced, the position returned will be 0. |
30 | /// |
31 | /// The position may also exceed the bounds of the iterator to allow for calculating |
32 | /// the displacement of the iterator from following calls to [`Iterator::next`]. |
33 | /// |
34 | /// # Examples |
35 | /// |
36 | /// ``` |
37 | /// #![feature(next_index)] |
38 | /// |
39 | /// let arr = ['a' , 'b' ]; |
40 | /// |
41 | /// let mut iter = arr.iter().enumerate(); |
42 | /// |
43 | /// assert_eq!(iter.next_index(), 0); |
44 | /// assert_eq!(iter.next(), Some((0, &'a' ))); |
45 | /// |
46 | /// assert_eq!(iter.next_index(), 1); |
47 | /// assert_eq!(iter.next_index(), 1); |
48 | /// assert_eq!(iter.next(), Some((1, &'b' ))); |
49 | /// |
50 | /// assert_eq!(iter.next_index(), 2); |
51 | /// assert_eq!(iter.next(), None); |
52 | /// assert_eq!(iter.next_index(), 2); |
53 | /// ``` |
54 | #[inline ] |
55 | #[unstable (feature = "next_index" , issue = "130711" )] |
56 | pub fn next_index(&self) -> usize { |
57 | self.count |
58 | } |
59 | } |
60 | |
61 | #[stable (feature = "rust1" , since = "1.0.0" )] |
62 | impl<I> Iterator for Enumerate<I> |
63 | where |
64 | I: Iterator, |
65 | { |
66 | type Item = (usize, <I as Iterator>::Item); |
67 | |
68 | /// # Overflow Behavior |
69 | /// |
70 | /// The method does no guarding against overflows, so enumerating more than |
71 | /// `usize::MAX` elements either produces the wrong result or panics. If |
72 | /// overflow checks are enabled, a panic is guaranteed. |
73 | /// |
74 | /// # Panics |
75 | /// |
76 | /// Might panic if the index of the element overflows a `usize`. |
77 | #[inline ] |
78 | #[rustc_inherit_overflow_checks ] |
79 | fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> { |
80 | let a = self.iter.next()?; |
81 | let i = self.count; |
82 | self.count += 1; |
83 | Some((i, a)) |
84 | } |
85 | |
86 | #[inline ] |
87 | fn size_hint(&self) -> (usize, Option<usize>) { |
88 | self.iter.size_hint() |
89 | } |
90 | |
91 | #[inline ] |
92 | #[rustc_inherit_overflow_checks ] |
93 | fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> { |
94 | let a = self.iter.nth(n)?; |
95 | let i = self.count + n; |
96 | self.count = i + 1; |
97 | Some((i, a)) |
98 | } |
99 | |
100 | #[inline ] |
101 | fn count(self) -> usize { |
102 | self.iter.count() |
103 | } |
104 | |
105 | #[inline ] |
106 | fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R |
107 | where |
108 | Self: Sized, |
109 | Fold: FnMut(Acc, Self::Item) -> R, |
110 | R: Try<Output = Acc>, |
111 | { |
112 | #[inline ] |
113 | fn enumerate<'a, T, Acc, R>( |
114 | count: &'a mut usize, |
115 | mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a, |
116 | ) -> impl FnMut(Acc, T) -> R + 'a { |
117 | #[rustc_inherit_overflow_checks ] |
118 | move |acc, item| { |
119 | let acc = fold(acc, (*count, item)); |
120 | *count += 1; |
121 | acc |
122 | } |
123 | } |
124 | |
125 | self.iter.try_fold(init, enumerate(&mut self.count, fold)) |
126 | } |
127 | |
128 | #[inline ] |
129 | fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc |
130 | where |
131 | Fold: FnMut(Acc, Self::Item) -> Acc, |
132 | { |
133 | #[inline ] |
134 | fn enumerate<T, Acc>( |
135 | mut count: usize, |
136 | mut fold: impl FnMut(Acc, (usize, T)) -> Acc, |
137 | ) -> impl FnMut(Acc, T) -> Acc { |
138 | #[rustc_inherit_overflow_checks ] |
139 | move |acc, item| { |
140 | let acc = fold(acc, (count, item)); |
141 | count += 1; |
142 | acc |
143 | } |
144 | } |
145 | |
146 | self.iter.fold(init, enumerate(self.count, fold)) |
147 | } |
148 | |
149 | #[inline ] |
150 | #[rustc_inherit_overflow_checks ] |
151 | fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
152 | let remaining = self.iter.advance_by(n); |
153 | let advanced = match remaining { |
154 | Ok(()) => n, |
155 | Err(rem) => n - rem.get(), |
156 | }; |
157 | self.count += advanced; |
158 | remaining |
159 | } |
160 | |
161 | #[rustc_inherit_overflow_checks ] |
162 | #[inline ] |
163 | unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item |
164 | where |
165 | Self: TrustedRandomAccessNoCoerce, |
166 | { |
167 | // SAFETY: the caller must uphold the contract for |
168 | // `Iterator::__iterator_get_unchecked`. |
169 | let value = unsafe { try_get_unchecked(&mut self.iter, idx) }; |
170 | (self.count + idx, value) |
171 | } |
172 | } |
173 | |
174 | #[stable (feature = "rust1" , since = "1.0.0" )] |
175 | impl<I> DoubleEndedIterator for Enumerate<I> |
176 | where |
177 | I: ExactSizeIterator + DoubleEndedIterator, |
178 | { |
179 | #[inline ] |
180 | fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> { |
181 | let a = self.iter.next_back()?; |
182 | let len = self.iter.len(); |
183 | // Can safely add, `ExactSizeIterator` promises that the number of |
184 | // elements fits into a `usize`. |
185 | Some((self.count + len, a)) |
186 | } |
187 | |
188 | #[inline ] |
189 | fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> { |
190 | let a = self.iter.nth_back(n)?; |
191 | let len = self.iter.len(); |
192 | // Can safely add, `ExactSizeIterator` promises that the number of |
193 | // elements fits into a `usize`. |
194 | Some((self.count + len, a)) |
195 | } |
196 | |
197 | #[inline ] |
198 | fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R |
199 | where |
200 | Self: Sized, |
201 | Fold: FnMut(Acc, Self::Item) -> R, |
202 | R: Try<Output = Acc>, |
203 | { |
204 | // Can safely add and subtract the count, as `ExactSizeIterator` promises |
205 | // that the number of elements fits into a `usize`. |
206 | fn enumerate<T, Acc, R>( |
207 | mut count: usize, |
208 | mut fold: impl FnMut(Acc, (usize, T)) -> R, |
209 | ) -> impl FnMut(Acc, T) -> R { |
210 | move |acc, item| { |
211 | count -= 1; |
212 | fold(acc, (count, item)) |
213 | } |
214 | } |
215 | |
216 | let count = self.count + self.iter.len(); |
217 | self.iter.try_rfold(init, enumerate(count, fold)) |
218 | } |
219 | |
220 | #[inline ] |
221 | fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc |
222 | where |
223 | Fold: FnMut(Acc, Self::Item) -> Acc, |
224 | { |
225 | // Can safely add and subtract the count, as `ExactSizeIterator` promises |
226 | // that the number of elements fits into a `usize`. |
227 | fn enumerate<T, Acc>( |
228 | mut count: usize, |
229 | mut fold: impl FnMut(Acc, (usize, T)) -> Acc, |
230 | ) -> impl FnMut(Acc, T) -> Acc { |
231 | move |acc, item| { |
232 | count -= 1; |
233 | fold(acc, (count, item)) |
234 | } |
235 | } |
236 | |
237 | let count = self.count + self.iter.len(); |
238 | self.iter.rfold(init, enumerate(count, fold)) |
239 | } |
240 | |
241 | #[inline ] |
242 | fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
243 | // we do not need to update the count since that only tallies the number of items |
244 | // consumed from the front. consuming items from the back can never reduce that. |
245 | self.iter.advance_back_by(n) |
246 | } |
247 | } |
248 | |
249 | #[stable (feature = "rust1" , since = "1.0.0" )] |
250 | impl<I> ExactSizeIterator for Enumerate<I> |
251 | where |
252 | I: ExactSizeIterator, |
253 | { |
254 | fn len(&self) -> usize { |
255 | self.iter.len() |
256 | } |
257 | |
258 | fn is_empty(&self) -> bool { |
259 | self.iter.is_empty() |
260 | } |
261 | } |
262 | |
263 | #[doc (hidden)] |
264 | #[unstable (feature = "trusted_random_access" , issue = "none" )] |
265 | unsafe impl<I> TrustedRandomAccess for Enumerate<I> where I: TrustedRandomAccess {} |
266 | |
267 | #[doc (hidden)] |
268 | #[unstable (feature = "trusted_random_access" , issue = "none" )] |
269 | unsafe impl<I> TrustedRandomAccessNoCoerce for Enumerate<I> |
270 | where |
271 | I: TrustedRandomAccessNoCoerce, |
272 | { |
273 | const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT; |
274 | } |
275 | |
276 | #[stable (feature = "fused" , since = "1.26.0" )] |
277 | impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {} |
278 | |
279 | #[unstable (issue = "none" , feature = "trusted_fused" )] |
280 | unsafe impl<I: TrustedFused> TrustedFused for Enumerate<I> {} |
281 | |
282 | #[unstable (feature = "trusted_len" , issue = "37572" )] |
283 | unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {} |
284 | |
285 | #[unstable (issue = "none" , feature = "inplace_iteration" )] |
286 | unsafe impl<I> SourceIter for Enumerate<I> |
287 | where |
288 | I: SourceIter, |
289 | { |
290 | type Source = I::Source; |
291 | |
292 | #[inline ] |
293 | unsafe fn as_inner(&mut self) -> &mut I::Source { |
294 | // SAFETY: unsafe function forwarding to unsafe function with the same requirements |
295 | unsafe { SourceIter::as_inner(&mut self.iter) } |
296 | } |
297 | } |
298 | |
299 | #[unstable (issue = "none" , feature = "inplace_iteration" )] |
300 | unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> { |
301 | const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY; |
302 | const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY; |
303 | } |
304 | |
305 | #[stable (feature = "default_iters" , since = "1.70.0" )] |
306 | impl<I: Default> Default for Enumerate<I> { |
307 | /// Creates an `Enumerate` iterator from the default value of `I` |
308 | /// ``` |
309 | /// # use core::slice; |
310 | /// # use std::iter::Enumerate; |
311 | /// let iter: Enumerate<slice::Iter<'_, u8>> = Default::default(); |
312 | /// assert_eq!(iter.len(), 0); |
313 | /// ``` |
314 | fn default() -> Self { |
315 | Enumerate::new(iter:Default::default()) |
316 | } |
317 | } |
318 | |