commonware_utils/
bitvec.rs

1//! Bit-vector implementation
2//!
3//! The bit-vector is a compact representation of a sequence of bits, using [u8] "blocks" for a
4//! more-efficient memory layout than doing a [`Vec<bool>`]. Thus, if the length of the bit-vector
5//! is not a multiple of 8, the last block will contain some bits that are not part of the vector.
6//! An invariant of the implementation is that any bits in the last block that are not part of the
7//! vector are set to 0.
8//!
9//! The implementation is focused on being compact when encoding small bit vectors, so [u8] is
10//! used over more performant types like [usize] or [u64]. Such types would result in more
11//! complex encoding and decoding logic.
12
13#[cfg(not(feature = "std"))]
14use alloc::{vec, vec::Vec};
15use bytes::{Buf, BufMut};
16use commonware_codec::{
17    EncodeSize, Error as CodecError, FixedSize, RangeCfg, Read, ReadExt, Write,
18};
19use core::{
20    fmt::{self, Formatter, Write as _},
21    ops::{BitAnd, BitOr, BitXor, Index},
22};
23
24/// Type alias for the underlying block type.
25type Block = u8;
26
27/// Number of bits in a [Block].
28const BITS_PER_BLOCK: usize = Block::BITS as usize;
29
30/// Empty block of bits (all bits set to 0).
31const EMPTY_BLOCK: Block = 0;
32
33/// Full block of bits (all bits set to 1).
34const FULL_BLOCK: Block = Block::MAX;
35
36/// Represents a vector of bits.
37///
38/// Stores bits using [u8] blocks for efficient storage.
39#[derive(Clone, PartialEq, Eq)]
40pub struct BitVec {
41    /// The underlying storage for the bits.
42    storage: Vec<Block>,
43    /// The total number of bits
44    num_bits: usize,
45}
46
47impl BitVec {
48    /// Creates a new, empty `BitVec`.
49    #[inline]
50    pub fn new() -> Self {
51        BitVec {
52            storage: Vec::new(),
53            num_bits: 0,
54        }
55    }
56
57    /// Creates a new `BitVec` with the specified capacity in bits.
58    #[inline]
59    pub fn with_capacity(size: usize) -> Self {
60        BitVec {
61            storage: Vec::with_capacity(Self::num_blocks(size)),
62            num_bits: 0,
63        }
64    }
65
66    /// Creates a new `BitVec` with `size` bits, all initialized to zero.
67    #[inline]
68    pub fn zeroes(size: usize) -> Self {
69        BitVec {
70            storage: vec![EMPTY_BLOCK; Self::num_blocks(size)],
71            num_bits: size,
72        }
73    }
74
75    /// Creates a new `BitVec` with `size` bits, all initialized to one.
76    #[inline]
77    pub fn ones(size: usize) -> Self {
78        let mut result = Self {
79            storage: vec![FULL_BLOCK; Self::num_blocks(size)],
80            num_bits: size,
81        };
82        result.clear_trailing_bits();
83        result
84    }
85
86    /// Creates a new `BitVec` from a slice of booleans.
87    #[inline]
88    pub fn from_bools(bools: &[bool]) -> Self {
89        let mut bv = Self::with_capacity(bools.len());
90        for &b in bools {
91            bv.push(b);
92        }
93        bv
94    }
95
96    /// Returns the number of bits in the vector.
97    #[inline]
98    pub fn len(&self) -> usize {
99        self.num_bits
100    }
101
102    /// Returns true if the vector contains no bits.
103    #[inline]
104    pub fn is_empty(&self) -> bool {
105        self.num_bits == 0
106    }
107
108    /// Appends a bit to the end of the vector.
109    #[inline]
110    pub fn push(&mut self, value: bool) {
111        // Increment the number of bits and get the index for the new bit
112        let index = self.num_bits;
113        self.num_bits += 1;
114
115        // Ensure the storage has enough blocks to hold the new bit
116        if Self::block_index(index) >= self.storage.len() {
117            self.storage.push(EMPTY_BLOCK);
118        }
119
120        // Set the bit
121        if value {
122            self.set_bit_unchecked(index);
123        }
124    }
125
126    /// Removes the last bit from the vector and returns it.
127    ///
128    /// Returns `None` if the vector is empty.
129    #[inline]
130    pub fn pop(&mut self) -> Option<bool> {
131        if self.is_empty() {
132            return None;
133        }
134
135        // Decrement the number of bits and get the value of the last bit
136        self.num_bits -= 1;
137        let index = self.num_bits;
138        let value = self.get_bit_unchecked(index);
139
140        // If that was the last bit in the block, drop the block;
141        // otherwise, if the bit was 1, we need to clear it
142        if Self::bit_offset(index) == 0 {
143            self.storage.pop().expect("Storage should not be empty");
144        } else if value {
145            self.clear_bit_unchecked(index);
146        }
147
148        Some(value)
149    }
150
151    /// Gets the value of the bit at `index` (true if 1, false if 0).
152    ///
153    /// Returns `None` if the index is out of bounds.
154    #[inline]
155    pub fn get(&self, index: usize) -> Option<bool> {
156        if index >= self.num_bits {
157            return None;
158        }
159        Some(self.get_bit_unchecked(index))
160    }
161
162    /// Gets the value of the bit at the specified index without bounds checking.
163    ///
164    /// # Safety
165    ///
166    /// Caller must ensure `index` is less than the length of the BitVec.
167    #[inline]
168    pub unsafe fn get_unchecked(&self, index: usize) -> bool {
169        self.get_bit_unchecked(index)
170    }
171
172    /// Sets the bit at `index` to 1.
173    ///
174    /// # Panics
175    ///
176    /// Panics if `index` is out of bounds.
177    #[inline]
178    pub fn set(&mut self, index: usize) {
179        self.assert_index(index);
180        self.set_bit_unchecked(index);
181    }
182
183    /// Sets the bit at `index` to 0.
184    ///
185    /// # Panics
186    ///
187    /// Panics if `index` is out of bounds.
188    #[inline]
189    pub fn clear(&mut self, index: usize) {
190        self.assert_index(index);
191        self.clear_bit_unchecked(index);
192    }
193
194    /// Flips the bit at `index`.
195    ///
196    /// # Panics
197    ///
198    /// Panics if `index` is out of bounds.
199    #[inline]
200    pub fn toggle(&mut self, index: usize) {
201        self.assert_index(index);
202        self.toggle_bit_unchecked(index);
203    }
204
205    /// Sets the bit at `index` to the specified `value`.
206    ///
207    /// # Panics
208    ///
209    /// Panics if `index` is out of bounds.
210    #[inline]
211    pub fn set_to(&mut self, index: usize, value: bool) {
212        self.assert_index(index);
213        if value {
214            self.set_bit_unchecked(index);
215        } else {
216            self.clear_bit_unchecked(index);
217        }
218    }
219
220    /// Sets all bits to 0.
221    #[inline]
222    pub fn clear_all(&mut self) {
223        for block in &mut self.storage {
224            *block = EMPTY_BLOCK;
225        }
226    }
227
228    /// Sets all bits to 1.
229    #[inline]
230    pub fn set_all(&mut self) {
231        for block in &mut self.storage {
232            *block = FULL_BLOCK;
233        }
234        self.clear_trailing_bits();
235    }
236
237    /// Returns the number of bits set to 1.
238    #[inline]
239    pub fn count_ones(&self) -> usize {
240        self.storage
241            .iter()
242            .map(|block| block.count_ones() as usize)
243            .sum()
244    }
245
246    /// Returns the number of bits set to 0.
247    #[inline]
248    pub fn count_zeros(&self) -> usize {
249        self.num_bits
250            .checked_sub(self.count_ones())
251            .expect("Overflow in count_zeros")
252    }
253
254    /// Performs a bitwise AND with another BitVec.
255    ///
256    /// # Panics
257    ///
258    /// Panics if the lengths don't match.
259    pub fn and(&mut self, other: &BitVec) {
260        self.binary_op(other, |a, b| a & b);
261        self.clear_trailing_bits();
262    }
263
264    /// Performs a bitwise OR with another BitVec.
265    ///
266    /// # Panics
267    ///
268    /// Panics if the lengths don't match.
269    pub fn or(&mut self, other: &BitVec) {
270        self.binary_op(other, |a, b| a | b);
271        self.clear_trailing_bits();
272    }
273
274    /// Performs a bitwise XOR with another BitVec.
275    ///
276    /// # Panics
277    ///
278    /// Panics if the lengths don't match.
279    pub fn xor(&mut self, other: &BitVec) {
280        self.binary_op(other, |a, b| a ^ b);
281        self.clear_trailing_bits();
282    }
283
284    /// Flips all bits (1s become 0s and vice versa).
285    pub fn invert(&mut self) {
286        for block in &mut self.storage {
287            *block = !*block;
288        }
289        self.clear_trailing_bits();
290    }
291
292    /// Creates an iterator over the bits.
293    pub fn iter(&self) -> BitIterator<'_> {
294        BitIterator { vec: self, pos: 0 }
295    }
296
297    // ---------- Helper Functions ----------
298
299    /// Calculates the block index for a given bit index.
300    #[inline(always)]
301    fn block_index(index: usize) -> usize {
302        index / BITS_PER_BLOCK
303    }
304
305    /// Calculates the bit offset within a block.
306    #[inline(always)]
307    fn bit_offset(index: usize) -> usize {
308        index % BITS_PER_BLOCK
309    }
310
311    /// Calculates the number of blocks needed to store `num_bits`.
312    #[inline(always)]
313    fn num_blocks(num_bits: usize) -> usize {
314        num_bits.div_ceil(BITS_PER_BLOCK)
315    }
316
317    /// Creates a mask with the first `num_bits` bits set to 1.
318    #[inline(always)]
319    fn mask_over_first_n_bits(num_bits: usize) -> Block {
320        match num_bits {
321            BITS_PER_BLOCK => FULL_BLOCK,
322            n if n < BITS_PER_BLOCK => FULL_BLOCK.unbounded_shr((BITS_PER_BLOCK - n) as u32),
323            _ => panic!("num_bits exceeds block size: {num_bits}"),
324        }
325    }
326
327    #[inline(always)]
328    fn get_bit_unchecked(&self, index: usize) -> bool {
329        let block_index = Self::block_index(index);
330        let bit_index = Self::bit_offset(index);
331        (self.storage[block_index] & (1 << bit_index)) != 0
332    }
333
334    #[inline(always)]
335    fn set_bit_unchecked(&mut self, index: usize) {
336        let block_index = Self::block_index(index);
337        let bit_index = Self::bit_offset(index);
338        self.storage[block_index] |= 1 << bit_index;
339    }
340
341    #[inline(always)]
342    fn clear_bit_unchecked(&mut self, index: usize) {
343        let block_index = Self::block_index(index);
344        let bit_index = Self::bit_offset(index);
345        self.storage[block_index] &= !(1 << bit_index);
346    }
347
348    #[inline(always)]
349    fn toggle_bit_unchecked(&mut self, index: usize) {
350        let block_index = Self::block_index(index);
351        let bit_index = Self::bit_offset(index);
352        self.storage[block_index] ^= 1 << bit_index;
353    }
354
355    /// Asserts that the index is within bounds.
356    #[inline(always)]
357    fn assert_index(&self, index: usize) {
358        assert!(index < self.num_bits, "Index out of bounds");
359    }
360
361    /// Asserts that the lengths of two BitVecs match.
362    #[inline(always)]
363    fn assert_eq_len(&self, other: &BitVec) {
364        assert_eq!(self.num_bits, other.num_bits, "BitVec lengths don't match");
365    }
366
367    /// Helper for binary operations (AND, OR, XOR)
368    #[inline]
369    fn binary_op<F: Fn(Block, Block) -> Block>(&mut self, other: &BitVec, op: F) {
370        self.assert_eq_len(other);
371        for (a, b) in self.storage.iter_mut().zip(other.storage.iter()) {
372            *a = op(*a, *b);
373        }
374    }
375
376    /// Clears any bits in storage beyond the last valid bit. Returns true if any bits were cleared.
377    #[inline]
378    fn clear_trailing_bits(&mut self) -> bool {
379        let bit_offset = Self::bit_offset(self.num_bits);
380        if bit_offset == 0 {
381            // No extra bits to clear
382            return false;
383        }
384
385        // Clear the bits in the last block
386        let block = self
387            .storage
388            .last_mut()
389            .expect("Storage should not be empty");
390        let old_block = *block;
391        let mask = Self::mask_over_first_n_bits(bit_offset);
392        *block &= mask;
393
394        // Check if the last block was modified
395        *block != old_block
396    }
397}
398
399// ---------- Constructors ----------
400
401impl Default for BitVec {
402    fn default() -> Self {
403        Self::new()
404    }
405}
406
407impl From<Vec<bool>> for BitVec {
408    fn from(v: Vec<bool>) -> Self {
409        Self::from_bools(&v)
410    }
411}
412
413impl From<&[bool]> for BitVec {
414    fn from(s: &[bool]) -> Self {
415        Self::from_bools(s)
416    }
417}
418
419impl<const N: usize> From<[bool; N]> for BitVec {
420    fn from(arr: [bool; N]) -> Self {
421        Self::from_bools(&arr)
422    }
423}
424
425impl<const N: usize> From<&[bool; N]> for BitVec {
426    fn from(arr: &[bool; N]) -> Self {
427        Self::from_bools(arr)
428    }
429}
430
431// ---------- Converters ----------
432
433impl From<BitVec> for Vec<bool> {
434    fn from(bv: BitVec) -> Self {
435        bv.iter().collect()
436    }
437}
438
439// ---------- Debug ----------
440
441impl fmt::Debug for BitVec {
442    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
443        // For very large BitVecs, only show a preview
444        const MAX_DISPLAY: usize = 64;
445        const HALF_DISPLAY: usize = MAX_DISPLAY / 2;
446
447        // Closure for writing a bit
448        let write_bit = |formatter: &mut Formatter<'_>, index: usize| -> core::fmt::Result {
449            formatter.write_char(if self.get_bit_unchecked(index) {
450                '1'
451            } else {
452                '0'
453            })
454        };
455
456        f.write_str("BitVec[")?;
457        if self.num_bits <= MAX_DISPLAY {
458            // Show all bits
459            for i in 0..self.num_bits {
460                write_bit(f, i)?;
461            }
462        } else {
463            // Show first and last bits with ellipsis
464            for i in 0..HALF_DISPLAY {
465                write_bit(f, i)?;
466            }
467
468            f.write_str("...")?;
469
470            for i in (self.num_bits - HALF_DISPLAY)..self.num_bits {
471                write_bit(f, i)?;
472            }
473        }
474        f.write_str("]")
475    }
476}
477
478// ---------- Operations ----------
479
480impl Index<usize> for BitVec {
481    type Output = bool;
482
483    /// Allows accessing bits using the `[]` operator.
484    ///
485    /// Panics if out of bounds.
486    #[inline]
487    fn index(&self, index: usize) -> &Self::Output {
488        self.assert_index(index);
489        let value = self.get_bit_unchecked(index);
490        if value {
491            &true
492        } else {
493            &false
494        }
495    }
496}
497
498impl BitAnd for &BitVec {
499    type Output = BitVec;
500
501    fn bitand(self, rhs: Self) -> Self::Output {
502        self.assert_eq_len(rhs);
503        let mut result = self.clone();
504        result.and(rhs);
505        result
506    }
507}
508
509impl BitOr for &BitVec {
510    type Output = BitVec;
511
512    fn bitor(self, rhs: Self) -> Self::Output {
513        self.assert_eq_len(rhs);
514        let mut result = self.clone();
515        result.or(rhs);
516        result
517    }
518}
519
520impl BitXor for &BitVec {
521    type Output = BitVec;
522
523    fn bitxor(self, rhs: Self) -> Self::Output {
524        self.assert_eq_len(rhs);
525        let mut result = self.clone();
526        result.xor(rhs);
527        result
528    }
529}
530
531// ---------- Codec ----------
532
533impl Write for BitVec {
534    fn write(&self, buf: &mut impl BufMut) {
535        // Prefix with the number of bits, which is generally larger than the length of the storage
536        self.num_bits.write(buf);
537
538        // Write full blocks
539        for &block in &self.storage {
540            block.write(buf);
541        }
542    }
543}
544
545impl Read for BitVec {
546    type Cfg = RangeCfg;
547
548    fn read_cfg(buf: &mut impl Buf, range: &Self::Cfg) -> Result<Self, CodecError> {
549        // Parse length
550        let num_bits = usize::read_cfg(buf, range)?;
551
552        // Parse blocks
553        let num_blocks = num_bits.div_ceil(BITS_PER_BLOCK);
554        let mut storage = Vec::with_capacity(num_blocks);
555        for _ in 0..num_blocks {
556            let block = Block::read(buf)?;
557            storage.push(block);
558        }
559
560        // Ensure there were no trailing bits
561        let mut result = BitVec { storage, num_bits };
562        if result.clear_trailing_bits() {
563            return Err(CodecError::Invalid("BitVec", "trailing bits"));
564        }
565
566        Ok(result)
567    }
568}
569
570impl EncodeSize for BitVec {
571    fn encode_size(&self) -> usize {
572        self.num_bits.encode_size() + (Block::SIZE * self.storage.len())
573    }
574}
575
576// ---------- Iterator ----------
577
578/// Iterator over bits in a BitVec
579pub struct BitIterator<'a> {
580    /// Reference to the BitVec being iterated over
581    vec: &'a BitVec,
582
583    /// Current position in the BitVec (0-indexed)
584    pos: usize,
585}
586
587impl Iterator for BitIterator<'_> {
588    type Item = bool;
589
590    fn next(&mut self) -> Option<Self::Item> {
591        if self.pos >= self.vec.len() {
592            return None;
593        }
594
595        let bit = self.vec.get_bit_unchecked(self.pos);
596        self.pos += 1;
597        Some(bit)
598    }
599
600    fn size_hint(&self) -> (usize, Option<usize>) {
601        let remaining = self.vec.len() - self.pos;
602        (remaining, Some(remaining))
603    }
604}
605
606impl ExactSizeIterator for BitIterator<'_> {}
607
608// ---------- Tests ----------
609
610#[cfg(test)]
611mod tests {
612    use super::*;
613    use bytes::BytesMut;
614    use commonware_codec::{Decode, Encode};
615
616    #[test]
617    fn test_constructors() {
618        // Test new()
619        let bv = BitVec::new();
620        assert_eq!(bv.len(), 0);
621        assert!(bv.is_empty());
622        assert_eq!(bv.storage.len(), 0);
623
624        // Test with_capacity()
625        let bv = BitVec::with_capacity(100);
626        assert_eq!(bv.len(), 0);
627        assert!(bv.is_empty());
628        assert!(bv.storage.capacity() >= BitVec::num_blocks(100));
629
630        // Test zeroes()
631        let bv = BitVec::zeroes(100);
632        assert_eq!(bv.len(), 100);
633        assert!(!bv.is_empty());
634        assert_eq!(bv.count_zeros(), 100);
635        for i in 0..100 {
636            assert!(!bv.get(i).unwrap());
637        }
638
639        // Test ones()
640        let bv = BitVec::ones(100);
641        assert_eq!(bv.len(), 100);
642        assert!(!bv.is_empty());
643        assert_eq!(bv.count_ones(), 100);
644        for i in 0..100 {
645            assert!(bv.get(i).unwrap());
646        }
647
648        // Test from_bools()
649        let bools = [true, false, true, false, true];
650        let bv = BitVec::from_bools(&bools);
651        assert_eq!(bv.len(), 5);
652        assert_eq!(bv.count_ones(), 3);
653
654        // Test From trait implementations
655        let vec_bool = vec![true, false, true];
656        let bv: BitVec = vec_bool.into();
657        assert_eq!(bv.len(), 3);
658        assert_eq!(bv.count_ones(), 2);
659
660        let bools_slice = [false, true, false];
661        let bv: BitVec = bools_slice.into();
662        assert_eq!(bv.len(), 3);
663        assert_eq!(bv.count_ones(), 1);
664
665        // Test Default trait
666        let bv: BitVec = Default::default();
667        assert_eq!(bv.len(), 0);
668        assert!(bv.is_empty());
669    }
670
671    #[test]
672    fn test_basic_operations() {
673        let mut bv = BitVec::zeroes(100);
674
675        // Test initial state
676        for i in 0..100 {
677            assert_eq!(bv.get(i), Some(false));
678        }
679
680        // Test set
681        bv.set(0);
682        bv.set(50);
683        bv.set(63); // Last bit in first block
684        bv.set(64); // First bit in second block
685        bv.set(99); // Last bit
686
687        assert_eq!(bv.get(0), Some(true));
688        assert_eq!(bv.get(50), Some(true));
689        assert_eq!(bv.get(63), Some(true));
690        assert_eq!(bv.get(64), Some(true));
691        assert_eq!(bv.get(99), Some(true));
692        assert_eq!(bv.get(30), Some(false));
693
694        // Test clear
695        bv.clear(0);
696        bv.clear(50);
697        bv.clear(64);
698
699        assert_eq!(bv.get(0), Some(false));
700        assert_eq!(bv.get(50), Some(false));
701        assert_eq!(bv.get(63), Some(true));
702        assert_eq!(bv.get(64), Some(false));
703        assert_eq!(bv.get(99), Some(true));
704
705        // Test toggle
706        bv.toggle(0); // false -> true
707        bv.toggle(63); // true -> false
708
709        assert_eq!(bv.get(0), Some(true));
710        assert_eq!(bv.get(63), Some(false));
711
712        // Test toggle again
713        bv.toggle(0);
714        assert!(!bv.get(0).unwrap());
715        bv.toggle(0);
716        assert!(bv.get(0).unwrap());
717
718        // Test set_to
719        bv.set_to(10, true);
720        bv.set_to(11, false);
721
722        assert_eq!(bv.get(10), Some(true));
723        assert_eq!(bv.get(11), Some(false));
724
725        // Test push and pop
726        bv.push(true);
727        assert_eq!(bv.len(), 101);
728        assert!(bv.get(100).unwrap());
729
730        bv.push(false);
731        assert_eq!(bv.len(), 102);
732        assert!(!bv.get(101).unwrap());
733
734        assert_eq!(bv.pop(), Some(false));
735        assert_eq!(bv.len(), 101);
736        assert_eq!(bv.pop(), Some(true));
737        assert_eq!(bv.len(), 100);
738
739        // Test out of bounds
740        assert_eq!(bv.get(100), None);
741        assert_eq!(bv.get(1000), None);
742    }
743
744    #[test]
745    fn test_conversions() {
746        // Test conversion from/to Vec<bool>
747        let original = vec![true, false, true];
748        let bv: BitVec = original.clone().into();
749        assert_eq!(bv.len(), 3);
750        assert_eq!(bv.count_ones(), 2);
751
752        let converted: Vec<bool> = bv.into();
753        assert_eq!(converted.len(), 3);
754        assert_eq!(converted, original);
755    }
756
757    #[test]
758    fn test_bitwise_operations() {
759        // Create test bitvecs
760        let a = BitVec::from_bools(&[true, false, true, false, true]);
761        let b = BitVec::from_bools(&[true, true, false, false, true]);
762
763        // Test AND
764        let mut result = a.clone();
765        result.and(&b);
766        assert_eq!(
767            result,
768            BitVec::from_bools(&[true, false, false, false, true])
769        );
770
771        // Test OR
772        let mut result = a.clone();
773        result.or(&b);
774        assert_eq!(result, BitVec::from_bools(&[true, true, true, false, true]));
775
776        // Test XOR
777        let mut result = a.clone();
778        result.xor(&b);
779        assert_eq!(
780            result,
781            BitVec::from_bools(&[false, true, true, false, false])
782        );
783
784        // Test INVERT
785        let mut result = a.clone();
786        result.invert();
787        assert_eq!(
788            result,
789            BitVec::from_bools(&[false, true, false, true, false])
790        );
791
792        // Test operator overloads
793        let a_ref = &a;
794        let b_ref = &b;
795
796        let result = a_ref & b_ref;
797        assert_eq!(
798            result,
799            BitVec::from_bools(&[true, false, false, false, true])
800        );
801
802        let result = a_ref | b_ref;
803        assert_eq!(result, BitVec::from_bools(&[true, true, true, false, true]));
804
805        let result = a_ref ^ b_ref;
806        assert_eq!(
807            result,
808            BitVec::from_bools(&[false, true, true, false, false])
809        );
810
811        // Test multi-block bitwise operations
812        let mut bv_long1 = BitVec::zeroes(70);
813        bv_long1.set(0);
814        bv_long1.set(65);
815
816        let mut bv_long2 = BitVec::zeroes(70);
817        bv_long2.set(1);
818        bv_long2.set(65);
819
820        let mut bv_long_and = bv_long1.clone();
821        bv_long_and.and(&bv_long2);
822        let mut expected_and = BitVec::zeroes(70);
823        expected_and.set(65);
824        assert_eq!(bv_long_and, expected_and);
825    }
826
827    #[test]
828    fn test_out_of_bounds_get() {
829        let bv = BitVec::zeroes(10);
830        // Test get returns None for out-of-bounds
831        assert_eq!(bv.get(10), None);
832        assert_eq!(bv.get(100), None);
833
834        // Test empty BitVec
835        let empty_bv = BitVec::new();
836        assert_eq!(empty_bv.get(0), None);
837    }
838
839    #[test]
840    #[should_panic(expected = "Index out of bounds")]
841    fn test_set_out_of_bounds() {
842        let mut bv = BitVec::zeroes(10);
843        bv.set(10);
844    }
845
846    #[test]
847    #[should_panic(expected = "Index out of bounds")]
848    fn test_clear_out_of_bounds() {
849        let mut bv = BitVec::zeroes(10);
850        bv.clear(10);
851    }
852
853    #[test]
854    #[should_panic(expected = "Index out of bounds")]
855    fn test_toggle_out_of_bounds() {
856        let mut bv = BitVec::zeroes(10);
857        bv.toggle(10);
858    }
859
860    #[test]
861    #[should_panic(expected = "Index out of bounds")]
862    fn test_set_to_out_of_bounds() {
863        let mut bv = BitVec::zeroes(10);
864        bv.set_to(10, true);
865    }
866
867    #[test]
868    #[should_panic(expected = "Index out of bounds")]
869    fn test_index_out_of_bounds() {
870        let bv = BitVec::zeroes(10);
871        let _ = bv[10];
872    }
873
874    #[test]
875    fn test_count_operations() {
876        // Small BitVec
877        let bv = BitVec::from_bools(&[true, false, true, true, false, true]);
878        assert_eq!(bv.count_ones(), 4);
879        assert_eq!(bv.count_zeros(), 2);
880
881        // Empty BitVec
882        let empty = BitVec::new();
883        assert_eq!(empty.count_ones(), 0);
884        assert_eq!(empty.count_zeros(), 0);
885
886        // Large BitVecs
887        let zeroes = BitVec::zeroes(100);
888        assert_eq!(zeroes.count_ones(), 0);
889        assert_eq!(zeroes.count_zeros(), 100);
890
891        let ones = BitVec::ones(100);
892        assert_eq!(ones.count_ones(), 100);
893        assert_eq!(ones.count_zeros(), 0);
894
895        // Test across block boundary
896        let mut bv_multi = BitVec::zeroes(70);
897        bv_multi.set(0);
898        bv_multi.set(63); // Last bit in first block
899        bv_multi.set(64); // First bit in second block
900        bv_multi.set(69);
901        assert_eq!(bv_multi.count_ones(), 4);
902        assert_eq!(bv_multi.count_zeros(), 66);
903    }
904
905    #[test]
906    fn test_clear_set_all_invert() {
907        // Test on small BitVec
908        let mut bv = BitVec::from_bools(&[true, false, true, false, true]); // 5 bits
909
910        // Set all
911        bv.set_all();
912        assert_eq!(bv.len(), 5);
913        assert_eq!(bv.count_ones(), 5);
914        for i in 0..5 {
915            assert_eq!(bv.get(i), Some(true));
916        }
917        // Check trailing bits in the block were cleared
918        assert_eq!(bv.storage[0], (1 << 5) - 1);
919
920        // Clear all
921        bv.clear_all();
922        assert_eq!(bv.len(), 5);
923        assert_eq!(bv.count_ones(), 0);
924        assert_eq!(bv.storage[0], 0);
925
926        // Set some bits and test invert
927        bv.set(1);
928        bv.set(3); // 01010
929        bv.invert(); // Should become 10101
930        assert_eq!(bv.count_ones(), 3);
931        assert_eq!(bv.get(0), Some(true));
932        assert_eq!(bv.get(1), Some(false));
933        assert_eq!(bv.get(2), Some(true));
934        assert_eq!(bv.get(3), Some(false));
935        assert_eq!(bv.get(4), Some(true));
936
937        // Test invert with blocks
938        let mut bv_full = BitVec::ones(64);
939        bv_full.invert();
940        assert_eq!(bv_full.count_ones(), 0);
941
942        let mut bv_part = BitVec::ones(67);
943        bv_part.invert();
944        assert_eq!(bv_part.count_ones(), 0);
945    }
946
947    #[test]
948    fn test_mask_over_first_n_bits() {
949        // Test with various sizes
950        for i in 0..=BITS_PER_BLOCK {
951            let mask = BitVec::mask_over_first_n_bits(i);
952            let ones = mask.trailing_ones() as usize;
953            let zeroes = mask.leading_zeros() as usize;
954            assert_eq!(ones, i);
955            assert_eq!(ones.checked_add(zeroes).unwrap(), BITS_PER_BLOCK);
956            assert_eq!(
957                mask,
958                ((1 as Block)
959                    .checked_shl(i as u32)
960                    .unwrap_or(0)
961                    .wrapping_sub(1))
962            );
963        }
964    }
965
966    #[test]
967    fn test_codec_roundtrip() {
968        let original = BitVec::from_bools(&[true, false, true, false, true]);
969        let mut buf = original.encode();
970        let decoded = BitVec::decode_cfg(&mut buf, &(..).into()).unwrap();
971        assert_eq!(original, decoded);
972    }
973
974    #[test]
975    fn test_codec_error_invalid_length() {
976        let original = BitVec::from_bools(&[true, false, true, false, true]);
977        let buf = original.encode();
978
979        let mut buf_clone1 = buf.clone();
980        assert!(matches!(
981            BitVec::decode_cfg(&mut buf_clone1, &(..=4usize).into()),
982            Err(CodecError::InvalidLength(_))
983        ));
984
985        let mut buf_clone2 = buf.clone();
986        assert!(matches!(
987            BitVec::decode_cfg(&mut buf_clone2, &(6usize..).into()),
988            Err(CodecError::InvalidLength(_))
989        ));
990    }
991
992    #[test]
993    fn test_codec_error_trailing_bits() {
994        let mut buf = BytesMut::new();
995        1usize.write(&mut buf); // write the bit length as 1
996        (2 as Block).write(&mut buf); // set two bits
997        assert!(matches!(
998            BitVec::decode_cfg(&mut buf, &(..).into()),
999            Err(CodecError::Invalid("BitVec", "trailing bits"))
1000        ));
1001    }
1002}