Skip to main content

bit_string/bit_string/
impls_for_access.rs

1use alloc::vec::Vec;
2
3use super::*;
4
5impl BitString {
6    #[inline]
7    pub fn bit_len(&self) -> usize {
8        self.bit_len
9    }
10
11    #[inline]
12    pub fn is_empty(&self) -> bool {
13        self.bit_len == 0
14    }
15
16    #[inline]
17    pub fn get(&self, index: usize) -> Option<bool> {
18        (index < self.bit_len).then(|| {
19            let word = self.words[index / 64];
20            let mask = 1u64 << (index % 64);
21            word & mask != 0
22        })
23    }
24}
25
26impl BitString {
27    #[inline]
28    pub fn any(&self) -> bool {
29        self.count_ones() != 0
30    }
31
32    #[inline]
33    pub fn all(&self) -> bool {
34        self.count_ones() == self.bit_len
35    }
36
37    #[inline]
38    pub fn is_all_zeros(&self) -> bool {
39        !self.any()
40    }
41
42    #[inline]
43    pub fn is_all_ones(&self) -> bool {
44        self.all()
45    }
46}
47
48impl BitString {
49    /// Returns the internal little-endian words.
50    ///
51    /// Bit index `i` is stored in word `i / 64`, bit offset `i % 64`.
52    /// Unused high bits in the last word are guaranteed to be zero.
53    #[inline]
54    pub fn as_words(&self) -> &[u64] {
55        &self.words
56    }
57
58    #[inline]
59    pub fn first(&self) -> Option<bool> {
60        self.get(0)
61    }
62
63    /// Reads up to 64 bits starting at `bit_start`, returning them in the
64    /// low bits of a `u64`.
65    ///
66    /// Bits beyond `self.len()` are treated as zero.
67    #[inline]
68    pub fn get_chunk(&self, bit_start: usize) -> u64 {
69        let word = bit_start / WORD_BITS;
70        let shift = bit_start % WORD_BITS;
71
72        let lo = self.words.get(word).copied().unwrap_or(0) >> shift;
73
74        if shift == 0 {
75            lo
76        } else {
77            let hi = self.words.get(word + 1).copied().unwrap_or(0);
78            lo | (hi << (WORD_BITS - shift))
79        }
80    }
81
82    #[inline]
83    pub fn last(&self) -> Option<bool> {
84        self.bit_len
85            .checked_sub(1)
86            .and_then(|index| self.get(index))
87    }
88
89    #[inline]
90    pub fn to_bool_vec(&self) -> Vec<bool> {
91        self.iter().collect()
92    }
93}
94
95#[cfg(test)]
96mod tests_for_get;
97#[cfg(test)]
98mod tests_for_get_chunk;