Add iteration support to SparseMap.

This is simply the slice iterator for the dense vector.

- map.values() returns an iterator with references to the values.
- for i in &map iterates over references to the values.
This commit is contained in:
Jakob Stoklund Olesen
2017-01-10 13:51:20 -08:00
parent 56177ce351
commit a26a8b5f0d

View File

@@ -37,6 +37,7 @@
use entity_map::{EntityRef, EntityMap}; use entity_map::{EntityRef, EntityMap};
use std::mem; use std::mem;
use std::slice;
use std::u32; use std::u32;
/// Trait for extracting keys from values stored in a `SparseMap`. /// Trait for extracting keys from values stored in a `SparseMap`.
@@ -163,6 +164,28 @@ impl<K, V> SparseMap<K, V>
// Nothing to remove. // Nothing to remove.
None None
} }
/// Get an iterator over the values in the map.
///
/// The iteration order is entirely determined by the preceding sequence of `insert` and
/// `remove` operations. In particular, if no elements were removed, this is the insertion
/// order.
pub fn values(&self) -> slice::Iter<V> {
self.dense.iter()
}
}
/// Iterating over the elements of a set.
impl<'a, K, V> IntoIterator for &'a SparseMap<K, V>
where K: EntityRef,
V: SparseMapValue<K>
{
type Item = &'a V;
type IntoIter = slice::Iter<'a, V>;
fn into_iter(self) -> Self::IntoIter {
self.values()
}
} }
/// Any `EntityRef` can be used as a sparse map value representing itself. /// Any `EntityRef` can be used as a sparse map value representing itself.
@@ -203,6 +226,7 @@ mod tests {
assert!(map.is_empty()); assert!(map.is_empty());
assert_eq!(map.len(), 0); assert_eq!(map.len(), 0);
assert_eq!(map.get(i1), None); assert_eq!(map.get(i1), None);
assert_eq!(map.values().count(), 0);
} }
#[test] #[test]
@@ -251,6 +275,10 @@ mod tests {
assert_eq!(map.insert(Obj(i1, "bar")), None); assert_eq!(map.insert(Obj(i1, "bar")), None);
assert_eq!(map.insert(Obj(i0, "baz")), None); assert_eq!(map.insert(Obj(i0, "baz")), None);
// Iteration order = insertion order when nothing has been removed yet.
assert_eq!(map.values().map(|obj| obj.1).collect::<Vec<_>>(),
["foo", "bar", "baz"]);
assert_eq!(map.len(), 3); assert_eq!(map.len(), 3);
assert_eq!(map.get(i0), Some(&Obj(i0, "baz"))); assert_eq!(map.get(i0), Some(&Obj(i0, "baz")));
assert_eq!(map.get(i1), Some(&Obj(i1, "bar"))); assert_eq!(map.get(i1), Some(&Obj(i1, "bar")));
@@ -280,6 +308,13 @@ mod tests {
assert_eq!(map.get(i1), Some(&Obj(i1, "barbar"))); assert_eq!(map.get(i1), Some(&Obj(i1, "barbar")));
assert_eq!(map.get(i2), Some(&Obj(i2, "foo"))); assert_eq!(map.get(i2), Some(&Obj(i2, "foo")));
assert_eq!(map.get(i3), None); assert_eq!(map.get(i3), None);
// Check the reference `IntoIter` impl.
let mut v = Vec::new();
for i in &map {
v.push(i.1);
}
assert_eq!(v.len(), map.len());
} }
#[test] #[test]