use core::fmt;
#[derive(Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct Set<T> {
state: T,
}
impl<T> Set<T>
where
T: Number,
{
#[inline]
pub fn clear(&mut self, index: u32) {
self.state.unset(index);
}
#[inline]
pub(crate) fn new(state: T) -> Self {
Self { state }
}
#[inline]
pub(crate) fn state(&self) -> T {
self.state
}
#[inline]
pub(crate) fn is_empty(&self) -> bool {
self.state.is_zero()
}
#[inline]
pub(crate) fn iter(self) -> Iter<T> {
Iter { state: self.state }
}
}
#[derive(Debug)]
pub struct Iter<T> {
state: T,
}
impl<T> Iterator for Iter<T>
where
T: Number,
{
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.state.is_zero() {
return None;
}
let index = self.state.trailing_zeros();
self.state.unset(index);
Some(index)
}
}
impl<T> fmt::Debug for Set<T>
where
T: Number,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
pub trait Number: Sized + Copy {
const BITS: u32;
fn from_bit(bit: u32) -> Self;
fn trailing_zeros(self) -> u32;
fn is_zero(self) -> bool;
fn unset(&mut self, index: u32);
fn rotate_left(self, bits: u32) -> Self;
fn rotate_right(self, bits: u32) -> Self;
}
macro_rules! number {
($ty:ty) => {
impl Number for $ty {
const BITS: u32 = <$ty>::BITS as u32;
fn from_bit(bit: u32) -> Self {
1 << bit
}
fn trailing_zeros(self) -> u32 {
<$ty>::trailing_zeros(self)
}
fn is_zero(self) -> bool {
self == 0
}
fn unset(&mut self, index: u32) {
*self &= !(1 << index);
}
fn rotate_left(self, bits: u32) -> Self {
<$ty>::rotate_left(self, bits)
}
fn rotate_right(self, bits: u32) -> Self {
<$ty>::rotate_right(self, bits)
}
}
};
}
number!(u128);
number!(u64);
number!(u32);
number!(u16);
number!(u8);