blob: b09433c40225d01f1d015070d6ae609f7f0cf332 [file] [log] [blame]
#![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<K, V> {
// Wrap ranges so that they are `Ord`.
// See `range_wrapper.rs` for explanation.
btm: BTreeMap<RangeStartWrapper<K>, V>,
}
impl<K, V> Default for RangeMap<K, V>
where
K: Ord + Clone,
V: Eq + Clone,
{
fn default() -> Self {
Self::new()
}
}
impl<K, V> RangeMap<K, V>
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<K>, &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<K>) -> 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<K>) -> 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<K>, &'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<K>, &'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<K>, 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<K> = 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<T> for RangeStartWrapper<T>`
// 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<K>) {
// 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<K> = 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<T> for RangeStartWrapper<T>`
// 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<K>,
stored_value: V,
new_range: &mut Range<K>,
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<K>,
stored_value: V,
range_to_remove: &Range<K>,
) {
// 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<K>, &V)`.
pub fn range(&self, range: &Range<K>) -> 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<K>, &mut V)`.
pub fn range_mut(&mut self, range: &Range<K>) -> 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<K>`.
///
/// 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<K>) -> 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<K>, &'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<K>, V>,
}
impl<'a, K, V> Iterator for Iter<'a, K, V>
where
K: 'a,
V: 'a,
{
type Item = (&'a Range<K>, &'a V);
fn next(&mut self) -> Option<(&'a Range<K>, &'a V)> {
self.inner.next().map(|(by_start, v)| (&by_start.range, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
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<K>, &'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<K>, V>,
}
impl<'a, K, V> Iterator for IterMut<'a, K, V>
where
K: 'a,
V: 'a,
{
type Item = (&'a Range<K>, &'a mut V);
fn next(&mut self) -> Option<(&'a Range<K>, &'a mut V)> {
self.inner.next().map(|(by_start, v)| (&by_start.range, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
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<K>, 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<K, V> {
inner: btree_map::IntoIter<RangeStartWrapper<K>, V>,
}
impl<K, V> IntoIterator for RangeMap<K, V> {
type Item = (Range<K>, V);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
inner: self.btm.into_iter(),
}
}
}
impl<K, V> Iterator for IntoIter<K, V> {
type Item = (Range<K>, V);
fn next(&mut self) -> Option<(Range<K>, V)> {
self.inner.next().map(|(by_start, v)| (by_start.range, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<K, V> FusedIterator for IntoIter<K, V> where K: Ord + Clone {}
impl<K, V> ExactSizeIterator for IntoIter<K, V> 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<K: Debug, V: Debug> Debug for RangeMap<K, V>
where
K: Ord + Clone,
V: Eq + Clone,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
f.debug_map().entries(self.iter()).finish()
}
}
impl<K, V> FromIterator<(Range<K>, V)> for RangeMap<K, V>
where
K: Ord + Clone,
V: Eq + Clone,
{
fn from_iter<T: IntoIterator<Item = (Range<K>, V)>>(iter: T) -> Self {
let mut range_map = RangeMap::new();
range_map.extend(iter);
range_map
}
}
impl<K, V> Extend<(Range<K>, V)> for RangeMap<K, V>
where
K: Ord + Clone,
V: Eq + Clone,
{
fn extend<T: IntoIterator<Item = (Range<K>, 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<K>, &'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<K>, 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<K>, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(by_start, v)| (&by_start.range, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
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<K>, &'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<K>, 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<K>, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(by_start, v)| (&by_start.range, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
/// An iterator over all ranges not covered by a `RangeMap`.
///
/// The iterator element type is `Range<K>`.
///
/// 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<K>,
keys: Peekable<btree_map::Keys<'a, RangeStartWrapper<K>, 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<K>;
fn next(&mut self) -> Option<Self::Item> {
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<T> {
pub range: Range<T>,
}
impl<T> RangeStartWrapper<T> {
#[inline]
pub fn new(range: Range<T>) -> RangeStartWrapper<T> {
RangeStartWrapper { range }
}
}
impl<T> PartialEq for RangeStartWrapper<T>
where
T: Eq,
{
fn eq(&self, other: &RangeStartWrapper<T>) -> bool {
self.range.start == other.range.start
}
}
impl<T> Ord for RangeStartWrapper<T>
where
T: Ord,
{
fn cmp(&self, other: &RangeStartWrapper<T>) -> Ordering {
self.range.start.cmp(&other.range.start)
}
}
impl<T> PartialOrd for RangeStartWrapper<T>
where
T: Ord,
{
fn partial_cmp(&self, other: &RangeStartWrapper<T>) -> Option<Ordering> {
Some(self.cmp(other))
}
}
pub trait RangeExt<T> {
fn overlaps(&self, other: &Self) -> bool;
fn touches(&self, other: &Self) -> bool;
}
impl<T> RangeExt<T> for Range<T>
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<T> {
/// 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<T> StepFns<T> 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<K, V> {
fn to_vec(&self) -> Vec<(Range<K>, V)>;
}
impl<K, V> RangeMapExt<K, V> for RangeMap<K, V>
where
K: Ord + Clone,
V: Eq + Clone,
{
fn to_vec(&self) -> Vec<(Range<K>, V)> {
self.iter().map(|(kr, v)| (kr.clone(), v.clone())).collect()
}
}
//
// Insertion tests
//
#[test]
fn empty_map_is_empty() {
let range_map: RangeMap<u32, bool> = RangeMap::new();
assert_eq!(range_map.to_vec(), vec![]);
}
#[test]
fn insert_into_empty_map() {
let mut range_map: RangeMap<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, bool> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, ()> = 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<u32, bool> = 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<u32, ()> = 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<u32, bool> = 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::<Vec<_>>();
// Correct value
assert_eq!(cloned, vec![(1..3, false), (3..5, true)]);
// Equality
assert_eq!(cloned, consumed);
}
}