Skip to main content

btree_range_map/generic/
set.rs

1use crate::{AnyRange, AsRange, IntoRange, RangePartialOrd, generic::RangeMap};
2use range_traits::{Bounded, Measure, PartialEnum};
3use raw_btree::{Item, Storage};
4use std::{
5	cmp::Ordering,
6	fmt,
7	hash::{Hash, Hasher},
8};
9
10/// Range set.
11///
12/// This is based on a range map, where the values are `()`.
13pub struct RangeSet<T, C: Storage<Item<AnyRange<T>, ()>>> {
14	map: RangeMap<T, (), C>,
15}
16
17impl<T: Clone, C: Storage<Item<AnyRange<T>, ()>>> Clone for RangeSet<T, C> {
18	fn clone(&self) -> Self {
19		RangeSet {
20			map: self.map.clone(),
21		}
22	}
23}
24
25impl<T, C: Storage<Item<AnyRange<T>, ()>>> RangeSet<T, C> {
26	pub fn new() -> RangeSet<T, C> {
27		RangeSet {
28			map: RangeMap::new(),
29		}
30	}
31}
32
33impl<T, C: Storage<Item<AnyRange<T>, ()>>> Default for RangeSet<T, C> {
34	fn default() -> Self {
35		Self::new()
36	}
37}
38
39impl<T, C: Storage<Item<AnyRange<T>, ()>>> RangeSet<T, C> {
40	pub fn range_count(&self) -> usize {
41		self.map.range_count()
42	}
43
44	pub fn len(&self) -> T::Len
45	where
46		T: Measure + PartialEnum + Bounded,
47	{
48		self.map.len()
49	}
50
51	pub fn bounded_len(&self) -> Option<T::Len>
52	where
53		T: Measure + PartialEnum,
54	{
55		self.map.bounded_len()
56	}
57
58	pub fn is_empty(&self) -> bool
59	where
60		T: Measure + PartialEnum,
61	{
62		self.map.is_empty()
63	}
64
65	pub fn intersects<R: AsRange<Item = T>>(&self, values: R) -> bool
66	where
67		T: Clone + PartialEnum + Measure,
68	{
69		self.map.intersects(values)
70	}
71
72	/// # Complexity
73	///
74	/// `O(log n)`, where `n` is [`Self::range_count`]. Delegates to
75	/// [`RangeMap::contains_key`].
76	pub fn contains(&self, value: T) -> bool
77	where
78		T: Clone + PartialEnum + RangePartialOrd + Measure,
79	{
80		self.map.contains_key(value)
81	}
82
83	pub fn iter(&self) -> Iter<'_, T, C> {
84		Iter {
85			inner: self.map.iter(),
86		}
87	}
88
89	/// Returns an iterator over the gaps (missing values) of the set.
90	pub fn gaps(&self) -> Gaps<'_, T, C> {
91		self.map.gaps()
92	}
93}
94
95impl<T: fmt::Debug, C: Storage<Item<AnyRange<T>, ()>>> fmt::Debug for RangeSet<T, C> {
96	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97		write!(f, "{{")?;
98
99		for range in self {
100			write!(f, "{:?}", range)?
101		}
102
103		write!(f, "}}")
104	}
105}
106
107impl<'a, T, C: Storage<Item<AnyRange<T>, ()>>> IntoIterator for &'a RangeSet<T, C> {
108	type Item = &'a AnyRange<T>;
109	type IntoIter = Iter<'a, T, C>;
110
111	fn into_iter(self) -> Self::IntoIter {
112		self.iter()
113	}
114}
115
116impl<T, C: Storage<Item<AnyRange<T>, ()>>> RangeSet<T, C> {
117	/// # Complexity
118	///
119	/// `O((k + 1) log n)`, where `n` is [`Self::range_count`] and `k` is the
120	/// number of existing ranges that overlap, or are connected to, `key`.
121	/// Delegates to [`RangeMap::insert`].
122	pub fn insert<R: IntoRange<Item = T>>(&mut self, key: R)
123	where
124		T: Clone + PartialEnum + Measure,
125	{
126		self.map.insert(key, ())
127	}
128
129	/// # Complexity
130	///
131	/// `O((k + 1) log n)`, where `n` is [`Self::range_count`] and `k` is the
132	/// number of existing ranges that intersect `key`. Delegates to
133	/// [`RangeMap::remove`].
134	pub fn remove<R: AsRange<Item = T>>(&mut self, key: R)
135	where
136		T: Clone + PartialEnum + Measure,
137	{
138		self.map.remove(key)
139	}
140
141	pub fn complement(&self) -> Self
142	where
143		T: Clone + Measure + PartialEnum,
144	{
145		self.gaps().map(AnyRange::cloned).collect()
146	}
147}
148
149impl<K, C, D> PartialEq<RangeSet<K, D>> for RangeSet<K, C>
150where
151	K: Measure + PartialOrd + PartialEnum,
152	C: Storage<Item<AnyRange<K>, ()>>,
153	D: Storage<Item<AnyRange<K>, ()>>,
154{
155	fn eq(&self, other: &RangeSet<K, D>) -> bool {
156		self.map == other.map
157	}
158}
159
160impl<K, C: Storage<Item<AnyRange<K>, ()>>> Eq for RangeSet<K, C> where K: Measure + PartialEnum + Ord
161{}
162
163impl<K, C, D> PartialOrd<RangeSet<K, D>> for RangeSet<K, C>
164where
165	K: Measure + PartialOrd + PartialEnum,
166	C: Storage<Item<AnyRange<K>, ()>>,
167	D: Storage<Item<AnyRange<K>, ()>>,
168{
169	fn partial_cmp(&self, other: &RangeSet<K, D>) -> Option<Ordering> {
170		self.map.partial_cmp(&other.map)
171	}
172}
173
174impl<K, C: Storage<Item<AnyRange<K>, ()>>> Ord for RangeSet<K, C>
175where
176	K: Measure + PartialEnum + Ord,
177{
178	fn cmp(&self, other: &Self) -> Ordering {
179		self.map.cmp(&other.map)
180	}
181}
182
183impl<K, C: Storage<Item<AnyRange<K>, ()>>> Hash for RangeSet<K, C>
184where
185	K: Hash + PartialEnum,
186{
187	fn hash<H: Hasher>(&self, h: &mut H) {
188		self.map.hash(h)
189	}
190}
191
192impl<T, C: Storage<Item<AnyRange<T>, ()>>> IntoIterator for RangeSet<T, C> {
193	type Item = AnyRange<T>;
194	type IntoIter = IntoIter<T, C>;
195
196	fn into_iter(self) -> Self::IntoIter {
197		IntoIter {
198			inner: self.map.into_iter(),
199		}
200	}
201}
202
203pub struct Iter<'a, T, C: Storage<Item<AnyRange<T>, ()>>> {
204	inner: crate::generic::map::Iter<'a, T, (), C>,
205}
206
207impl<'a, T, C: Storage<Item<AnyRange<T>, ()>>> Iterator for Iter<'a, T, C> {
208	type Item = &'a AnyRange<T>;
209
210	fn next(&mut self) -> Option<Self::Item> {
211		match self.inner.next() {
212			Some((range, ())) => Some(range),
213			None => None,
214		}
215	}
216}
217
218pub struct IntoIter<T, C: Storage<Item<AnyRange<T>, ()>>> {
219	inner: crate::generic::map::IntoIter<T, (), C>,
220}
221
222impl<T, C: Storage<Item<AnyRange<T>, ()>>> Iterator for IntoIter<T, C> {
223	type Item = AnyRange<T>;
224
225	fn next(&mut self) -> Option<Self::Item> {
226		self.inner.next().map(|(range, _)| range)
227	}
228}
229
230/// Iterator over the gaps (unbound keys) of a `RangeSet`.
231pub type Gaps<'a, T, C> = crate::generic::map::Gaps<'a, T, (), C>;
232
233impl<R: IntoRange, C: Storage<Item<AnyRange<R::Item>, ()>>> std::iter::Extend<R>
234	for RangeSet<R::Item, C>
235where
236	R::Item: Clone + Measure + PartialOrd,
237{
238	fn extend<I: IntoIterator<Item = R>>(&mut self, iter: I) {
239		for range in iter {
240			self.insert(range)
241		}
242	}
243}
244
245impl<R: IntoRange, C: Storage<Item<AnyRange<R::Item>, ()>>> FromIterator<R> for RangeSet<R::Item, C>
246where
247	R::Item: Clone + Measure + PartialOrd,
248{
249	fn from_iter<I: IntoIterator<Item = R>>(iter: I) -> Self {
250		let mut result = Self::default();
251		result.extend(iter);
252		result
253	}
254}
255
256#[cfg(test)]
257mod test {
258	use crate::{AnyRange, RangeSet};
259
260	#[test]
261	fn gaps1() {
262		let mut a: RangeSet<u8> = RangeSet::new();
263		let mut b: RangeSet<u8> = RangeSet::new();
264
265		a.insert(10..20);
266
267		b.insert(0..10);
268		b.insert(20..);
269
270		assert_eq!(a.complement(), b)
271	}
272
273	#[test]
274	fn gaps2() {
275		let mut a: RangeSet<u8> = RangeSet::new();
276		let mut b: RangeSet<u8> = RangeSet::new();
277
278		a.insert(0..10);
279		b.insert(10..);
280
281		assert_eq!(a.complement(), b)
282	}
283
284	#[test]
285	fn gaps3() {
286		let mut a: RangeSet<u8> = RangeSet::new();
287		let mut b: RangeSet<u8> = RangeSet::new();
288
289		a.insert(20..);
290		b.insert(0..=19);
291
292		assert_eq!(a.complement(), b)
293	}
294
295	#[test]
296	fn gaps4() {
297		let mut a: RangeSet<u8> = RangeSet::new();
298
299		a.insert(10..20);
300
301		let mut gaps = a.gaps().map(AnyRange::cloned);
302		assert_eq!(gaps.next(), Some(AnyRange::from(..10u8)));
303		assert_eq!(gaps.next(), Some(AnyRange::from(20u8..)));
304		assert_eq!(gaps.next(), None)
305	}
306
307	#[test]
308	fn gaps5() {
309		let mut a: RangeSet<u8> = RangeSet::new();
310
311		a.insert(..10);
312		a.insert(20..);
313
314		let mut gaps = a.gaps().map(AnyRange::cloned);
315		assert_eq!(gaps.next(), Some(AnyRange::from(10..20)));
316		assert_eq!(gaps.next(), None)
317	}
318
319	#[test]
320	fn gaps6() {
321		let mut a: RangeSet<u8> = RangeSet::new();
322
323		a.insert(10..20);
324
325		assert_eq!(a.complement().complement(), a)
326	}
327}