1#![no_std]
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5
6use core::{
7 cmp::{max, min},
8 fmt::Debug,
9 marker::PhantomData,
10 ops::{Deref, Range, RangeBounds},
11};
12
13pub type RangeSetHeapless<T, const C: usize = 128> = RangeSet<T, heapless::Vec<T, C>>;
14#[cfg(feature = "alloc")]
15pub type RangeSetAlloc<T> = RangeSet<T, alloc::vec::Vec<T>>;
16
17#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
19pub enum RangeError<T>
20where
21 T: RangeInfo,
22{
23 #[error("RangeSet capacity exceeded")]
25 Capacity,
26 #[error("Range conflict: new {new:?} conflicts with existing non-overwritable {existing:?}")]
28 Conflict {
29 new: T,
31 existing: T,
33 },
34}
35
36pub trait RangeInfo: Debug + Clone + Sized {
37 type Kind: Debug + Eq + Clone;
38 type Type: Ord + Copy;
39 fn range(&self) -> Range<Self::Type>;
40 fn kind(&self) -> Self::Kind;
41 fn overwritable(&self) -> bool;
42 fn clone_with_range(&self, range: Range<Self::Type>) -> Self;
43}
44
45pub trait VecOp<T>: Default + Deref<Target = [T]> {
46 fn push_back(&mut self, item: T) -> Result<(), T>;
47 fn clear(&mut self);
48 fn insert(&mut self, index: usize, item: T) -> Result<(), T>;
49 fn remove(&mut self, index: usize) -> T;
50 fn drain<R>(&mut self, range: R) -> impl Iterator<Item = T>
51 where
52 R: RangeBounds<usize>;
53}
54
55#[derive(Clone, Debug)]
62pub struct RangeSet<T, V>
63where
64 T: RangeInfo,
65 V: VecOp<T>,
66{
67 elements: V,
68 _marker: PhantomData<T>,
69}
70
71impl<T, V> Default for RangeSet<T, V>
72where
73 T: RangeInfo,
74 V: VecOp<T>,
75{
76 fn default() -> Self {
77 Self::new(V::default())
78 }
79}
80
81impl<T, V> RangeSet<T, V>
82where
83 T: RangeInfo,
84 V: VecOp<T>,
85{
86 pub const fn new(v: V) -> Self {
88 Self {
89 elements: v,
90 _marker: PhantomData,
91 }
92 }
93
94 #[inline]
96 fn ranges_overlap<T1: Ord + Copy>(r1: &Range<T1>, r2: &Range<T1>) -> bool {
97 !(r1.end <= r2.start || r1.start >= r2.end)
98 }
99
100 fn split_range(elem: &T, split_range: &Range<T::Type>) -> [Option<T>; 2] {
104 let elem_range = elem.range();
105 let has_left = elem_range.start < split_range.start;
106 let has_right = elem_range.end > split_range.end;
107
108 match (has_left, has_right) {
109 (true, true) => {
110 let left = elem_range.start..split_range.start;
112 let right = split_range.end..elem_range.end;
113 [
114 if left.start < left.end {
115 Some(elem.clone_with_range(left))
116 } else {
117 None
118 },
119 if right.start < right.end {
120 Some(elem.clone_with_range(right))
121 } else {
122 None
123 },
124 ]
125 }
126 (true, false) => {
127 let left = elem_range.start..min(elem_range.end, split_range.start);
129 [
130 if left.start < left.end {
131 Some(elem.clone_with_range(left))
132 } else {
133 None
134 },
135 None,
136 ]
137 }
138 (false, true) => {
139 let right = max(elem_range.start, split_range.end)..elem_range.end;
141 [
142 None,
143 if right.start < right.end {
144 Some(elem.clone_with_range(right))
145 } else {
146 None
147 },
148 ]
149 }
150 (false, false) => {
151 [None, None]
153 }
154 }
155 }
156
157 #[inline]
159 pub fn as_slice(&self) -> &[T] {
160 &self.elements
161 }
162
163 #[inline]
165 pub fn iter(&self) -> impl Iterator<Item = &T> {
166 self.elements.iter()
167 }
168
169 #[inline]
170 pub fn is_empty(&self) -> bool {
171 self.elements.is_empty()
172 }
173
174 #[inline]
175 pub fn len(&self) -> usize {
176 self.elements.len()
177 }
178
179 pub fn clear(&mut self) {
180 self.elements.clear();
181 }
182
183 fn push_back(out: &mut V, elem: T) -> Result<(), RangeError<T>> {
184 out.push_back(elem).map_err(|_| RangeError::Capacity)
185 }
186
187 pub fn add(&mut self, new_info: T) -> Result<(), RangeError<T>> {
197 if new_info.range().start >= new_info.range().end {
198 return Ok(());
199 }
200
201 for elem in self.iter() {
202 if !Self::ranges_overlap(&elem.range(), &new_info.range()) {
204 continue;
205 }
206
207 if elem.kind() == new_info.kind() {
209 continue;
210 }
211
212 if !elem.overwritable() {
214 return Err(RangeError::Conflict {
216 new: new_info,
217 existing: elem.clone(),
218 });
219 }
220 }
221
222 let mut out = V::default();
224
225 for elem in self.elements.drain(..) {
226 if !Self::ranges_overlap(&elem.range(), &new_info.range()) {
228 Self::push_back(&mut out, elem)?;
229 continue;
230 }
231
232 if elem.kind() == new_info.kind() {
234 Self::push_back(&mut out, elem)?;
235 continue;
236 }
237
238 let split_parts = Self::split_range(&elem, &new_info.range());
240 for part in split_parts.iter().flatten() {
241 Self::push_back(&mut out, part.clone())?;
242 }
243 }
244
245 self.elements = out;
246
247 if self.elements.is_empty() {
249 Self::push_back(&mut self.elements, new_info.clone())?;
250 return Ok(());
251 }
252
253 let insert_at = self
255 .elements
256 .binary_search_by(|e| {
257 if e.range().start < new_info.range().start {
258 core::cmp::Ordering::Less
259 } else {
260 core::cmp::Ordering::Greater
261 }
262 })
263 .unwrap_or_else(|pos| pos);
264
265 let mut merged_range = new_info.range().clone();
266 let mut insert_at = insert_at;
267
268 while insert_at > 0 {
270 let left = &self.elements[insert_at - 1];
271 if left.range().end < merged_range.start || left.kind() != new_info.kind() {
272 break;
273 }
274 merged_range.start = min(merged_range.start, left.range().start);
275 merged_range.end = max(merged_range.end, left.range().end);
276 self.elements.remove(insert_at - 1);
277 insert_at -= 1;
278 }
279
280 while insert_at < self.elements.len() {
282 let right = &self.elements[insert_at];
283 if right.range().start > merged_range.end || right.kind() != new_info.kind() {
284 break;
285 }
286 merged_range.start = min(merged_range.start, right.range().start);
287 merged_range.end = max(merged_range.end, right.range().end);
288 self.elements.remove(insert_at);
289 }
290
291 self.elements
292 .insert(insert_at, new_info.clone_with_range(merged_range))
293 .map_err(|_| RangeError::Capacity)?;
294 Ok(())
295 }
296
297 #[inline]
299 pub fn contains(&self, value: T::Type) -> bool {
300 self.elements
302 .binary_search_by(|e| {
303 if e.range().end <= value {
304 core::cmp::Ordering::Less
305 } else if e.range().start > value {
306 core::cmp::Ordering::Greater
307 } else {
308 core::cmp::Ordering::Equal
309 }
310 })
311 .is_ok()
312 }
313
314 pub fn remove(&mut self, range: Range<T::Type>) -> Result<(), RangeError<T>> {
322 if range.start >= range.end || self.elements.is_empty() {
323 return Ok(());
324 }
325
326 let mut out = V::default();
327 for elem in self.elements.drain(..) {
328 if !Self::ranges_overlap(&elem.range(), &range) {
330 Self::push_back(&mut out, elem)?;
331 continue;
332 }
333
334 let split_parts = Self::split_range(&elem, &range);
336 for part in split_parts.iter().flatten() {
337 Self::push_back(&mut out, part.clone())?;
338 }
339 }
340 self.elements = out;
341 Ok(())
342 }
343
344 pub fn extend<I>(&mut self, ranges: I) -> Result<(), RangeError<T>>
350 where
351 I: IntoIterator<Item = T>,
352 {
353 for v in ranges {
354 self.add(v)?;
355 }
356 Ok(())
357 }
358}
359
360impl<T, const C: usize> VecOp<T> for heapless::Vec<T, C> {
361 fn push_back(&mut self, item: T) -> Result<(), T> {
362 self.push(item)
363 }
364
365 fn clear(&mut self) {
366 self.clear();
367 }
368
369 fn insert(&mut self, index: usize, item: T) -> Result<(), T> {
370 self.insert(index, item)
371 }
372
373 fn remove(&mut self, index: usize) -> T {
374 self.remove(index)
375 }
376
377 fn drain<R>(&mut self, range: R) -> impl Iterator<Item = T>
378 where
379 R: RangeBounds<usize>,
380 {
381 self.drain(range)
382 }
383}
384
385#[cfg(feature = "alloc")]
386impl<T> VecOp<T> for alloc::vec::Vec<T> {
387 fn push_back(&mut self, item: T) -> Result<(), T> {
388 self.push(item);
389 Ok(())
390 }
391
392 fn clear(&mut self) {
393 self.clear();
394 }
395
396 fn insert(&mut self, index: usize, item: T) -> Result<(), T> {
397 self.insert(index, item);
398 Ok(())
399 }
400
401 fn remove(&mut self, index: usize) -> T {
402 self.remove(index)
403 }
404
405 fn drain<R>(&mut self, range: R) -> impl Iterator<Item = T>
406 where
407 R: RangeBounds<usize>,
408 {
409 self.drain(range)
410 }
411}