vulkano/range_set.rs
1use std::ops::Range;
2
3/// A set of ordered types.
4///
5/// Implemented as an ordered list of ranges that do not touch or overlap.
6#[derive(Clone, Debug, Default)]
7pub struct RangeSet<T>(Vec<Range<T>>);
8
9impl<T: Ord + Copy> RangeSet<T> {
10 /// Returns a new empty `RangeSet`.
11 #[inline]
12 pub fn new() -> Self {
13 RangeSet(Vec::new())
14 }
15
16 /// Returns whether all elements of `range` are contained in the set.
17 #[inline]
18 pub fn contains(&self, elements: Range<T>) -> bool {
19 self.0
20 .iter()
21 .any(|range| range.start <= elements.end && range.end >= elements.end)
22 }
23
24 /// Removes all ranges from the set.
25 #[inline]
26 pub fn clear(&mut self) {
27 self.0.clear();
28 }
29
30 /// Inserts the elements of `range` into the set.
31 pub fn insert(&mut self, elements: Range<T>) {
32 // Find the first range that is not less than `elements`, and the first range that is
33 // greater.
34 let index_start = self
35 .0
36 .iter()
37 .position(|range| range.end >= elements.start)
38 .unwrap_or(self.0.len());
39 let index_end = self
40 .0
41 .iter()
42 .position(|range| range.start > elements.end)
43 .unwrap_or(self.0.len());
44
45 if index_start == index_end {
46 // `elements` fits in between index_start - 1 and index_start.
47 self.0.insert(index_start, elements);
48 } else {
49 // `elements` touches the ranges between index_start and index_end.
50 // Expand `elements` with the touched ranges, then store it in the first.
51 self.0[index_start] = self.0[index_start..index_end]
52 .iter()
53 .fold(elements, |Range { start, end }, range| {
54 start.min(range.start)..end.max(range.end)
55 });
56 // Delete the remaining elements.
57 self.0.drain(index_start + 1..index_end);
58 }
59 }
60}