@@ -647,7 +647,6 @@ impl<'py> BoundListIterator<'py> {
647
647
}
648
648
}
649
649
650
- #[ cfg( not( Py_LIMITED_API ) ) ]
651
650
fn with_critical_section < R > (
652
651
& mut self ,
653
652
f : impl FnOnce ( & mut Index , & mut Length , & Bound < ' py , PyList > ) -> R ,
@@ -819,25 +818,12 @@ impl<'py> Iterator for BoundListIterator<'py> {
819
818
#[ cfg( feature = "nightly" ) ]
820
819
fn advance_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > {
821
820
self . with_critical_section ( |index, length, list| {
822
- let max_len = length. 0 . min ( list. len ( ) ) ;
823
- let currently_at = index. 0 ;
824
- if currently_at >= max_len {
825
- if n == 0 {
826
- return Ok ( ( ) ) ;
827
- } else {
828
- return Err ( unsafe { NonZero :: new_unchecked ( n) } ) ;
821
+ for i in 0 ..n {
822
+ if unsafe { Self :: next_unchecked ( index, length, list) . is_none ( ) } {
823
+ return Err ( unsafe { NonZero :: new_unchecked ( n - i) } ) ;
829
824
}
830
825
}
831
-
832
- let items_left = max_len - currently_at;
833
- if n <= items_left {
834
- index. 0 += n;
835
- Ok ( ( ) )
836
- } else {
837
- index. 0 = max_len;
838
- let remainder = n - items_left;
839
- Err ( unsafe { NonZero :: new_unchecked ( remainder) } )
840
- }
826
+ Ok ( ( ) )
841
827
} )
842
828
}
843
829
}
@@ -900,6 +886,19 @@ impl DoubleEndedIterator for BoundListIterator<'_> {
900
886
R :: from_output ( accum)
901
887
} )
902
888
}
889
+
890
+ #[ inline]
891
+ #[ cfg( feature = "nightly" ) ]
892
+ fn advance_back_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > {
893
+ self . with_critical_section ( |index, length, list| {
894
+ for i in 0 ..n {
895
+ if unsafe { Self :: next_back_unchecked ( index, length, list) . is_none ( ) } {
896
+ return Err ( unsafe { NonZero :: new_unchecked ( n - i) } ) ;
897
+ }
898
+ }
899
+ Ok ( ( ) )
900
+ } )
901
+ }
903
902
}
904
903
905
904
impl ExactSizeIterator for BoundListIterator < ' _ > {
@@ -1638,7 +1637,8 @@ mod tests {
1638
1637
assert_eq ! ( iter. next( ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) , 10 ) ;
1639
1638
1640
1639
let mut iter = list. iter ( ) ;
1641
- iter. nth_back ( 1 ) ;
1640
+ println ! ( "iter.nth_back(1) = {:?}" , iter. nth_back( 1 ) ) ;
1641
+ // assert_eq!(iter.nth_back(1).unwrap().extract::<i32>().unwrap(), 9);
1642
1642
assert_eq ! ( iter. nth( 2 ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) , 8 ) ;
1643
1643
assert ! ( iter. next( ) . is_none( ) ) ;
1644
1644
} ) ;
@@ -1726,4 +1726,30 @@ mod tests {
1726
1726
assert_eq ! ( iter4. next( ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) , 1 ) ;
1727
1727
} )
1728
1728
}
1729
+
1730
+ #[ cfg( feature = "nightly" ) ]
1731
+ #[ test]
1732
+ fn test_iter_advance_back_by ( ) {
1733
+ Python :: with_gil ( |py| {
1734
+ let v = vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
1735
+ let ob = ( & v) . into_pyobject ( py) . unwrap ( ) ;
1736
+ let list = ob. downcast :: < PyList > ( ) . unwrap ( ) ;
1737
+
1738
+ let mut iter = list. iter ( ) ;
1739
+ assert_eq ! ( iter. advance_back_by( 2 ) , Ok ( ( ) ) ) ;
1740
+ assert_eq ! ( iter. next_back( ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) , 3 ) ;
1741
+ assert_eq ! ( iter. advance_back_by( 0 ) , Ok ( ( ) ) ) ;
1742
+ assert_eq ! ( iter. advance_back_by( 100 ) , Err ( NonZero :: new( 98 ) . unwrap( ) ) ) ;
1743
+
1744
+ let mut iter2 = list. iter ( ) ;
1745
+ assert_eq ! ( iter2. advance_back_by( 6 ) , Err ( NonZero :: new( 1 ) . unwrap( ) ) ) ;
1746
+
1747
+ let mut iter3 = list. iter ( ) ;
1748
+ assert_eq ! ( iter3. advance_back_by( 5 ) , Ok ( ( ) ) ) ;
1749
+
1750
+ let mut iter4 = list. iter ( ) ;
1751
+ assert_eq ! ( iter4. advance_back_by( 0 ) , Ok ( ( ) ) ) ;
1752
+ assert_eq ! ( iter4. next_back( ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) , 5 ) ;
1753
+ } )
1754
+ }
1729
1755
}
0 commit comments