4040//! ```
4141
4242use std:: borrow:: Borrow ;
43- use std:: collections:: hash_map:: Iter ;
43+ use std:: collections:: hash_map;
4444use std:: collections:: HashMap ;
4545use std:: fmt:: { self , Debug } ;
4646use 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
@@ -246,6 +249,93 @@ impl<K1: Eq + Hash + Debug, K2: Eq + Hash + Debug, V: Debug> fmt::Debug for Mult
246249 }
247250}
248251
252+ /// An iterator over the entries of a `MultiMap` like in a `HashMap` but with
253+ /// values of the form (K2, V) instead of V.
254+ ///
255+ ///
256+ /// This `struct` is created by the [`iter`] method on [`MultiMap`]. See its
257+ /// documentation for more.
258+ ///
259+ #[ derive( Clone , Debug ) ]
260+ pub struct Iter < ' a , K1 : ' a , K2 : ' a , V : ' a > {
261+ base : hash_map:: Iter < ' a , K1 , ( K2 , V ) > ,
262+ }
263+
264+ /// An owning iterator over the entries of a `MultiMap`.
265+ ///
266+ /// This `struct` is created by the [`into_iter`] method on [`MultiMap`]
267+ /// (provided by the `IntoIterator` trait). See its documentation for more.
268+ ///
269+ pub struct IntoIter < K1 , K2 , V > {
270+ base : hash_map:: IntoIter < K1 , ( K2 , V ) > ,
271+ }
272+ // TODO: `HashMap` also implements this, do we need this as well?
273+ // impl<K, V> IntoIter<K, V> {
274+ // /// Returns a iterator of references over the remaining items.
275+ // #[inline]
276+ // pub(super) fn iter(&self) -> Iter<'_, K, V> {
277+ // Iter { base: self.base.rustc_iter() }
278+ // }
279+ // }
280+
281+ impl < K1 , K2 , V > IntoIterator for MultiMap < K1 , K2 , V >
282+ where
283+ K1 : Eq + Hash + Debug ,
284+ K2 : Eq + Hash + Debug ,
285+ V : Debug ,
286+ {
287+ type Item = ( K1 , ( K2 , V ) ) ;
288+ type IntoIter = IntoIter < K1 , K2 , V > ;
289+
290+ /// Creates a consuming iterator, that is, one that moves each key-value
291+ /// pair out of the map in arbitrary order. The map cannot be used after
292+ /// calling this.
293+ ///
294+ fn into_iter ( self ) -> IntoIter < K1 , K2 , V > {
295+ IntoIter {
296+ base : self . value_map . into_iter ( ) ,
297+ }
298+ }
299+ }
300+
301+ impl < ' a , K1 , K2 , V > IntoIterator for & ' a MultiMap < K1 , K2 , V >
302+ where
303+ K1 : Eq + Hash + Debug + Clone ,
304+ K2 : Eq + Hash + Debug + Clone ,
305+ V : Debug ,
306+ {
307+ type Item = ( & ' a K1 , & ' a ( K2 , V ) ) ;
308+ type IntoIter = Iter < ' a , K1 , K2 , V > ;
309+
310+ fn into_iter ( self ) -> Iter < ' a , K1 , K2 , V > {
311+ self . iter ( )
312+ }
313+ }
314+
315+ impl < ' a , K1 , K2 , V > Iterator for Iter < ' a , K1 , K2 , V > {
316+ type Item = ( & ' a K1 , & ' a ( K2 , V ) ) ;
317+
318+ fn next ( & mut self ) -> Option < ( & ' a K1 , & ' a ( K2 , V ) ) > {
319+ self . base . next ( )
320+ }
321+ #[ inline]
322+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
323+ self . base . size_hint ( )
324+ }
325+ }
326+
327+ impl < K1 , K2 , V > Iterator for IntoIter < K1 , K2 , V > {
328+ type Item = ( K1 , ( K2 , V ) ) ;
329+
330+ #[ inline]
331+ fn next ( & mut self ) -> Option < ( K1 , ( K2 , V ) ) > {
332+ self . base . next ( )
333+ }
334+ #[ inline]
335+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
336+ self . base . size_hint ( )
337+ }
338+ }
249339#[ macro_export]
250340/// Create a `MultiMap` from a list of key-value tuples
251341///
@@ -333,6 +423,48 @@ mod test {
333423 assert ! ( map. get_alt( & "Three" ) == None ) ;
334424 assert ! ( map. get( & 3 ) == None ) ;
335425 }
426+ #[ derive( Debug , Eq , Ord , PartialEq , PartialOrd ) ]
427+ struct MultiCount < ' a > ( i32 , & ' a str , & ' a str ) ;
428+ #[ derive( Debug , Eq , Ord , PartialEq , PartialOrd ) ]
429+ struct MultiCountOwned ( i32 , String , String ) ;
430+
431+ #[ test]
432+ fn into_iter_test ( ) {
433+ use MultiMap ;
434+ let mut map = MultiMap :: new ( ) ;
435+
436+ map. insert ( 1 , "One" , String :: from ( "Eins" ) ) ;
437+ map. insert ( 2 , "Two" , String :: from ( "Zwei" ) ) ;
438+ map. insert ( 3 , "Three" , String :: from ( "Drei" ) ) ;
439+
440+ let mut vec_borrow = Vec :: new ( ) ;
441+ for ( k1, ( k2, v) ) in & map {
442+ vec_borrow. push ( MultiCount ( * k1, * k2, v) ) ;
443+ }
444+ vec_borrow. sort ( ) ;
445+ assert_eq ! (
446+ vec_borrow,
447+ vec!(
448+ MultiCount ( 1 , "One" , "Eins" ) ,
449+ MultiCount ( 2 , "Two" , "Zwei" ) ,
450+ MultiCount ( 3 , "Three" , "Drei" )
451+ )
452+ ) ;
453+
454+ let mut vec_owned = Vec :: new ( ) ;
455+ for ( k1, ( k2, v) ) in map {
456+ vec_owned. push ( MultiCountOwned ( k1, String :: from ( k2) , v) ) ;
457+ }
458+ vec_owned. sort ( ) ;
459+ assert_eq ! (
460+ vec_owned,
461+ vec!(
462+ MultiCountOwned ( 1 , String :: from( "One" ) , String :: from( "Eins" ) ) ,
463+ MultiCountOwned ( 2 , String :: from( "Two" ) , String :: from( "Zwei" ) ) ,
464+ MultiCountOwned ( 3 , String :: from( "Three" ) , String :: from( "Drei" ) )
465+ )
466+ )
467+ }
336468
337469 #[ test]
338470 fn macro_test ( ) {
0 commit comments