Path: blob/main/crates/polars-utils/src/itertools/enumerate_idx.rs
6940 views
use num_traits::{FromPrimitive, One, Zero};12/// An iterator that yields the current count and the element during iteration.3///4/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its5/// documentation for more.6///7/// [`enumerate`]: Iterator::enumerate8/// [`Iterator`]: trait.Iterator.html9#[derive(Clone, Debug)]10#[must_use = "iterators are lazy and do nothing unless consumed"]11pub struct EnumerateIdx<I, IdxType> {12iter: I,13count: IdxType,14}1516impl<I, IdxType: Zero> EnumerateIdx<I, IdxType> {17pub fn new(iter: I) -> Self {18Self {19iter,20count: IdxType::zero(),21}22}23}2425impl<I, IdxType> Iterator for EnumerateIdx<I, IdxType>26where27I: Iterator,28IdxType: std::ops::Add<Output = IdxType> + FromPrimitive + std::ops::AddAssign + One + Copy,29{30type Item = (IdxType, <I as Iterator>::Item);3132/// # Overflow Behavior33///34/// The method does no guarding against overflows, so enumerating more than35/// `idx::MAX` elements either produces the wrong result or panics. If36/// debug assertions are enabled, a panic is guaranteed.37///38/// # Panics39///40/// Might panic if the index of the element overflows a `idx`.41#[inline]42fn next(&mut self) -> Option<Self::Item> {43let a = self.iter.next()?;44let i = self.count;45self.count += IdxType::one();46Some((i, a))47}4849#[inline]50fn size_hint(&self) -> (usize, Option<usize>) {51self.iter.size_hint()52}5354#[inline]55fn nth(&mut self, n: usize) -> Option<Self::Item> {56let a = self.iter.nth(n)?;57let i = self.count + IdxType::from_usize(n).unwrap();58self.count = i + IdxType::one();59Some((i, a))60}6162#[inline]63fn count(self) -> usize {64self.iter.count()65}66}6768impl<I, IdxType> DoubleEndedIterator for EnumerateIdx<I, IdxType>69where70I: ExactSizeIterator + DoubleEndedIterator,71IdxType: std::ops::Add<Output = IdxType> + FromPrimitive + std::ops::AddAssign + One + Copy,72{73#[inline]74fn next_back(&mut self) -> Option<(IdxType, <I as Iterator>::Item)> {75let a = self.iter.next_back()?;76let len = IdxType::from_usize(self.iter.len()).unwrap();77// Can safely add, `ExactSizeIterator` promises that the number of78// elements fits into a `usize`.79Some((self.count + len, a))80}8182#[inline]83fn nth_back(&mut self, n: usize) -> Option<(IdxType, <I as Iterator>::Item)> {84let a = self.iter.nth_back(n)?;85let len = IdxType::from_usize(self.iter.len()).unwrap();86// Can safely add, `ExactSizeIterator` promises that the number of87// elements fits into a `usize`.88Some((self.count + len, a))89}90}9192impl<I, IdxType> ExactSizeIterator for EnumerateIdx<I, IdxType>93where94I: ExactSizeIterator,95IdxType: std::ops::Add<Output = IdxType> + FromPrimitive + std::ops::AddAssign + One + Copy,96{97fn len(&self) -> usize {98self.iter.len()99}100}101102103