#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Flag<T> {
bit: u32,
mask: T,
}
macro_rules! impl_flag {
($($ty:ty),*) => {
$(
impl Flag<$ty> {
#[inline]
pub const fn new(bit: u32) -> Self {
assert!(bit < <$ty>::BITS, "bit position exceeds integer bounds");
let mask = 1 << bit;
Self { bit, mask }
}
#[inline]
pub const fn bit(self) -> u32 {
self.bit
}
#[inline]
pub const fn mask(self) -> $ty {
self.mask
}
#[inline]
pub const fn is_set(self, val: $ty) -> bool {
(val & self.mask) != 0
}
#[inline]
pub const fn set(self, val: $ty) -> $ty {
val | self.mask
}
#[inline]
pub const fn clear(self, val: $ty) -> $ty {
val & !self.mask
}
#[inline]
pub const fn toggle(self, val: $ty) -> $ty {
val ^ self.mask
}
#[inline]
pub const fn set_to(self, val: $ty, enabled: bool) -> $ty {
if enabled {
self.set(val)
} else {
self.clear(val)
}
}
}
)*
};
}
impl_flag!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);