Skip to content

Commit b39f6b2

Browse files
committed
Merge branch 'master' into default
2 parents 84325d1 + f98dbf5 commit b39f6b2

File tree

1 file changed

+137
-4
lines changed

1 file changed

+137
-4
lines changed

src/lib.rs

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
//! ```
4141
4242
use std::borrow::Borrow;
43-
use std::collections::hash_map::Iter;
43+
use std::collections::hash_map;
4444
use std::collections::HashMap;
4545
use std::fmt::{self, Debug};
4646
use std::hash::Hash;
@@ -221,10 +221,13 @@ impl<K1: Eq + Hash + Clone, K2: Eq + Hash + Clone, V> MultiMap<K1, K2, V> {
221221
result
222222
}
223223

224-
/// Iterate through all the values in the MultiMap. Note that the values
224+
/// Iterate through all the values in the MultiMap in random order.
225+
/// Note that the values
225226
/// are `(K2, V)` tuples, not `V`, as you would get with a HashMap.
226-
pub fn iter(&self) -> Iter<K1, (K2, V)> {
227-
self.value_map.iter()
227+
pub fn iter(&self) -> Iter<'_, K1, K2, V> {
228+
Iter {
229+
base: self.value_map.iter(),
230+
}
228231
}
229232
}
230233

@@ -258,6 +261,94 @@ where
258261
}
259262
}
260263

264+
/// An iterator over the entries of a `MultiMap` like in a `HashMap` but with
265+
/// values of the form (K2, V) instead of V.
266+
///
267+
///
268+
/// This `struct` is created by the [`iter`] method on [`MultiMap`]. See its
269+
/// documentation for more.
270+
///
271+
#[derive(Clone, Debug)]
272+
pub struct Iter<'a, K1: 'a, K2: 'a, V: 'a> {
273+
base: hash_map::Iter<'a, K1, (K2, V)>,
274+
}
275+
276+
/// An owning iterator over the entries of a `MultiMap`.
277+
///
278+
/// This `struct` is created by the [`into_iter`] method on [`MultiMap`]
279+
/// (provided by the `IntoIterator` trait). See its documentation for more.
280+
///
281+
pub struct IntoIter<K1, K2, V> {
282+
base: hash_map::IntoIter<K1, (K2, V)>,
283+
}
284+
// TODO: `HashMap` also implements this, do we need this as well?
285+
// impl<K, V> IntoIter<K, V> {
286+
// /// Returns a iterator of references over the remaining items.
287+
// #[inline]
288+
// pub(super) fn iter(&self) -> Iter<'_, K, V> {
289+
// Iter { base: self.base.rustc_iter() }
290+
// }
291+
// }
292+
293+
impl<K1, K2, V> IntoIterator for MultiMap<K1, K2, V>
294+
where
295+
K1: Eq + Hash + Debug,
296+
K2: Eq + Hash + Debug,
297+
V: Debug,
298+
{
299+
type Item = (K1, (K2, V));
300+
type IntoIter = IntoIter<K1, K2, V>;
301+
302+
/// Creates a consuming iterator, that is, one that moves each key-value
303+
/// pair out of the map in arbitrary order. The map cannot be used after
304+
/// calling this.
305+
///
306+
fn into_iter(self) -> IntoIter<K1, K2, V> {
307+
IntoIter {
308+
base: self.value_map.into_iter(),
309+
}
310+
}
311+
}
312+
313+
impl<'a, K1, K2, V> IntoIterator for &'a MultiMap<K1, K2, V>
314+
where
315+
K1: Eq + Hash + Debug + Clone,
316+
K2: Eq + Hash + Debug + Clone,
317+
V: Debug,
318+
{
319+
type Item = (&'a K1, &'a (K2, V));
320+
type IntoIter = Iter<'a, K1, K2, V>;
321+
322+
fn into_iter(self) -> Iter<'a, K1, K2, V> {
323+
self.iter()
324+
}
325+
}
326+
327+
impl<'a, K1, K2, V> Iterator for Iter<'a, K1, K2, V> {
328+
type Item = (&'a K1, &'a (K2, V));
329+
330+
fn next(&mut self) -> Option<(&'a K1, &'a (K2, V))> {
331+
self.base.next()
332+
}
333+
#[inline]
334+
fn size_hint(&self) -> (usize, Option<usize>) {
335+
self.base.size_hint()
336+
}
337+
}
338+
339+
impl<K1, K2, V> Iterator for IntoIter<K1, K2, V> {
340+
type Item = (K1, (K2, V));
341+
342+
#[inline]
343+
fn next(&mut self) -> Option<(K1, (K2, V))> {
344+
self.base.next()
345+
}
346+
#[inline]
347+
fn size_hint(&self) -> (usize, Option<usize>) {
348+
self.base.size_hint()
349+
}
350+
}
351+
261352
#[macro_export]
262353
/// Create a `MultiMap` from a list of key-value tuples
263354
///
@@ -345,6 +436,48 @@ mod test {
345436
assert!(map.get_alt(&"Three") == None);
346437
assert!(map.get(&3) == None);
347438
}
439+
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
440+
struct MultiCount<'a>(i32, &'a str, &'a str);
441+
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
442+
struct MultiCountOwned(i32, String, String);
443+
444+
#[test]
445+
fn into_iter_test() {
446+
use MultiMap;
447+
let mut map = MultiMap::new();
448+
449+
map.insert(1, "One", String::from("Eins"));
450+
map.insert(2, "Two", String::from("Zwei"));
451+
map.insert(3, "Three", String::from("Drei"));
452+
453+
let mut vec_borrow = Vec::new();
454+
for (k1, (k2, v)) in &map {
455+
vec_borrow.push(MultiCount(*k1, *k2, v));
456+
}
457+
vec_borrow.sort();
458+
assert_eq!(
459+
vec_borrow,
460+
vec!(
461+
MultiCount(1, "One", "Eins"),
462+
MultiCount(2, "Two", "Zwei"),
463+
MultiCount(3, "Three", "Drei")
464+
)
465+
);
466+
467+
let mut vec_owned = Vec::new();
468+
for (k1, (k2, v)) in map {
469+
vec_owned.push(MultiCountOwned(k1, String::from(k2), v));
470+
}
471+
vec_owned.sort();
472+
assert_eq!(
473+
vec_owned,
474+
vec!(
475+
MultiCountOwned(1, String::from("One"), String::from("Eins")),
476+
MultiCountOwned(2, String::from("Two"), String::from("Zwei")),
477+
MultiCountOwned(3, String::from("Three"), String::from("Drei"))
478+
)
479+
)
480+
}
348481

349482
#[test]
350483
fn macro_test() {

0 commit comments

Comments
 (0)