// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. pub struct BitChunkAccessor { pub threshold: u32, pub shift: u32, pub word_id: u32, pub mask: u64, } impl Default for BitChunkAccessor { /// # Panics /// When `CHUNK_SIZE` does not fit into u32 fn default() -> Self { Self { threshold: (u64::BITS / u32::try_from(CHUNK_SIZE).unwrap() - 1) * u32::try_from(CHUNK_SIZE).unwrap(), shift: 0, word_id: 0, mask: u64::MAX >> (u64::BITS - u32::try_from(CHUNK_SIZE).unwrap()), } } } impl BitChunkAccessor { /// # Panics /// When `CHUNK_SIZE` does not fit into u32 pub fn next(&mut self) { if self.shift == self.threshold { self.shift = 0; self.word_id += 1; } else { self.shift += u32::try_from(CHUNK_SIZE).unwrap(); } } pub fn xor(&self, what: &mut [u64], val: u64) { what[self.word_id as usize] ^= val << self.shift; } #[must_use] pub fn get(&self, what: &[u64]) -> u64 { (what[self.word_id as usize] >> self.shift) & self.mask } }