use std::fmt::Debug;
#[derive(Clone)]
pub struct DirtySparseSet<Key: Debug + Copy + Ord> {
set: Vec<Key>,
}
#[derive(Clone)]
pub struct SparseSet<Key: Debug + Copy + Ord> {
set: Vec<Key>,
}
impl<Key: Debug + Copy + Ord> DirtySparseSet<Key> {
pub fn new() -> DirtySparseSet<Key> {
DirtySparseSet { set: vec![] }
}
pub fn clean(&mut self) {
self.set.sort_unstable();
self.set.dedup();
}
pub fn to_clean(mut self) -> SparseSet<Key> {
self.clean();
SparseSet { set: self.set }
}
pub fn add(&mut self, key: Key) {
self.set.push(key);
}
pub fn with_clean<R>(&mut self, f: impl FnOnce(&mut SparseSet<Key>) -> R) -> R {
self.clean();
let mut m = SparseSet {
set: core::mem::take(&mut self.set),
};
let res = f(&mut m);
self.set = m.set;
res
}
}
impl<Key: Debug + Copy + Ord> SparseSet<Key> {
pub fn new() -> SparseSet<Key> {
SparseSet { set: vec![] }
}
pub fn to_dirty(self) -> DirtySparseSet<Key> {
DirtySparseSet { set: self.set }
}
pub fn to_vec(self) -> Vec<Key> {
self.set
}
pub fn pick_subset(&self, mut f: impl FnMut(Key) -> bool) -> SparseSet<Key> {
let mut new_set = vec![];
for &elem in &self.set {
if f(elem) {
new_set.push(elem);
}
}
SparseSet { set: new_set }
}
pub fn with_dirty<R>(&mut self, f: impl FnOnce(&mut DirtySparseSet<Key>) -> R) -> R {
let mut p = DirtySparseSet {
set: core::mem::take(&mut self.set),
};
let r = f(&mut p);
self.set = p.to_clean().set;
r
}
pub fn has(&self, key: Key) -> bool {
self.set.binary_search_by_key(&key, |&k| k).is_ok()
}
pub fn del(&mut self, key: Key) {
if let Ok(idx) = self.set.binary_search_by_key(&key, |&k| k) {
self.set.remove(idx);
}
}
pub fn union(&mut self, other: SparseSet<Key>) {
let mut new = vec![];
let mut this = core::mem::take(&mut self.set).into_iter().peekable();
let mut other = other.set.into_iter().peekable();
while let (Some(a), Some(b)) = (this.peek(), other.peek()) {
if a == b {
this.next();
} else if a < b {
new.push(this.next().unwrap());
} else {
new.push(other.next().unwrap());
}
}
while let Some(el) = this.next() {
new.push(el);
}
while let Some(el) = other.next() {
new.push(el);
}
self.set = new;
}
pub fn len(&self) -> usize {
self.set.len()
}
pub fn iter(&self) -> impl Iterator<Item = Key> {
self.set.iter().copied()
}
}
impl<Key: Debug + Copy + Ord> Debug for SparseSet<Key> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}