loro/crates/rle/src/rle_impl.rs

72 lines
1.8 KiB
Rust
Raw Normal View History

2022-10-24 03:51:36 +00:00
use std::ops::Range;
use crate::{HasLength, Mergable, Sliceable};
use num::{cast, Integer, NumCast};
use smallvec::{Array, SmallVec};
2022-10-08 08:04:25 +00:00
impl Sliceable for bool {
fn slice(&self, _: usize, _: usize) -> Self {
*self
}
}
2022-10-24 03:51:36 +00:00
impl<T: Integer + NumCast + Copy> Sliceable for Range<T> {
fn slice(&self, start: usize, end: usize) -> Self {
self.start + cast(start).unwrap()..self.start + cast(end).unwrap()
}
}
impl<T: PartialOrd<T> + Copy> Mergable for Range<T> {
fn is_mergable(&self, other: &Self, _: &()) -> bool {
other.start <= self.end && other.start >= self.start
}
fn merge(&mut self, other: &Self, _conf: &())
where
Self: Sized,
{
self.end = other.end;
}
}
impl<T: num::Integer + NumCast + Copy> HasLength for Range<T> {
fn len(&self) -> usize {
cast(self.end - self.start).unwrap()
}
}
/// this can make iter return type has len
impl<A, T: HasLength> HasLength for (A, T) {
fn len(&self) -> usize {
self.1.len()
}
}
/// this can make iter return type has len
impl<T: HasLength> HasLength for &T {
fn len(&self) -> usize {
(*self).len()
}
}
impl<T: HasLength + Sliceable, A: Array<Item = T>> Sliceable for SmallVec<A> {
fn slice(&self, from: usize, to: usize) -> Self {
let mut index = 0;
let mut ans: SmallVec<A> = smallvec::smallvec![];
if to == from {
return ans;
}
for item in self.iter() {
if index < to && from < index + item.content_len() {
let start = if index < from { from - index } else { 0 };
ans.push(item.slice(start, item.content_len().min(to - index)));
}
index += item.content_len();
}
ans
}
}