Skip to content

Commit 00e4802

Browse files
committed
Impl advance_back_by. Remove cfg flag for with_critical_section
1 parent cae0981 commit 00e4802

File tree

1 file changed

+45
-19
lines changed

1 file changed

+45
-19
lines changed

src/types/list.rs

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,6 @@ impl<'py> BoundListIterator<'py> {
647647
}
648648
}
649649

650-
#[cfg(not(Py_LIMITED_API))]
651650
fn with_critical_section<R>(
652651
&mut self,
653652
f: impl FnOnce(&mut Index, &mut Length, &Bound<'py, PyList>) -> R,
@@ -819,25 +818,12 @@ impl<'py> Iterator for BoundListIterator<'py> {
819818
#[cfg(feature = "nightly")]
820819
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
821820
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) });
829824
}
830825
}
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(())
841827
})
842828
}
843829
}
@@ -900,6 +886,19 @@ impl DoubleEndedIterator for BoundListIterator<'_> {
900886
R::from_output(accum)
901887
})
902888
}
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+
}
903902
}
904903

905904
impl ExactSizeIterator for BoundListIterator<'_> {
@@ -1638,7 +1637,8 @@ mod tests {
16381637
assert_eq!(iter.next().unwrap().extract::<i32>().unwrap(), 10);
16391638

16401639
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);
16421642
assert_eq!(iter.nth(2).unwrap().extract::<i32>().unwrap(), 8);
16431643
assert!(iter.next().is_none());
16441644
});
@@ -1726,4 +1726,30 @@ mod tests {
17261726
assert_eq!(iter4.next().unwrap().extract::<i32>().unwrap(), 1);
17271727
})
17281728
}
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+
}
17291755
}

0 commit comments

Comments
 (0)