addr_range.rs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. use super::addr::Addr;
  2. use core::{cmp::Ordering, fmt, ops::RangeBounds};
  3. #[derive(Clone, Copy)]
  4. /// A range of addresses.
  5. ///
  6. /// The range is defined by two addresses, `start` and `end` and is inclusive
  7. /// on the start and exclusive on the end.
  8. ///
  9. /// # Relations
  10. ///
  11. /// ## Comparison
  12. ///
  13. /// ### Equal
  14. /// Any two ranges that have one of them **containing** the other are considered equal.
  15. ///
  16. /// ### Less
  17. /// If the two are not equal, the one that has the **smallest** start address is considered less.
  18. ///
  19. /// ### Greater
  20. /// If the two are not equal, the one that has the **largest** end address is considered greater.
  21. ///
  22. /// ## Overlapping Check
  23. /// Use `overlap_with` instead of `==` to check if two ranges overlap.
  24. pub struct AddrRange<A: Addr> {
  25. start: A,
  26. end: A,
  27. }
  28. impl<A: Addr> Eq for AddrRange<A> {}
  29. impl<A: Addr> PartialOrd for AddrRange<A> {
  30. fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
  31. Some(self.cmp(other))
  32. }
  33. }
  34. impl<A: Addr> PartialEq for AddrRange<A> {
  35. fn eq(&self, other: &Self) -> bool {
  36. self.cmp(other) == Ordering::Equal
  37. }
  38. }
  39. impl<A: Addr> Ord for AddrRange<A> {
  40. fn cmp(&self, other: &Self) -> Ordering {
  41. if self.start == other.start {
  42. return Ordering::Equal;
  43. }
  44. if self.end == other.end {
  45. if self.start == self.end {
  46. return Ordering::Greater;
  47. }
  48. if other.start == other.end {
  49. return Ordering::Less;
  50. }
  51. return Ordering::Equal;
  52. }
  53. if self.start < other.start {
  54. if other.end < self.end {
  55. return Ordering::Equal;
  56. } else {
  57. return Ordering::Less;
  58. }
  59. }
  60. if other.start < self.start {
  61. if self.end < other.end {
  62. return Ordering::Equal;
  63. } else {
  64. return Ordering::Greater;
  65. }
  66. }
  67. unreachable!()
  68. }
  69. }
  70. impl<A: Addr> From<A> for AddrRange<A> {
  71. fn from(addr: A) -> Self {
  72. Self {
  73. start: addr,
  74. end: addr,
  75. }
  76. }
  77. }
  78. impl<A: Addr> AddrRange<A> {
  79. /// Creates a new `AddrRange` with the given start and end addresses.
  80. ///
  81. /// # Panics
  82. /// Panics if the start address is greater than the end address.
  83. ///
  84. /// # Hint
  85. /// Use `AddrRange::from(addr).grow(size)` to create a range of size `size`
  86. /// starting from `addr`.
  87. pub fn new(start: A, end: A) -> Self {
  88. assert!(start <= end);
  89. Self { start, end }
  90. }
  91. pub const fn start(&self) -> A {
  92. self.start
  93. }
  94. pub const fn end(&self) -> A {
  95. self.end
  96. }
  97. pub fn len(&self) -> usize {
  98. self.end - self.start
  99. }
  100. pub fn shrink(&self, size: usize) -> Self {
  101. assert!(size <= self.len());
  102. Self::new(self.start, self.end - size)
  103. }
  104. pub fn grow(&self, count: usize) -> Self {
  105. Self::new(self.start, self.end + count)
  106. }
  107. pub fn into_bounds(&self) -> impl RangeBounds<Self> {
  108. if self.len() == 0 {
  109. Self::from(self.start())..=Self::from(self.start())
  110. } else {
  111. Self::from(self.start())..=Self::from(self.end() - 1)
  112. }
  113. }
  114. pub fn overlap_with(&self, other: &Self) -> bool {
  115. self.start < other.end && self.end > other.start
  116. }
  117. pub fn split_at_checked(&self, at: A) -> (Option<Self>, Option<Self>) {
  118. if self.end <= at {
  119. (Some(*self), None)
  120. } else if at <= self.start {
  121. (None, Some(*self))
  122. } else {
  123. (
  124. Some(Self::new(self.start, at)),
  125. Some(Self::new(at, self.end)),
  126. )
  127. }
  128. }
  129. pub fn split_at(&self, at: A) -> (Self, Self) {
  130. let (left, right) = self.split_at_checked(at);
  131. (
  132. left.expect("`at` is too large"),
  133. right.expect("`at` is too small"),
  134. )
  135. }
  136. pub fn mask_with_checked(&self, mask: &Self) -> Option<(Option<Self>, Self, Option<Self>)> {
  137. if mask.len() == 0 || !self.overlap_with(mask) {
  138. return None;
  139. }
  140. let left;
  141. let mut mid;
  142. let right;
  143. if self.start < mask.start && mask.start < self.end {
  144. let (l, r) = self.split_at(mask.start);
  145. left = Some(l);
  146. mid = r;
  147. } else {
  148. left = None;
  149. mid = *self;
  150. }
  151. if mask.end < self.end {
  152. let (l, r) = mid.split_at(mask.end);
  153. mid = l;
  154. right = Some(r);
  155. } else {
  156. right = None;
  157. }
  158. Some((left, mid, right))
  159. }
  160. }
  161. impl<A: Addr + fmt::Debug> fmt::Debug for AddrRange<A> {
  162. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  163. write!(f, "[{:?}, {:?})", self.start, self.end)
  164. }
  165. }