#![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},
};
#[derive(Clone)]
pub struct RangeMap<K, V> {
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,
{
#[inline]
pub fn new() -> Self {
RangeMap {
btm: BTreeMap::new(),
}
}
#[inline]
pub fn get(&self, key: &K) -> Option<&V> {
self.get_key_value(key).map(|(_range, value)| value)
}
#[inline]
pub fn get_key_value(&self, key: &K) -> Option<(&Range<K>, &V)> {
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)| {
range_start_wrapper.range.contains(key)
})
.map(|(range_start_wrapper, value)| (&range_start_wrapper.range, value))
}
#[inline]
pub fn contains_key(&self, key: &K) -> bool {
self.get(key).is_some()
}
#[inline]
pub fn contains_any(&self, range: &Range<K>) -> bool {
self.range(range).next().is_some()
}
#[inline]
pub fn contains_all(&self, range: &Range<K>) -> bool {
self.gaps(range).next().is_none()
}
#[inline]
pub fn iter(&self) -> Iter<'_, K, V> {
Iter {
inner: self.btm.iter(),
}
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut {
inner: self.btm.iter_mut(),
}
}
pub fn insert(&mut self, range: Range<K>, value: V) {
assert!(range.start < range.end);
let mut new_range_start_wrapper: RangeStartWrapper<K> = RangeStartWrapper::new(range);
let new_value = value;
let mut candidates = self
.btm
.range((Bound::Unbounded, Bound::Included(&new_range_start_wrapper)))
.rev()
.take(2)
.filter(|(stored_range_start_wrapper, _stored_value)| {
stored_range_start_wrapper
.range
.touches(&new_range_start_wrapper.range)
});
if let Some(mut candidate) = candidates.next() {
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,
);
}
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()
{
#[allow(clippy::suspicious_operation_groupings)]
if stored_range_start_wrapper.range.start == new_range_start_wrapper.range.end
&& *stored_value != new_value
{
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,
);
}
self.btm.insert(new_range_start_wrapper, new_value);
}
pub fn remove(&mut self, range: Range<K>) {
assert!(range.start < range.end);
let range_start_wrapper: RangeStartWrapper<K> = RangeStartWrapper::new(range);
let range = &range_start_wrapper.range;
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)| {
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,
);
}
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 {
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 {
if new_range.overlaps(&stored_range_start_wrapper.range) {
self.btm.remove(&stored_range_start_wrapper);
if stored_range_start_wrapper.range.start < new_range.start {
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 {
self.btm.insert(
RangeStartWrapper::new(
new_range.end.clone()..stored_range_start_wrapper.range.end,
),
stored_value,
);
}
} else {
}
}
}
fn adjust_overlapping_ranges_for_remove(
&mut self,
stored_range_start_wrapper: RangeStartWrapper<K>,
stored_value: V,
range_to_remove: &Range<K>,
) {
self.btm.remove(&stored_range_start_wrapper);
let stored_range = stored_range_start_wrapper.range;
if stored_range.start < range_to_remove.start {
self.btm.insert(
RangeStartWrapper::new(stored_range.start..range_to_remove.start.clone()),
stored_value.clone(),
);
}
if stored_range.end > range_to_remove.end {
self.btm.insert(
RangeStartWrapper::new(range_to_remove.end.clone()..stored_range.end),
stored_value,
);
}
}
pub fn split_at(&mut self, key: &K) {
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,
};
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,
);
}
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())),
)),
}
}
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),
}
}
pub fn gaps<'a>(&'a self, outer_range: &'a Range<K>) -> Gaps<'a, K, V> {
let mut keys = self.btm.keys().peekable();
let mut candidate_start = &outer_range.start;
while let Some(item) = keys.peek() {
if item.range.end <= outer_range.start {
let _ = keys.next();
} else if item.range.start <= outer_range.start {
candidate_start = &item.range.end;
let _ = keys.next();
} else {
break;
}
}
Gaps {
outer_range,
keys,
candidate_start,
}
}
}
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 {}
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 {}
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 {}
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);
})
}
}
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()
}
}
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()
}
}
pub struct Gaps<'a, K, V> {
outer_range: &'a Range<K>,
keys: Peekable<btree_map::Keys<'a, RangeStartWrapper<K>, V>>,
candidate_start: &'a K,
}
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 {
return None;
}
let (gap_end, mut next_candidate_start) = if let Some(next_item) = self.keys.next() {
if next_item.range.start < self.outer_range.end {
(&next_item.range.start, &next_item.range.end)
} else {
(&self.outer_range.end, &self.outer_range.end)
}
} else {
(&self.outer_range.end, &self.outer_range.end)
};
while let Some(next_item) = self.keys.peek() {
if next_item.range.start == *next_candidate_start {
next_candidate_start = &next_item.range.end;
self.keys.next().expect("We just checked that this exists");
} else {
break;
}
}
let gap = self.candidate_start.clone()..gap_end.clone();
self.candidate_start = next_candidate_start;
Some(gap)
}
}
#[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 {
cmp::max(&self.start, &other.start) < cmp::min(&self.end, &other.end)
}
fn touches(&self, other: &Self) -> bool {
cmp::max(&self.start, &other.start) <= cmp::min(&self.end, &other.end)
}
}
pub trait StepLite {
fn add_one(&self) -> Self;
fn sub_one(&self) -> Self;
}
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);
pub trait StepFns<T> {
fn add_one(start: &T) -> T;
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()
}
}
#[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();
range_map.insert(1..3, false);
range_map.insert(3..5, false);
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();
range_map.insert(1..3, false);
range_map.insert(3..5, true);
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();
range_map.insert(1..4, false);
range_map.insert(3..5, false);
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();
range_map.insert(1..4, false);
range_map.insert(3..5, true);
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();
range_map.insert(3..5, false);
range_map.insert(1..3, false);
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();
range_map.insert(3..5, true);
range_map.insert(1..3, false);
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();
range_map.insert(1..5, false);
range_map.insert(2..4, false);
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();
range_map.insert(1..5, true);
range_map.insert(2..4, false);
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();
range_map.insert(1..3, false);
range_map.insert(3..5, true);
range_map.insert(3..5, false);
assert_eq!(range_map.to_vec(), vec![(1..5, false)]);
}
#[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);
}
#[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![]);
}
#[test]
fn whole_range_is_a_gap() {
let range_map: RangeMap<u32, ()> = RangeMap::new();
let outer_range = 1..8;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(1..8));
assert_eq!(gaps.next(), None);
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();
range_map.insert(1..6, ());
let outer_range = 1..6;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
}
#[test]
fn item_before_outer_range() {
let mut range_map: RangeMap<u32, ()> = RangeMap::new();
range_map.insert(1..3, ());
let outer_range = 5..8;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(5..8));
assert_eq!(gaps.next(), None);
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();
range_map.insert(1..5, ());
let outer_range = 5..8;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(5..8));
assert_eq!(gaps.next(), None);
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();
range_map.insert(1..6, ());
let outer_range = 5..8;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(6..8));
assert_eq!(gaps.next(), None);
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();
range_map.insert(5..6, ());
let outer_range = 5..8;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(6..8));
assert_eq!(gaps.next(), None);
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();
range_map.insert(5..6, ());
range_map.insert(3..4, ());
let outer_range = 1..8;
let mut gaps = range_map.gaps(&outer_range);
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);
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();
range_map.insert(7..8, ());
let outer_range = 5..8;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(5..7));
assert_eq!(gaps.next(), None);
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();
range_map.insert(4..6, ());
let outer_range = 2..5;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(2..4));
assert_eq!(gaps.next(), None);
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();
range_map.insert(4..8, ());
let outer_range = 1..4;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(1..4));
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
}
#[test]
fn item_after_outer_range() {
let mut range_map: RangeMap<u32, ()> = RangeMap::new();
range_map.insert(6..7, ());
let outer_range = 1..4;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(1..4));
assert_eq!(gaps.next(), None);
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();
range_map.insert(1..3, ());
range_map.insert(5..7, ());
let outer_range = 4..4;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), None);
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();
range_map.insert(2..4, ());
range_map.insert(4..6, ());
let outer_range = 4..4;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), None);
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();
range_map.insert(2..5, ());
let outer_range = 4..4;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
}
#[test]
fn no_empty_gaps() {
let mut range_map: RangeMap<u32, bool> = RangeMap::new();
range_map.insert(4..5, true);
range_map.insert(3..4, false);
let outer_range = 1..8;
let mut gaps = range_map.gaps(&outer_range);
assert_eq!(gaps.next(), Some(1..3));
assert_eq!(gaps.next(), Some(5..8));
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
assert_eq!(gaps.next(), None);
}
#[test]
fn map_debug_repr_looks_right() {
let mut map: RangeMap<u32, ()> = RangeMap::new();
assert_eq!(format!("{:?}", map), "{}");
map.insert(2..5, ());
assert_eq!(format!("{:?}", map), "{2..5: ()}");
map.insert(6..7, ());
map.insert(8..9, ());
assert_eq!(format!("{:?}", map), "{2..5: (), 6..7: (), 8..9: ()}");
}
#[test]
fn into_iter_matches_iter() {
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<_>>();
assert_eq!(cloned, vec![(1..3, false), (3..5, true)]);
assert_eq!(cloned, consumed);
}
}