1use crate::iter::adapters::zip::try_get_unchecked;
2use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
3use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen};
4use crate::num::NonZero;
5use crate::ops::Try;
6
7#[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#[ferrocene::prevalidated]
19pub struct Enumerate<I> {
20 iter: I,
21 count: usize,
22}
23impl<I> Enumerate<I> {
24 #[ferrocene::prevalidated]
25 pub(in crate::iter) fn new(iter: I) -> Enumerate<I> {
26 Enumerate { iter, count: 0 }
27 }
28
29 #[inline]
57 #[unstable(feature = "next_index", issue = "130711")]
58 pub fn next_index(&self) -> usize {
59 self.count
60 }
61}
62
63#[stable(feature = "rust1", since = "1.0.0")]
64impl<I> Iterator for Enumerate<I>
65where
66 I: Iterator,
67{
68 type Item = (usize, <I as Iterator>::Item);
69
70 #[inline]
80 #[rustc_inherit_overflow_checks]
81 #[ferrocene::prevalidated]
82 fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
83 let a = self.iter.next()?;
84 let i = self.count;
85 self.count += 1;
86 Some((i, a))
87 }
88
89 #[inline]
90 #[ferrocene::prevalidated]
91 fn size_hint(&self) -> (usize, Option<usize>) {
92 self.iter.size_hint()
93 }
94
95 #[inline]
96 #[rustc_inherit_overflow_checks]
97 #[ferrocene::prevalidated]
98 fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> {
99 let a = self.iter.nth(n)?;
100 let i = self.count + n;
101 self.count = i + 1;
102 Some((i, a))
103 }
104
105 #[inline]
106 #[ferrocene::prevalidated]
107 fn count(self) -> usize {
108 self.iter.count()
109 }
110
111 #[inline]
112 #[ferrocene::prevalidated]
113 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
114 where
115 Self: Sized,
116 Fold: FnMut(Acc, Self::Item) -> R,
117 R: Try<Output = Acc>,
118 {
119 #[inline]
120 #[ferrocene::prevalidated]
121 fn enumerate<'a, T, Acc, R>(
122 count: &'a mut usize,
123 mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
124 ) -> impl FnMut(Acc, T) -> R + 'a {
125 #[rustc_inherit_overflow_checks]
126 move |acc, item| {
127 let acc = fold(acc, (*count, item));
128 *count += 1;
129 acc
130 }
131 }
132
133 self.iter.try_fold(init, enumerate(&mut self.count, fold))
134 }
135
136 #[inline]
137 #[ferrocene::prevalidated]
138 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
139 where
140 Fold: FnMut(Acc, Self::Item) -> Acc,
141 {
142 #[inline]
143 #[ferrocene::prevalidated]
144 fn enumerate<T, Acc>(
145 mut count: usize,
146 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
147 ) -> impl FnMut(Acc, T) -> Acc {
148 #[rustc_inherit_overflow_checks]
149 move |acc, item| {
150 let acc = fold(acc, (count, item));
151 count += 1;
152 acc
153 }
154 }
155
156 self.iter.fold(init, enumerate(self.count, fold))
157 }
158
159 #[inline]
160 #[rustc_inherit_overflow_checks]
161 #[ferrocene::prevalidated]
162 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
163 let remaining = self.iter.advance_by(n);
164 let advanced = match remaining {
165 Ok(()) => n,
166 Err(rem) => n - rem.get(),
167 };
168 self.count += advanced;
169 remaining
170 }
171
172 #[rustc_inherit_overflow_checks]
173 #[inline]
174 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
175 where
176 Self: TrustedRandomAccessNoCoerce,
177 {
178 let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
181 (self.count + idx, value)
182 }
183}
184
185#[stable(feature = "rust1", since = "1.0.0")]
186impl<I> DoubleEndedIterator for Enumerate<I>
187where
188 I: ExactSizeIterator + DoubleEndedIterator,
189{
190 #[inline]
191 fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
192 let a = self.iter.next_back()?;
193 let len = self.iter.len();
194 Some((self.count + len, a))
197 }
198
199 #[inline]
200 fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
201 let a = self.iter.nth_back(n)?;
202 let len = self.iter.len();
203 Some((self.count + len, a))
206 }
207
208 #[inline]
209 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
210 where
211 Self: Sized,
212 Fold: FnMut(Acc, Self::Item) -> R,
213 R: Try<Output = Acc>,
214 {
215 fn enumerate<T, Acc, R>(
218 mut count: usize,
219 mut fold: impl FnMut(Acc, (usize, T)) -> R,
220 ) -> impl FnMut(Acc, T) -> R {
221 move |acc, item| {
222 count -= 1;
223 fold(acc, (count, item))
224 }
225 }
226
227 let count = self.count + self.iter.len();
228 self.iter.try_rfold(init, enumerate(count, fold))
229 }
230
231 #[inline]
232 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
233 where
234 Fold: FnMut(Acc, Self::Item) -> Acc,
235 {
236 fn enumerate<T, Acc>(
239 mut count: usize,
240 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
241 ) -> impl FnMut(Acc, T) -> Acc {
242 move |acc, item| {
243 count -= 1;
244 fold(acc, (count, item))
245 }
246 }
247
248 let count = self.count + self.iter.len();
249 self.iter.rfold(init, enumerate(count, fold))
250 }
251
252 #[inline]
253 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
254 self.iter.advance_back_by(n)
257 }
258}
259
260#[stable(feature = "rust1", since = "1.0.0")]
261impl<I> ExactSizeIterator for Enumerate<I>
262where
263 I: ExactSizeIterator,
264{
265 fn len(&self) -> usize {
266 self.iter.len()
267 }
268
269 fn is_empty(&self) -> bool {
270 self.iter.is_empty()
271 }
272}
273
274#[doc(hidden)]
275#[unstable(feature = "trusted_random_access", issue = "none")]
276unsafe impl<I> TrustedRandomAccess for Enumerate<I> where I: TrustedRandomAccess {}
277
278#[doc(hidden)]
279#[unstable(feature = "trusted_random_access", issue = "none")]
280unsafe impl<I> TrustedRandomAccessNoCoerce for Enumerate<I>
281where
282 I: TrustedRandomAccessNoCoerce,
283{
284 const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
285}
286
287#[stable(feature = "fused", since = "1.26.0")]
288impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
289
290#[unstable(issue = "none", feature = "trusted_fused")]
291unsafe impl<I: TrustedFused> TrustedFused for Enumerate<I> {}
292
293#[unstable(feature = "trusted_len", issue = "37572")]
294unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
295
296#[unstable(issue = "none", feature = "inplace_iteration")]
297unsafe impl<I> SourceIter for Enumerate<I>
298where
299 I: SourceIter,
300{
301 type Source = I::Source;
302
303 #[inline]
304 unsafe fn as_inner(&mut self) -> &mut I::Source {
305 unsafe { SourceIter::as_inner(&mut self.iter) }
307 }
308}
309
310#[unstable(issue = "none", feature = "inplace_iteration")]
311unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {
312 const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
313 const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
314}
315
316#[stable(feature = "default_iters", since = "1.70.0")]
317impl<I: Default> Default for Enumerate<I> {
318 fn default() -> Self {
326 Enumerate::new(Default::default())
327 }
328}