1pub trait BinIter {
13 type Iter: Iterator<Item = bool>;
14 fn bin_iter(&self) -> Self::Iter;
15}
16
17pub struct UIntIter<U>(U);
18
19pub trait Binary {
20 fn pop(&mut self) -> Option<bool>;
21}
22
23macro_rules! impl_binary {
24 ( $($ty:ty)* ) => { $(
25 impl Binary for $ty {
26 fn pop(&mut self) -> Option<bool> {
27 if *self == 0 {
28 None
29 } else {
30 let tmp = *self & 1 != 0;
31 *self >>= 1;
32 Some(tmp)
33 }
34 }
35 }
36 )* }
37}
38
39impl_binary! { u8 u16 u32 u64 u128 usize }
40
41impl<U: Binary> UIntIter<U> {
42 pub fn new(u: U) -> Self { Self(u) }
43}
44
45impl<U: Binary> Iterator for UIntIter<U> {
46 type Item = bool;
47 fn next(&mut self) -> Option<Self::Item> { self.0.pop() }
48}
49
50macro_rules! impl_bin_iter {
51 ( $($ty:ty)* ) => { $(
52 impl BinIter for $ty {
53 type Iter = UIntIter<$ty>;
54 fn bin_iter(&self) -> Self::Iter { Self::Iter::new(*self) }
55 }
56 )* }
57}
58
59impl_bin_iter! { u8 u16 u32 u64 u128 usize }
60
61#[test]
62fn sanity_check() {
63 assert!(0_u32.bin_iter().eq([]));
64 assert!(1_u32.bin_iter().map(u32::from).eq([1]));
65 assert!(0b_1001011_u64.bin_iter().map(u32::from).eq([1, 1, 0, 1, 0, 0, 1]));
66 assert!((!0_u128).bin_iter().map(u32::from).eq([1; 128]));
67}