1use core::cmp::Ordering;
2use core::iter::{FusedIterator, Peekable};
3use core::ops::{Range, RangeInclusive};
4
5trait RangeOrder {
7 fn order_start(&self, other: &Self) -> Ordering;
9
10 fn order_end(&self, other: &Self) -> Ordering;
12}
13
14impl<T: Ord> RangeOrder for Range<T> {
15 fn order_start(&self, other: &Self) -> Ordering {
16 self.start.cmp(&other.start)
17 }
18
19 fn order_end(&self, other: &Self) -> Ordering {
20 self.end.cmp(&other.end)
21 }
22}
23
24impl<T: Ord> RangeOrder for RangeInclusive<T> {
25 fn order_start(&self, other: &Self) -> Ordering {
26 self.start().cmp(other.start())
27 }
28
29 fn order_end(&self, other: &Self) -> Ordering {
30 self.end().cmp(other.end())
31 }
32}
33
34trait RangeMerge: Sized {
36 fn merge(&mut self, next: &Self) -> bool;
38}
39
40impl<T: Ord + Clone> RangeMerge for Range<T> {
41 fn merge(&mut self, other: &Self) -> bool {
42 if !self.contains(&other.start) {
43 return false;
44 }
45
46 if other.end > self.end {
47 self.end = other.end.clone();
48 }
49
50 true
51 }
52}
53
54impl<T: Ord + Clone> RangeMerge for RangeInclusive<T> {
55 fn merge(&mut self, other: &Self) -> bool {
56 if !self.contains(other.start()) {
57 return false;
58 }
59
60 if other.end() > self.end() {
61 *self = RangeInclusive::new(self.start().clone(), other.end().clone());
62 }
63
64 true
65 }
66}
67
68trait RangeIntersect: Sized {
70 fn intersect(&self, next: &Self) -> Option<Self>;
72}
73
74impl<T: Ord + Clone> RangeIntersect for Range<T> {
75 fn intersect(&self, other: &Self) -> Option<Self> {
76 let start = (&self.start).max(&other.start);
77 let end = (&self.end).min(&other.end);
78
79 if start >= end {
80 return None;
81 }
82
83 Some(start.clone()..end.clone())
84 }
85}
86
87impl<T: Ord + Clone> RangeIntersect for RangeInclusive<T> {
88 fn intersect(&self, other: &Self) -> Option<Self> {
89 let start = self.start().max(other.start());
90 let end = self.end().min(other.end());
91
92 if start > end {
93 return None;
94 }
95
96 Some(start.clone()..=end.clone())
97 }
98}
99
100#[test]
101fn test_intersect() {
102 assert_eq!((0..5).intersect(&(0..3)), Some(0..3));
103 assert_eq!((0..3).intersect(&(0..5)), Some(0..3));
104 assert_eq!((0..3).intersect(&(3..3)), None);
105}
106
107pub struct Union<'a, T, L, R = L>
109where
110 T: 'a,
111 L: Iterator<Item = &'a T>,
112 R: Iterator<Item = &'a T>,
113{
114 left: Peekable<L>,
115 right: Peekable<R>,
116}
117
118impl<'a, T, L, R> Union<'a, T, L, R>
119where
120 T: 'a,
121 L: Iterator<Item = &'a T>,
122 R: Iterator<Item = &'a T>,
123{
124 pub fn new(left: L, right: R) -> Self {
128 Self {
129 left: left.peekable(),
130 right: right.peekable(),
131 }
132 }
133}
134
135impl<'a, R, I> Iterator for Union<'a, R, I>
136where
137 R: RangeOrder + RangeMerge + Clone,
138 I: Iterator<Item = &'a R>,
139{
140 type Item = R;
141
142 fn next(&mut self) -> Option<Self::Item> {
143 let mut range = match (self.left.peek(), self.right.peek()) {
145 (Some(_), None) => self.left.next().unwrap(),
147 (None, Some(_)) => self.right.next().unwrap(),
148 (Some(left), Some(right)) => {
150 if left.order_start(right).is_lt() {
151 self.left.next().unwrap()
152 } else {
153 self.right.next().unwrap()
154 }
155 }
156 (None, None) => return None,
158 }
159 .clone();
160
161 let mut join = |iter: &mut Peekable<I>| {
163 if let Some(next) = iter.peek() {
164 if range.merge(next) {
165 iter.next().unwrap();
166 return true;
167 }
168 }
169 false
170 };
171
172 loop {
174 if !(join(&mut self.left) || join(&mut self.right)) {
175 break;
176 }
177 }
178
179 Some(range)
180 }
181}
182
183impl<'a, R, I> FusedIterator for Union<'a, R, I>
184where
185 R: RangeOrder + RangeMerge + Clone,
186 I: Iterator<Item = &'a R>,
187{
188}
189
190pub struct Intersection<'a, T, L, R = L>
192where
193 T: 'a,
194 L: Iterator<Item = &'a T>,
195 R: Iterator<Item = &'a T>,
196{
197 left: Peekable<L>,
198 right: Peekable<R>,
199}
200
201impl<'a, T, L, R> Intersection<'a, T, L, R>
202where
203 T: 'a,
204 L: Iterator<Item = &'a T>,
205 R: Iterator<Item = &'a T>,
206{
207 pub fn new(left: L, right: R) -> Self {
211 Self {
212 left: left.peekable(),
213 right: right.peekable(),
214 }
215 }
216}
217
218impl<'a, R, I> Iterator for Intersection<'a, R, I>
219where
220 R: RangeOrder + RangeIntersect + Clone,
221 I: Iterator<Item = &'a R>,
222{
223 type Item = R;
224
225 fn next(&mut self) -> Option<Self::Item> {
226 loop {
227 let (Some(left), Some(right)) = (self.left.peek(), self.right.peek()) else {
229 return None;
230 };
231
232 let intersection = left.intersect(right);
233
234 if left.order_end(right).is_lt() {
236 self.left.next();
237 } else {
238 self.right.next();
239 }
240
241 if let Some(intersection) = intersection {
242 return Some(intersection);
243 }
244 }
245 }
246}