1#![no_std]
2
3extern crate alloc;
4
5use alloc::vec::Vec;
6use core::cmp::{max, min};
7use core::ops::Range;
8
9#[cfg(test)]
10extern crate std;
11
12#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct OriginalRange<T, M> {
15 pub range: Range<T>,
16 pub meta: M,
17}
18
19#[derive(Clone)]
21pub struct MergedRange<T, M> {
22 pub merged: Range<T>,
24 pub originals: Vec<OriginalRange<T, M>>,
26}
27
28impl<T, M> core::fmt::Debug for MergedRange<T, M>
29where
30 T: core::fmt::Debug,
31 M: core::fmt::Debug,
32{
33 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
34 f.debug_struct("MergedRange")
35 .field(
36 "merged",
37 &format_args!("[{:?}..{:?})", self.merged.start, self.merged.end),
38 )
39 .field("originals", &OriginalsList(&self.originals))
40 .finish()
41 }
42}
43
44struct OriginalsList<'a, T, M>(&'a [OriginalRange<T, M>]);
46
47impl<T, M> core::fmt::Debug for OriginalsList<'_, T, M>
48where
49 T: core::fmt::Debug,
50 M: core::fmt::Debug,
51{
52 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
53 let mut list = f.debug_list();
54 for orig in self.0 {
55 list.entry(&format_args!(
56 "[{:?}..{:?}) → {:?}",
57 orig.range.start, orig.range.end, orig.meta
58 ));
59 }
60 list.finish()
61 }
62}
63
64impl<T, M> core::fmt::Display for MergedRange<T, M>
65where
66 T: core::fmt::Display,
67{
68 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
69 write!(f, "[{}..{})", self.merged.start, self.merged.end)
70 }
71}
72
73impl<T, M> core::fmt::LowerHex for MergedRange<T, M>
74where
75 T: core::fmt::LowerHex,
76{
77 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
78 if f.alternate() {
79 write!(f, "[{:#x}..{:#x})", self.merged.start, self.merged.end)
80 } else {
81 write!(f, "[{:x}..{:x})", self.merged.start, self.merged.end)
82 }
83 }
84}
85
86impl<T, M> core::fmt::UpperHex for MergedRange<T, M>
87where
88 T: core::fmt::UpperHex,
89{
90 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
91 if f.alternate() {
92 write!(f, "[{:#X}..{:#X})", self.merged.start, self.merged.end)
93 } else {
94 write!(f, "[{:X}..{:X})", self.merged.start, self.merged.end)
95 }
96 }
97}
98
99impl<T, M> core::fmt::Binary for MergedRange<T, M>
100where
101 T: core::fmt::Binary,
102{
103 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
104 if f.alternate() {
105 write!(f, "[{:#b}..{:#b})", self.merged.start, self.merged.end)
106 } else {
107 write!(f, "[{:b}..{:b})", self.merged.start, self.merged.end)
108 }
109 }
110}
111
112impl<T, M> core::fmt::Octal for MergedRange<T, M>
113where
114 T: core::fmt::Octal,
115{
116 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
117 if f.alternate() {
118 write!(f, "[{:#o}..{:#o})", self.merged.start, self.merged.end)
119 } else {
120 write!(f, "[{:o}..{:o})", self.merged.start, self.merged.end)
121 }
122 }
123}
124
125#[derive(Clone, Debug)]
134pub struct RangeSet<T, M = ()>
135where
136 T: Ord + Copy,
137{
138 elements: Vec<MergedRange<T, M>>,
139}
140
141impl<T, M> Default for RangeSet<T, M>
142where
143 T: Ord + Copy,
144{
145 fn default() -> Self {
146 Self {
147 elements: Vec::new(),
148 }
149 }
150}
151
152impl<T, M> RangeSet<T, M>
153where
154 T: Ord + Copy,
155{
156 pub fn new() -> Self {
158 Self::default()
159 }
160
161 #[inline]
163 pub fn elements(&self) -> &[MergedRange<T, M>] {
164 &self.elements
165 }
166
167 pub fn as_slice(&self) -> Vec<Range<T>> {
169 self.elements.iter().map(|e| e.merged.clone()).collect()
170 }
171
172 #[inline]
174 pub fn iter(&self) -> impl Iterator<Item = &Range<T>> {
175 self.elements.iter().map(|e| &e.merged)
176 }
177
178 #[inline]
179 pub fn is_empty(&self) -> bool {
180 self.elements.is_empty()
181 }
182
183 #[inline]
184 pub fn len(&self) -> usize {
185 self.elements.len()
186 }
187
188 pub fn clear(&mut self) {
189 self.elements.clear();
190 }
191
192 pub fn add(&mut self, range: Range<T>, meta: M)
194 where
195 M: PartialEq,
196 {
197 if range.start >= range.end {
198 return;
199 }
200
201 let original = OriginalRange {
202 range: range.clone(),
203 meta,
204 };
205
206 if self.elements.is_empty() {
207 self.elements.push(MergedRange {
208 merged: range,
209 originals: alloc::vec![original],
210 });
211 return;
212 }
213
214 let insert_at = self
216 .elements
217 .binary_search_by(|e| {
218 if e.merged.start < range.start {
219 core::cmp::Ordering::Less
220 } else {
221 core::cmp::Ordering::Greater
222 }
223 })
224 .unwrap_or_else(|pos| pos);
225
226 let mut merged_range = range;
227 let mut merged_originals = alloc::vec![original];
228
229 let mut insert_at = insert_at;
231 while insert_at > 0 {
232 let left = &self.elements[insert_at - 1];
233 if left.merged.end < merged_range.start {
234 break;
235 }
236 merged_range.start = min(merged_range.start, left.merged.start);
237 merged_range.end = max(merged_range.end, left.merged.end);
238 let left_elem = self.elements.remove(insert_at - 1);
239 merged_originals.reserve(left_elem.originals.len());
240 merged_originals.extend(left_elem.originals);
241 insert_at -= 1;
242 }
243
244 while insert_at < self.elements.len() {
246 let right = &self.elements[insert_at];
247 if right.merged.start > merged_range.end {
248 break;
249 }
250 merged_range.start = min(merged_range.start, right.merged.start);
251 merged_range.end = max(merged_range.end, right.merged.end);
252 let right_elem = self.elements.remove(insert_at);
253 merged_originals.reserve(right_elem.originals.len());
254 merged_originals.extend(right_elem.originals);
255 }
256
257 merged_originals = Self::merge_originals(merged_originals);
259
260 self.elements.insert(
261 insert_at,
262 MergedRange {
263 merged: merged_range,
264 originals: merged_originals,
265 },
266 );
267 }
268
269 fn merge_originals(mut originals: Vec<OriginalRange<T, M>>) -> Vec<OriginalRange<T, M>>
271 where
272 M: PartialEq,
273 {
274 if originals.len() <= 1 {
275 return originals;
276 }
277
278 originals.sort_unstable_by(|a, b| a.range.start.cmp(&b.range.start));
280
281 let mut result = Vec::with_capacity(originals.len());
282 let mut iter = originals.into_iter();
283 let mut current = iter.next().unwrap();
284
285 for next in iter {
286 if current.meta == next.meta && current.range.end >= next.range.start {
288 current.range.end = max(current.range.end, next.range.end);
289 } else {
290 result.push(current);
291 current = next;
292 }
293 }
294 result.push(current);
295
296 result
297 }
298
299 #[inline]
301 pub fn contains(&self, value: T) -> bool {
302 self.elements
304 .binary_search_by(|e| {
305 if e.merged.end <= value {
306 core::cmp::Ordering::Less
307 } else if e.merged.start > value {
308 core::cmp::Ordering::Greater
309 } else {
310 core::cmp::Ordering::Equal
311 }
312 })
313 .is_ok()
314 }
315
316 pub fn remove_range(&mut self, range: Range<T>)
321 where
322 M: Clone,
323 {
324 if range.start >= range.end || self.elements.is_empty() {
325 return;
326 }
327
328 let mut out: Vec<MergedRange<T, M>> = Vec::with_capacity(self.elements.len() + 1);
329 for elem in self.elements.drain(..) {
330 if elem.merged.end <= range.start || elem.merged.start >= range.end {
332 out.push(elem);
333 continue;
334 }
335
336 let filtered_originals: Vec<_> = elem
338 .originals
339 .into_iter()
340 .filter(|orig| {
341 !(range.start <= orig.range.start && orig.range.end <= range.end)
343 })
344 .collect();
345
346 if filtered_originals.is_empty() {
348 continue;
349 }
350
351 let has_left = elem.merged.start < range.start;
352 let has_right = elem.merged.end > range.end;
353
354 match (has_left, has_right) {
355 (true, true) => {
356 let left = elem.merged.start..min(elem.merged.end, range.start);
358 if left.start < left.end {
359 out.push(MergedRange {
360 merged: left,
361 originals: filtered_originals.clone(),
362 });
363 }
364 let right = max(elem.merged.start, range.end)..elem.merged.end;
365 if right.start < right.end {
366 out.push(MergedRange {
367 merged: right,
368 originals: filtered_originals,
369 });
370 }
371 }
372 (true, false) => {
373 let left = elem.merged.start..min(elem.merged.end, range.start);
375 if left.start < left.end {
376 out.push(MergedRange {
377 merged: left,
378 originals: filtered_originals,
379 });
380 }
381 }
382 (false, true) => {
383 let right = max(elem.merged.start, range.end)..elem.merged.end;
385 if right.start < right.end {
386 out.push(MergedRange {
387 merged: right,
388 originals: filtered_originals,
389 });
390 }
391 }
392 (false, false) => {
393 }
395 }
396 }
397 self.elements = out;
398 }
399}
400
401impl<T> RangeSet<T, ()>
402where
403 T: Ord + Copy,
404{
405 pub fn add_range(&mut self, range: Range<T>) {
407 self.add(range, ());
408 }
409
410 pub fn extend<I>(&mut self, ranges: I)
412 where
413 I: IntoIterator<Item = Range<T>>,
414 {
415 for r in ranges {
416 self.add_range(r);
417 }
418 }
419}