aoc/util/
bitset.rs

1//! Add `biterator` method that treats an integer as a set, iterating over each element where
2//! the respective bit is set. For example `1101` would return 0, 2 and 3.
3use crate::util::integer::*;
4
5pub trait BitOps<T> {
6    fn biterator(self) -> Bitset<T>;
7}
8
9impl<T> BitOps<T> for T
10where
11    T: Integer<T>,
12{
13    fn biterator(self) -> Bitset<T> {
14        Bitset { t: self }
15    }
16}
17
18pub struct Bitset<T> {
19    t: T,
20}
21
22impl<T> Iterator for Bitset<T>
23where
24    T: Integer<T>,
25    T: TryInto<usize>,
26{
27    type Item = usize;
28
29    #[inline]
30    fn next(&mut self) -> Option<Self::Item> {
31        if self.t == T::ZERO {
32            return None;
33        }
34
35        let tz = self.t.trailing_zeros();
36        self.t = self.t ^ (T::ONE << tz);
37
38        tz.try_into().ok()
39    }
40}