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}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy