Skip to content

Commit 2e278fa

Browse files
Merge pull request #20 from LukasKalbertodt/iter-opt
Implement `size_hint` and `ExactSizeIterator` for all three iterators
2 parents 77d5005 + c3df049 commit 2e278fa

4 files changed

Lines changed: 87 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
66

77
## [Unreleased]
88

9+
## [0.2.2] - 2019-01-07
10+
### Added
11+
- All three iterators implement `Iterator::size_hint` and `ExactSizeIterator`
12+
now and report the correct length.
13+
914
## [0.2.1] - 2018-09-26
1015
### Added
1116
- `StableVec::insert_into_hole()`
@@ -65,7 +70,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6570
- Everything.
6671

6772

68-
[Unreleased]: https://github.com/LukasKalbertodt/stable-vec/compare/v0.2.1...HEAD
73+
[Unreleased]: https://github.com/LukasKalbertodt/stable-vec/compare/v0.2.2...HEAD
74+
[0.2.2]: https://github.com/LukasKalbertodt/stable-vec/compare/v0.2.1...v0.2.2
6975
[0.2.1]: https://github.com/LukasKalbertodt/stable-vec/compare/v0.2.0...v0.2.1
7076
[0.2.0]: https://github.com/LukasKalbertodt/stable-vec/compare/v0.1.2...v0.2.0
7177
[0.1.2]: https://github.com/LukasKalbertodt/stable-vec/compare/v0.1.1...v0.1.2

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "stable-vec"
3-
version = "0.2.1"
3+
version = "0.2.2"
44
authors = ["Lukas Kalbertodt <lukas.kalbertodt@gmail.com>"]
55

66
description = """

src/lib.rs

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ impl<T> StableVec<T> {
731731
/// }
732732
/// ```
733733
pub fn iter(&self) -> Iter<T> {
734-
Iter { sv: self, pos: 0 }
734+
Iter { sv: self, pos: 0, count: self.used_count }
735735
}
736736

737737
/// Returns an iterator over mutable references to the existing elements
@@ -781,6 +781,7 @@ impl<T> StableVec<T> {
781781
pub fn iter_mut(&mut self) -> IterMut<T> {
782782
IterMut {
783783
deleted: &mut self.deleted,
784+
count: self.used_count,
784785
used_count: &mut self.used_count,
785786
vec_iter: self.data.iter_mut(),
786787
pos: 0,
@@ -817,6 +818,7 @@ impl<T> StableVec<T> {
817818
Keys {
818819
deleted: &self.deleted,
819820
pos: 0,
821+
count: self.used_count,
820822
}
821823
}
822824

@@ -884,8 +886,8 @@ impl<T> StableVec<T> {
884886

885887
/// Retains only the elements specified by the given predicate.
886888
///
887-
/// Each element `e` for which `predicate(&e)` returns `false` is removed
888-
/// from the stable vector.
889+
/// Each element `e` for which `should_be_kept(&e)` returns `false` is
890+
/// removed from the stable vector.
889891
///
890892
/// # Example
891893
///
@@ -896,14 +898,15 @@ impl<T> StableVec<T> {
896898
///
897899
/// assert_eq!(sv, &[2, 4] as &[_]);
898900
/// ```
899-
pub fn retain<P>(&mut self, mut predicate: P)
901+
pub fn retain<P>(&mut self, mut should_be_kept: P)
900902
where
901903
P: FnMut(&T) -> bool,
902904
{
903-
let mut it = self.iter_mut();
904-
while let Some(e) = it.next() {
905-
if !predicate(e) {
906-
it.remove_current();
905+
let mut pos = 0;
906+
907+
while let Some(idx) = next_valid_index(&mut pos, &self.deleted) {
908+
if !should_be_kept(&self[idx]) {
909+
self.remove(idx);
907910
}
908911
}
909912
}
@@ -1068,16 +1071,28 @@ impl<'a, T> IntoIterator for &'a mut StableVec<T> {
10681071
pub struct Iter<'a, T: 'a> {
10691072
sv: &'a StableVec<T>,
10701073
pos: usize,
1074+
count: usize,
10711075
}
10721076

10731077
impl<'a, T: 'a> Iterator for Iter<'a, T> {
10741078
type Item = &'a T;
10751079
fn next(&mut self) -> Option<Self::Item> {
1076-
next_valid_index(&mut self.pos, &self.sv.deleted)
1077-
.map(|i| &self.sv.data[i])
1080+
let out = next_valid_index(&mut self.pos, &self.sv.deleted)
1081+
.map(|i| &self.sv.data[i]);
1082+
if out.is_some() {
1083+
self.count -= 1;
1084+
}
1085+
1086+
out
1087+
}
1088+
1089+
fn size_hint(&self) -> (usize, Option<usize>) {
1090+
(self.count, Some(self.count))
10781091
}
10791092
}
10801093

1094+
impl<T> ExactSizeIterator for Iter<'_, T> {}
1095+
10811096
/// Iterator over mutable references to the elements of a `StableVec`.
10821097
///
10831098
/// Use the method [`StableVec::iter_mut()`](struct.StableVec.html#method.iter_mut)
@@ -1089,6 +1104,7 @@ pub struct IterMut<'a, T: 'a> {
10891104
used_count: &'a mut usize,
10901105
vec_iter: ::std::slice::IterMut<'a, T>,
10911106
pos: usize,
1107+
count: usize,
10921108
}
10931109

10941110
impl<'a, T: 'a> IterMut<'a, T> {
@@ -1124,11 +1140,19 @@ impl<'a, T> Iterator for IterMut<'a, T> {
11241140
} else {
11251141
// Advance the iterator by one and return current element.
11261142
self.pos += 1;
1143+
self.count -= 1;
11271144
self.vec_iter.next()
11281145
}
11291146
}
1147+
1148+
fn size_hint(&self) -> (usize, Option<usize>) {
1149+
(self.count, Some(self.count))
1150+
}
11301151
}
11311152

1153+
impl<T> ExactSizeIterator for IterMut<'_, T> {}
1154+
1155+
11321156
/// Iterator over all valid indices of a `StableVec`.
11331157
///
11341158
/// Use the method [`StableVec::keys()`](struct.StableVec.html#method.keys) to
@@ -1137,15 +1161,27 @@ impl<'a, T> Iterator for IterMut<'a, T> {
11371161
pub struct Keys<'a> {
11381162
deleted: &'a BitVec,
11391163
pos: usize,
1164+
count: usize,
11401165
}
11411166

11421167
impl<'a> Iterator for Keys<'a> {
11431168
type Item = usize;
11441169
fn next(&mut self) -> Option<Self::Item> {
1145-
next_valid_index(&mut self.pos, self.deleted)
1170+
let out = next_valid_index(&mut self.pos, self.deleted);
1171+
if out.is_some() {
1172+
self.count -= 1;
1173+
}
1174+
1175+
out
1176+
}
1177+
1178+
fn size_hint(&self) -> (usize, Option<usize>) {
1179+
(self.count, Some(self.count))
11461180
}
11471181
}
11481182

1183+
impl ExactSizeIterator for Keys<'_> {}
1184+
11491185
/// Advances the index `pos` while it points to a deleted element. Stops
11501186
/// advancing once an existing element is found or the end is reached. In the
11511187
/// former case, this element's index is returned; in the latter case, `None`

src/tests.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,35 @@ fn insert_into_hole_and_grow() {
112112
assert_eq!(sv.num_elements(), 3);
113113
assert_eq!(sv.clone().into_vec(), &['a', 'c', 'd']);
114114
}
115+
116+
#[test]
117+
fn size_hints() {
118+
let mut sv = StableVec::<()>::new();
119+
120+
assert_eq!(sv.iter().size_hint(), (0, Some(0)));
121+
assert_eq!(sv.iter_mut().size_hint(), (0, Some(0)));
122+
assert_eq!(sv.keys().size_hint(), (0, Some(0)));
123+
124+
125+
let mut sv = StableVec::from(&[0, 1, 2, 3, 4]);
126+
sv.remove(1);
127+
128+
macro_rules! check_iter {
129+
($it:expr) => {{
130+
let mut it = $it;
131+
assert_eq!(it.size_hint(), (4, Some(4)));
132+
assert!(it.next().is_some());
133+
assert_eq!(it.size_hint(), (3, Some(3)));
134+
assert!(it.next().is_some());
135+
assert_eq!(it.size_hint(), (2, Some(2)));
136+
assert!(it.next().is_some());
137+
assert_eq!(it.size_hint(), (1, Some(1)));
138+
assert!(it.next().is_some());
139+
assert_eq!(it.size_hint(), (0, Some(0)));
140+
}}
141+
}
142+
143+
check_iter!(sv.iter());
144+
check_iter!(sv.iter_mut());
145+
check_iter!(sv.keys());
146+
}

0 commit comments

Comments
 (0)