1#![doc = include_str!("../README.md")]
2
3mod cover;
4mod difference;
5mod index;
6mod intersection;
7mod subset;
8mod symmetric_difference;
9mod union;
10
11pub use cover::Cover;
12pub use difference::{Difference, DifferenceMut};
13pub use index::IndexRanges;
14pub use intersection::Intersection;
15pub use subset::Subset;
16pub use symmetric_difference::{SymmetricDifference, SymmetricDifferenceMut};
17pub use union::{Union, UnionMut};
18
19use std::ops::{Add, Range, Sub};
20
21#[derive(Debug, Clone, Hash, PartialEq, Eq)]
58#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
59#[cfg_attr(
60 feature = "serde",
61 serde(
62 bound = "for<'a> T: serde::Serialize + serde::de::Deserialize<'a> + Copy + Ord",
63 from = "Vec<Range<T>>",
64 into = "Vec<Range<T>>"
65 )
66)]
67pub struct RangeSet<T> {
68 ranges: Vec<Range<T>>,
72}
73
74impl<T: Copy + Ord> From<Vec<Range<T>>> for RangeSet<T> {
75 fn from(ranges: Vec<Range<T>>) -> Self {
76 Self::new(&ranges)
77 }
78}
79
80impl<T> From<RangeSet<T>> for Vec<Range<T>> {
81 fn from(ranges: RangeSet<T>) -> Self {
82 ranges.into_inner()
83 }
84}
85
86impl<T: Copy + Ord> Default for RangeSet<T> {
87 fn default() -> Self {
88 Self {
89 ranges: Default::default(),
90 }
91 }
92}
93
94impl<T> RangeSet<T> {
95 pub fn into_inner(self) -> Vec<Range<T>> {
97 self.ranges
98 }
99
100 pub fn is_empty(&self) -> bool {
102 self.ranges.is_empty()
103 }
104
105 pub fn len_ranges(&self) -> usize {
107 self.ranges.len()
108 }
109
110 pub fn clear(&mut self) {
112 self.ranges.clear();
113 }
114}
115
116impl<T: Copy + Ord> RangeSet<T> {
117 pub fn new(ranges: &[Range<T>]) -> Self
121 where
122 Self: Union<Range<T>, Output = Self>,
123 {
124 let mut set = Self::default();
125
126 for range in ranges {
127 set = set.union(range);
128 }
129
130 set
131 }
132
133 pub fn iter(&self) -> RangeSetIter<'_, T> {
135 RangeSetIter {
136 iter: self.ranges.iter(),
137 current: None,
138 }
139 }
140
141 pub fn iter_ranges(&self) -> RangeIter<'_, T> {
143 RangeIter {
144 iter: self.ranges.iter(),
145 }
146 }
147
148 pub fn contains(&self, value: &T) -> bool {
150 self.ranges.iter().any(|range| range.contains(value))
151 }
152
153 pub fn min(&self) -> Option<T> {
155 self.ranges.first().map(|range| range.start)
156 }
157
158 pub fn end(&self) -> Option<T> {
165 self.ranges.last().map(|range| range.end)
166 }
167}
168
169impl<T: Copy + Ord + Step + Sub<Output = T>> RangeSet<T> {
170 pub fn max(&self) -> Option<T> {
172 self.ranges
175 .last()
176 .map(|range| Step::backward(range.end, 1).expect("set is not empty"))
177 }
178
179 pub fn split_off(&mut self, at: &T) -> Self {
188 let idx = self
190 .ranges
191 .iter()
192 .position(|range| range.contains(at))
193 .expect("`at` is in the set");
194
195 let mut split_ranges = self.ranges.split_off(idx);
197
198 if *at > split_ranges[0].start {
201 self.ranges.push(Range {
202 start: split_ranges[0].start,
203 end: *at,
204 });
205 split_ranges[0].start = *at;
206 }
207
208 Self {
209 ranges: split_ranges,
210 }
211 }
212}
213
214impl<T: Copy + Ord + Sub<Output = T>> RangeSet<T> {
215 pub fn shift_left(&mut self, offset: &T) {
221 self.ranges.iter_mut().for_each(|range| {
222 range.start = range.start - *offset;
223 range.end = range.end - *offset;
224 });
225 }
226}
227
228impl<T: Copy + Ord + Add<Output = T>> RangeSet<T> {
229 pub fn shift_right(&mut self, offset: &T) {
235 self.ranges.iter_mut().for_each(|range| {
236 range.start = range.start + *offset;
237 range.end = range.end + *offset;
238 });
239 }
240}
241
242impl<T: Copy + Ord> RangeSet<T>
243where
244 Range<T>: ExactSizeIterator<Item = T>,
245{
246 #[must_use]
248 pub fn len(&self) -> usize {
249 self.ranges.iter().map(|range| range.len()).sum()
250 }
251}
252
253impl<T: Copy + Ord> TryFrom<RangeSet<T>> for Range<T> {
254 type Error = RangeSet<T>;
255
256 fn try_from(set: RangeSet<T>) -> Result<Self, Self::Error> {
259 if set.len_ranges() == 1 {
260 Ok(set.ranges.into_iter().next().unwrap())
261 } else {
262 Err(set)
263 }
264 }
265}
266
267impl<T: Copy + Ord> From<Range<T>> for RangeSet<T> {
268 fn from(range: Range<T>) -> Self {
269 if range.is_empty() {
270 return Self::default();
271 }
272
273 Self {
274 ranges: Vec::from([range]),
275 }
276 }
277}
278
279impl<const N: usize, T: Copy + Ord> From<[Range<T>; N]> for RangeSet<T> {
280 fn from(ranges: [Range<T>; N]) -> Self {
281 Self::new(&ranges)
282 }
283}
284
285impl<T: Copy + Ord> From<&[Range<T>]> for RangeSet<T> {
286 fn from(ranges: &[Range<T>]) -> Self {
287 Self::new(ranges)
288 }
289}
290
291impl<T: Copy + Ord> PartialEq<Range<T>> for RangeSet<T> {
292 fn eq(&self, other: &Range<T>) -> bool {
293 self.ranges.len() == 1 && self.ranges[0] == *other
294 }
295}
296
297impl<T: Copy + Ord> PartialEq<Range<T>> for &RangeSet<T> {
298 fn eq(&self, other: &Range<T>) -> bool {
299 *self == other
300 }
301}
302
303impl<T: Copy + Ord> PartialEq<RangeSet<T>> for Range<T> {
304 fn eq(&self, other: &RangeSet<T>) -> bool {
305 other == self
306 }
307}
308
309impl<T: Copy + Ord> PartialEq<RangeSet<T>> for &Range<T> {
310 fn eq(&self, other: &RangeSet<T>) -> bool {
311 other == *self
312 }
313}
314
315pub struct RangeSetIter<'a, T> {
317 iter: std::slice::Iter<'a, Range<T>>,
318 current: Option<Range<T>>,
319}
320
321impl<T> Iterator for RangeSetIter<'_, T>
322where
323 T: Copy + Ord,
324 Range<T>: Iterator<Item = T>,
325{
326 type Item = T;
327
328 fn next(&mut self) -> Option<Self::Item> {
329 if let Some(range) = &mut self.current {
330 if let Some(value) = range.next() {
331 return Some(value);
332 } else {
333 self.current = None;
334 return self.next();
335 }
336 }
337
338 if let Some(range) = self.iter.next() {
339 self.current = Some(range.clone());
340 return self.next();
341 }
342
343 None
344 }
345}
346
347pub struct RangeIter<'a, T> {
349 iter: std::slice::Iter<'a, Range<T>>,
350}
351
352impl<T> Iterator for RangeIter<'_, T>
353where
354 T: Copy + Ord,
355 Range<T>: Iterator<Item = T>,
356{
357 type Item = Range<T>;
358
359 fn next(&mut self) -> Option<Self::Item> {
360 self.iter.next().cloned()
361 }
362}
363
364impl<T> ExactSizeIterator for RangeIter<'_, T>
365where
366 T: Copy + Ord,
367 Range<T>: Iterator<Item = T>,
368{
369 fn len(&self) -> usize {
370 self.iter.len()
371 }
372}
373
374impl<T> DoubleEndedIterator for RangeIter<'_, T>
375where
376 T: Copy + Ord,
377 Range<T>: Iterator<Item = T>,
378{
379 fn next_back(&mut self) -> Option<Self::Item> {
380 self.iter.next_back().cloned()
381 }
382}
383
384pub trait ToRangeSet<T: Copy + Ord> {
386 fn to_range_set(&self) -> RangeSet<T>;
388}
389
390impl<T: Copy + Ord> ToRangeSet<T> for RangeSet<T> {
391 fn to_range_set(&self) -> RangeSet<T> {
392 self.clone()
393 }
394}
395
396impl<T: Copy + Ord> ToRangeSet<T> for Range<T> {
397 fn to_range_set(&self) -> RangeSet<T> {
398 RangeSet::from(self.clone())
399 }
400}
401
402pub trait Disjoint<Rhs> {
403 #[must_use]
405 fn is_disjoint(&self, other: &Rhs) -> bool;
406}
407
408pub trait Contains<Rhs> {
409 #[must_use]
411 fn contains(&self, other: &Rhs) -> bool;
412}
413
414pub trait Step: Sized {
418 fn forward(start: Self, count: usize) -> Option<Self>;
420
421 fn backward(start: Self, count: usize) -> Option<Self>;
423}
424
425macro_rules! impl_step {
426 ($($ty:ty),+) => {
427 $(
428 impl Step for $ty {
429 fn forward(start: Self, count: usize) -> Option<Self> {
430 start.checked_add(count as Self)
431 }
432
433 fn backward(start: Self, count: usize) -> Option<Self> {
434 start.checked_sub(count as Self)
435 }
436 }
437 )*
438 };
439}
440
441impl_step!(
442 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
443);
444
445impl<T: Copy + Ord> Disjoint<Range<T>> for Range<T> {
446 fn is_disjoint(&self, other: &Range<T>) -> bool {
447 self.start >= other.end || self.end <= other.start
448 }
449}
450
451impl<T: Copy + Ord> Disjoint<RangeSet<T>> for Range<T> {
452 fn is_disjoint(&self, other: &RangeSet<T>) -> bool {
453 other.ranges.iter().all(|range| self.is_disjoint(range))
454 }
455}
456
457impl<T: Copy + Ord> Disjoint<RangeSet<T>> for RangeSet<T> {
458 fn is_disjoint(&self, other: &RangeSet<T>) -> bool {
459 self.ranges.iter().all(|range| range.is_disjoint(other))
460 }
461}
462
463impl<T: Copy + Ord> Disjoint<Range<T>> for RangeSet<T> {
464 fn is_disjoint(&self, other: &Range<T>) -> bool {
465 other.is_disjoint(self)
466 }
467}
468
469#[cfg(test)]
471pub fn assert_invariants<T: Copy + Ord>(set: &RangeSet<T>) {
472 assert!(set.ranges.windows(2).all(|w| w[0].start < w[1].start
473 && w[0].end < w[1].start
474 && w[0].start < w[0].end
475 && w[1].start < w[1].end));
476}
477
478#[cfg(test)]
479#[allow(clippy::all)]
480mod tests {
481 use super::*;
482 use rstest::*;
483
484 #[test]
485 fn test_range_disjoint() {
486 let a = 10..20;
487
488 assert!(a.is_disjoint(&(20..30)));
490 assert!(!a.is_disjoint(&(19..25)));
492 assert!(a.is_disjoint(&(0..10)));
494 assert!(!a.is_disjoint(&(5..11)));
496 assert!(!a.is_disjoint(&(15..25)));
498 assert!(!a.is_disjoint(&(5..15)));
500 assert!(!a.is_disjoint(&(5..25)));
502 assert!(!a.is_disjoint(&(10..20)));
504 }
505
506 #[test]
507 fn test_range_set_iter() {
508 let a = RangeSet::from([(10..20), (30..40), (50..60)]);
509
510 let values = a.iter().collect::<Vec<_>>();
511 let expected_values = (10..20).chain(30..40).chain(50..60).collect::<Vec<_>>();
512 assert_eq!(values, expected_values);
513 }
514
515 #[test]
516 fn test_range_iter() {
517 let a = RangeSet::from([(10..20), (30..40), (50..60)]);
518
519 let values = a.iter_ranges().collect::<Vec<_>>();
520 let expected_values = vec![10..20, 30..40, 50..60];
521
522 assert_eq!(values, expected_values);
523
524 let reversed_values = a.iter_ranges().rev().collect::<Vec<_>>();
525 let expected_reversed_values = vec![50..60, 30..40, 10..20];
526
527 assert_eq!(reversed_values, expected_reversed_values);
528
529 let mut iter = a.iter_ranges();
530 assert_eq!(iter.len(), 3);
531 _ = iter.next();
532 assert_eq!(iter.len(), 2);
533 }
534
535 #[rstest]
536 #[case(RangeSet::from([(0..1)]), 0)]
537 #[case(RangeSet::from([(0..5)]), 1)]
538 #[case(RangeSet::from([(0..5), (6..10)]), 4)]
539 #[case(RangeSet::from([(0..5), (6..10)]), 6)]
540 #[case(RangeSet::from([(0..5), (6..10)]), 9)]
541 fn test_range_set_split_off(#[case] set: RangeSet<usize>, #[case] at: usize) {
542 let mut a = set.clone();
543 let b = a.split_off(&at);
544
545 assert!(
546 a.ranges
547 .last()
548 .map(|range| !range.is_empty())
549 .unwrap_or(true)
550 );
551 assert!(
552 b.ranges
553 .first()
554 .map(|range| !range.is_empty())
555 .unwrap_or(true)
556 );
557 assert_eq!(a.len() + b.len(), set.len());
558 assert!(a.iter().chain(b.iter()).eq(set.iter()));
559 }
560
561 #[test]
562 #[should_panic = "`at` is in the set"]
563 fn test_range_set_split_off_panic_not_in_set() {
564 RangeSet::from([0..1]).split_off(&1);
565 }
566
567 #[test]
568 fn test_range_set_shift_left() {
569 let mut a = RangeSet::from([(1..5), (6..10)]);
570 a.shift_left(&1);
571
572 assert_eq!(a, RangeSet::from([(0..4), (5..9)]));
573 }
574
575 #[test]
576 fn test_range_set_shift_right() {
577 let mut a = RangeSet::from([(0..4), (5..9)]);
578 a.shift_right(&1);
579
580 assert_eq!(a, RangeSet::from([(1..5), (6..10)]));
581 }
582
583 #[test]
584 fn test_range_set_max() {
585 assert!(RangeSet::<u8>::default().max().is_none());
586 assert_eq!(RangeSet::from([0..1]).max(), Some(0));
587 assert_eq!(RangeSet::from([0..2]).max(), Some(1));
588 assert_eq!(RangeSet::from([(0..5), (6..10)]).max(), Some(9));
589 }
590}