#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct RangeMapEntry<T> {
offset: usize,
len: usize,
value: T,
}
impl<T> RangeMapEntry<T> {
pub fn offset(&self) -> usize {
self.offset
}
pub fn len(&self) -> usize {
self.len
}
pub fn end(&self) -> usize {
self.offset + self.len
}
pub fn value(&self) -> &T {
&self.value
}
pub fn value_mut(&mut self) -> &mut T {
&mut self.value
}
}
#[derive(Clone, Debug)]
pub struct RangeMap<T> {
values: Vec<RangeMapEntry<T>>,
}
impl<T: Clone> RangeMap<T> {
pub fn new(size: usize, value: T) -> Self {
RangeMap {
values: vec![RangeMapEntry {
offset: 0,
len: size,
value,
}],
}
}
pub fn len(&self) -> usize {
self.values[self.values.len() - 1].end()
}
fn range_index(&self, index: usize) -> usize {
for (i, w) in self.values.iter().enumerate() {
if index >= w.offset && index < w.end() {
return i;
}
}
self.values.len()
}
pub fn ranges(&self) -> impl DoubleEndedIterator<Item = &RangeMapEntry<T>> {
self.values.iter()
}
pub fn ranges_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut RangeMapEntry<T>> {
self.values.iter_mut()
}
pub fn range_for_index(&self, index: usize) -> &RangeMapEntry<T> {
let range_index = self.range_index(index);
&self.values[range_index]
}
fn _split(&mut self, index: usize) -> usize {
for i in 0..self.values.len() {
let w = self.values[i].clone();
if w.offset == index {
return i;
}
if index > w.offset && index < w.end() {
self.values.insert(
i + 1,
RangeMapEntry {
offset: index,
len: w.end() - index,
value: w.value,
},
);
self.values[i].len = index - w.offset;
return i + 1;
}
}
self.values.len()
}
pub fn split(
&mut self,
index: usize,
) -> (
impl DoubleEndedIterator<Item = &mut RangeMapEntry<T>>,
impl DoubleEndedIterator<Item = &mut RangeMapEntry<T>>,
) {
let range_index = self._split(index);
let (left, right) = self.values.split_at_mut(range_index);
(left.iter_mut(), right.iter_mut())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn range_for_index_empty() {
let m = RangeMap::new(10, 0.0);
assert_eq!(
m.range_for_index(0),
&RangeMapEntry {
offset: 0,
len: 10,
value: 0.0
}
);
assert_eq!(
m.range_for_index(9),
&RangeMapEntry {
offset: 0,
len: 10,
value: 0.0
}
);
}
#[test]
fn split() {
let mut m = RangeMap::new(10, 0.0);
assert_eq!(
m.ranges().collect::<Vec<_>>(),
vec![&RangeMapEntry {
offset: 0,
len: 10,
value: 0.0
}]
);
let (left, right) = m.split(5);
assert_eq!(
left.collect::<Vec<_>>(),
vec![&RangeMapEntry {
offset: 0,
len: 5,
value: 0.0
}]
);
assert_eq!(
right.collect::<Vec<_>>(),
vec![&RangeMapEntry {
offset: 5,
len: 5,
value: 0.0
}]
);
assert_eq!(
m.range_for_index(0),
&RangeMapEntry {
offset: 0,
len: 5,
value: 0.0
}
);
assert_eq!(
m.range_for_index(4),
&RangeMapEntry {
offset: 0,
len: 5,
value: 0.0
}
);
assert_eq!(
m.range_for_index(5),
&RangeMapEntry {
offset: 5,
len: 5,
value: 0.0
}
);
assert_eq!(
m.range_for_index(9),
&RangeMapEntry {
offset: 5,
len: 5,
value: 0.0
}
);
}
}