From 3a56cbd5c8bcf18099a5b9f190a40d9060a875ca Mon Sep 17 00:00:00 2001 From: Zsombor Gegesy Date: Wed, 6 Dec 2023 00:00:36 +0100 Subject: [PATCH] Add intersection/translate and size to the interval type --- src/discrete_range_map.rs | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/discrete_range_map.rs b/src/discrete_range_map.rs index 0293d60..4d039cd 100644 --- a/src/discrete_range_map.rs +++ b/src/discrete_range_map.rs @@ -1502,6 +1502,44 @@ pub trait InclusiveRange { self.contains(other.start()) || self.contains(other.end()) } + // Intersect the range with the other one, and return Some if the intersection is not empty. + fn intersect(&self, other: &Self) -> Option + where + I: PointType, + Self: From>, + { + let intersect_start = I::max(self.start(), other.start()); + let intersect_end = I::min(self.end(), other.end()); + if intersect_start <= intersect_end { + Some(Self::from(InclusiveInterval { + start: intersect_start, + end: intersect_end, + })) + } else { + None + } + } + + fn translate(&self, delta: I) -> Self + where + I: PointType, + I: core::ops::Add, + Self: From>, + { + Self::from(InclusiveInterval { + start: self.start() + delta, + end: self.end() + delta, + }) + } + + fn size(&self) -> I + where + I: PointType, + I: core::ops::Sub, + { + (self.end() - self.start()).up().unwrap() + } + ///requires that self comes before other fn merge_ordered(&self, other: &Self) -> Self where @@ -2272,6 +2310,36 @@ mod tests { } } + #[test] + fn test_intersection() { + let input = InclusiveInterval { start: 5, end: 10 }; + assert_eq!( + input.intersect(&InclusiveInterval { start: 8, end: 13 }), + Some(InclusiveInterval { start: 8, end: 10 }) + ); + assert_eq!( + input.intersect(&InclusiveInterval { start: 10, end: 13 }), + Some(InclusiveInterval { start: 10, end: 10 }) + ); + assert_eq!( + input.intersect(&InclusiveInterval { start: 11, end: 13 }), + None + ); + } + + #[test] + fn test_translate() { + let input = InclusiveInterval { start: 5, end: 10 }; + assert_eq!(input.translate(3), InclusiveInterval { start: 8, end: 13 }); + assert_eq!(input.translate(-2), InclusiveInterval { start: 3, end: 8 }); + } + + #[test] + fn test_size() { + assert_eq!(InclusiveInterval { start: 5, end: 10 }.size(), 6); + assert_eq!(InclusiveInterval { start: 6, end: 6 }.size(), 1); + } + // Test Helper Functions //====================== fn all_non_overlapping_test_bound_entries()