diff --git a/CHANGELOG.md b/CHANGELOG.md index 5237e787..ecba3b5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). subset of ARM targets. See the module level documentation of the `pool` module for details - relax trait requirements on `IndexMap` and `IndexSet`. - export `IndexSet` and `IndexMap` iterator types. +- [breaking-change] export `IndexMapKeys`, `IndexMapValues` and + `IndexMapValuesMut` iterator types. - [breaking-change] this crate now depends on `atomic-polyfill` v1.0.1, meaning that targets that require a polyfill need a `critical-section` **v1.x.x** implementation. diff --git a/src/indexmap.rs b/src/indexmap.rs index c80dd143..e8843db5 100644 --- a/src/indexmap.rs +++ b/src/indexmap.rs @@ -567,8 +567,10 @@ impl IndexMap { /// println!("{}", key); /// } /// ``` - pub fn keys(&self) -> impl Iterator { - self.core.entries.iter().map(|bucket| &bucket.key) + pub fn keys(&self) -> Keys<'_, K, V> { + Keys { + iter: self.core.entries.iter(), + } } /// Return an iterator over the values of the map, in insertion order @@ -585,8 +587,10 @@ impl IndexMap { /// println!("{}", val); /// } /// ``` - pub fn values(&self) -> impl Iterator { - self.core.entries.iter().map(|bucket| &bucket.value) + pub fn values(&self) -> Values<'_, K, V> { + Values { + iter: self.core.entries.iter(), + } } /// Return an iterator over mutable references to the the values of the map, in insertion order @@ -607,8 +611,10 @@ impl IndexMap { /// println!("{}", val); /// } /// ``` - pub fn values_mut(&mut self) -> impl Iterator { - self.core.entries.iter_mut().map(|bucket| &mut bucket.value) + pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { + ValuesMut { + iter: self.core.entries.iter_mut(), + } } /// Return an iterator over the key-value pairs of the map, in insertion order @@ -1163,6 +1169,10 @@ impl<'a, K, V> Clone for Iter<'a, K, V> { } } +/// A mutable iterator over the items of a [`IndexMap`]. +/// +/// This `struct` is created by the [`iter_mut`](IndexMap::iter_mut) method on [`IndexMap`]. See its +/// documentation for more. pub struct IterMut<'a, K, V> { iter: slice::IterMut<'a, Bucket>, } @@ -1177,6 +1187,54 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> { } } +/// An iterator over the keys of a [`IndexMap`]. +/// +/// This `struct` is created by the [`keys`](IndexMap::keys) method on [`IndexMap`]. See its +/// documentation for more. +pub struct Keys<'a, K, V> { + iter: slice::Iter<'a, Bucket>, +} + +impl<'a, K, V> Iterator for Keys<'a, K, V> { + type Item = &'a K; + + fn next(&mut self) -> Option { + self.iter.next().map(|bucket| &bucket.key) + } +} + +/// An iterator over the values of a [`IndexMap`]. +/// +/// This `struct` is created by the [`values`](IndexMap::values) method on [`IndexMap`]. See its +/// documentation for more. +pub struct Values<'a, K, V> { + iter: slice::Iter<'a, Bucket>, +} + +impl<'a, K, V> Iterator for Values<'a, K, V> { + type Item = &'a V; + + fn next(&mut self) -> Option { + self.iter.next().map(|bucket| &bucket.value) + } +} + +/// A mutable iterator over the values of a [`IndexMap`]. +/// +/// This `struct` is created by the [`values_mut`](IndexMap::values_mut) method on [`IndexMap`]. See its +/// documentation for more. +pub struct ValuesMut<'a, K, V> { + iter: slice::IterMut<'a, Bucket>, +} + +impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { + type Item = &'a mut V; + + fn next(&mut self) -> Option { + self.iter.next().map(|bucket| &mut bucket.value) + } +} + fn hash_with(key: &K, build_hasher: &S) -> HashValue where K: ?Sized + Hash, @@ -1468,4 +1526,32 @@ mod tests { assert_eq!(Some((&0, &1)), map.first()); assert_eq!(Some((&1, &2)), map.last()); } + + #[test] + fn keys_iter() { + let map = almost_filled_map(); + for (&key, i) in map.keys().zip(1..MAP_SLOTS) { + assert_eq!(key, i); + } + } + + #[test] + fn values_iter() { + let map = almost_filled_map(); + for (&value, i) in map.values().zip(1..MAP_SLOTS) { + assert_eq!(value, i); + } + } + + #[test] + fn values_mut_iter() { + let mut map = almost_filled_map(); + for value in map.values_mut() { + *value += 1; + } + + for (&value, i) in map.values().zip(1..MAP_SLOTS) { + assert_eq!(value, i + 1); + } + } } diff --git a/src/lib.rs b/src/lib.rs index 62b8886f..b6ca41ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,7 +83,9 @@ pub use binary_heap::BinaryHeap; pub use deque::Deque; pub use histbuf::{HistoryBuffer, OldestOrdered}; pub use indexmap::{ - Bucket, Entry, FnvIndexMap, IndexMap, Iter as IndexMapIter, OccupiedEntry, Pos, VacantEntry, + Bucket, Entry, FnvIndexMap, IndexMap, Iter as IndexMapIter, IterMut as IndexMapIterMut, + Keys as IndexMapKeys, OccupiedEntry, Pos, VacantEntry, Values as IndexMapValues, + ValuesMut as IndexMapValuesMut, }; pub use indexset::{FnvIndexSet, IndexSet, Iter as IndexSetIter}; pub use linear_map::LinearMap;