1#[cfg(not(feature = "ferrocene_subset"))]
2use crate::iter::adapters::zip::try_get_unchecked;
3#[cfg(not(feature = "ferrocene_subset"))]
4use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
5#[cfg(not(feature = "ferrocene_subset"))]
6use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused, TrustedLen};
7use crate::num::NonZero;
8use crate::ops::Try;
9
10#[cfg_attr(not(feature = "ferrocene_subset"), 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_subset"))]
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 fn count(self) -> usize {
106 self.iter.count()
107 }
108
109 #[inline]
110 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
111 where
112 Self: Sized,
113 Fold: FnMut(Acc, Self::Item) -> R,
114 R: Try<Output = Acc>,
115 {
116 #[inline]
117 fn enumerate<'a, T, Acc, R>(
118 count: &'a mut usize,
119 mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
120 ) -> impl FnMut(Acc, T) -> R + 'a {
121 #[rustc_inherit_overflow_checks]
122 move |acc, item| {
123 let acc = fold(acc, (*count, item));
124 *count += 1;
125 acc
126 }
127 }
128
129 self.iter.try_fold(init, enumerate(&mut self.count, fold))
130 }
131
132 #[inline]
133 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
134 where
135 Fold: FnMut(Acc, Self::Item) -> Acc,
136 {
137 #[inline]
138 fn enumerate<T, Acc>(
139 mut count: usize,
140 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
141 ) -> impl FnMut(Acc, T) -> Acc {
142 #[rustc_inherit_overflow_checks]
143 move |acc, item| {
144 let acc = fold(acc, (count, item));
145 count += 1;
146 acc
147 }
148 }
149
150 self.iter.fold(init, enumerate(self.count, fold))
151 }
152
153 #[inline]
154 #[rustc_inherit_overflow_checks]
155 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
156 let remaining = self.iter.advance_by(n);
157 let advanced = match remaining {
158 Ok(()) => n,
159 Err(rem) => n - rem.get(),
160 };
161 self.count += advanced;
162 remaining
163 }
164
165 #[rustc_inherit_overflow_checks]
166 #[inline]
167 #[cfg(not(feature = "ferrocene_subset"))]
168 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
169 where
170 Self: TrustedRandomAccessNoCoerce,
171 {
172 let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
175 (self.count + idx, value)
176 }
177}
178
179#[stable(feature = "rust1", since = "1.0.0")]
180#[cfg(not(feature = "ferrocene_subset"))]
181impl<I> DoubleEndedIterator for Enumerate<I>
182where
183 I: ExactSizeIterator + DoubleEndedIterator,
184{
185 #[inline]
186 fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
187 let a = self.iter.next_back()?;
188 let len = self.iter.len();
189 Some((self.count + len, a))
192 }
193
194 #[inline]
195 fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
196 let a = self.iter.nth_back(n)?;
197 let len = self.iter.len();
198 Some((self.count + len, a))
201 }
202
203 #[inline]
204 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
205 where
206 Self: Sized,
207 Fold: FnMut(Acc, Self::Item) -> R,
208 R: Try<Output = Acc>,
209 {
210 fn enumerate<T, Acc, R>(
213 mut count: usize,
214 mut fold: impl FnMut(Acc, (usize, T)) -> R,
215 ) -> impl FnMut(Acc, T) -> R {
216 move |acc, item| {
217 count -= 1;
218 fold(acc, (count, item))
219 }
220 }
221
222 let count = self.count + self.iter.len();
223 self.iter.try_rfold(init, enumerate(count, fold))
224 }
225
226 #[inline]
227 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
228 where
229 Fold: FnMut(Acc, Self::Item) -> Acc,
230 {
231 fn enumerate<T, Acc>(
234 mut count: usize,
235 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
236 ) -> impl FnMut(Acc, T) -> Acc {
237 move |acc, item| {
238 count -= 1;
239 fold(acc, (count, item))
240 }
241 }
242
243 let count = self.count + self.iter.len();
244 self.iter.rfold(init, enumerate(count, fold))
245 }
246
247 #[inline]
248 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
249 self.iter.advance_back_by(n)
252 }
253}
254
255#[stable(feature = "rust1", since = "1.0.0")]
256#[cfg(not(feature = "ferrocene_subset"))]
257impl<I> ExactSizeIterator for Enumerate<I>
258where
259 I: ExactSizeIterator,
260{
261 fn len(&self) -> usize {
262 self.iter.len()
263 }
264
265 fn is_empty(&self) -> bool {
266 self.iter.is_empty()
267 }
268}
269
270#[doc(hidden)]
271#[unstable(feature = "trusted_random_access", issue = "none")]
272#[cfg(not(feature = "ferrocene_subset"))]
273unsafe impl<I> TrustedRandomAccess for Enumerate<I> where I: TrustedRandomAccess {}
274
275#[doc(hidden)]
276#[unstable(feature = "trusted_random_access", issue = "none")]
277#[cfg(not(feature = "ferrocene_subset"))]
278unsafe impl<I> TrustedRandomAccessNoCoerce for Enumerate<I>
279where
280 I: TrustedRandomAccessNoCoerce,
281{
282 const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
283}
284
285#[stable(feature = "fused", since = "1.26.0")]
286#[cfg(not(feature = "ferrocene_subset"))]
287impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
288
289#[unstable(issue = "none", feature = "trusted_fused")]
290#[cfg(not(feature = "ferrocene_subset"))]
291unsafe impl<I: TrustedFused> TrustedFused for Enumerate<I> {}
292
293#[unstable(feature = "trusted_len", issue = "37572")]
294#[cfg(not(feature = "ferrocene_subset"))]
295unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
296
297#[unstable(issue = "none", feature = "inplace_iteration")]
298#[cfg(not(feature = "ferrocene_subset"))]
299unsafe impl<I> SourceIter for Enumerate<I>
300where
301 I: SourceIter,
302{
303 type Source = I::Source;
304
305 #[inline]
306 unsafe fn as_inner(&mut self) -> &mut I::Source {
307 unsafe { SourceIter::as_inner(&mut self.iter) }
309 }
310}
311
312#[unstable(issue = "none", feature = "inplace_iteration")]
313#[cfg(not(feature = "ferrocene_subset"))]
314unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {
315 const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
316 const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
317}
318
319#[stable(feature = "default_iters", since = "1.70.0")]
320#[cfg(not(feature = "ferrocene_subset"))]
321impl<I: Default> Default for Enumerate<I> {
322 fn default() -> Self {
330 Enumerate::new(Default::default())
331 }
332}