1 use crate::iter::adapters::{zip::try_get_unchecked, SourceIter, TrustedRandomAccess};
2 use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
3 use crate::ops::{Add, AddAssign, Try};
5 /// An iterator that yields the current count and the element during iteration.
7 /// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
8 /// documentation for more.
10 /// [`enumerate`]: Iterator::enumerate
11 /// [`Iterator`]: trait.Iterator.html
12 #[derive(Clone, Debug)]
13 #[must_use = "iterators are lazy and do nothing unless consumed"]
14 #[stable(feature = "rust1", since = "1.0.0")]
15 pub struct Enumerate<I> {
19 impl<I> Enumerate<I> {
20 pub(in crate::iter) fn new(iter: I) -> Enumerate<I> {
21 Enumerate { iter, count: 0 }
25 #[stable(feature = "rust1", since = "1.0.0")]
26 impl<I> Iterator for Enumerate<I>
30 type Item = (usize, <I as Iterator>::Item);
32 /// # Overflow Behavior
34 /// The method does no guarding against overflows, so enumerating more than
35 /// `usize::MAX` elements either produces the wrong result or panics. If
36 /// debug assertions are enabled, a panic is guaranteed.
40 /// Might panic if the index of the element overflows a `usize`.
42 fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
43 let a = self.iter.next()?;
45 // Possible undefined overflow.
46 AddAssign::add_assign(&mut self.count, 1);
51 fn size_hint(&self) -> (usize, Option<usize>) {
56 fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> {
57 let a = self.iter.nth(n)?;
58 // Possible undefined overflow.
59 let i = Add::add(self.count, n);
60 self.count = Add::add(i, 1);
65 fn count(self) -> usize {
70 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
73 Fold: FnMut(Acc, Self::Item) -> R,
77 fn enumerate<'a, T, Acc, R>(
79 mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
80 ) -> impl FnMut(Acc, T) -> R + 'a {
82 let acc = fold(acc, (*count, item));
83 // Possible undefined overflow.
84 AddAssign::add_assign(count, 1);
89 self.iter.try_fold(init, enumerate(&mut self.count, fold))
93 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
95 Fold: FnMut(Acc, Self::Item) -> Acc,
100 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
101 ) -> impl FnMut(Acc, T) -> Acc {
103 let acc = fold(acc, (count, item));
104 // Possible undefined overflow.
105 AddAssign::add_assign(&mut count, 1);
110 self.iter.fold(init, enumerate(self.count, fold))
113 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
115 Self: TrustedRandomAccess,
117 // SAFETY: the caller must uphold the contract for
118 // `Iterator::__iterator_get_unchecked`.
119 let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
120 (Add::add(self.count, idx), value)
124 #[stable(feature = "rust1", since = "1.0.0")]
125 impl<I> DoubleEndedIterator for Enumerate<I>
127 I: ExactSizeIterator + DoubleEndedIterator,
130 fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
131 let a = self.iter.next_back()?;
132 let len = self.iter.len();
133 // Can safely add, `ExactSizeIterator` promises that the number of
134 // elements fits into a `usize`.
135 Some((self.count + len, a))
139 fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
140 let a = self.iter.nth_back(n)?;
141 let len = self.iter.len();
142 // Can safely add, `ExactSizeIterator` promises that the number of
143 // elements fits into a `usize`.
144 Some((self.count + len, a))
148 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
151 Fold: FnMut(Acc, Self::Item) -> R,
154 // Can safely add and subtract the count, as `ExactSizeIterator` promises
155 // that the number of elements fits into a `usize`.
156 fn enumerate<T, Acc, R>(
158 mut fold: impl FnMut(Acc, (usize, T)) -> R,
159 ) -> impl FnMut(Acc, T) -> R {
162 fold(acc, (count, item))
166 let count = self.count + self.iter.len();
167 self.iter.try_rfold(init, enumerate(count, fold))
171 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
173 Fold: FnMut(Acc, Self::Item) -> Acc,
175 // Can safely add and subtract the count, as `ExactSizeIterator` promises
176 // that the number of elements fits into a `usize`.
177 fn enumerate<T, Acc>(
179 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
180 ) -> impl FnMut(Acc, T) -> Acc {
183 fold(acc, (count, item))
187 let count = self.count + self.iter.len();
188 self.iter.rfold(init, enumerate(count, fold))
192 #[stable(feature = "rust1", since = "1.0.0")]
193 impl<I> ExactSizeIterator for Enumerate<I>
195 I: ExactSizeIterator,
197 fn len(&self) -> usize {
201 fn is_empty(&self) -> bool {
207 #[unstable(feature = "trusted_random_access", issue = "none")]
208 unsafe impl<I> TrustedRandomAccess for Enumerate<I>
210 I: TrustedRandomAccess,
212 fn may_have_side_effect() -> bool {
213 I::may_have_side_effect()
217 #[stable(feature = "fused", since = "1.26.0")]
218 impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
220 #[unstable(feature = "trusted_len", issue = "37572")]
221 unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
223 #[unstable(issue = "none", feature = "inplace_iteration")]
224 unsafe impl<S: Iterator, I: Iterator> SourceIter for Enumerate<I>
226 I: SourceIter<Source = S>,
231 unsafe fn as_inner(&mut self) -> &mut S {
232 // SAFETY: unsafe function forwarding to unsafe function with the same requirements
233 unsafe { SourceIter::as_inner(&mut self.iter) }
237 #[unstable(issue = "none", feature = "inplace_iteration")]
238 unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {}