Skip to content

Commit

Permalink
fix: Fix Vec Iter::count() after next_back() (#250)
Browse files Browse the repository at this point in the history
There is a bug in the current implementation that returns the count
until the end of the vector even if some elements have been taken from
the iterator using `next_back()` (see the testcase in the PR).
  • Loading branch information
frankdavid authored Nov 25, 2024
1 parent 2129c23 commit 5fc208d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
9 changes: 4 additions & 5 deletions src/base_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,10 @@ where
}

fn count(self) -> usize {
let n = self.vec.len().saturating_sub(self.range.start);
if n > usize::MAX as u64 {
panic!("The number of items in the vec {n} does not fit into usize");
}
n as usize
min(self.vec.len(), self.range.end)
.saturating_sub(self.range.start)
.try_into()
.expect("Cannot express count as usize")
}

fn nth(&mut self, n: usize) -> Option<T> {
Expand Down
21 changes: 21 additions & 0 deletions src/vec/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,27 @@ fn test_iter() {
assert_eq!(sv.iter().skip(usize::MAX).count(), 0);
}

#[test]
fn test_iter_count() {
let sv = StableVec::<u64, M>::new(M::default()).unwrap();
sv.push(&1).unwrap();
sv.push(&2).unwrap();
sv.push(&3).unwrap();
sv.push(&4).unwrap();
{
let mut iter = sv.iter();
iter.next_back();
assert_eq!(iter.count(), 3);
}
{
let mut iter = sv.iter();
iter.next_back();
sv.pop(); // this pops the element that we iterated through on the previous line
sv.pop();
assert_eq!(iter.count(), 2);
}
}

// A struct with a bugg implementation of storable where the max_size can
// smaller than the serialized size.
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)]
Expand Down

0 comments on commit 5fc208d

Please sign in to comment.