#![allow(dead_code)] use std::{ cmp, cmp::Ordering, collections::{btree_map, BTreeMap}, fmt::{Debug, Error as FmtError, Formatter}, iter::{FromIterator, FusedIterator, Peekable}, ops::{Add, Bound, Range, Sub}, }; /// A map whose keys are stored as (half-open) ranges bounded /// inclusively below and exclusively above `(start..end)`. /// /// Contiguous and overlapping ranges that map to the same value /// are coalesced into a single range. #[derive(Clone)] pub struct RangeMap { // Wrap ranges so that they are `Ord`. // See `range_wrapper.rs` for explanation. btm: BTreeMap, V>, } impl Default for RangeMap where K: Ord + Clone, V: Eq + Clone, { fn default() -> Self { Self::new() } } impl RangeMap where K: Ord + Clone, V: Eq + Clone, { /// Makes a new empty `RangeMap`. #[inline] pub fn new() -> Self { RangeMap { btm: BTreeMap::new(), } } /// Returns a reference to the value corresponding to the given key, /// if the key is covered by any range in the map. #[inline] pub fn get(&self, key: &K) -> Option<&V> { self.get_key_value(key).map(|(_range, value)| value) } /// Returns the range-value pair (as a pair of references) corresponding /// to the given key, if the key is covered by any range in the map. #[inline] pub fn get_key_value(&self, key: &K) -> Option<(&Range, &V)> { // The only stored range that could contain the given key is the // last stored range whose start is less than or equal to this key. let key_as_start = RangeStartWrapper::new(key.clone()..key.clone()); self.btm .range((Bound::Unbounded, Bound::Included(key_as_start))) .next_back() .filter(|(range_start_wrapper, _value)| { // Does the only candidate range contain // the requested key? range_start_wrapper.range.contains(key) }) .map(|(range_start_wrapper, value)| (&range_start_wrapper.range, value)) } /// Returns `true` if any range in the map covers the specified key. #[inline] pub fn contains_key(&self, key: &K) -> bool { self.get(key).is_some() } /// Returns `true` if any part of the provided range overlaps with a range in the map. #[inline] pub fn contains_any(&self, range: &Range) -> bool { self.range(range).next().is_some() } /// Returns `true` if all of the provided range is covered by ranges in the map. #[inline] pub fn contains_all(&self, range: &Range) -> bool { self.gaps(range).next().is_none() } /// Gets an iterator over all pairs of key range and value, /// ordered by key range. /// /// The iterator element type is `(&'a Range, &'a V)`. #[inline] pub fn iter(&self) -> Iter<'_, K, V> { Iter { inner: self.btm.iter(), } } /// Gets a mutable iterator over all pairs of key range and value, /// ordered by key range. /// /// The iterator element type is `(&'a Range, &'a mut V)`. #[inline] pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { IterMut { inner: self.btm.iter_mut(), } } /// Insert a pair of key range and value into the map. /// /// If the inserted range partially or completely overlaps any /// existing range in the map, then the existing range (or ranges) will be /// partially or completely replaced by the inserted range. /// /// If the inserted range either overlaps or is immediately adjacent /// any existing range _mapping to the same value_, then the ranges /// will be coalesced into a single contiguous range. /// /// # Panics /// /// Panics if range `start >= end`. pub fn insert(&mut self, range: Range, value: V) { // We don't want to have to make empty ranges make sense; // they don't represent anything meaningful in this structure. assert!(range.start < range.end); // Wrap up the given range so that we can "borrow" // it as a wrapper reference to either its start or end. // See `range_wrapper.rs` for explanation of these hacks. let mut new_range_start_wrapper: RangeStartWrapper = RangeStartWrapper::new(range); let new_value = value; // Is there a stored range either overlapping the start of // the range to insert or immediately preceding it? // // If there is any such stored range, it will be the last // whose start is less than or equal to the start of the range to insert, // or the one before that if both of the above cases exist. let mut candidates = self .btm .range((Bound::Unbounded, Bound::Included(&new_range_start_wrapper))) .rev() .take(2) .filter(|(stored_range_start_wrapper, _stored_value)| { // Does the candidate range either overlap // or immediately precede the range to insert? // (Remember that it might actually cover the _whole_ // range to insert and then some.) stored_range_start_wrapper .range .touches(&new_range_start_wrapper.range) }); if let Some(mut candidate) = candidates.next() { // Or the one before it if both cases described above exist. if let Some(another_candidate) = candidates.next() { candidate = another_candidate; } let (stored_range_start_wrapper, stored_value) = (candidate.0.clone(), candidate.1.clone()); self.adjust_touching_ranges_for_insert( stored_range_start_wrapper, stored_value, &mut new_range_start_wrapper.range, &new_value, ); } // Are there any stored ranges whose heads overlap or immediately // follow the range to insert? // // If there are any such stored ranges (that weren't already caught above), // their starts will fall somewhere after the start of the range to insert, // and on or before its end. // // This time around, if the latter holds, it also implies // the former so we don't need to check here if they touch. // // REVISIT: Possible micro-optimisation: `impl Borrow for RangeStartWrapper` // and use that to search here, to avoid constructing another `RangeStartWrapper`. let new_range_end_as_start = RangeStartWrapper::new( new_range_start_wrapper.range.end.clone()..new_range_start_wrapper.range.end.clone(), ); while let Some((stored_range_start_wrapper, stored_value)) = self .btm .range(( Bound::Included(&new_range_start_wrapper), Bound::Included(&new_range_end_as_start), )) .next() { // One extra exception: if we have different values, // and the stored range starts at the end of the range to insert, // then we don't want to keep looping forever trying to find more! #[allow(clippy::suspicious_operation_groupings)] if stored_range_start_wrapper.range.start == new_range_start_wrapper.range.end && *stored_value != new_value { // We're beyond the last stored range that could be relevant. // Avoid wasting time on irrelevant ranges, or even worse, looping forever. // (`adjust_touching_ranges_for_insert` below assumes that the given range // is relevant, and behaves very poorly if it is handed a range that it // shouldn't be touching.) break; } let stored_range_start_wrapper = stored_range_start_wrapper.clone(); let stored_value = stored_value.clone(); self.adjust_touching_ranges_for_insert( stored_range_start_wrapper, stored_value, &mut new_range_start_wrapper.range, &new_value, ); } // Insert the (possibly expanded) new range, and we're done! self.btm.insert(new_range_start_wrapper, new_value); } /// Removes a range from the map, if all or any of it was present. /// /// If the range to be removed _partially_ overlaps any ranges /// in the map, then those ranges will be contracted to no /// longer cover the removed range. /// /// /// # Panics /// /// Panics if range `start >= end`. pub fn remove(&mut self, range: Range) { // We don't want to have to make empty ranges make sense; // they don't represent anything meaningful in this structure. assert!(range.start < range.end); let range_start_wrapper: RangeStartWrapper = RangeStartWrapper::new(range); let range = &range_start_wrapper.range; // Is there a stored range overlapping the start of // the range to insert? // // If there is any such stored range, it will be the last // whose start is less than or equal to the start of the range to insert. if let Some((stored_range_start_wrapper, stored_value)) = self .btm .range((Bound::Unbounded, Bound::Included(&range_start_wrapper))) .next_back() .filter(|(stored_range_start_wrapper, _stored_value)| { // Does the only candidate range overlap // the range to insert? stored_range_start_wrapper.range.overlaps(range) }) .map(|(stored_range_start_wrapper, stored_value)| { (stored_range_start_wrapper.clone(), stored_value.clone()) }) { self.adjust_overlapping_ranges_for_remove( stored_range_start_wrapper, stored_value, range, ); } // Are there any stored ranges whose heads overlap the range to insert? // // If there are any such stored ranges (that weren't already caught above), // their starts will fall somewhere after the start of the range to insert, // and before its end. // // REVISIT: Possible micro-optimisation: `impl Borrow for RangeStartWrapper` // and use that to search here, to avoid constructing another `RangeStartWrapper`. let new_range_end_as_start = RangeStartWrapper::new(range.end.clone()..range.end.clone()); while let Some((stored_range_start_wrapper, stored_value)) = self .btm .range(( Bound::Excluded(&range_start_wrapper), Bound::Excluded(&new_range_end_as_start), )) .next() .map(|(stored_range_start_wrapper, stored_value)| { (stored_range_start_wrapper.clone(), stored_value.clone()) }) { self.adjust_overlapping_ranges_for_remove( stored_range_start_wrapper, stored_value, range, ); } } fn adjust_touching_ranges_for_insert( &mut self, stored_range_start_wrapper: RangeStartWrapper, stored_value: V, new_range: &mut Range, new_value: &V, ) { if stored_value == *new_value { // The ranges have the same value, so we can "adopt" // the stored range. // // This means that no matter how big or where the stored range is, // we will expand the new range's bounds to subsume it, // and then delete the stored range. new_range.start = cmp::min(&new_range.start, &stored_range_start_wrapper.range.start).clone(); new_range.end = cmp::max(&new_range.end, &stored_range_start_wrapper.range.end).clone(); self.btm.remove(&stored_range_start_wrapper); } else { // The ranges have different values. if new_range.overlaps(&stored_range_start_wrapper.range) { // The ranges overlap. This is a little bit more complicated. // Delete the stored range, and then add back between // 0 and 2 subranges at the ends of the range to insert. self.btm.remove(&stored_range_start_wrapper); if stored_range_start_wrapper.range.start < new_range.start { // Insert the piece left of the range to insert. self.btm.insert( RangeStartWrapper::new( stored_range_start_wrapper.range.start..new_range.start.clone(), ), stored_value.clone(), ); } if stored_range_start_wrapper.range.end > new_range.end { // Insert the piece right of the range to insert. self.btm.insert( RangeStartWrapper::new( new_range.end.clone()..stored_range_start_wrapper.range.end, ), stored_value, ); } } else { // No-op; they're not overlapping, // so we can just keep both ranges as they are. } } } fn adjust_overlapping_ranges_for_remove( &mut self, stored_range_start_wrapper: RangeStartWrapper, stored_value: V, range_to_remove: &Range, ) { // Delete the stored range, and then add back between // 0 and 2 subranges at the ends of the range to insert. self.btm.remove(&stored_range_start_wrapper); let stored_range = stored_range_start_wrapper.range; if stored_range.start < range_to_remove.start { // Insert the piece left of the range to insert. self.btm.insert( RangeStartWrapper::new(stored_range.start..range_to_remove.start.clone()), stored_value.clone(), ); } if stored_range.end > range_to_remove.end { // Insert the piece right of the range to insert. self.btm.insert( RangeStartWrapper::new(range_to_remove.end.clone()..stored_range.end), stored_value, ); } } /// Splits a range in two at the provided key. /// /// Does nothing if no range exists at the key, or if the key is at a range boundary. pub fn split_at(&mut self, key: &K) { // Find a range that contains the key, but doesn't start or end with the key. let bounds = ( Bound::Unbounded, Bound::Excluded(RangeStartWrapper::new(key.clone()..key.clone())), ); let range_to_remove = match self .btm .range(bounds) .next_back() .filter(|(range_start_wrapper, _value)| range_start_wrapper.range.contains(key)) { Some((k, _v)) => k.clone(), None => return, }; // Remove the range, and re-insert two new ranges with the same value, separated by the key. let value = self.btm.remove(&range_to_remove).unwrap(); self.btm.insert( RangeStartWrapper::new(range_to_remove.range.start..key.clone()), value.clone(), ); self.btm.insert( RangeStartWrapper::new(key.clone()..range_to_remove.range.end), value, ); } /// Gets an iterator over all pairs of key range and value, where the key range overlaps with /// the provided range. /// /// The iterator element type is `(&Range, &V)`. pub fn range(&self, range: &Range) -> RangeIter<'_, K, V> { let start = self .get_key_value(&range.start) .map_or(&range.start, |(k, _v)| &k.start); let end = &range.end; RangeIter { inner: self.btm.range(( Bound::Included(RangeStartWrapper::new(start.clone()..start.clone())), Bound::Excluded(RangeStartWrapper::new(end.clone()..end.clone())), )), } } /// Gets a mutable iterator over all pairs of key range and value, where the key range overlaps /// with the provided range. /// /// The iterator element type is `(&Range, &mut V)`. pub fn range_mut(&mut self, range: &Range) -> RangeMutIter<'_, K, V> { let start = self .get_key_value(&range.start) .map_or(&range.start, |(k, _v)| &k.start); let end = &range.end; let bounds = ( Bound::Included(RangeStartWrapper::new(start.clone()..start.clone())), Bound::Excluded(RangeStartWrapper::new(end.clone()..end.clone())), ); RangeMutIter { inner: self.btm.range_mut(bounds), } } /// Gets an iterator over all the maximally-sized ranges /// contained in `outer_range` that are not covered by /// any range stored in the map. /// /// The iterator element type is `Range`. /// /// NOTE: Calling `gaps` eagerly finds the first gap, /// even if the iterator is never consumed. pub fn gaps<'a>(&'a self, outer_range: &'a Range) -> Gaps<'a, K, V> { let mut keys = self.btm.keys().peekable(); // Find the first potential gap. let mut candidate_start = &outer_range.start; while let Some(item) = keys.peek() { if item.range.end <= outer_range.start { // This range sits entirely before the start of // the outer range; just skip it. let _ = keys.next(); } else if item.range.start <= outer_range.start { // This range overlaps the start of the // outer range, so the first possible candidate // range begins at its end. candidate_start = &item.range.end; let _ = keys.next(); } else { // The rest of the items might contribute to gaps. break; } } Gaps { outer_range, keys, candidate_start, } } } /// An iterator over the entries of a `RangeMap`, ordered by key range. /// /// The iterator element type is `(&'a Range, &'a V)`. /// /// This `struct` is created by the [`iter`] method on [`RangeMap`]. See its /// documentation for more. /// /// [`iter`]: RangeMap::iter pub struct Iter<'a, K, V> { inner: btree_map::Iter<'a, RangeStartWrapper, V>, } impl<'a, K, V> Iterator for Iter<'a, K, V> where K: 'a, V: 'a, { type Item = (&'a Range, &'a V); fn next(&mut self) -> Option<(&'a Range, &'a V)> { self.inner.next().map(|(by_start, v)| (&by_start.range, v)) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl<'a, K, V> FusedIterator for Iter<'a, K, V> where K: Ord + Clone {} impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> where K: Ord + Clone {} /// An iterator over the entries of a `RangeMap`, ordered by key range. /// /// The iterator element type is `(&'a Range, &'a V)`. /// /// This `struct` is created by the [`iter`] method on [`RangeMap`]. See its /// documentation for more. /// /// [`iter`]: RangeMap::iter pub struct IterMut<'a, K, V> { inner: btree_map::IterMut<'a, RangeStartWrapper, V>, } impl<'a, K, V> Iterator for IterMut<'a, K, V> where K: 'a, V: 'a, { type Item = (&'a Range, &'a mut V); fn next(&mut self) -> Option<(&'a Range, &'a mut V)> { self.inner.next().map(|(by_start, v)| (&by_start.range, v)) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl<'a, K, V> FusedIterator for IterMut<'a, K, V> where K: Ord + Clone {} impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> where K: Ord + Clone {} /// An owning iterator over the entries of a `RangeMap`, ordered by key range. /// /// The iterator element type is `(Range, V)`. /// /// This `struct` is created by the [`into_iter`] method on [`RangeMap`] /// (provided by the `IntoIterator` trait). See its documentation for more. /// /// [`into_iter`]: IntoIterator::into_iter pub struct IntoIter { inner: btree_map::IntoIter, V>, } impl IntoIterator for RangeMap { type Item = (Range, V); type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter { inner: self.btm.into_iter(), } } } impl Iterator for IntoIter { type Item = (Range, V); fn next(&mut self) -> Option<(Range, V)> { self.inner.next().map(|(by_start, v)| (by_start.range, v)) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } impl FusedIterator for IntoIter where K: Ord + Clone {} impl ExactSizeIterator for IntoIter where K: Ord + Clone {} // We can't just derive this automatically, because that would // expose irrelevant (and private) implementation details. // Instead implement it in the same way that the underlying BTreeMap does. impl Debug for RangeMap where K: Ord + Clone, V: Eq + Clone, { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { f.debug_map().entries(self.iter()).finish() } } impl FromIterator<(Range, V)> for RangeMap where K: Ord + Clone, V: Eq + Clone, { fn from_iter, V)>>(iter: T) -> Self { let mut range_map = RangeMap::new(); range_map.extend(iter); range_map } } impl Extend<(Range, V)> for RangeMap where K: Ord + Clone, V: Eq + Clone, { fn extend, V)>>(&mut self, iter: T) { iter.into_iter().for_each(move |(k, v)| { self.insert(k, v); }) } } /// An iterator over entries of a `RangeMap` whose range overlaps with a specified range. /// /// The iterator element type is `(&'a Range, &'a V)`. /// /// This `struct` is created by the [`range`] method on [`RangeMap`]. See its /// documentation for more. /// /// [`range`]: RangeMap::range pub struct RangeIter<'a, K, V> { inner: btree_map::Range<'a, RangeStartWrapper, V>, } impl<'a, K, V> FusedIterator for RangeIter<'a, K, V> where K: Ord + Clone {} impl<'a, K, V> Iterator for RangeIter<'a, K, V> where K: 'a, V: 'a, { type Item = (&'a Range, &'a V); fn next(&mut self) -> Option { self.inner.next().map(|(by_start, v)| (&by_start.range, v)) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } /// A mutable iterator over entries of a `RangeMap` whose range overlaps with a specified range. /// /// The iterator element type is `(&'a Range, &'a mut V)`. /// /// This `struct` is created by the [`range_mut`] method on [`RangeMap`]. See its /// documentation for more. /// /// [`range_mut`]: RangeMap::range_mut pub struct RangeMutIter<'a, K, V> { inner: btree_map::RangeMut<'a, RangeStartWrapper, V>, } impl<'a, K, V> FusedIterator for RangeMutIter<'a, K, V> where K: Ord + Clone {} impl<'a, K, V> Iterator for RangeMutIter<'a, K, V> where K: 'a, V: 'a, { type Item = (&'a Range, &'a mut V); fn next(&mut self) -> Option { self.inner.next().map(|(by_start, v)| (&by_start.range, v)) } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } /// An iterator over all ranges not covered by a `RangeMap`. /// /// The iterator element type is `Range`. /// /// This `struct` is created by the [`gaps`] method on [`RangeMap`]. See its /// documentation for more. /// /// [`gaps`]: RangeMap::gaps pub struct Gaps<'a, K, V> { outer_range: &'a Range, keys: Peekable, V>>, candidate_start: &'a K, } // `Gaps` is always fused. (See definition of `next` below.) impl<'a, K, V> FusedIterator for Gaps<'a, K, V> where K: Ord + Clone {} impl<'a, K, V> Iterator for Gaps<'a, K, V> where K: Ord + Clone, { type Item = Range; fn next(&mut self) -> Option { if *self.candidate_start >= self.outer_range.end { // We've already passed the end of the outer range; // there are no more gaps to find. return None; } // Figure out where this gap ends. let (gap_end, mut next_candidate_start) = if let Some(next_item) = self.keys.next() { if next_item.range.start < self.outer_range.end { // The gap goes up until the start of the next item, // and the next candidate starts after it. (&next_item.range.start, &next_item.range.end) } else { // The item sits after the end of the outer range, // so this gap ends at the end of the outer range. // This also means there will be no more gaps. (&self.outer_range.end, &self.outer_range.end) } } else { // There's no next item; the end is at the // end of the outer range. // This also means there will be no more gaps. (&self.outer_range.end, &self.outer_range.end) }; // Find the start of the next gap. while let Some(next_item) = self.keys.peek() { if next_item.range.start == *next_candidate_start { // There's another item at the start of our candidate range. // Gaps can't have zero width, so skip to the end of this // item and try again. next_candidate_start = &next_item.range.end; self.keys.next().expect("We just checked that this exists"); } else { // We found an item that actually has a gap before it. break; } } // Move the next candidate gap start past the end // of this gap, and yield the gap we found. let gap = self.candidate_start.clone()..gap_end.clone(); self.candidate_start = next_candidate_start; Some(gap) } } // Wrappers to allow storing (and sorting/searching) // ranges as the keys of a `BTreeMap`. // // We can do this because we maintain the invariants // that the order of range starts is the same as the order // of range ends, and that no two stored ranges have the // same start or end as each other. // // NOTE: Be very careful not to accidentally use these // if you really do want to compare equality of the // inner range! // // Range start wrapper // #[derive(Eq, Debug, Clone)] pub struct RangeStartWrapper { pub range: Range, } impl RangeStartWrapper { #[inline] pub fn new(range: Range) -> RangeStartWrapper { RangeStartWrapper { range } } } impl PartialEq for RangeStartWrapper where T: Eq, { fn eq(&self, other: &RangeStartWrapper) -> bool { self.range.start == other.range.start } } impl Ord for RangeStartWrapper where T: Ord, { fn cmp(&self, other: &RangeStartWrapper) -> Ordering { self.range.start.cmp(&other.range.start) } } impl PartialOrd for RangeStartWrapper where T: Ord, { fn partial_cmp(&self, other: &RangeStartWrapper) -> Option { Some(self.cmp(other)) } } pub trait RangeExt { fn overlaps(&self, other: &Self) -> bool; fn touches(&self, other: &Self) -> bool; } impl RangeExt for Range where T: Ord, { fn overlaps(&self, other: &Self) -> bool { // Strictly less than, because ends are excluded. cmp::max(&self.start, &other.start) < cmp::min(&self.end, &other.end) } fn touches(&self, other: &Self) -> bool { // Less-than-or-equal-to because if one end is excluded, the other is included. // I.e. the two could be joined into a single range, because they're overlapping // or immediately adjacent. cmp::max(&self.start, &other.start) <= cmp::min(&self.end, &other.end) } } /// Minimal version of unstable [`Step`](std::iter::Step) trait /// from the Rust standard library. /// /// This is needed for [`RangeInclusiveMap`](crate::RangeInclusiveMap) /// because ranges stored as its keys interact with each other /// when the start of one is _adjacent_ the end of another. /// I.e. we need a concept of successor values rather than just /// equality, and that is what `Step` will /// eventually provide once it is stabilized. /// /// **NOTE:** This will likely be deprecated and then eventually /// removed once the standard library's `Step` /// trait is stabilised, as most crates will then likely implement `Step` /// for their types where appropriate. /// /// See [this issue](https://github.com/rust-lang/rust/issues/42168) /// for details about that stabilization process. pub trait StepLite { /// Returns the _successor_ of `self`. /// /// If this would overflow the range of values supported by `Self`, /// this function is allowed to panic, wrap, or saturate. /// The suggested behavior is to panic when debug assertions are enabled, /// and to wrap or saturate otherwise. fn add_one(&self) -> Self; /// Returns the _predecessor_ of `self`. /// /// If this would overflow the range of values supported by `Self`, /// this function is allowed to panic, wrap, or saturate. /// The suggested behavior is to panic when debug assertions are enabled, /// and to wrap or saturate otherwise. fn sub_one(&self) -> Self; } // Implement for all common integer types. macro_rules! impl_step_lite { ($($t:ty)*) => ($( impl StepLite for $t { #[inline] fn add_one(&self) -> Self { Add::add(*self, 1) } #[inline] fn sub_one(&self) -> Self { Sub::sub(*self, 1) } } )*) } impl_step_lite!(usize u8 u16 u32 u64 u128 i8 i16 i32 i64 i128); // TODO: When on nightly, a blanket implementation for // all types that implement `std::iter::Step` instead // of the auto-impl above. /// Successor and predecessor functions defined for `T`, /// but as free functions rather than methods on `T` itself. /// /// This is useful as a workaround for Rust's "orphan rules", /// which prevent you from implementing [`StepLite`](crate::StepLite) for `T` if `T` /// is a foreign type. /// /// **NOTE:** This will likely be deprecated and then eventually /// removed once the standard library's [`Step`](std::iter::Step) /// trait is stabilised, as most crates will then likely implement `Step` /// for their types where appropriate. /// /// See [this issue](https://github.com/rust-lang/rust/issues/42168) /// for details about that stabilization process. /// /// There is also a blanket implementation of `StepFns` for all /// types implementing `StepLite`. Consumers of this crate should /// prefer to implement `StepLite` for their own types, and only /// fall back to `StepFns` when dealing with foreign types. pub trait StepFns { /// Returns the _successor_ of value `start`. /// /// If this would overflow the range of values supported by `Self`, /// this function is allowed to panic, wrap, or saturate. /// The suggested behavior is to panic when debug assertions are enabled, /// and to wrap or saturate otherwise. fn add_one(start: &T) -> T; /// Returns the _predecessor_ of value `start`. /// /// If this would overflow the range of values supported by `Self`, /// this function is allowed to panic, wrap, or saturate. /// The suggested behavior is to panic when debug assertions are enabled, /// and to wrap or saturate otherwise. fn sub_one(start: &T) -> T; } impl StepFns for T where T: StepLite, { fn add_one(start: &T) -> T { start.add_one() } fn sub_one(start: &T) -> T { start.sub_one() } } #[cfg(test)] mod tests { use super::*; use std::{format, vec, vec::Vec}; trait RangeMapExt { fn to_vec(&self) -> Vec<(Range, V)>; } impl RangeMapExt for RangeMap where K: Ord + Clone, V: Eq + Clone, { fn to_vec(&self) -> Vec<(Range, V)> { self.iter().map(|(kr, v)| (kr.clone(), v.clone())).collect() } } // // Insertion tests // #[test] fn empty_map_is_empty() { let range_map: RangeMap = RangeMap::new(); assert_eq!(range_map.to_vec(), vec![]); } #[test] fn insert_into_empty_map() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(0..50, false); assert_eq!(range_map.to_vec(), vec![(0..50, false)]); } #[test] fn new_same_value_immediately_following_stored() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(1..3, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ●---◌ ◌ ◌ ◌ ◌ range_map.insert(3..5, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-------◌ ◌ ◌ ◌ ◌ assert_eq!(range_map.to_vec(), vec![(1..5, false)]); } #[test] fn new_different_value_immediately_following_stored() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(1..3, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◆---◇ ◌ ◌ ◌ ◌ range_map.insert(3..5, true); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ // ◌ ◌ ◌ ◆---◇ ◌ ◌ ◌ ◌ assert_eq!(range_map.to_vec(), vec![(1..3, false), (3..5, true)]); } #[test] fn new_same_value_overlapping_end_of_stored() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-----◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(1..4, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ●---◌ ◌ ◌ ◌ ◌ range_map.insert(3..5, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-------◌ ◌ ◌ ◌ ◌ assert_eq!(range_map.to_vec(), vec![(1..5, false)]); } #[test] fn new_different_value_overlapping_end_of_stored() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-----◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(1..4, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◆---◇ ◌ ◌ ◌ ◌ range_map.insert(3..5, true); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ // ◌ ◌ ◌ ◆---◇ ◌ ◌ ◌ ◌ assert_eq!(range_map.to_vec(), vec![(1..3, false), (3..5, true)]); } #[test] fn new_same_value_immediately_preceding_stored() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ●---◌ ◌ ◌ ◌ ◌ range_map.insert(3..5, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(1..3, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-------◌ ◌ ◌ ◌ ◌ assert_eq!(range_map.to_vec(), vec![(1..5, false)]); } #[test] fn new_different_value_immediately_preceding_stored() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◆---◇ ◌ ◌ ◌ ◌ range_map.insert(3..5, true); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(1..3, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ // ◌ ◌ ◌ ◆---◇ ◌ ◌ ◌ ◌ assert_eq!(range_map.to_vec(), vec![(1..3, false), (3..5, true)]); } #[test] fn new_same_value_wholly_inside_stored() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-------◌ ◌ ◌ ◌ ◌ range_map.insert(1..5, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(2..4, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-------◌ ◌ ◌ ◌ ◌ assert_eq!(range_map.to_vec(), vec![(1..5, false)]); } #[test] fn new_different_value_wholly_inside_stored() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◆-------◇ ◌ ◌ ◌ ◌ range_map.insert(1..5, true); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(2..4, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ // ◌ ◌ ◆---◇ ◌ ◌ ◌ ◌ ◌ // ◌ ◌ ◌ ◌ ●-◌ ◌ ◌ ◌ ◌ assert_eq!( range_map.to_vec(), vec![(1..2, true), (2..4, false), (4..5, true)] ); } #[test] fn replace_at_end_of_existing_range_should_coalesce() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(1..3, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ●---◌ ◌ ◌ ◌ ◌ range_map.insert(3..5, true); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ●---◌ ◌ ◌ ◌ ◌ range_map.insert(3..5, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-------◌ ◌ ◌ ◌ ◌ assert_eq!(range_map.to_vec(), vec![(1..5, false)]); } // // Get* tests // #[test] fn get() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(0..50, false); assert_eq!(range_map.get(&49), Some(&false)); assert_eq!(range_map.get(&50), None); } #[test] fn get_key_value() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(0..50, false); assert_eq!(range_map.get_key_value(&49), Some((&(0..50), &false))); assert_eq!(range_map.get_key_value(&50), None); } // // Removal tests // #[test] fn remove_from_empty_map() { let mut range_map: RangeMap = RangeMap::new(); range_map.remove(0..50); assert_eq!(range_map.to_vec(), vec![]); } #[test] fn remove_non_covered_range_before_stored() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(25..75, false); range_map.remove(0..25); assert_eq!(range_map.to_vec(), vec![(25..75, false)]); } #[test] fn remove_non_covered_range_after_stored() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(25..75, false); range_map.remove(75..100); assert_eq!(range_map.to_vec(), vec![(25..75, false)]); } #[test] fn remove_overlapping_start_of_stored() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(25..75, false); range_map.remove(0..30); assert_eq!(range_map.to_vec(), vec![(30..75, false)]); } #[test] fn remove_middle_of_stored() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(25..75, false); range_map.remove(30..70); assert_eq!(range_map.to_vec(), vec![(25..30, false), (70..75, false)]); } #[test] fn remove_overlapping_end_of_stored() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(25..75, false); range_map.remove(70..100); assert_eq!(range_map.to_vec(), vec![(25..70, false)]); } #[test] fn remove_exactly_stored() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(25..75, false); range_map.remove(25..75); assert_eq!(range_map.to_vec(), vec![]); } #[test] fn remove_superset_of_stored() { let mut range_map: RangeMap = RangeMap::new(); range_map.insert(25..75, false); range_map.remove(0..100); assert_eq!(range_map.to_vec(), vec![]); } // Gaps tests #[test] fn whole_range_is_a_gap() { // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ let range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◆-------------◇ ◌ let outer_range = 1..8; let mut gaps = range_map.gaps(&outer_range); // Should yield the entire outer range. assert_eq!(gaps.next(), Some(1..8)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn whole_range_is_covered_exactly() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---------◌ ◌ ◌ ◌ range_map.insert(1..6, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◆---------◇ ◌ ◌ ◌ let outer_range = 1..6; let mut gaps = range_map.gaps(&outer_range); // Should yield no gaps. assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn item_before_outer_range() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---◌ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(1..3, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◆-----◇ ◌ let outer_range = 5..8; let mut gaps = range_map.gaps(&outer_range); // Should yield the entire outer range. assert_eq!(gaps.next(), Some(5..8)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn item_touching_start_of_outer_range() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●-------◌ ◌ ◌ ◌ ◌ range_map.insert(1..5, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◆-----◇ ◌ let outer_range = 5..8; let mut gaps = range_map.gaps(&outer_range); // Should yield the entire outer range. assert_eq!(gaps.next(), Some(5..8)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn item_overlapping_start_of_outer_range() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ●---------◌ ◌ ◌ ◌ range_map.insert(1..6, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◆-----◇ ◌ let outer_range = 5..8; let mut gaps = range_map.gaps(&outer_range); // Should yield from the end of the stored item // to the end of the outer range. assert_eq!(gaps.next(), Some(6..8)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn item_starting_at_start_of_outer_range() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ●-◌ ◌ ◌ ◌ range_map.insert(5..6, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◆-----◇ ◌ let outer_range = 5..8; let mut gaps = range_map.gaps(&outer_range); // Should yield from the item onwards. assert_eq!(gaps.next(), Some(6..8)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn items_floating_inside_outer_range() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ●-◌ ◌ ◌ ◌ range_map.insert(5..6, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ●-◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(3..4, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◆-------------◇ ◌ let outer_range = 1..8; let mut gaps = range_map.gaps(&outer_range); // Should yield gaps at start, between items, // and at end. assert_eq!(gaps.next(), Some(1..3)); assert_eq!(gaps.next(), Some(4..5)); assert_eq!(gaps.next(), Some(6..8)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn item_ending_at_end_of_outer_range() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◌ ◌ ●-◌ ◌ range_map.insert(7..8, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◆-----◇ ◌ let outer_range = 5..8; let mut gaps = range_map.gaps(&outer_range); // Should yield from the start of the outer range // up to the start of the stored item. assert_eq!(gaps.next(), Some(5..7)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn item_overlapping_end_of_outer_range() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ●---◌ ◌ ◌ ◌ range_map.insert(4..6, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◆-----◇ ◌ ◌ ◌ ◌ let outer_range = 2..5; let mut gaps = range_map.gaps(&outer_range); // Should yield from the start of the outer range // up to the start of the stored item. assert_eq!(gaps.next(), Some(2..4)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn item_touching_end_of_outer_range() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ●-------◌ ◌ range_map.insert(4..8, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◆-----◇ ◌ ◌ ◌ ◌ ◌ let outer_range = 1..4; let mut gaps = range_map.gaps(&outer_range); // Should yield the entire outer range. assert_eq!(gaps.next(), Some(1..4)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn item_after_outer_range() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◌ ●---◌ ◌ range_map.insert(6..7, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◆-----◇ ◌ ◌ ◌ ◌ ◌ let outer_range = 1..4; let mut gaps = range_map.gaps(&outer_range); // Should yield the entire outer range. assert_eq!(gaps.next(), Some(1..4)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn empty_outer_range_with_items_away_from_both_sides() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◆---◇ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(1..3, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◌ ◆---◇ ◌ ◌ range_map.insert(5..7, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◆ ◌ ◌ ◌ ◌ ◌ let outer_range = 4..4; let mut gaps = range_map.gaps(&outer_range); // Should yield no gaps. assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn empty_outer_range_with_items_touching_both_sides() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◆---◇ ◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(2..4, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◆---◇ ◌ ◌ ◌ range_map.insert(4..6, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◆ ◌ ◌ ◌ ◌ ◌ let outer_range = 4..4; let mut gaps = range_map.gaps(&outer_range); // Should yield no gaps. assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn empty_outer_range_with_item_straddling() { let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◆-----◇ ◌ ◌ ◌ ◌ ◌ range_map.insert(2..5, ()); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ◆ ◌ ◌ ◌ ◌ ◌ let outer_range = 4..4; let mut gaps = range_map.gaps(&outer_range); // Should yield no gaps. assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } #[test] fn no_empty_gaps() { // Make two ranges different values so they don't // get coalesced. let mut range_map: RangeMap = RangeMap::new(); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ◌ ●-◌ ◌ ◌ ◌ ◌ range_map.insert(4..5, true); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◌ ◌ ●-◌ ◌ ◌ ◌ ◌ ◌ range_map.insert(3..4, false); // 0 1 2 3 4 5 6 7 8 9 // ◌ ◆-------------◇ ◌ let outer_range = 1..8; let mut gaps = range_map.gaps(&outer_range); // Should yield gaps at start and end, but not between the // two touching items. (4 is covered, so there should be no gap.) assert_eq!(gaps.next(), Some(1..3)); assert_eq!(gaps.next(), Some(5..8)); assert_eq!(gaps.next(), None); // Gaps iterator should be fused. assert_eq!(gaps.next(), None); assert_eq!(gaps.next(), None); } /// /// impl Debug /// #[test] fn map_debug_repr_looks_right() { let mut map: RangeMap = RangeMap::new(); // Empty assert_eq!(format!("{:?}", map), "{}"); // One entry map.insert(2..5, ()); assert_eq!(format!("{:?}", map), "{2..5: ()}"); // Many entries map.insert(6..7, ()); map.insert(8..9, ()); assert_eq!(format!("{:?}", map), "{2..5: (), 6..7: (), 8..9: ()}"); } // Iterator Tests #[test] fn into_iter_matches_iter() { // Just use vec since that's the same implementation we'd expect let mut range_map: RangeMap = RangeMap::new(); range_map.insert(1..3, false); range_map.insert(3..5, true); let cloned = range_map.to_vec(); let consumed = range_map.into_iter().collect::>(); // Correct value assert_eq!(cloned, vec![(1..3, false), (3..5, true)]); // Equality assert_eq!(cloned, consumed); } }