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