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