calc_rational

CLI calculator for rational numbers.
git clone https://git.philomathiclife.com/repos/calc_rational
Log | Files | Refs | README

lending_iterator.rs (2670B)


      1 /// Unit tests.
      2 #[cfg(test)]
      3 mod tests;
      4 /// Generalizes [`Iterator`] by allowing one to yield references.
      5 pub trait LendingIterator {
      6     /// Read [`Iterator::Item`].
      7     type Item<'a>
      8     where
      9         Self: 'a;
     10     /// Read [`Iterator::next`].
     11     fn lend_next(&mut self) -> Option<Self::Item<'_>>;
     12     /// Read [`Iterator::size_hint`].
     13     #[inline]
     14     fn size_hint(&self) -> (usize, Option<usize>) {
     15         (0, None)
     16     }
     17     /// Read [`Iterator::count`].
     18     #[expect(
     19         clippy::arithmetic_side_effects,
     20         reason = "must, and overflow is no worry"
     21     )]
     22     #[inline]
     23     fn count(self) -> usize
     24     where
     25         Self: Sized,
     26     {
     27         self.lend_fold(0, |count, _| count + 1)
     28     }
     29     /// Read [`Iterator::advance_by`].
     30     ///
     31     /// # Errors
     32     ///
     33     /// Read [`Iterator::advance_by`].
     34     #[inline]
     35     fn advance_by(&mut self, n: usize) -> Result<(), usize> {
     36         for i in 0..n {
     37             drop(self.lend_next().ok_or(i)?);
     38         }
     39         Ok(())
     40     }
     41     /// Read [`Iterator::by_ref`].
     42     #[inline]
     43     fn by_ref(&mut self) -> &mut Self
     44     where
     45         Self: Sized,
     46     {
     47         self
     48     }
     49     /// Read [`Iterator::try_fold`].
     50     /// # Errors
     51     ///
     52     /// Read [`Iterator::try_fold`].
     53     #[inline]
     54     fn lend_try_fold<B, E, F>(&mut self, init: B, mut f: F) -> Result<B, E>
     55     where
     56         Self: Sized,
     57         F: FnMut(B, Self::Item<'_>) -> Result<B, E>,
     58     {
     59         let mut accum = init;
     60         while let Some(x) = self.lend_next() {
     61             accum = f(accum, x)?;
     62         }
     63         Ok(accum)
     64     }
     65     /// Read [`Iterator::fold`].
     66     #[inline]
     67     fn lend_fold<B, F>(mut self, init: B, mut f: F) -> B
     68     where
     69         Self: Sized,
     70         F: FnMut(B, Self::Item<'_>) -> B,
     71     {
     72         let mut accum = init;
     73         while let Some(x) = self.lend_next() {
     74             accum = f(accum, x);
     75         }
     76         accum
     77     }
     78 }
     79 impl<T> LendingIterator for T
     80 where
     81     T: Iterator,
     82 {
     83     type Item<'a>
     84         = T::Item
     85     where
     86         Self: 'a;
     87     #[inline]
     88     fn lend_next(&mut self) -> Option<Self::Item<'_>> {
     89         self.next()
     90     }
     91     #[inline]
     92     fn size_hint(&self) -> (usize, Option<usize>) {
     93         self.size_hint()
     94     }
     95     #[inline]
     96     fn count(self) -> usize
     97     where
     98         Self: Sized,
     99     {
    100         self.count()
    101     }
    102     #[inline]
    103     fn advance_by(&mut self, n: usize) -> Result<(), usize> {
    104         for i in 0..n {
    105             drop(self.lend_next().ok_or(i)?);
    106         }
    107         Ok(())
    108     }
    109     #[inline]
    110     fn by_ref(&mut self) -> &mut Self
    111     where
    112         Self: Sized,
    113     {
    114         self
    115     }
    116     // Due to a bug in GATs, fold and try_fold cannot be
    117     // implemented.
    118 }