1 use crate::iter::adapters::{
2 zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
4 use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
7 /// An iterator that yields the current count and the element during iteration.
9 /// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
10 /// documentation for more.
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 pub struct Enumerate<I> {
21 impl<I> Enumerate<I> {
22 pub(in crate::iter) fn new(iter: I) -> Enumerate<I> {
23 Enumerate { iter, count: 0 }
27 #[stable(feature = "rust1", since = "1.0.0")]
28 impl<I> Iterator for Enumerate<I>
32 type Item = (usize, <I as Iterator>::Item);
34 /// # Overflow Behavior
36 /// The method does no guarding against overflows, so enumerating more than
37 /// `usize::MAX` elements either produces the wrong result or panics. If
38 /// debug assertions are enabled, a panic is guaranteed.
42 /// Might panic if the index of the element overflows a `usize`.
44 #[rustc_inherit_overflow_checks]
45 fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
46 let a = self.iter.next()?;
53 fn size_hint(&self) -> (usize, Option<usize>) {
58 #[rustc_inherit_overflow_checks]
59 fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> {
60 let a = self.iter.nth(n)?;
61 let i = self.count + n;
67 fn count(self) -> usize {
72 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
75 Fold: FnMut(Acc, Self::Item) -> R,
79 fn enumerate<'a, T, Acc, R>(
81 mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
82 ) -> impl FnMut(Acc, T) -> R + 'a {
83 #[rustc_inherit_overflow_checks]
85 let acc = fold(acc, (*count, item));
91 self.iter.try_fold(init, enumerate(&mut self.count, fold))
95 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
97 Fold: FnMut(Acc, Self::Item) -> Acc,
100 fn enumerate<T, Acc>(
102 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
103 ) -> impl FnMut(Acc, T) -> Acc {
104 #[rustc_inherit_overflow_checks]
106 let acc = fold(acc, (count, item));
112 self.iter.fold(init, enumerate(self.count, fold))
116 #[rustc_inherit_overflow_checks]
117 fn advance_by(&mut self, n: usize) -> Result<(), usize> {
118 match self.iter.advance_by(n) {
123 ret @ Err(advanced) => {
124 self.count += advanced;
130 #[rustc_inherit_overflow_checks]
132 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
134 Self: TrustedRandomAccessNoCoerce,
136 // SAFETY: the caller must uphold the contract for
137 // `Iterator::__iterator_get_unchecked`.
138 let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
139 (self.count + idx, value)
143 #[stable(feature = "rust1", since = "1.0.0")]
144 impl<I> DoubleEndedIterator for Enumerate<I>
146 I: ExactSizeIterator + DoubleEndedIterator,
149 fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
150 let a = self.iter.next_back()?;
151 let len = self.iter.len();
152 // Can safely add, `ExactSizeIterator` promises that the number of
153 // elements fits into a `usize`.
154 Some((self.count + len, a))
158 fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
159 let a = self.iter.nth_back(n)?;
160 let len = self.iter.len();
161 // Can safely add, `ExactSizeIterator` promises that the number of
162 // elements fits into a `usize`.
163 Some((self.count + len, a))
167 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
170 Fold: FnMut(Acc, Self::Item) -> R,
171 R: Try<Output = Acc>,
173 // Can safely add and subtract the count, as `ExactSizeIterator` promises
174 // that the number of elements fits into a `usize`.
175 fn enumerate<T, Acc, R>(
177 mut fold: impl FnMut(Acc, (usize, T)) -> R,
178 ) -> impl FnMut(Acc, T) -> R {
181 fold(acc, (count, item))
185 let count = self.count + self.iter.len();
186 self.iter.try_rfold(init, enumerate(count, fold))
190 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
192 Fold: FnMut(Acc, Self::Item) -> Acc,
194 // Can safely add and subtract the count, as `ExactSizeIterator` promises
195 // that the number of elements fits into a `usize`.
196 fn enumerate<T, Acc>(
198 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
199 ) -> impl FnMut(Acc, T) -> Acc {
202 fold(acc, (count, item))
206 let count = self.count + self.iter.len();
207 self.iter.rfold(init, enumerate(count, fold))
211 fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
212 // we do not need to update the count since that only tallies the number of items
213 // consumed from the front. consuming items from the back can never reduce that.
214 self.iter.advance_back_by(n)
218 #[stable(feature = "rust1", since = "1.0.0")]
219 impl<I> ExactSizeIterator for Enumerate<I>
221 I: ExactSizeIterator,
223 fn len(&self) -> usize {
227 fn is_empty(&self) -> bool {
233 #[unstable(feature = "trusted_random_access", issue = "none")]
234 unsafe impl<I> TrustedRandomAccess for Enumerate<I> where I: TrustedRandomAccess {}
237 #[unstable(feature = "trusted_random_access", issue = "none")]
238 unsafe impl<I> TrustedRandomAccessNoCoerce for Enumerate<I>
240 I: TrustedRandomAccessNoCoerce,
242 const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
245 #[stable(feature = "fused", since = "1.26.0")]
246 impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
248 #[unstable(feature = "trusted_len", issue = "37572")]
249 unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
251 #[unstable(issue = "none", feature = "inplace_iteration")]
252 unsafe impl<I> SourceIter for Enumerate<I>
256 type Source = I::Source;
259 unsafe fn as_inner(&mut self) -> &mut I::Source {
260 // SAFETY: unsafe function forwarding to unsafe function with the same requirements
261 unsafe { SourceIter::as_inner(&mut self.iter) }
265 #[unstable(issue = "none", feature = "inplace_iteration")]
266 unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {}