1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use std::collections::{HashMap, BTreeMap};
use std::hash::Hash;
use std::iter::FromIterator;
pub trait Groupable<K, V> {
fn group<B: FromKeyedIterator<K, V>>(&mut self) -> B;
}
impl<K, V, I: Iterator<Item=(K, V)>> Groupable<K, V> for I {
fn group<B: FromKeyedIterator<K, V>>(&mut self) -> B {
FromKeyedIterator::from_keyed_iter(self.by_ref())
}
}
pub trait FromKeyedIterator<K, V> {
fn from_keyed_iter<I: Iterator<Item=(K, V)>>(I) -> Self;
}
macro_rules! group_into(
($iter:ident, $map:ident) => (
for (key, val) in $iter {
let val_iter = Some(val).into_iter();
match $map.get_mut(&key) {
Some(collection) => {
collection.extend(val_iter);
continue
},
None => {}
}
$map.insert(key, FromIterator::from_iter(val_iter));
}
)
);
macro_rules! impl_keyed_iter (
($name:ident: $($bounds:ident),+) => (
impl <K: $($bounds+)+, V, U: Extend<V> + FromIterator<V>> FromKeyedIterator<K, V> for $name<K, U> {
fn from_keyed_iter<T: Iterator<Item=(K, V)>>(iter: T) -> $name<K, U> {
let mut map = $name::<K, U>::new();
group_into!(iter, map);
map
}
}
)
);
macro_rules! impl_uint_keyed_iter {
($name:ident) => (
impl <V, U: Extend<V> + FromIterator<V>> FromKeyedIterator<usize, V> for $name<U> {
fn from_keyed_iter<T: Iterator<Item=(usize, V)>>(iter: T) -> $name<U> {
let mut map = $name::<U>::new();
group_into!(iter, map);
map
}
}
)
}
impl_keyed_iter!(HashMap: Ord, Hash);
impl_keyed_iter!(BTreeMap: Ord);