3 adapters::{zip::try_get_unchecked, SourceIter, TrustedRandomAccess},
4 FusedIterator, InPlaceIterable, TrustedLen,
6 ops::{Add, AddAssign, Try},
9 /// An iterator that yields the current count and the element during iteration.
11 /// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
12 /// documentation for more.
14 /// [`enumerate`]: Iterator::enumerate
15 /// [`Iterator`]: trait.Iterator.html
16 #[derive(Clone, Debug)]
17 #[must_use = "iterators are lazy and do nothing unless consumed"]
18 #[stable(feature = "rust1", since = "1.0.0")]
19 pub struct Enumerate<I> {
23 impl<I> Enumerate<I> {
24 pub(in crate::iter) fn new(iter: I) -> Enumerate<I> {
25 Enumerate { iter, count: 0 }
29 #[stable(feature = "rust1", since = "1.0.0")]
30 impl<I> Iterator for Enumerate<I>
34 type Item = (usize, <I as Iterator>::Item);
36 /// # Overflow Behavior
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.
44 /// Might panic if the index of the element overflows a `usize`.
46 fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
47 let a = self.iter.next()?;
49 // Possible undefined overflow.
50 AddAssign::add_assign(&mut self.count, 1);
55 fn size_hint(&self) -> (usize, Option<usize>) {
60 fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> {
61 let a = self.iter.nth(n)?;
62 // Possible undefined overflow.
63 let i = Add::add(self.count, n);
64 self.count = Add::add(i, 1);
69 fn count(self) -> usize {
74 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
77 Fold: FnMut(Acc, Self::Item) -> R,
81 fn enumerate<'a, T, Acc, R>(
83 mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a,
84 ) -> impl FnMut(Acc, T) -> R + 'a {
86 let acc = fold(acc, (*count, item));
87 // Possible undefined overflow.
88 AddAssign::add_assign(count, 1);
93 self.iter.try_fold(init, enumerate(&mut self.count, fold))
97 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
99 Fold: FnMut(Acc, Self::Item) -> Acc,
102 fn enumerate<T, Acc>(
104 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
105 ) -> impl FnMut(Acc, T) -> Acc {
107 let acc = fold(acc, (count, item));
108 // Possible undefined overflow.
109 AddAssign::add_assign(&mut count, 1);
114 self.iter.fold(init, enumerate(self.count, fold))
117 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
119 Self: TrustedRandomAccess,
121 // SAFETY: the caller must uphold the contract for
122 // `Iterator::__iterator_get_unchecked`.
123 let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
124 (Add::add(self.count, idx), value)
128 #[stable(feature = "rust1", since = "1.0.0")]
129 impl<I> DoubleEndedIterator for Enumerate<I>
131 I: ExactSizeIterator + DoubleEndedIterator,
134 fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
135 let a = self.iter.next_back()?;
136 let len = self.iter.len();
137 // Can safely add, `ExactSizeIterator` promises that the number of
138 // elements fits into a `usize`.
139 Some((self.count + len, a))
143 fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
144 let a = self.iter.nth_back(n)?;
145 let len = self.iter.len();
146 // Can safely add, `ExactSizeIterator` promises that the number of
147 // elements fits into a `usize`.
148 Some((self.count + len, a))
152 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
155 Fold: FnMut(Acc, Self::Item) -> R,
158 // Can safely add and subtract the count, as `ExactSizeIterator` promises
159 // that the number of elements fits into a `usize`.
160 fn enumerate<T, Acc, R>(
162 mut fold: impl FnMut(Acc, (usize, T)) -> R,
163 ) -> impl FnMut(Acc, T) -> R {
166 fold(acc, (count, item))
170 let count = self.count + self.iter.len();
171 self.iter.try_rfold(init, enumerate(count, fold))
175 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
177 Fold: FnMut(Acc, Self::Item) -> Acc,
179 // Can safely add and subtract the count, as `ExactSizeIterator` promises
180 // that the number of elements fits into a `usize`.
181 fn enumerate<T, Acc>(
183 mut fold: impl FnMut(Acc, (usize, T)) -> Acc,
184 ) -> impl FnMut(Acc, T) -> Acc {
187 fold(acc, (count, item))
191 let count = self.count + self.iter.len();
192 self.iter.rfold(init, enumerate(count, fold))
196 #[stable(feature = "rust1", since = "1.0.0")]
197 impl<I> ExactSizeIterator for Enumerate<I>
199 I: ExactSizeIterator,
201 fn len(&self) -> usize {
205 fn is_empty(&self) -> bool {
211 #[unstable(feature = "trusted_random_access", issue = "none")]
212 unsafe impl<I> TrustedRandomAccess for Enumerate<I>
214 I: TrustedRandomAccess,
216 fn may_have_side_effect() -> bool {
217 I::may_have_side_effect()
221 #[stable(feature = "fused", since = "1.26.0")]
222 impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
224 #[unstable(feature = "trusted_len", issue = "37572")]
225 unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {}
227 #[unstable(issue = "none", feature = "inplace_iteration")]
228 unsafe impl<S: Iterator, I: Iterator> SourceIter for Enumerate<I>
230 I: SourceIter<Source = S>,
235 unsafe fn as_inner(&mut self) -> &mut S {
236 // SAFETY: unsafe function forwarding to unsafe function with the same requirements
237 unsafe { SourceIter::as_inner(&mut self.iter) }
241 #[unstable(issue = "none", feature = "inplace_iteration")]
242 unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {}