core/iter/adapters/
enumerate.rs

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/// An iterator that yields the current count and the element during iteration.
8///
9/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
10/// documentation for more.
11///
12/// [`enumerate`]: Iterator::enumerate
13/// [`Iterator`]: trait.Iterator.html
14#[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    /// Retrieve the current position of the iterator.
28    ///
29    /// If the iterator has not advanced, the position returned will be 0.
30    ///
31    /// The position may also exceed the bounds of the iterator to allow for calculating
32    /// the displacement of the iterator from following calls to [`Iterator::next`].
33    ///
34    /// # Examples
35    ///
36    /// ```
37    /// #![feature(next_index)]
38    ///
39    /// let arr = ['a', 'b'];
40    ///
41    /// let mut iter = arr.iter().enumerate();
42    ///
43    /// assert_eq!(iter.next_index(), 0);
44    /// assert_eq!(iter.next(), Some((0, &'a')));
45    ///
46    /// assert_eq!(iter.next_index(), 1);
47    /// assert_eq!(iter.next_index(), 1);
48    /// assert_eq!(iter.next(), Some((1, &'b')));
49    ///
50    /// assert_eq!(iter.next_index(), 2);
51    /// assert_eq!(iter.next(), None);
52    /// assert_eq!(iter.next_index(), 2);
53    /// ```
54    #[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    /// # Overflow Behavior
69    ///
70    /// The method does no guarding against overflows, so enumerating more than
71    /// `usize::MAX` elements either produces the wrong result or panics. If
72    /// overflow checks are enabled, a panic is guaranteed.
73    ///
74    /// # Panics
75    ///
76    /// Might panic if the index of the element overflows a `usize`.
77    #[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        // SAFETY: the caller must uphold the contract for
168        // `Iterator::__iterator_get_unchecked`.
169        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        // Can safely add, `ExactSizeIterator` promises that the number of
184        // elements fits into a `usize`.
185        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        // Can safely add, `ExactSizeIterator` promises that the number of
193        // elements fits into a `usize`.
194        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        // Can safely add and subtract the count, as `ExactSizeIterator` promises
205        // that the number of elements fits into a `usize`.
206        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        // Can safely add and subtract the count, as `ExactSizeIterator` promises
226        // that the number of elements fits into a `usize`.
227        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        // we do not need to update the count since that only tallies the number of items
244        // consumed from the front. consuming items from the back can never reduce that.
245        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        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
295        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    /// Creates an `Enumerate` iterator from the default value of `I`
308    /// ```
309    /// # use core::slice;
310    /// # use std::iter::Enumerate;
311    /// let iter: Enumerate<slice::Iter<'_, u8>> = Default::default();
312    /// assert_eq!(iter.len(), 0);
313    /// ```
314    fn default() -> Self {
315        Enumerate::new(Default::default())
316    }
317}