diff --git a/cranelift/src/libcretonne/entity_map.rs b/cranelift/src/libcretonne/entity_map.rs index 0a7faccb41..9ce39bec19 100644 --- a/cranelift/src/libcretonne/entity_map.rs +++ b/cranelift/src/libcretonne/entity_map.rs @@ -81,6 +81,15 @@ impl EntityMap pub fn len(&self) -> usize { self.elems.len() } + + /// Iterate over all the keys in this map. + pub fn keys(&self) -> Keys { + Keys { + pos: 0, + len: self.elems.len(), + unused: PhantomData, + } + } } /// Additional methods for value types that implement `Clone` and `Default`. @@ -127,12 +136,37 @@ impl IndexMut for EntityMap } } +/// Iterate over all keys in order. +pub struct Keys + where K: EntityRef +{ + pos: usize, + len: usize, + unused: PhantomData, +} + +impl Iterator for Keys + where K: EntityRef +{ + type Item = K; + + fn next(&mut self) -> Option { + if self.pos < self.len { + let k = K::new(self.pos); + self.pos += 1; + Some(k) + } else { + None + } + } +} + #[cfg(test)] mod tests { use super::*; // EntityRef impl for testing. - #[derive(Clone, Copy, PartialEq, Eq)] + #[derive(Clone, Copy, Debug, PartialEq, Eq)] struct E(u32); impl EntityRef for E { @@ -151,6 +185,9 @@ mod tests { let r2 = E(2); let mut m = EntityMap::new(); + let v: Vec = m.keys().collect(); + assert_eq!(v, []); + assert!(!m.is_valid(r0)); m.ensure(r2); m[r2] = 3; @@ -160,6 +197,9 @@ mod tests { assert_eq!(m[r1], 5); assert_eq!(m[r2], 3); + let v: Vec = m.keys().collect(); + assert_eq!(v, [r0, r1, r2]); + let shared = &m; assert_eq!(shared[r0], 0); assert_eq!(shared[r1], 5);