Skip to content

Instantly share code, notes, and snippets.

@JayKickliter
Last active November 22, 2019 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JayKickliter/b3d7c8ee4f74d8fd9d6480b500a58329 to your computer and use it in GitHub Desktop.
Save JayKickliter/b3d7c8ee4f74d8fd9d6480b500a58329 to your computer and use it in GitHub Desktop.
Bit accumulator in Rust
#![feature(const_generics)]
use num::{PrimInt, Zero};
#[derive(Default)]
struct BitAcc<T: Default, const N: u8> {
acc: T,
n: u8,
}
impl<T: Default + PrimInt + Zero + ::std::convert::From<bool>, const N: u8> BitAcc<T, N> {
pub fn push(&mut self, bit: bool) -> Option<T> {
debug_assert!(self.n < N);
self.acc = self.acc.unsigned_shl(1) | ::std::convert::From::from(bit);
self.n += 1;
if self.n == N {
self.n = 0;
let ret = Some(self.acc);
self.acc = T::zero();
ret
} else {
None
}
}
}
fn main() {
let mut acc: BitAcc<u8, 1> = BitAcc::default();
assert_eq!(acc.push(true), Some(1));
assert_eq!(acc.push(false), Some(0));
let mut acc: BitAcc<u8, 2> = BitAcc::default();
assert_eq!(acc.push(true), None);
assert_eq!(acc.push(true), Some(3));
let mut acc: BitAcc<u8, 3> = BitAcc::default();
assert_eq!(acc.push(true), None);
assert_eq!(acc.push(true), None);
assert_eq!(acc.push(true), Some(7));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment