pub trait BitEmpty {
fn empty() -> Self;
}
pub trait BitFull {
fn full() -> Self;
}
pub trait BitTest {
fn test(&self, idx: usize) -> bool;
}
pub trait BitTestNone {
fn test_none(&self) -> bool;
}
pub trait BitTestAll {
fn test_all(&self) -> bool;
}
pub trait BitSetLimit {
const MAX_SET_INDEX: usize;
}
pub trait BitSet: BitSetLimit {
#[inline]
fn set(&mut self, idx: usize) {
assert!(idx <= Self::MAX_SET_INDEX, "Idx out of bounds");
unsafe {
self.set_unchecked(idx)
}
}
unsafe fn set_unchecked(&mut self, idx: usize);
}
pub trait BitUnsetLimit {
const MAX_UNSET_INDEX: usize;
}
pub trait BitUnset: BitUnsetLimit {
#[inline]
fn unset(&mut self, idx: usize) {
assert!(idx <= Self::MAX_UNSET_INDEX, "Idx out of bounds");
unsafe {
self.unset_unchecked(idx)
}
}
unsafe fn unset_unchecked(&mut self, idx: usize);
}
pub trait BitSearch {
fn find_first_set(&self, lower_bound: usize) -> Option<usize>;
#[inline]
fn find_set_in_range<R>(&self, range: R) -> Option<usize>
where
R: core::ops::RangeBounds<usize>,
{
use core::ops::Bound;
let lower_bound = match range.start_bound() {
Bound::Included(bound) => *bound,
Bound::Excluded(bound) => *bound + 1,
Bound::Unbounded => 0,
};
self.find_first_set(lower_bound)
.and_then(|idx| match range.end_bound() {
Bound::Included(bound) => {
if *bound >= idx {
Some(idx)
} else {
None
}
}
Bound::Excluded(bound) => {
if *bound > idx {
Some(idx)
} else {
None
}
}
Bound::Unbounded => Some(idx),
})
}
}
pub trait BitComplement {
type Output;
fn complement(self) -> Self::Output;
}
pub trait BitUnion<Rhs = Self> {
type Output;
fn union(self, rhs: Rhs) -> Self::Output;
}
pub trait BitIntersection<Rhs = Self> {
type Output;
fn intersection(self, rhs: Rhs) -> Self::Output;
}
pub trait BitDifference<Rhs = Self> {
type Output;
fn difference(self, rhs: Rhs) -> Self::Output;
}
pub trait BitSubset<Rhs = Self> {
fn is_subset_of(&self, rhs: &Rhs) -> bool;
}
pub trait BitDisjoint<Rhs = Self> {
fn is_disjoint(&self, rhs: &Rhs) -> bool;
}
pub trait UltimateBitSet:
Sized
+ BitEmpty
+ BitFull
+ BitTest
+ BitTestNone
+ BitTestAll
+ BitSet
+ BitUnset
+ BitSearch
+ BitComplement
+ BitUnion
+ BitIntersection
+ BitDifference
+ BitSubset
+ BitDisjoint
{
}
impl<T> UltimateBitSet for T where
T: BitEmpty
+ BitFull
+ BitTest
+ BitTestNone
+ BitTestAll
+ BitSet
+ BitUnset
+ BitSearch
+ BitComplement
+ BitUnion
+ BitIntersection
+ BitDifference
+ BitSubset
+ BitDisjoint
{
}