calc_rational

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

lending_iterator.rs (2591B)


      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> = T::Item where Self: 'a;
     81     #[inline]
     82     fn lend_next(&mut self) -> Option<Self::Item<'_>> {
     83         self.next()
     84     }
     85     #[inline]
     86     fn size_hint(&self) -> (usize, Option<usize>) {
     87         self.size_hint()
     88     }
     89     #[inline]
     90     fn count(self) -> usize
     91     where
     92         Self: Sized,
     93     {
     94         self.count()
     95     }
     96     #[inline]
     97     fn advance_by(&mut self, n: usize) -> Result<(), usize> {
     98         for i in 0..n {
     99             self.lend_next().ok_or(i)?;
    100         }
    101         Ok(())
    102     }
    103     #[inline]
    104     fn by_ref(&mut self) -> &mut Self
    105     where
    106         Self: Sized,
    107     {
    108         self
    109     }
    110     // Due to a bug in GATs, fold and try_fold cannot be
    111     // implemented.
    112 }