1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::cmp; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::ops::RangeInclusive; 7*bb4ee6a4SAndroid Build Coastguard Worker 8*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 9*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 10*bb4ee6a4SAndroid Build Coastguard Worker 11*bb4ee6a4SAndroid Build Coastguard Worker /// Represents a range of addresses from `start` to `end`, inclusive. 12*bb4ee6a4SAndroid Build Coastguard Worker /// 13*bb4ee6a4SAndroid Build Coastguard Worker /// Why not use the standard `RangeInclusive`? `RangeInclusive` is not `Copy`, because it tries to 14*bb4ee6a4SAndroid Build Coastguard Worker /// be an iterator as well as a range (which also means it is larger than necessary). Additionally, 15*bb4ee6a4SAndroid Build Coastguard Worker /// we would also like to implement some convenience functions for our own type. 16*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Deserialize, Serialize)] 17*bb4ee6a4SAndroid Build Coastguard Worker #[serde(deny_unknown_fields)] 18*bb4ee6a4SAndroid Build Coastguard Worker pub struct AddressRange { 19*bb4ee6a4SAndroid Build Coastguard Worker pub start: u64, 20*bb4ee6a4SAndroid Build Coastguard Worker pub end: u64, 21*bb4ee6a4SAndroid Build Coastguard Worker } 22*bb4ee6a4SAndroid Build Coastguard Worker 23*bb4ee6a4SAndroid Build Coastguard Worker impl AddressRange { 24*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a new `AddressRange` from `start` and `end` (inclusive) addresses. from_start_and_end(start: u64, end: u64) -> Self25*bb4ee6a4SAndroid Build Coastguard Worker pub const fn from_start_and_end(start: u64, end: u64) -> Self { 26*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start, end } 27*bb4ee6a4SAndroid Build Coastguard Worker } 28*bb4ee6a4SAndroid Build Coastguard Worker 29*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a new `AddressRange` from `start` extending `size` bytes. 30*bb4ee6a4SAndroid Build Coastguard Worker /// 31*bb4ee6a4SAndroid Build Coastguard Worker /// Returns `None` if the generated range is not representable as an `AddressRange`. from_start_and_size(start: u64, size: u64) -> Option<Self>32*bb4ee6a4SAndroid Build Coastguard Worker pub const fn from_start_and_size(start: u64, size: u64) -> Option<Self> { 33*bb4ee6a4SAndroid Build Coastguard Worker if size == 0 { 34*bb4ee6a4SAndroid Build Coastguard Worker Some(AddressRange::empty()) 35*bb4ee6a4SAndroid Build Coastguard Worker } else if let Some(end) = start.checked_add(size - 1) { 36*bb4ee6a4SAndroid Build Coastguard Worker Some(AddressRange { start, end }) 37*bb4ee6a4SAndroid Build Coastguard Worker } else { 38*bb4ee6a4SAndroid Build Coastguard Worker None 39*bb4ee6a4SAndroid Build Coastguard Worker } 40*bb4ee6a4SAndroid Build Coastguard Worker } 41*bb4ee6a4SAndroid Build Coastguard Worker 42*bb4ee6a4SAndroid Build Coastguard Worker /// Returns an empty range. empty() -> Self43*bb4ee6a4SAndroid Build Coastguard Worker pub const fn empty() -> Self { 44*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 1, end: 0 } 45*bb4ee6a4SAndroid Build Coastguard Worker } 46*bb4ee6a4SAndroid Build Coastguard Worker 47*bb4ee6a4SAndroid Build Coastguard Worker /// Returns `true` if this range is empty (contains no addresses). is_empty(&self) -> bool48*bb4ee6a4SAndroid Build Coastguard Worker pub fn is_empty(&self) -> bool { 49*bb4ee6a4SAndroid Build Coastguard Worker self.end < self.start 50*bb4ee6a4SAndroid Build Coastguard Worker } 51*bb4ee6a4SAndroid Build Coastguard Worker 52*bb4ee6a4SAndroid Build Coastguard Worker /// Returns `true` if this range contains `address`. contains(&self, address: u64) -> bool53*bb4ee6a4SAndroid Build Coastguard Worker pub fn contains(&self, address: u64) -> bool { 54*bb4ee6a4SAndroid Build Coastguard Worker address >= self.start && address <= self.end 55*bb4ee6a4SAndroid Build Coastguard Worker } 56*bb4ee6a4SAndroid Build Coastguard Worker 57*bb4ee6a4SAndroid Build Coastguard Worker /// Returns `true` if `other` is fully contained within this range. 58*bb4ee6a4SAndroid Build Coastguard Worker /// 59*bb4ee6a4SAndroid Build Coastguard Worker /// Empty ranges are considered to be not contained by any range. contains_range(&self, other: AddressRange) -> bool60*bb4ee6a4SAndroid Build Coastguard Worker pub fn contains_range(&self, other: AddressRange) -> bool { 61*bb4ee6a4SAndroid Build Coastguard Worker !other.is_empty() && other.start >= self.start && other.end <= self.end 62*bb4ee6a4SAndroid Build Coastguard Worker } 63*bb4ee6a4SAndroid Build Coastguard Worker 64*bb4ee6a4SAndroid Build Coastguard Worker /// Returns `true` if the two ranges have any addresses in common. overlaps(&self, other: AddressRange) -> bool65*bb4ee6a4SAndroid Build Coastguard Worker pub fn overlaps(&self, other: AddressRange) -> bool { 66*bb4ee6a4SAndroid Build Coastguard Worker !self.intersect(other).is_empty() 67*bb4ee6a4SAndroid Build Coastguard Worker } 68*bb4ee6a4SAndroid Build Coastguard Worker 69*bb4ee6a4SAndroid Build Coastguard Worker /// Find the intersection (overlapping region) of two ranges. 70*bb4ee6a4SAndroid Build Coastguard Worker /// 71*bb4ee6a4SAndroid Build Coastguard Worker /// If there is no intersection, the resulting `AddressRange` will be empty. intersect(&self, other: AddressRange) -> AddressRange72*bb4ee6a4SAndroid Build Coastguard Worker pub fn intersect(&self, other: AddressRange) -> AddressRange { 73*bb4ee6a4SAndroid Build Coastguard Worker let start = cmp::max(self.start, other.start); 74*bb4ee6a4SAndroid Build Coastguard Worker let end = cmp::min(self.end, other.end); 75*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start, end } 76*bb4ee6a4SAndroid Build Coastguard Worker } 77*bb4ee6a4SAndroid Build Coastguard Worker 78*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the ranges of addresses contained in `self` but not in `other`. 79*bb4ee6a4SAndroid Build Coastguard Worker /// 80*bb4ee6a4SAndroid Build Coastguard Worker /// The first returned range will contain the addresses in `self` that are less than the start 81*bb4ee6a4SAndroid Build Coastguard Worker /// of `other`, which will be empty if the starts of the ranges coincide. 82*bb4ee6a4SAndroid Build Coastguard Worker /// 83*bb4ee6a4SAndroid Build Coastguard Worker /// The second returned range will contain the addresses in `self` that are greater than the end 84*bb4ee6a4SAndroid Build Coastguard Worker /// of `other`, which will be empty if the ends of the ranges coincide. non_overlapping_ranges(&self, other: AddressRange) -> (AddressRange, AddressRange)85*bb4ee6a4SAndroid Build Coastguard Worker pub fn non_overlapping_ranges(&self, other: AddressRange) -> (AddressRange, AddressRange) { 86*bb4ee6a4SAndroid Build Coastguard Worker let before = if self.start >= other.start { 87*bb4ee6a4SAndroid Build Coastguard Worker Self::empty() 88*bb4ee6a4SAndroid Build Coastguard Worker } else { 89*bb4ee6a4SAndroid Build Coastguard Worker let start = cmp::min(self.start, other.start); 90*bb4ee6a4SAndroid Build Coastguard Worker 91*bb4ee6a4SAndroid Build Coastguard Worker // We know that self.start != other.start, so the maximum of the two cannot be 0, so it 92*bb4ee6a4SAndroid Build Coastguard Worker // is safe to subtract 1. 93*bb4ee6a4SAndroid Build Coastguard Worker let end = cmp::max(self.start, other.start) - 1; 94*bb4ee6a4SAndroid Build Coastguard Worker 95*bb4ee6a4SAndroid Build Coastguard Worker // For non-overlapping ranges, don't allow end to extend past self.end. 96*bb4ee6a4SAndroid Build Coastguard Worker let end = cmp::min(end, self.end); 97*bb4ee6a4SAndroid Build Coastguard Worker 98*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start, end } 99*bb4ee6a4SAndroid Build Coastguard Worker }; 100*bb4ee6a4SAndroid Build Coastguard Worker 101*bb4ee6a4SAndroid Build Coastguard Worker let after = if self.end <= other.end { 102*bb4ee6a4SAndroid Build Coastguard Worker Self::empty() 103*bb4ee6a4SAndroid Build Coastguard Worker } else { 104*bb4ee6a4SAndroid Build Coastguard Worker // We know that self.end != other.end, so the minimum of the two cannot be `u64::MAX`, 105*bb4ee6a4SAndroid Build Coastguard Worker // so it is safe to add 1. 106*bb4ee6a4SAndroid Build Coastguard Worker let start = cmp::min(self.end, other.end) + 1; 107*bb4ee6a4SAndroid Build Coastguard Worker 108*bb4ee6a4SAndroid Build Coastguard Worker // For non-overlapping ranges, don't allow start to extend before self.start. 109*bb4ee6a4SAndroid Build Coastguard Worker let start = cmp::max(start, self.start); 110*bb4ee6a4SAndroid Build Coastguard Worker 111*bb4ee6a4SAndroid Build Coastguard Worker let end = cmp::max(self.end, other.end); 112*bb4ee6a4SAndroid Build Coastguard Worker 113*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start, end } 114*bb4ee6a4SAndroid Build Coastguard Worker }; 115*bb4ee6a4SAndroid Build Coastguard Worker 116*bb4ee6a4SAndroid Build Coastguard Worker (before, after) 117*bb4ee6a4SAndroid Build Coastguard Worker } 118*bb4ee6a4SAndroid Build Coastguard Worker 119*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the two subsets of this range split at the `split_start` address. 120*bb4ee6a4SAndroid Build Coastguard Worker /// 121*bb4ee6a4SAndroid Build Coastguard Worker /// If `split_start` is not contained in this range, returns the original range and an empty 122*bb4ee6a4SAndroid Build Coastguard Worker /// range. split_at(&self, split_start: u64) -> (AddressRange, AddressRange)123*bb4ee6a4SAndroid Build Coastguard Worker pub fn split_at(&self, split_start: u64) -> (AddressRange, AddressRange) { 124*bb4ee6a4SAndroid Build Coastguard Worker // split_start == self.start is handled as a special case so we know that split_start - 1 is 125*bb4ee6a4SAndroid Build Coastguard Worker // safe below (and so the empty range is always returned second if present). 126*bb4ee6a4SAndroid Build Coastguard Worker if split_start <= self.start || split_start > self.end { 127*bb4ee6a4SAndroid Build Coastguard Worker (*self, Self::empty()) 128*bb4ee6a4SAndroid Build Coastguard Worker } else { 129*bb4ee6a4SAndroid Build Coastguard Worker ( 130*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 131*bb4ee6a4SAndroid Build Coastguard Worker start: self.start, 132*bb4ee6a4SAndroid Build Coastguard Worker end: split_start - 1, 133*bb4ee6a4SAndroid Build Coastguard Worker }, 134*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 135*bb4ee6a4SAndroid Build Coastguard Worker start: split_start, 136*bb4ee6a4SAndroid Build Coastguard Worker end: self.end, 137*bb4ee6a4SAndroid Build Coastguard Worker }, 138*bb4ee6a4SAndroid Build Coastguard Worker ) 139*bb4ee6a4SAndroid Build Coastguard Worker } 140*bb4ee6a4SAndroid Build Coastguard Worker } 141*bb4ee6a4SAndroid Build Coastguard Worker 142*bb4ee6a4SAndroid Build Coastguard Worker /// Computes the length of an `AddressRange`. 143*bb4ee6a4SAndroid Build Coastguard Worker /// 144*bb4ee6a4SAndroid Build Coastguard Worker /// Returns `None` if the length cannot be represented in `u64` (if the range is 145*bb4ee6a4SAndroid Build Coastguard Worker /// `0..=u64::MAX`). len(&self) -> Option<u64>146*bb4ee6a4SAndroid Build Coastguard Worker pub fn len(&self) -> Option<u64> { 147*bb4ee6a4SAndroid Build Coastguard Worker // Treat any range we consider "empty" (end < start) as having 0 length. 148*bb4ee6a4SAndroid Build Coastguard Worker if self.is_empty() { 149*bb4ee6a4SAndroid Build Coastguard Worker Some(0) 150*bb4ee6a4SAndroid Build Coastguard Worker } else { 151*bb4ee6a4SAndroid Build Coastguard Worker (self.end - self.start).checked_add(1) 152*bb4ee6a4SAndroid Build Coastguard Worker } 153*bb4ee6a4SAndroid Build Coastguard Worker } 154*bb4ee6a4SAndroid Build Coastguard Worker log(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result155*bb4ee6a4SAndroid Build Coastguard Worker fn log(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 156*bb4ee6a4SAndroid Build Coastguard Worker if self.is_empty() { 157*bb4ee6a4SAndroid Build Coastguard Worker f.write_str("empty") 158*bb4ee6a4SAndroid Build Coastguard Worker } else { 159*bb4ee6a4SAndroid Build Coastguard Worker f.write_fmt(format_args!("{:#x}..={:#x}", self.start, self.end)) 160*bb4ee6a4SAndroid Build Coastguard Worker } 161*bb4ee6a4SAndroid Build Coastguard Worker } 162*bb4ee6a4SAndroid Build Coastguard Worker } 163*bb4ee6a4SAndroid Build Coastguard Worker 164*bb4ee6a4SAndroid Build Coastguard Worker impl std::fmt::Display for AddressRange { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result165*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 166*bb4ee6a4SAndroid Build Coastguard Worker self.log(f) 167*bb4ee6a4SAndroid Build Coastguard Worker } 168*bb4ee6a4SAndroid Build Coastguard Worker } 169*bb4ee6a4SAndroid Build Coastguard Worker 170*bb4ee6a4SAndroid Build Coastguard Worker impl std::fmt::Debug for AddressRange { fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result171*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 172*bb4ee6a4SAndroid Build Coastguard Worker self.log(f) 173*bb4ee6a4SAndroid Build Coastguard Worker } 174*bb4ee6a4SAndroid Build Coastguard Worker } 175*bb4ee6a4SAndroid Build Coastguard Worker 176*bb4ee6a4SAndroid Build Coastguard Worker impl From<RangeInclusive<u64>> for AddressRange { from(range: RangeInclusive<u64>) -> AddressRange177*bb4ee6a4SAndroid Build Coastguard Worker fn from(range: RangeInclusive<u64>) -> AddressRange { 178*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 179*bb4ee6a4SAndroid Build Coastguard Worker start: *range.start(), 180*bb4ee6a4SAndroid Build Coastguard Worker end: *range.end(), 181*bb4ee6a4SAndroid Build Coastguard Worker } 182*bb4ee6a4SAndroid Build Coastguard Worker } 183*bb4ee6a4SAndroid Build Coastguard Worker } 184*bb4ee6a4SAndroid Build Coastguard Worker 185*bb4ee6a4SAndroid Build Coastguard Worker impl From<AddressRange> for RangeInclusive<u64> { from(address_range: AddressRange) -> RangeInclusive<u64>186*bb4ee6a4SAndroid Build Coastguard Worker fn from(address_range: AddressRange) -> RangeInclusive<u64> { 187*bb4ee6a4SAndroid Build Coastguard Worker address_range.start..=address_range.end 188*bb4ee6a4SAndroid Build Coastguard Worker } 189*bb4ee6a4SAndroid Build Coastguard Worker } 190*bb4ee6a4SAndroid Build Coastguard Worker 191*bb4ee6a4SAndroid Build Coastguard Worker /// Custom comparison function that provides a total order over all possible `AddressRange` values 192*bb4ee6a4SAndroid Build Coastguard Worker /// and considers all empty ranges to be equal. 193*bb4ee6a4SAndroid Build Coastguard Worker impl cmp::Ord for AddressRange { cmp(&self, other: &Self) -> cmp::Ordering194*bb4ee6a4SAndroid Build Coastguard Worker fn cmp(&self, other: &Self) -> cmp::Ordering { 195*bb4ee6a4SAndroid Build Coastguard Worker match (self.is_empty(), other.is_empty()) { 196*bb4ee6a4SAndroid Build Coastguard Worker // Any empty range is equal to any other empty range. 197*bb4ee6a4SAndroid Build Coastguard Worker (true, true) => cmp::Ordering::Equal, 198*bb4ee6a4SAndroid Build Coastguard Worker // An empty range is less than any non-empty range. 199*bb4ee6a4SAndroid Build Coastguard Worker (true, false) => cmp::Ordering::Less, 200*bb4ee6a4SAndroid Build Coastguard Worker // Any non-empty range is greater than an empty range. 201*bb4ee6a4SAndroid Build Coastguard Worker (false, true) => cmp::Ordering::Greater, 202*bb4ee6a4SAndroid Build Coastguard Worker // Two non-empty ranges are ordered based on `start`, and if those are equal, `end`. 203*bb4ee6a4SAndroid Build Coastguard Worker (false, false) => self 204*bb4ee6a4SAndroid Build Coastguard Worker .start 205*bb4ee6a4SAndroid Build Coastguard Worker .cmp(&other.start) 206*bb4ee6a4SAndroid Build Coastguard Worker .then_with(|| self.end.cmp(&other.end)), 207*bb4ee6a4SAndroid Build Coastguard Worker } 208*bb4ee6a4SAndroid Build Coastguard Worker } 209*bb4ee6a4SAndroid Build Coastguard Worker } 210*bb4ee6a4SAndroid Build Coastguard Worker 211*bb4ee6a4SAndroid Build Coastguard Worker impl cmp::PartialOrd for AddressRange { partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>212*bb4ee6a4SAndroid Build Coastguard Worker fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { 213*bb4ee6a4SAndroid Build Coastguard Worker Some(cmp::Ord::cmp(self, other)) 214*bb4ee6a4SAndroid Build Coastguard Worker } 215*bb4ee6a4SAndroid Build Coastguard Worker } 216*bb4ee6a4SAndroid Build Coastguard Worker 217*bb4ee6a4SAndroid Build Coastguard Worker impl cmp::PartialEq for AddressRange { eq(&self, other: &Self) -> bool218*bb4ee6a4SAndroid Build Coastguard Worker fn eq(&self, other: &Self) -> bool { 219*bb4ee6a4SAndroid Build Coastguard Worker cmp::Ord::cmp(self, other) == cmp::Ordering::Equal 220*bb4ee6a4SAndroid Build Coastguard Worker } 221*bb4ee6a4SAndroid Build Coastguard Worker } 222*bb4ee6a4SAndroid Build Coastguard Worker 223*bb4ee6a4SAndroid Build Coastguard Worker // The `PartialEq` implementation is reflexive, symmetric, and transitive. 224*bb4ee6a4SAndroid Build Coastguard Worker impl cmp::Eq for AddressRange {} 225*bb4ee6a4SAndroid Build Coastguard Worker 226*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)] 227*bb4ee6a4SAndroid Build Coastguard Worker mod tests { 228*bb4ee6a4SAndroid Build Coastguard Worker use super::*; 229*bb4ee6a4SAndroid Build Coastguard Worker 230*bb4ee6a4SAndroid Build Coastguard Worker #[test] is_empty()231*bb4ee6a4SAndroid Build Coastguard Worker fn is_empty() { 232*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange { start: 1, end: 0 }.is_empty()); 233*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange { 234*bb4ee6a4SAndroid Build Coastguard Worker start: u64::MAX, 235*bb4ee6a4SAndroid Build Coastguard Worker end: 0 236*bb4ee6a4SAndroid Build Coastguard Worker } 237*bb4ee6a4SAndroid Build Coastguard Worker .is_empty()); 238*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange { 239*bb4ee6a4SAndroid Build Coastguard Worker start: u64::MAX, 240*bb4ee6a4SAndroid Build Coastguard Worker end: u64::MAX - 1 241*bb4ee6a4SAndroid Build Coastguard Worker } 242*bb4ee6a4SAndroid Build Coastguard Worker .is_empty()); 243*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange::empty().is_empty()); 244*bb4ee6a4SAndroid Build Coastguard Worker 245*bb4ee6a4SAndroid Build Coastguard Worker assert!(!AddressRange { start: 0, end: 1 }.is_empty()); 246*bb4ee6a4SAndroid Build Coastguard Worker assert!(!AddressRange { start: 1, end: 1 }.is_empty()); 247*bb4ee6a4SAndroid Build Coastguard Worker } 248*bb4ee6a4SAndroid Build Coastguard Worker 249*bb4ee6a4SAndroid Build Coastguard Worker #[test] contains()250*bb4ee6a4SAndroid Build Coastguard Worker fn contains() { 251*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange { start: 0, end: 5 }.contains(3)); 252*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange { start: 0, end: 0 }.contains(0)); 253*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange { 254*bb4ee6a4SAndroid Build Coastguard Worker start: 0, 255*bb4ee6a4SAndroid Build Coastguard Worker end: u64::MAX 256*bb4ee6a4SAndroid Build Coastguard Worker } 257*bb4ee6a4SAndroid Build Coastguard Worker .contains(u64::MAX)); 258*bb4ee6a4SAndroid Build Coastguard Worker 259*bb4ee6a4SAndroid Build Coastguard Worker // Empty ranges do not contain any addresses 260*bb4ee6a4SAndroid Build Coastguard Worker assert!(!AddressRange { start: 5, end: 0 }.contains(3)); 261*bb4ee6a4SAndroid Build Coastguard Worker } 262*bb4ee6a4SAndroid Build Coastguard Worker 263*bb4ee6a4SAndroid Build Coastguard Worker #[test] contains_range()264*bb4ee6a4SAndroid Build Coastguard Worker fn contains_range() { 265*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 0, end: 5 })); 266*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 1, end: 3 })); 267*bb4ee6a4SAndroid Build Coastguard Worker 268*bb4ee6a4SAndroid Build Coastguard Worker // Partly overlapping ranges 269*bb4ee6a4SAndroid Build Coastguard Worker assert!( 270*bb4ee6a4SAndroid Build Coastguard Worker !AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 3, end: 9 }) 271*bb4ee6a4SAndroid Build Coastguard Worker ); 272*bb4ee6a4SAndroid Build Coastguard Worker assert!( 273*bb4ee6a4SAndroid Build Coastguard Worker !AddressRange { start: 3, end: 9 }.contains_range(AddressRange { start: 0, end: 5 }) 274*bb4ee6a4SAndroid Build Coastguard Worker ); 275*bb4ee6a4SAndroid Build Coastguard Worker 276*bb4ee6a4SAndroid Build Coastguard Worker // Completely discontiguous ranges 277*bb4ee6a4SAndroid Build Coastguard Worker assert!( 278*bb4ee6a4SAndroid Build Coastguard Worker !AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 6, end: 9 }) 279*bb4ee6a4SAndroid Build Coastguard Worker ); 280*bb4ee6a4SAndroid Build Coastguard Worker assert!( 281*bb4ee6a4SAndroid Build Coastguard Worker !AddressRange { start: 6, end: 9 }.contains_range(AddressRange { start: 0, end: 5 }) 282*bb4ee6a4SAndroid Build Coastguard Worker ); 283*bb4ee6a4SAndroid Build Coastguard Worker 284*bb4ee6a4SAndroid Build Coastguard Worker // Empty ranges do not contain anything 285*bb4ee6a4SAndroid Build Coastguard Worker assert!( 286*bb4ee6a4SAndroid Build Coastguard Worker !AddressRange { start: 5, end: 0 }.contains_range(AddressRange { start: 0, end: 5 }) 287*bb4ee6a4SAndroid Build Coastguard Worker ); 288*bb4ee6a4SAndroid Build Coastguard Worker assert!( 289*bb4ee6a4SAndroid Build Coastguard Worker !AddressRange { start: 5, end: 0 }.contains_range(AddressRange { start: 5, end: 0 }) 290*bb4ee6a4SAndroid Build Coastguard Worker ); 291*bb4ee6a4SAndroid Build Coastguard Worker assert!( 292*bb4ee6a4SAndroid Build Coastguard Worker !AddressRange { start: 5, end: 0 }.contains_range(AddressRange { start: 1, end: 3 }) 293*bb4ee6a4SAndroid Build Coastguard Worker ); 294*bb4ee6a4SAndroid Build Coastguard Worker 295*bb4ee6a4SAndroid Build Coastguard Worker // An empty range is not contained by anything 296*bb4ee6a4SAndroid Build Coastguard Worker assert!( 297*bb4ee6a4SAndroid Build Coastguard Worker !AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 3, end: 1 }) 298*bb4ee6a4SAndroid Build Coastguard Worker ); 299*bb4ee6a4SAndroid Build Coastguard Worker } 300*bb4ee6a4SAndroid Build Coastguard Worker test_intersect(a: (u64, u64), b: (u64, u64), answer: (u64, u64))301*bb4ee6a4SAndroid Build Coastguard Worker fn test_intersect(a: (u64, u64), b: (u64, u64), answer: (u64, u64)) { 302*bb4ee6a4SAndroid Build Coastguard Worker let a = AddressRange { 303*bb4ee6a4SAndroid Build Coastguard Worker start: a.0, 304*bb4ee6a4SAndroid Build Coastguard Worker end: a.1, 305*bb4ee6a4SAndroid Build Coastguard Worker }; 306*bb4ee6a4SAndroid Build Coastguard Worker let b = AddressRange { 307*bb4ee6a4SAndroid Build Coastguard Worker start: b.0, 308*bb4ee6a4SAndroid Build Coastguard Worker end: b.1, 309*bb4ee6a4SAndroid Build Coastguard Worker }; 310*bb4ee6a4SAndroid Build Coastguard Worker let answer = AddressRange { 311*bb4ee6a4SAndroid Build Coastguard Worker start: answer.0, 312*bb4ee6a4SAndroid Build Coastguard Worker end: answer.1, 313*bb4ee6a4SAndroid Build Coastguard Worker }; 314*bb4ee6a4SAndroid Build Coastguard Worker 315*bb4ee6a4SAndroid Build Coastguard Worker // intersect() should be commutative, so try it both ways 316*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(a.intersect(b), answer); 317*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(b.intersect(a), answer); 318*bb4ee6a4SAndroid Build Coastguard Worker } 319*bb4ee6a4SAndroid Build Coastguard Worker 320*bb4ee6a4SAndroid Build Coastguard Worker #[test] intersect()321*bb4ee6a4SAndroid Build Coastguard Worker fn intersect() { 322*bb4ee6a4SAndroid Build Coastguard Worker test_intersect((0, 5), (0, 5), (0, 5)); 323*bb4ee6a4SAndroid Build Coastguard Worker test_intersect((0, 5), (0, 3), (0, 3)); 324*bb4ee6a4SAndroid Build Coastguard Worker test_intersect((0, 5), (3, 5), (3, 5)); 325*bb4ee6a4SAndroid Build Coastguard Worker test_intersect((0, 5), (5, 5), (5, 5)); 326*bb4ee6a4SAndroid Build Coastguard Worker test_intersect((0, 5), (4, 9), (4, 5)); 327*bb4ee6a4SAndroid Build Coastguard Worker test_intersect((0, u64::MAX), (3, 5), (3, 5)); 328*bb4ee6a4SAndroid Build Coastguard Worker test_intersect((10, 20), (5, 15), (10, 15)); 329*bb4ee6a4SAndroid Build Coastguard Worker } 330*bb4ee6a4SAndroid Build Coastguard Worker test_intersect_empty(a: (u64, u64), b: (u64, u64))331*bb4ee6a4SAndroid Build Coastguard Worker fn test_intersect_empty(a: (u64, u64), b: (u64, u64)) { 332*bb4ee6a4SAndroid Build Coastguard Worker let a = AddressRange { 333*bb4ee6a4SAndroid Build Coastguard Worker start: a.0, 334*bb4ee6a4SAndroid Build Coastguard Worker end: a.1, 335*bb4ee6a4SAndroid Build Coastguard Worker }; 336*bb4ee6a4SAndroid Build Coastguard Worker let b = AddressRange { 337*bb4ee6a4SAndroid Build Coastguard Worker start: b.0, 338*bb4ee6a4SAndroid Build Coastguard Worker end: b.1, 339*bb4ee6a4SAndroid Build Coastguard Worker }; 340*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.intersect(b).is_empty()); 341*bb4ee6a4SAndroid Build Coastguard Worker assert!(b.intersect(a).is_empty()); 342*bb4ee6a4SAndroid Build Coastguard Worker } 343*bb4ee6a4SAndroid Build Coastguard Worker 344*bb4ee6a4SAndroid Build Coastguard Worker #[test] intersect_empty()345*bb4ee6a4SAndroid Build Coastguard Worker fn intersect_empty() { 346*bb4ee6a4SAndroid Build Coastguard Worker test_intersect_empty((0, 5), (10, 20)); 347*bb4ee6a4SAndroid Build Coastguard Worker test_intersect_empty((5, 0), (3, 4)); 348*bb4ee6a4SAndroid Build Coastguard Worker test_intersect_empty((10, 20), (20, 10)); 349*bb4ee6a4SAndroid Build Coastguard Worker test_intersect_empty((10, 20), (30, 40)); 350*bb4ee6a4SAndroid Build Coastguard Worker } 351*bb4ee6a4SAndroid Build Coastguard Worker 352*bb4ee6a4SAndroid Build Coastguard Worker #[test] non_overlapping_ranges()353*bb4ee6a4SAndroid Build Coastguard Worker fn non_overlapping_ranges() { 354*bb4ee6a4SAndroid Build Coastguard Worker // Two identical ranges have no non-overlapping ranges. 355*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 356*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 0, end: 100 } 357*bb4ee6a4SAndroid Build Coastguard Worker .non_overlapping_ranges(AddressRange { start: 0, end: 100 }), 358*bb4ee6a4SAndroid Build Coastguard Worker (AddressRange::empty(), AddressRange::empty()) 359*bb4ee6a4SAndroid Build Coastguard Worker ); 360*bb4ee6a4SAndroid Build Coastguard Worker 361*bb4ee6a4SAndroid Build Coastguard Worker // Non-overlapping regions on both sides. 362*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 363*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 0, end: 100 } 364*bb4ee6a4SAndroid Build Coastguard Worker .non_overlapping_ranges(AddressRange { start: 10, end: 20 }), 365*bb4ee6a4SAndroid Build Coastguard Worker ( 366*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 0, end: 9 }, 367*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 368*bb4ee6a4SAndroid Build Coastguard Worker start: 21, 369*bb4ee6a4SAndroid Build Coastguard Worker end: 100 370*bb4ee6a4SAndroid Build Coastguard Worker } 371*bb4ee6a4SAndroid Build Coastguard Worker ) 372*bb4ee6a4SAndroid Build Coastguard Worker ); 373*bb4ee6a4SAndroid Build Coastguard Worker 374*bb4ee6a4SAndroid Build Coastguard Worker // Non-overlapping region on the left but not on the right. 375*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 376*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 0, end: 100 }.non_overlapping_ranges(AddressRange { 377*bb4ee6a4SAndroid Build Coastguard Worker start: 10, 378*bb4ee6a4SAndroid Build Coastguard Worker end: 100 379*bb4ee6a4SAndroid Build Coastguard Worker }), 380*bb4ee6a4SAndroid Build Coastguard Worker (AddressRange { start: 0, end: 9 }, AddressRange::empty()) 381*bb4ee6a4SAndroid Build Coastguard Worker ); 382*bb4ee6a4SAndroid Build Coastguard Worker 383*bb4ee6a4SAndroid Build Coastguard Worker // Non-overlapping region on the right but not on the left. 384*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 385*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 0, end: 100 } 386*bb4ee6a4SAndroid Build Coastguard Worker .non_overlapping_ranges(AddressRange { start: 0, end: 50 }), 387*bb4ee6a4SAndroid Build Coastguard Worker ( 388*bb4ee6a4SAndroid Build Coastguard Worker AddressRange::empty(), 389*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 390*bb4ee6a4SAndroid Build Coastguard Worker start: 51, 391*bb4ee6a4SAndroid Build Coastguard Worker end: 100 392*bb4ee6a4SAndroid Build Coastguard Worker } 393*bb4ee6a4SAndroid Build Coastguard Worker ) 394*bb4ee6a4SAndroid Build Coastguard Worker ); 395*bb4ee6a4SAndroid Build Coastguard Worker 396*bb4ee6a4SAndroid Build Coastguard Worker // Other range not contained within this range and greater than this range. 397*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 398*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 0, end: 100 }.non_overlapping_ranges(AddressRange { 399*bb4ee6a4SAndroid Build Coastguard Worker start: 200, 400*bb4ee6a4SAndroid Build Coastguard Worker end: 300 401*bb4ee6a4SAndroid Build Coastguard Worker }), 402*bb4ee6a4SAndroid Build Coastguard Worker (AddressRange { start: 0, end: 100 }, AddressRange::empty()) 403*bb4ee6a4SAndroid Build Coastguard Worker ); 404*bb4ee6a4SAndroid Build Coastguard Worker 405*bb4ee6a4SAndroid Build Coastguard Worker // Other range not contained within this range and less than this range. 406*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 407*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 408*bb4ee6a4SAndroid Build Coastguard Worker start: 200, 409*bb4ee6a4SAndroid Build Coastguard Worker end: 300 410*bb4ee6a4SAndroid Build Coastguard Worker } 411*bb4ee6a4SAndroid Build Coastguard Worker .non_overlapping_ranges(AddressRange { start: 0, end: 100 }), 412*bb4ee6a4SAndroid Build Coastguard Worker ( 413*bb4ee6a4SAndroid Build Coastguard Worker AddressRange::empty(), 414*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 415*bb4ee6a4SAndroid Build Coastguard Worker start: 200, 416*bb4ee6a4SAndroid Build Coastguard Worker end: 300 417*bb4ee6a4SAndroid Build Coastguard Worker } 418*bb4ee6a4SAndroid Build Coastguard Worker ) 419*bb4ee6a4SAndroid Build Coastguard Worker ); 420*bb4ee6a4SAndroid Build Coastguard Worker 421*bb4ee6a4SAndroid Build Coastguard Worker // Partially overlapping region with non-overlapping region on the left. 422*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 423*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 10, end: 20 } 424*bb4ee6a4SAndroid Build Coastguard Worker .non_overlapping_ranges(AddressRange { start: 15, end: 35 }), 425*bb4ee6a4SAndroid Build Coastguard Worker (AddressRange { start: 10, end: 14 }, AddressRange::empty()) 426*bb4ee6a4SAndroid Build Coastguard Worker ); 427*bb4ee6a4SAndroid Build Coastguard Worker 428*bb4ee6a4SAndroid Build Coastguard Worker // Partially overlapping region with non-overlapping region on the right. 429*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 430*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 10, end: 20 } 431*bb4ee6a4SAndroid Build Coastguard Worker .non_overlapping_ranges(AddressRange { start: 5, end: 15 }), 432*bb4ee6a4SAndroid Build Coastguard Worker (AddressRange::empty(), AddressRange { start: 16, end: 20 }) 433*bb4ee6a4SAndroid Build Coastguard Worker ); 434*bb4ee6a4SAndroid Build Coastguard Worker } 435*bb4ee6a4SAndroid Build Coastguard Worker 436*bb4ee6a4SAndroid Build Coastguard Worker #[test] split_at()437*bb4ee6a4SAndroid Build Coastguard Worker fn split_at() { 438*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 439*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 10, end: 20 }.split_at(15), 440*bb4ee6a4SAndroid Build Coastguard Worker ( 441*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 10, end: 14 }, 442*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 15, end: 20 } 443*bb4ee6a4SAndroid Build Coastguard Worker ) 444*bb4ee6a4SAndroid Build Coastguard Worker ); 445*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 446*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 10, end: 20 }.split_at(20), 447*bb4ee6a4SAndroid Build Coastguard Worker ( 448*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 10, end: 19 }, 449*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 20, end: 20 } 450*bb4ee6a4SAndroid Build Coastguard Worker ) 451*bb4ee6a4SAndroid Build Coastguard Worker ); 452*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 453*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 10, end: 20 }.split_at(10), 454*bb4ee6a4SAndroid Build Coastguard Worker (AddressRange { start: 10, end: 20 }, AddressRange::empty()) 455*bb4ee6a4SAndroid Build Coastguard Worker ); 456*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 457*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 10, end: 20 }.split_at(21), 458*bb4ee6a4SAndroid Build Coastguard Worker (AddressRange { start: 10, end: 20 }, AddressRange::empty()) 459*bb4ee6a4SAndroid Build Coastguard Worker ); 460*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 461*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { start: 10, end: 20 }.split_at(9), 462*bb4ee6a4SAndroid Build Coastguard Worker (AddressRange { start: 10, end: 20 }, AddressRange::empty()) 463*bb4ee6a4SAndroid Build Coastguard Worker ); 464*bb4ee6a4SAndroid Build Coastguard Worker } 465*bb4ee6a4SAndroid Build Coastguard Worker 466*bb4ee6a4SAndroid Build Coastguard Worker #[test] from_start_and_size_valid()467*bb4ee6a4SAndroid Build Coastguard Worker fn from_start_and_size_valid() { 468*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 469*bb4ee6a4SAndroid Build Coastguard Worker AddressRange::from_start_and_size(0x100, 0x20), 470*bb4ee6a4SAndroid Build Coastguard Worker Some(AddressRange { 471*bb4ee6a4SAndroid Build Coastguard Worker start: 0x100, 472*bb4ee6a4SAndroid Build Coastguard Worker end: 0x11f 473*bb4ee6a4SAndroid Build Coastguard Worker }) 474*bb4ee6a4SAndroid Build Coastguard Worker ); 475*bb4ee6a4SAndroid Build Coastguard Worker 476*bb4ee6a4SAndroid Build Coastguard Worker // Max-sized range based at 0 477*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 478*bb4ee6a4SAndroid Build Coastguard Worker AddressRange::from_start_and_size(0, u64::MAX), 479*bb4ee6a4SAndroid Build Coastguard Worker Some(AddressRange { 480*bb4ee6a4SAndroid Build Coastguard Worker start: 0, 481*bb4ee6a4SAndroid Build Coastguard Worker end: u64::MAX - 1 482*bb4ee6a4SAndroid Build Coastguard Worker }) 483*bb4ee6a4SAndroid Build Coastguard Worker ); 484*bb4ee6a4SAndroid Build Coastguard Worker 485*bb4ee6a4SAndroid Build Coastguard Worker // Max-sized range based at 1 486*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 487*bb4ee6a4SAndroid Build Coastguard Worker AddressRange::from_start_and_size(1, u64::MAX), 488*bb4ee6a4SAndroid Build Coastguard Worker Some(AddressRange { 489*bb4ee6a4SAndroid Build Coastguard Worker start: 1, 490*bb4ee6a4SAndroid Build Coastguard Worker end: u64::MAX 491*bb4ee6a4SAndroid Build Coastguard Worker }) 492*bb4ee6a4SAndroid Build Coastguard Worker ); 493*bb4ee6a4SAndroid Build Coastguard Worker 494*bb4ee6a4SAndroid Build Coastguard Worker // One-byte range based at u64::MAX 495*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 496*bb4ee6a4SAndroid Build Coastguard Worker AddressRange::from_start_and_size(u64::MAX, 1), 497*bb4ee6a4SAndroid Build Coastguard Worker Some(AddressRange { 498*bb4ee6a4SAndroid Build Coastguard Worker start: u64::MAX, 499*bb4ee6a4SAndroid Build Coastguard Worker end: u64::MAX 500*bb4ee6a4SAndroid Build Coastguard Worker }) 501*bb4ee6a4SAndroid Build Coastguard Worker ); 502*bb4ee6a4SAndroid Build Coastguard Worker 503*bb4ee6a4SAndroid Build Coastguard Worker // Empty range (size = 0) with arbitrary start 504*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange::from_start_and_size(u64::MAX, 0) 505*bb4ee6a4SAndroid Build Coastguard Worker .unwrap() 506*bb4ee6a4SAndroid Build Coastguard Worker .is_empty()); 507*bb4ee6a4SAndroid Build Coastguard Worker } 508*bb4ee6a4SAndroid Build Coastguard Worker 509*bb4ee6a4SAndroid Build Coastguard Worker #[test] from_start_and_size_invalid()510*bb4ee6a4SAndroid Build Coastguard Worker fn from_start_and_size_invalid() { 511*bb4ee6a4SAndroid Build Coastguard Worker // 2 + u64::MAX - 1 overflows 512*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AddressRange::from_start_and_size(2, u64::MAX), None); 513*bb4ee6a4SAndroid Build Coastguard Worker 514*bb4ee6a4SAndroid Build Coastguard Worker // 0x100 + u64::MAX - 1 overflows 515*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(AddressRange::from_start_and_size(0x100, u64::MAX), None); 516*bb4ee6a4SAndroid Build Coastguard Worker 517*bb4ee6a4SAndroid Build Coastguard Worker // 0x100 + (u64::MAX - 0xfe) - 1 overflows 518*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 519*bb4ee6a4SAndroid Build Coastguard Worker AddressRange::from_start_and_size(0x100, u64::MAX - 0xfe), 520*bb4ee6a4SAndroid Build Coastguard Worker None 521*bb4ee6a4SAndroid Build Coastguard Worker ); 522*bb4ee6a4SAndroid Build Coastguard Worker } 523*bb4ee6a4SAndroid Build Coastguard Worker 524*bb4ee6a4SAndroid Build Coastguard Worker #[test] display()525*bb4ee6a4SAndroid Build Coastguard Worker fn display() { 526*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!( 527*bb4ee6a4SAndroid Build Coastguard Worker format!( 528*bb4ee6a4SAndroid Build Coastguard Worker "{}", 529*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 530*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1234, 531*bb4ee6a4SAndroid Build Coastguard Worker end: 0x5678 532*bb4ee6a4SAndroid Build Coastguard Worker } 533*bb4ee6a4SAndroid Build Coastguard Worker ), 534*bb4ee6a4SAndroid Build Coastguard Worker "0x1234..=0x5678" 535*bb4ee6a4SAndroid Build Coastguard Worker ); 536*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(format!("{}", AddressRange::empty()), "empty"); 537*bb4ee6a4SAndroid Build Coastguard Worker } 538*bb4ee6a4SAndroid Build Coastguard Worker 539*bb4ee6a4SAndroid Build Coastguard Worker #[test] cmp()540*bb4ee6a4SAndroid Build Coastguard Worker fn cmp() { 541*bb4ee6a4SAndroid Build Coastguard Worker assert!( 542*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 543*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1000, 544*bb4ee6a4SAndroid Build Coastguard Worker end: 0x2000 545*bb4ee6a4SAndroid Build Coastguard Worker } < AddressRange { 546*bb4ee6a4SAndroid Build Coastguard Worker start: 0x3000, 547*bb4ee6a4SAndroid Build Coastguard Worker end: 0x4000 548*bb4ee6a4SAndroid Build Coastguard Worker } 549*bb4ee6a4SAndroid Build Coastguard Worker ); 550*bb4ee6a4SAndroid Build Coastguard Worker assert!( 551*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 552*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1000, 553*bb4ee6a4SAndroid Build Coastguard Worker end: 0x2000 554*bb4ee6a4SAndroid Build Coastguard Worker } == AddressRange { 555*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1000, 556*bb4ee6a4SAndroid Build Coastguard Worker end: 0x2000 557*bb4ee6a4SAndroid Build Coastguard Worker } 558*bb4ee6a4SAndroid Build Coastguard Worker ); 559*bb4ee6a4SAndroid Build Coastguard Worker assert!( 560*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 561*bb4ee6a4SAndroid Build Coastguard Worker start: 0x3000, 562*bb4ee6a4SAndroid Build Coastguard Worker end: 0x4000 563*bb4ee6a4SAndroid Build Coastguard Worker } > AddressRange { 564*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1000, 565*bb4ee6a4SAndroid Build Coastguard Worker end: 0x2000 566*bb4ee6a4SAndroid Build Coastguard Worker } 567*bb4ee6a4SAndroid Build Coastguard Worker ); 568*bb4ee6a4SAndroid Build Coastguard Worker assert!( 569*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 570*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1000, 571*bb4ee6a4SAndroid Build Coastguard Worker end: 0x2000 572*bb4ee6a4SAndroid Build Coastguard Worker } < AddressRange { 573*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1000, 574*bb4ee6a4SAndroid Build Coastguard Worker end: 0x3000 575*bb4ee6a4SAndroid Build Coastguard Worker } 576*bb4ee6a4SAndroid Build Coastguard Worker ); 577*bb4ee6a4SAndroid Build Coastguard Worker } 578*bb4ee6a4SAndroid Build Coastguard Worker 579*bb4ee6a4SAndroid Build Coastguard Worker #[test] cmp_empty()580*bb4ee6a4SAndroid Build Coastguard Worker fn cmp_empty() { 581*bb4ee6a4SAndroid Build Coastguard Worker // Empty ranges are less than any non-empty range and equal to any other empty range. 582*bb4ee6a4SAndroid Build Coastguard Worker assert!( 583*bb4ee6a4SAndroid Build Coastguard Worker AddressRange { 584*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1000, 585*bb4ee6a4SAndroid Build Coastguard Worker end: 0x2000 586*bb4ee6a4SAndroid Build Coastguard Worker } > AddressRange::empty() 587*bb4ee6a4SAndroid Build Coastguard Worker ); 588*bb4ee6a4SAndroid Build Coastguard Worker assert!( 589*bb4ee6a4SAndroid Build Coastguard Worker AddressRange::empty() 590*bb4ee6a4SAndroid Build Coastguard Worker < AddressRange { 591*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1000, 592*bb4ee6a4SAndroid Build Coastguard Worker end: 0x2000 593*bb4ee6a4SAndroid Build Coastguard Worker } 594*bb4ee6a4SAndroid Build Coastguard Worker ); 595*bb4ee6a4SAndroid Build Coastguard Worker assert!(AddressRange { start: 5, end: 3 } == AddressRange { start: 10, end: 1 }); 596*bb4ee6a4SAndroid Build Coastguard Worker } 597*bb4ee6a4SAndroid Build Coastguard Worker } 598