| use core::fmt; |
| use core::marker::PhantomData; |
| |
| pub struct Set<T>(PhantomData<T>, pub(crate) u16); |
| |
| pub trait SetMember: Copy + fmt::Debug { |
| const MAX_VALUE: u8; |
| |
| fn bit_mask(self) -> u16; |
| fn from_bit_mask(value: u16) -> Option<Self>; |
| } |
| |
| impl<T: SetMember> Set<T> { |
| pub const EMPTY: Self = Set(PhantomData, 0); |
| |
| pub fn contains(self, value: T) -> bool { |
| (value.bit_mask() & self.1) == value.bit_mask() |
| } |
| |
| pub const fn iter(self) -> Iter<T> { |
| Iter { index: 0, set: self } |
| } |
| } |
| |
| pub struct Iter<T> { |
| index: u8, |
| set: Set<T>, |
| } |
| |
| impl<T: SetMember> Iterator for Iter<T> { |
| type Item = T; |
| |
| fn next(&mut self) -> Option<Self::Item> { |
| while self.index <= T::MAX_VALUE { |
| let mask: u16 = 1 << self.index; |
| |
| self.index += 1; |
| if let Some(v) = T::from_bit_mask(mask) { |
| if self.set.contains(v) { |
| return Some(v); |
| } |
| } |
| } |
| |
| None |
| } |
| } |
| |
| impl<T: SetMember> Default for Set<T> { |
| fn default() -> Self { |
| Set::EMPTY |
| } |
| } |
| |
| impl<T: SetMember> fmt::Debug for Set<T> { |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| f.debug_set().entries(self.iter()).finish() |
| } |
| } |
| |
| impl<T> Copy for Set<T> { } |
| |
| impl<T> Clone for Set<T> { |
| fn clone(&self) -> Self { |
| Self(self.0, self.1) |
| } |
| } |
| |
| impl<T> PartialEq for Set<T> { |
| fn eq(&self, other: &Self) -> bool { |
| self.1 == other.1 |
| } |
| } |
| |
| impl<T> Eq for Set<T> { } |
| |
| impl<T> PartialOrd for Set<T> { |
| fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { |
| self.1.partial_cmp(&other.1) |
| } |
| } |
| |
| impl<T> Ord for Set<T> { |
| fn cmp(&self, other: &Self) -> core::cmp::Ordering { |
| self.1.cmp(&other.1) |
| } |
| } |
| |
| impl<T> core::hash::Hash for Set<T> { |
| fn hash<H: core::hash::Hasher>(&self, state: &mut H) { |
| self.1.hash(state); |
| } |
| } |