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