use bitflags::_core::fmt::Binary;
use bitflags::_core::iter::FromIterator;
use bitflags::_core::marker::PhantomData;
use bitflags::_core::ops::{BitAndAssign, BitOr, BitXor, BitXorAssign, Index};
use fixedbitset::{FixedBitSet, IndexRange};
use index_vec::Idx;
use std::fmt;
use std::fmt::{Display, Formatter};
use std::ops::{BitAnd, BitOrAssign};
type Block = u32;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct BitSet<I: Idx + From<usize>> {
internal: FixedBitSet,
tag: PhantomData<fn(&I)>,
}
impl<I: Idx + From<usize>> BitSet<I> {
pub fn new_empty(end_index: I) -> Self {
Self {
internal: FixedBitSet::with_capacity(end_index.index()),
tag: PhantomData,
}
}
pub fn new_filled(end_index: I) -> Self {
let mut res = Self {
internal: FixedBitSet::with_capacity(end_index.index()),
tag: PhantomData,
};
res.enable_all();
res
}
pub fn with_capacity_and_blocks<Iter: IntoIterator<Item = Block>>(
bits: I,
blocks: Iter,
) -> Self {
Self {
internal: FixedBitSet::with_capacity_and_blocks(bits.index(), blocks),
tag: PhantomData,
}
}
pub fn grow(&mut self, len_idx: I) {
self.internal.grow(len_idx.index())
}
#[inline]
pub fn len(&self) -> usize {
self.internal.len()
}
#[inline]
pub fn len_idx(&self) -> I {
self.internal.len().into()
}
#[inline]
pub fn max(&self) -> I {
I::from_usize(self.internal.len())
}
#[inline]
pub fn contains(&self, bit: I) -> bool {
self.internal.contains(bit.index())
}
#[inline]
pub fn clear(&mut self) {
self.internal.clear()
}
#[inline]
pub fn insert(&mut self, bit: I) {
self.internal.insert(bit.index())
}
#[inline]
pub fn remove(&mut self, bit: I) -> bool {
let prev = self.internal[bit.index()];
self.internal.set(bit.index(), false);
prev
}
#[inline]
pub fn put(&mut self, bit: I) -> bool {
self.internal.put(bit.index())
}
#[inline]
pub fn toggle(&mut self, bit: I) {
self.internal.toggle(bit.index())
}
#[inline]
pub fn set(&mut self, bit: I, enabled: bool) {
self.internal.set(bit.index(), enabled)
}
#[inline]
pub fn copy_bit(&mut self, from: I, to: I) {
self.internal.copy_bit(from.index(), to.index())
}
#[inline]
pub fn count_ones<T: IndexRange<I>>(&self, range: T) -> usize {
let start = range.start().map_or(0, |idx| idx.index());
let end = range.end().map_or(self.internal.len(), |idx| idx.index());
self.internal.count_ones(start..end)
}
#[inline]
pub fn set_range<T: IndexRange<I>>(&mut self, range: T, enabled: bool) {
let start = range.start().map_or(0, |idx| idx.index());
let end = range.end().map_or(self.internal.len(), |idx| idx.index());
self.internal.set_range(start..end, enabled)
}
#[inline]
pub fn insert_range<T: IndexRange<I>>(&mut self, range: T) {
let start = range.start().map_or(0, |idx| idx.index());
let end = range.end().map_or(self.internal.len(), |idx| idx.index());
self.internal.insert_range(start..end)
}
#[inline]
pub fn enable_all(&mut self) {
for block in self.as_mut_slice().iter_mut() {
*block = Block::MAX
}
}
#[inline]
pub fn toggle_range<T: IndexRange<I>>(&mut self, range: T) {
let start = range.start().map_or(0, |idx| idx.index());
let end = range.end().map_or(self.internal.len(), |idx| idx.index());
self.internal.toggle_range(start..end)
}
#[inline]
pub fn as_slice(&self) -> &[u32] {
self.internal.as_slice()
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u32] {
self.internal.as_mut_slice()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.as_slice().iter().all(|block| *block == 0)
}
#[inline]
pub fn ones(&self) -> Ones<'_, I> {
Ones {
iter: self.internal.ones(),
tag: PhantomData,
}
}
pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, I> {
Intersection {
iter: self.internal.intersection(&other.internal),
tag: PhantomData,
}
}
pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, I> {
Union {
iter: self.internal.union(&other.internal),
tag: PhantomData,
}
}
pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, I> {
Difference {
iter: self.internal.difference(&other.internal),
tag: PhantomData,
}
}
pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, I> {
SymmetricDifference {
iter: self.internal.symmetric_difference(&other.internal),
tag: PhantomData,
}
}
pub fn union_with(&mut self, other: &Self) {
self.internal.union_with(&other.internal)
}
pub fn intersect_with(&mut self, other: &Self) {
self.internal.intersect_with(&other.internal)
}
pub fn difference_with(&mut self, other: &Self) {
self.internal.difference_with(&other.internal)
}
pub fn symmetric_difference_with(&mut self, other: &Self) {
self.internal.symmetric_difference_with(&other.internal)
}
pub fn is_disjoint(&self, other: &Self) -> bool {
self.internal.is_disjoint(&other.internal)
}
pub fn is_subset(&self, other: &Self) -> bool {
self.internal.is_subset(&other.internal)
}
pub fn is_superset(&self, other: &Self) -> bool {
self.internal.is_superset(&other.internal)
}
}
impl<I: Idx + From<usize>> Binary for BitSet<I> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
Binary::fmt(&self.internal, f)
}
}
impl<I: Idx + From<usize> + Display> Display for BitSet<I> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("{")?;
for idx in self.ones() {
Display::fmt(&idx, f)?;
f.write_str(",")?;
}
f.write_str("}")
}
}
pub struct Difference<'a, I: Idx + From<usize>> {
iter: fixedbitset::Difference<'a>,
tag: PhantomData<fn(&I)>,
}
impl<'a, I: Idx + From<usize>> Iterator for Difference<'a, I> {
type Item = I;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|idx| idx.into())
}
}
pub struct SymmetricDifference<'a, I: Idx + From<usize>> {
iter: fixedbitset::SymmetricDifference<'a>,
tag: PhantomData<fn(&I)>,
}
impl<'a, I: Idx + From<usize>> Iterator for SymmetricDifference<'a, I> {
type Item = I;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|idx| idx.into())
}
}
pub struct Intersection<'a, I: Idx + From<usize>> {
iter: fixedbitset::Intersection<'a>,
tag: PhantomData<fn(&I)>,
}
impl<'a, I: Idx + From<usize>> Iterator for Intersection<'a, I> {
type Item = I;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|idx| idx.into())
}
}
pub struct Union<'a, I: Idx + From<usize>> {
iter: fixedbitset::Union<'a>,
tag: PhantomData<fn(&I)>,
}
impl<'a, I: Idx + From<usize>> Iterator for Union<'a, I> {
type Item = I;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|idx| idx.into())
}
}
pub struct Ones<'a, I: Idx + From<usize>> {
iter: fixedbitset::Ones<'a>,
tag: PhantomData<fn(&I)>,
}
impl<'a, I: Idx + From<usize>> Iterator for Ones<'a, I> {
type Item = I;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|idx| idx.into())
}
}
impl<I: Idx + From<usize>> Clone for BitSet<I> {
#[inline]
fn clone(&self) -> Self {
Self {
internal: self.internal.clone(),
tag: PhantomData,
}
}
}
impl<I: Idx + From<usize>> Index<I> for BitSet<I> {
type Output = bool;
#[inline]
fn index(&self, bit: I) -> &bool {
&self.internal[bit.index()]
}
}
impl<I: Idx + From<usize>> Extend<I> for BitSet<I> {
fn extend<Iter: IntoIterator<Item = I>>(&mut self, src: Iter) {
let src = src.into_iter().map(|id| id.index());
self.internal.extend(src)
}
}
impl<I: Idx + From<usize>> FromIterator<I> for BitSet<I> {
fn from_iter<Iter: IntoIterator<Item = I>>(src: Iter) -> Self {
let iter = src.into_iter();
let mut res = BitSet::new_empty(iter.size_hint().0.into());
res.extend(iter);
res
}
}
impl<'a, I: Idx + From<usize>> BitAnd for &'a BitSet<I> {
type Output = BitSet<I>;
fn bitand(self, other: &BitSet<I>) -> BitSet<I> {
BitSet {
internal: (&self.internal) & (&other.internal),
tag: PhantomData,
}
}
}
impl<'a, I: Idx + From<usize>> BitAndAssign for BitSet<I> {
fn bitand_assign(&mut self, other: Self) {
self.internal &= other.internal
}
}
impl<'a, I: Idx + From<usize>> BitOr for &'a BitSet<I> {
type Output = BitSet<I>;
fn bitor(self, other: &BitSet<I>) -> BitSet<I> {
BitSet {
internal: (&self.internal) | (&other.internal),
tag: PhantomData,
}
}
}
impl<'a, I: Idx + From<usize>> BitOrAssign for BitSet<I> {
fn bitor_assign(&mut self, other: Self) {
self.internal |= other.internal
}
}
impl<'a, I: Idx + From<usize>> BitXor for &'a BitSet<I> {
type Output = BitSet<I>;
fn bitxor(self, other: &BitSet<I>) -> BitSet<I> {
BitSet {
internal: (&self.internal) ^ (&other.internal),
tag: PhantomData,
}
}
}
impl<'a, I: Idx + From<usize>> BitXorAssign for BitSet<I> {
fn bitxor_assign(&mut self, other: Self) {
self.internal ^= other.internal
}
}