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 }