calc_rational

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

lending_iterator.rs (2618B)


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