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"]
18pub struct Enumerate<I> {
19 iter: I,
20 count: usize,
21}
22impl<I> Enumerate<I> {
23 pub(in crate::iter) fn new(iter: I) -> Enumerate<I> {
24 Enumerate { iter, count: 0 }
25 }
26
27 #[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")]
62impl<I> Iterator for Enumerate<I>
63where
64 I: Iterator,
65{
66 type Item = (usize, <I as Iterator>::Item);
67
68 #[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 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")]
175impl<I> DoubleEndedIterator for Enumerate<I>
176where
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 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 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 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 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 self.iter.advance_back_by(n)
246 }
247}
248
249#[stable(feature = "rust1", since = "1.0.0")]
250impl<I> ExactSizeIterator for Enumerate<I>
251where
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")]
265unsafe impl<I> TrustedRandomAccess for Enumerate<I> where I: TrustedRandomAccess {}
266
267#[doc(hidden)]
268#[unstable(feature = "trusted_random_access", issue = "none")]
269unsafe impl<I> TrustedRandomAccessNoCoerce for Enumerate<I>
270where
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")]
277impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
278
279#[unstable(issue = "none", feature = "trusted_fused")]
280unsafe impl<I: TrustedFused> TrustedFused for Enumerate<I> {}
281
282#[unstable(feature = "trusted_len", issue = "37572")]
283unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
284
285#[unstable(issue = "none", feature = "inplace_iteration")]
286unsafe impl<I> SourceIter for Enumerate<I>
287where
288 I: SourceIter,
289{
290 type Source = I::Source;
291
292 #[inline]
293 unsafe fn as_inner(&mut self) -> &mut I::Source {
294 unsafe { SourceIter::as_inner(&mut self.iter) }
296 }
297}
298
299#[unstable(issue = "none", feature = "inplace_iteration")]
300unsafe 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")]
306impl<I: Default> Default for Enumerate<I> {
307 fn default() -> Self {
315 Enumerate::new(Default::default())
316 }
317}