Skip to main content

mask_tracked_array/
mask_trait.rs

1use bit_iter::BitIter;
2/// An integer mask trait
3pub trait Mask:
4    num_traits::PrimInt
5    + num_traits::ConstZero
6    + num_traits::ConstOne
7    + num_traits::Bounded
8    + num_traits::Euclid
9{
10    /// An instance of the mask with all indices selected.
11    const ALL_SELECTED: Self;
12    /// An instance of the mask with no indices selected.
13    const NONE_SELECTED: Self;
14    /// An instance of the mask with the lowest index (1) selected.
15    const ONE_SELECTED: Self;
16    /// The number of bits in the mask
17    const MAX_SELECTIONS: u32;
18    /// Convert an index into an instance of this mask.
19    #[inline]
20    fn index_to_mask(index: usize) -> Self {
21        Self::ONE_SELECTED << index
22    }
23    /// Convert this mask into an iterator of indices.
24    fn mask_to_indices(self) -> impl Iterator<Item = usize>;
25}
26macro_rules! impl_mask_trait {
27    ($t:ty) => {
28        impl Mask for $t {
29            const ALL_SELECTED: Self = Self::MAX;
30            const NONE_SELECTED: Self = 0;
31            const ONE_SELECTED: Self = 1;
32            const MAX_SELECTIONS: u32 = Self::BITS;
33            #[inline]
34            fn mask_to_indices(self) -> impl Iterator<Item = usize> {
35                BitIter::from(self)
36            }
37        }
38        paste::paste! {
39            #[test]
40            fn [< correct_inverse_ $t >]() {
41                let mask = $t::index_to_mask(2);
42                let mut iter = mask.mask_to_indices();
43                assert_eq!(iter.next().unwrap(), 2);
44                assert_eq!(iter.next(), None);
45            }
46        }
47    };
48    ($($t:ty),*) => {
49        $(
50            impl_mask_trait!($t);
51        )*
52    };
53}
54impl_mask_trait!(u8, u16, u32, u64, u128);