rust-lang/rust · #165132
Implement `advance_back_by` on `Fuse`
library/core/src/iter/adapters/fuse.rs41 + / 0 −
@@ -138,6 +138,11 @@ where FuseImpl::next_back(self) } + #[inline]+ fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {+ FuseImpl::advance_back_by(self, n)+ }+ #[inline] fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> { FuseImpl::nth_back(self, n)@@ -277,6 +282,9 @@ trait FuseImpl<I> { // Functions specific to DoubleEndedIterators fn next_back(&mut self) -> Option<Self::Item>+ where+ I: DoubleEndedIterator;+ fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> where I: DoubleEndedIterator; fn nth_back(&mut self, n: usize) -> Option<Self::Item>@@ -358,6 +366,25 @@ where and_then_or_clear(&mut self.iter, |iter| iter.next_back()) } + #[inline]+ default fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>+ where+ I: DoubleEndedIterator,+ {+ let Some(iter) = &mut self.iter else {+ return match NonZero::new(n) {+ Some(n) => Err(n),+ None => Ok(()),+ };+ };++ let res = iter.advance_back_by(n);+ if res.is_err() {+ self.iter = None;+ }+ res+ }+ #[inline] default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> where@@ -448,6 +475,20 @@ where self.iter.as_mut()?.next_back() } + #[inline]+ fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>+ where+ I: DoubleEndedIterator,+ {+ match &mut self.iter {+ Some(iter) => iter.advance_back_by(n),+ None => match NonZero::new(n) {+ Some(n) => Err(n),+ None => Ok(()),+ },+ }+ }+ #[inline] fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> wherelibrary/coretests/tests/iter/adapters/fuse.rs67 + / 5 −
@@ -1,9 +1,9 @@ use core::iter::*; #[test]-fn test_fuse_nth() {+fn test_fuse_fused_nth() { let xs = [0, 1, 2];- let mut it = xs.iter();+ let mut it = xs.iter().fuse(); assert_eq!(it.len(), 3); assert_eq!(it.nth(2), Some(&2));@@ -12,10 +12,72 @@ fn test_fuse_nth() { assert_eq!(it.len(), 0); } +#[test]+fn test_fuse_fused_nth_back() {+ let xs = [0, 1, 2];+ let mut it = xs.iter().fuse();++ assert_eq!(it.len(), 3);+ assert_eq!(it.nth_back(2), Some(&0));+ assert_eq!(it.len(), 0);+ assert_eq!(it.nth_back(2), None);+ assert_eq!(it.len(), 0);+}++#[test]+fn test_fuse_fused_advance() {+ let xs = [0, 1, 2, 3];+ let mut it = xs.iter().fuse();++ assert_eq!(it.len(), 4);+ assert_eq!(it.advance_by(2), Ok(()));+ assert_eq!(it.next(), Some(&2));+ assert_eq!(it.len(), 1);+ assert_eq!(it.advance_by(2).map_err(|it| it.get()), Err(1));+ assert_eq!(it.next(), None);+ assert_eq!(it.len(), 0);+}++#[test]+fn test_fuse_fused_advance_back() {+ let xs = [0, 1, 2, 3];+ let mut it = xs.iter().fuse();++ assert_eq!(it.len(), 4);+ assert_eq!(it.advance_back_by(2), Ok(()));+ assert_eq!(it.next_back(), Some(&1));+ assert_eq!(it.len(), 1);+ assert_eq!(it.advance_back_by(2).map_err(|it| it.get()), Err(1));+ assert_eq!(it.next(), None);+ assert_eq!(it.len(), 0);+}++#[test]+fn test_fuse_unfused_nth() {+ let mut xs = [0, 1, 2].into_iter().map(Some).chain([None]).chain([3, 4, 5].map(Some));+ let mut it = core::iter::from_fn(|| xs.next().flatten()).fuse();++ assert_eq!(it.nth(1), Some(1));+ assert_eq!(it.nth(1), None);+ assert_eq!(xs.next(), Some(Some(3)));+}++#[test]+fn test_fuse_unfused_advance() {+ let mut xs = [0, 1, 2].into_iter().map(Some).chain([None]).chain([3, 4, 5].map(Some));+ let mut it = core::iter::from_fn(|| xs.next().flatten()).fuse();++ assert_eq!(it.advance_by(1), Ok(()));+ assert_eq!(it.next(), Some(1));+ assert_eq!(it.advance_by(2).map_err(|it| it.get()), Err(1));+ assert_eq!(it.next(), None);+ assert_eq!(xs.next(), Some(Some(3)));+}+ #[test] fn test_fuse_last() { let xs = [0, 1, 2];- let it = xs.iter();+ let it = xs.iter().fuse(); assert_eq!(it.len(), 3); assert_eq!(it.last(), Some(&2));@@ -24,7 +86,7 @@ fn test_fuse_last() { #[test] fn test_fuse_count() { let xs = [0, 1, 2];- let it = xs.iter();+ let it = xs.iter().fuse(); assert_eq!(it.len(), 3); assert_eq!(it.count(), 3);@@ -58,7 +120,7 @@ fn test_fuse_fold() { #[test] fn test_fuse() {- let mut it = 0..3;+ let mut it = (0..3).fuse(); assert_eq!(it.len(), 3); assert_eq!(it.next(), Some(0)); assert_eq!(it.len(), 2);