use std::collections::HashSet;
use std::{hash::Hash, iter::FusedIterator};
use bitvec::{
slice::{BitSlice, IterOnes},
vec::BitVec,
};
pub trait SecondaryMap<K, V> {
type Iter<'a>: Iterator<Item = (K, &'a V)> + 'a
where
Self: 'a,
K: 'a,
V: 'a;
fn new() -> Self;
fn with_capacity(capacity: usize) -> Self;
fn default_value(&self) -> V;
fn ensure_capacity(&mut self, capacity: usize);
fn capacity(&self) -> usize;
fn get(&self, key: K) -> &V;
fn set(&mut self, key: K, val: V);
#[must_use = "Use `SecondaryMap::remove` if the stored value is not needed."]
fn take(&mut self, key: K) -> V;
#[inline]
fn remove(&mut self, key: K) {
let _ = self.take(key);
}
#[inline]
fn rekey(&mut self, old: K, new: Option<K>) {
let val = self.take(old);
if let Some(key) = new {
self.set(key, val);
}
}
#[inline]
fn swap(&mut self, key0: K, key1: K)
where
K: Clone,
V: Clone,
{
let val0 = self.get(key0.clone()).clone();
let val1 = self.get(key1.clone()).clone();
self.set(key0, val1);
self.set(key1, val0);
}
fn iter<'a>(&'a self) -> Self::Iter<'a>
where
K: 'a,
V: 'a;
}
impl<K> SecondaryMap<K, bool> for BitVec
where
K: Into<usize> + TryFrom<usize>,
{
type Iter<'a>
= BitVecIter<'a, K>
where
Self: 'a,
K: 'a;
#[inline]
fn new() -> Self {
BitVec::new()
}
#[inline]
fn with_capacity(capacity: usize) -> Self {
BitVec::with_capacity(capacity)
}
#[inline]
fn default_value(&self) -> bool {
false
}
#[inline]
fn ensure_capacity(&mut self, capacity: usize) {
BitVec::reserve(self, capacity.saturating_sub(self.capacity()));
}
#[inline]
fn capacity(&self) -> usize {
BitVec::capacity(self)
}
#[inline]
fn get(&self, key: K) -> &bool {
if BitSlice::get(self, key.into()).is_some_and(|f| *f) {
&true
} else {
&false
}
}
#[inline]
fn set(&mut self, key: K, val: bool) {
let key = key.into();
if key >= BitVec::len(self) {
if val {
BitVec::resize(self, key + 1, false);
BitSlice::set(self, key, true);
}
} else {
BitSlice::set(self, key, val);
}
}
#[inline]
fn take(&mut self, key: K) -> bool {
let key = key.into();
if key < BitVec::len(self) {
BitSlice::replace(self, key, false)
} else {
false
}
}
#[inline]
fn rekey(&mut self, old: K, new: Option<K>) {
let val = self.take(old);
if let Some(new) = new {
self.set(new, val);
}
}
#[inline]
fn swap(&mut self, key0: K, key1: K) {
let key0: usize = key0.into();
let key1: usize = key1.into();
let val0 = *self.get(key0);
let val1 = *self.get(key1);
if val0 != val1 {
self.set(key0, val1);
self.set(key1, val0);
}
}
#[inline]
fn iter<'a>(&'a self) -> Self::Iter<'a>
where
K: 'a,
{
BitVecIter {
iter: BitSlice::iter_ones(self),
phantom: std::marker::PhantomData,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct BitVecIter<'a, K> {
iter: IterOnes<'a, usize, bitvec::order::Lsb0>,
phantom: std::marker::PhantomData<K>,
}
impl<'a, K> Iterator for BitVecIter<'a, K>
where
K: TryFrom<usize>,
{
type Item = (K, &'a bool);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|i| (i.try_into().ok().unwrap(), &true))
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter
.nth(n)
.map(|i| (i.try_into().ok().unwrap(), &true))
}
#[inline]
fn count(self) -> usize {
self.iter.count()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<K> DoubleEndedIterator for BitVecIter<'_, K>
where
K: TryFrom<usize>,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.iter
.next_back()
.map(|i| (i.try_into().ok().unwrap(), &true))
}
}
impl<K> FusedIterator for BitVecIter<'_, K> where K: TryFrom<usize> {}
impl<K> SecondaryMap<K, bool> for HashSet<K>
where
K: Hash + Eq + Clone,
{
type Iter<'a>
= HashSetIter<'a, K>
where
Self: 'a,
K: 'a;
#[inline]
fn new() -> Self {
HashSet::new()
}
#[inline]
fn with_capacity(capacity: usize) -> Self {
HashSet::with_capacity(capacity)
}
#[inline]
fn default_value(&self) -> bool {
false
}
#[inline]
fn ensure_capacity(&mut self, capacity: usize) {
HashSet::reserve(self, capacity.saturating_sub(self.capacity()));
}
#[inline]
fn capacity(&self) -> usize {
HashSet::capacity(self)
}
#[inline]
fn get(&self, key: K) -> &bool {
if HashSet::contains(self, &key) {
&true
} else {
&false
}
}
#[inline]
fn set(&mut self, key: K, val: bool) {
match val {
true => HashSet::insert(self, key),
false => HashSet::remove(self, &key),
};
}
#[inline]
fn take(&mut self, key: K) -> bool {
HashSet::take(self, &key).is_some()
}
#[inline]
fn iter<'a>(&'a self) -> Self::Iter<'a>
where
K: 'a,
{
HashSetIter {
iter: HashSet::iter(self),
}
}
}
#[derive(Debug, Clone)]
pub struct HashSetIter<'a, K> {
iter: std::collections::hash_set::Iter<'a, K>,
}
impl<'a, K> Iterator for HashSetIter<'a, K>
where
K: Clone,
{
type Item = (K, &'a bool);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|k| (k.clone(), &true))
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n).map(|k| (k.clone(), &true))
}
#[inline]
fn count(self) -> usize {
self.iter.count()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}