use core::cmp::Ordering;
#[derive(Default)]
pub struct VecSet<T> {
sorted: Vec<T>,
}
impl<T> VecSet<T> {
pub fn insert(&mut self, a: T, f: impl Fn(&T, &T) -> Ordering) {
match self.sorted.binary_search_by(|e| f(e, &a)) {
Ok(_) => (),
Err(i) => self.sorted.insert(i, a),
}
}
pub fn range(&self, f: impl Fn(&T) -> Ordering) -> &[T] {
let start = self
.sorted
.binary_search_by(|a| match f(a) {
Ordering::Equal => Ordering::Greater,
o => o,
})
.unwrap_err();
let top = &self.sorted[start..]; let end = top
.binary_search_by(|a| match f(a) {
Ordering::Equal => Ordering::Less,
o => o,
})
.unwrap_err();
&top[..end] }
pub fn as_slice(&self) -> &[T] {
self.sorted.as_slice()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn vecset() {
let ordering = |a: &u8, b: &u8| -> Ordering { a.cmp(&b) };
let sub_ordering = |a: &u8, b: &u8| -> Ordering { (a / 2).cmp(&(b / 2)) };
let mut vs: VecSet<u8> = VecSet::default();
for n in &[32u8, 5, 2, 2, 4, 3, 2, 23, 24, 253] {
vs.insert(*n, ordering);
}
assert_eq!(vs.as_slice(), [2, 3, 4, 5, 23, 24, 32, 253]);
assert_eq!(vs.range(|a| ordering(a, &4)), [4]);
assert_eq!(vs.range(|a| sub_ordering(a, &4)), [4, 5]);
assert_eq!(vs.range(|a| sub_ordering(a, &2)), [2, 3]);
assert_eq!(vs.range(|a| sub_ordering(a, &3)), [2, 3]);
}
}