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