interval.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. use serde::{Deserialize, Serialize};
  2. use std::{
  3. cmp::{max, min},
  4. fmt,
  5. ops::{Range, RangeInclusive, RangeTo, RangeToInclusive},
  6. };
  7. /// Representing a closed-open range;
  8. /// the interval [5, 7) is the set {5, 6}.
  9. ///
  10. /// It is an invariant that `start <= end`. An interval where `end < start` is
  11. /// considered empty.
  12. #[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
  13. pub struct Interval {
  14. pub start: usize,
  15. pub end: usize,
  16. }
  17. impl Interval {
  18. /// Construct a new `Interval` representing the range [start..end).
  19. /// It is an invariant that `start <= end`.
  20. pub fn new(start: usize, end: usize) -> Interval {
  21. debug_assert!(start <= end);
  22. Interval { start, end }
  23. }
  24. pub fn start(&self) -> usize {
  25. self.start
  26. }
  27. pub fn end(&self) -> usize {
  28. self.end
  29. }
  30. pub fn start_end(&self) -> (usize, usize) {
  31. (self.start, self.end)
  32. }
  33. pub fn is_before(&self, val: usize) -> bool {
  34. self.end <= val
  35. }
  36. pub fn contains(&self, val: usize) -> bool {
  37. self.start <= val && val < self.end
  38. }
  39. pub fn contains_range(&self, start: usize, end: usize) -> bool {
  40. !self.intersect(Interval::new(start, end)).is_empty()
  41. }
  42. pub fn is_after(&self, val: usize) -> bool {
  43. self.start > val
  44. }
  45. pub fn is_empty(&self) -> bool {
  46. self.end <= self.start
  47. }
  48. pub fn intersect(&self, other: Interval) -> Interval {
  49. let start = max(self.start, other.start);
  50. let end = min(self.end, other.end);
  51. Interval {
  52. start,
  53. end: max(start, end),
  54. }
  55. }
  56. // the first half of self - other
  57. pub fn prefix(&self, other: Interval) -> Interval {
  58. Interval {
  59. start: min(self.start, other.start),
  60. end: min(self.end, other.start),
  61. }
  62. }
  63. // the second half of self - other
  64. pub fn suffix(&self, other: Interval) -> Interval {
  65. Interval {
  66. start: max(self.start, other.end),
  67. end: max(self.end, other.end),
  68. }
  69. }
  70. pub fn translate(&self, amount: usize) -> Interval {
  71. Interval {
  72. start: self.start + amount,
  73. end: self.end + amount,
  74. }
  75. }
  76. pub fn translate_neg(&self, amount: usize) -> Interval {
  77. debug_assert!(self.start >= amount);
  78. Interval {
  79. start: self.start - amount,
  80. end: self.end - amount,
  81. }
  82. }
  83. pub fn union(&self, other: Interval) -> Interval {
  84. if self.is_empty() {
  85. return other;
  86. }
  87. if other.is_empty() {
  88. return *self;
  89. }
  90. let start = min(self.start, other.start);
  91. let end = max(self.end, other.end);
  92. Interval { start, end }
  93. }
  94. pub fn size(&self) -> usize {
  95. self.end - self.start
  96. }
  97. }
  98. impl std::default::Default for Interval {
  99. fn default() -> Self {
  100. Interval::new(0, 0)
  101. }
  102. }
  103. impl fmt::Display for Interval {
  104. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  105. write!(f, "[{}, {})", self.start(), self.end())
  106. }
  107. }
  108. impl fmt::Debug for Interval {
  109. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  110. fmt::Display::fmt(self, f)
  111. }
  112. }
  113. impl From<Range<usize>> for Interval {
  114. fn from(src: Range<usize>) -> Interval {
  115. let Range { start, end } = src;
  116. Interval { start, end }
  117. }
  118. }
  119. impl From<RangeTo<usize>> for Interval {
  120. fn from(src: RangeTo<usize>) -> Interval {
  121. Interval::new(0, src.end)
  122. }
  123. }
  124. impl From<RangeInclusive<usize>> for Interval {
  125. fn from(src: RangeInclusive<usize>) -> Interval {
  126. Interval::new(*src.start(), src.end().saturating_add(1))
  127. }
  128. }
  129. impl From<RangeToInclusive<usize>> for Interval {
  130. fn from(src: RangeToInclusive<usize>) -> Interval {
  131. Interval::new(0, src.end.saturating_add(1))
  132. }
  133. }
  134. #[cfg(test)]
  135. mod tests {
  136. use crate::core::interval::Interval;
  137. #[test]
  138. fn contains() {
  139. let i = Interval::new(2, 42);
  140. assert!(!i.contains(1));
  141. assert!(i.contains(2));
  142. assert!(i.contains(3));
  143. assert!(i.contains(41));
  144. assert!(!i.contains(42));
  145. assert!(!i.contains(43));
  146. }
  147. #[test]
  148. fn before() {
  149. let i = Interval::new(2, 42);
  150. assert!(!i.is_before(1));
  151. assert!(!i.is_before(2));
  152. assert!(!i.is_before(3));
  153. assert!(!i.is_before(41));
  154. assert!(i.is_before(42));
  155. assert!(i.is_before(43));
  156. }
  157. #[test]
  158. fn after() {
  159. let i = Interval::new(2, 42);
  160. assert!(i.is_after(1));
  161. assert!(!i.is_after(2));
  162. assert!(!i.is_after(3));
  163. assert!(!i.is_after(41));
  164. assert!(!i.is_after(42));
  165. assert!(!i.is_after(43));
  166. }
  167. #[test]
  168. fn translate() {
  169. let i = Interval::new(2, 42);
  170. assert_eq!(Interval::new(5, 45), i.translate(3));
  171. assert_eq!(Interval::new(1, 41), i.translate_neg(1));
  172. }
  173. #[test]
  174. fn empty() {
  175. assert!(Interval::new(0, 0).is_empty());
  176. assert!(Interval::new(1, 1).is_empty());
  177. assert!(!Interval::new(1, 2).is_empty());
  178. }
  179. #[test]
  180. fn intersect() {
  181. assert_eq!(
  182. Interval::new(2, 3),
  183. Interval::new(1, 3).intersect(Interval::new(2, 4))
  184. );
  185. assert!(Interval::new(1, 2)
  186. .intersect(Interval::new(2, 43))
  187. .is_empty());
  188. }
  189. #[test]
  190. fn prefix() {
  191. assert_eq!(
  192. Interval::new(1, 2),
  193. Interval::new(1, 4).prefix(Interval::new(2, 3))
  194. );
  195. }
  196. #[test]
  197. fn suffix() {
  198. assert_eq!(
  199. Interval::new(3, 4),
  200. Interval::new(1, 4).suffix(Interval::new(2, 3))
  201. );
  202. }
  203. #[test]
  204. fn size() {
  205. assert_eq!(40, Interval::new(2, 42).size());
  206. assert_eq!(0, Interval::new(1, 1).size());
  207. assert_eq!(1, Interval::new(1, 2).size());
  208. }
  209. }