1use std::ops::Range;
4
5pub trait HasRestLen {
9 fn rest_len(&self) -> usize;
12}
13
14pub struct IterWithRange<I> {
17 original_len: usize,
18 inner: I,
19}
20
21impl<I> IterWithRange<I> {
22 pub fn original_len(&self) -> usize {
27 self.original_len
28 }
29
30 pub fn inner(&self) -> &I {
32 &self.inner
33 }
34
35 pub fn inner_mut(&mut self) -> &mut I {
44 &mut self.inner
45 }
46
47 #[inline(always)]
49 pub fn pos(&self) -> usize
50 where
51 I: HasRestLen,
52 {
53 self.original_len - self.inner.rest_len()
54 }
55}
56
57impl<I: Iterator> Iterator for IterWithRange<I>
58where
59 I: HasRestLen,
60{
61 type Item = (Range<usize>, I::Item);
62
63 fn next(&mut self) -> Option<Self::Item> {
64 let pos_before = self.pos();
65 let item = self.inner.next()?;
66 let pos_after = self.pos();
67 Some((pos_before..pos_after, item))
68 }
69}
70
71pub trait IteratorWithRangesExt: Sized {
74 fn with_ranges(self) -> IterWithRange<Self>;
76}
77
78impl<I> IteratorWithRangesExt for I
79where
80 I: Iterator + HasRestLen,
81{
82 fn with_ranges(self) -> IterWithRange<Self> {
83 IterWithRange {
84 original_len: self.rest_len(),
85 inner: self,
86 }
87 }
88}
89
90use std::collections::BTreeMap;
91
92pub fn group_by<'a, T, F, K>(s: &'a [T], f: F) -> BTreeMap<K, Vec<&'a T>>
94where
95 F: Fn(&T) -> K,
96 K: Ord + Eq,
97{
98 let mut out: BTreeMap<K, Vec<&'a T>> = BTreeMap::new();
99
100 for item in s.iter() {
101 let key = f(item);
102 if let Some(list) = out.get_mut(&key) {
103 list.push(item);
104 } else {
105 out.insert(key, vec![item]);
106 }
107 }
108
109 out
110}
111
112pub fn group_by_iter_ref<'a, T, F, I, K>(iter: I, f: F) -> BTreeMap<K, Vec<&'a T>>
114where
115 I: Iterator<Item = &'a T>,
116 F: Fn(&T) -> K,
117 K: Ord + Eq,
118{
119 let mut out: BTreeMap<K, Vec<&'a T>> = BTreeMap::new();
120
121 for item in iter {
122 let key = f(item);
123 if let Some(list) = out.get_mut(&key) {
124 list.push(item);
125 } else {
126 out.insert(key, vec![item]);
127 }
128 }
129
130 out
131}
132
133pub fn group_by_iter<I, F, K>(iter: I, f: F) -> BTreeMap<K, Vec<I::Item>>
135where
136 I: Iterator,
137 F: Fn(&I::Item) -> K,
138 K: Ord + Eq,
139{
140 let mut out: BTreeMap<K, Vec<I::Item>> = BTreeMap::new();
141
142 for item in iter {
143 let key = f(&item);
144 if let Some(list) = out.get_mut(&key) {
145 list.push(item);
146 } else {
147 out.insert(key, vec![item]);
148 }
149 }
150
151 out
152}