1use std::ops::Not;
5
6use bitvec::view::BitView;
7
8use crate::BitBuffer;
9use crate::BufferAllocatorRef;
10use crate::BufferMut;
11use crate::ByteBufferMut;
12use crate::bit::collect_bool_words;
13use crate::bit::get_bit_unchecked;
14use crate::bit::ops;
15use crate::bit::pack::collect_bool_words_multiversioned;
16use crate::bit::set_bit_unchecked;
17use crate::bit::unset_bit_unchecked;
18use crate::buffer_mut;
19
20#[allow(clippy::inline_always)]
22#[inline(always)]
23pub(crate) fn fill_bits(slice: &mut [u8], start_bit: usize, end_bit: usize, value: bool) {
24 if start_bit >= end_bit {
25 return;
26 }
27
28 let fill_byte: u8 = if value { 0xFF } else { 0x00 };
29
30 let start_byte = start_bit / 8;
31 let start_rem = start_bit % 8;
32 let end_byte = end_bit / 8;
33 let end_rem = end_bit % 8;
34
35 if start_byte == end_byte {
36 let mask = ((1u8 << (end_rem - start_rem)) - 1) << start_rem;
38 if value {
39 slice[start_byte] |= mask;
40 } else {
41 slice[start_byte] &= !mask;
42 }
43 } else {
44 if start_rem != 0 {
46 let mask = !((1u8 << start_rem) - 1);
47 if value {
48 slice[start_byte] |= mask;
49 } else {
50 slice[start_byte] &= !mask;
51 }
52 }
53
54 let fill_start = if start_rem != 0 {
56 start_byte + 1
57 } else {
58 start_byte
59 };
60 if fill_start < end_byte {
61 slice[fill_start..end_byte].fill(fill_byte);
62 }
63
64 if end_rem != 0 {
66 let mask = (1u8 << end_rem) - 1;
67 if value {
68 slice[end_byte] |= mask;
69 } else {
70 slice[end_byte] &= !mask;
71 }
72 }
73 }
74}
75
76#[derive(Debug, Clone)]
96pub struct BitBufferMut {
97 buffer: ByteBufferMut,
98 offset: usize,
102 len: usize,
103}
104
105impl BitBufferMut {
106 #[inline]
108 pub fn from_buffer(buffer: ByteBufferMut, offset: usize, len: usize) -> Self {
109 assert!(
110 len <= buffer.len() * 8,
111 "Buffer len {} is too short for the given length {len}",
112 buffer.len()
113 );
114 Self {
115 buffer,
116 offset,
117 len,
118 }
119 }
120
121 pub fn copy_from(bit_buffer: &BitBuffer) -> Self {
123 Self::copy_from_in(bit_buffer, bit_buffer.inner().allocator().clone())
124 }
125
126 pub fn copy_from_in(bit_buffer: &BitBuffer, allocator: BufferAllocatorRef) -> Self {
128 Self {
129 buffer: ByteBufferMut::copy_from_in(bit_buffer.inner(), allocator),
130 offset: bit_buffer.offset(),
131 len: bit_buffer.len(),
132 }
133 }
134
135 #[inline]
137 pub fn with_capacity(capacity: usize) -> Self {
138 Self::with_capacity_in(capacity, BufferAllocatorRef::statically_allocated())
139 }
140
141 #[inline]
143 pub fn with_capacity_in(capacity: usize, allocator: BufferAllocatorRef) -> Self {
144 Self {
145 buffer: BufferMut::with_capacity_in(capacity.div_ceil(8), allocator),
146 offset: 0,
147 len: 0,
148 }
149 }
150
151 #[inline]
153 pub fn new_set(len: usize) -> Self {
154 Self {
155 buffer: buffer_mut![0xFF; len.div_ceil(8)],
156 offset: 0,
157 len,
158 }
159 }
160
161 #[inline]
163 pub fn new_unset(len: usize) -> Self {
164 Self {
165 buffer: BufferMut::zeroed(len.div_ceil(8)),
166 offset: 0,
167 len,
168 }
169 }
170
171 #[allow(clippy::inline_always)]
173 #[inline(always)]
174 pub fn empty() -> Self {
175 Self::with_capacity(0)
176 }
177
178 pub fn empty_in(allocator: BufferAllocatorRef) -> Self {
180 Self::with_capacity_in(0, allocator)
181 }
182
183 pub fn allocator(&self) -> &BufferAllocatorRef {
185 self.buffer.allocator()
186 }
187
188 #[inline]
190 pub fn full(value: bool, len: usize) -> Self {
191 if value {
192 Self::new_set(len)
193 } else {
194 Self::new_unset(len)
195 }
196 }
197
198 pub fn from_indices(len: usize, indices: impl IntoIterator<Item = usize>) -> BitBufferMut {
200 let mut buffer = BufferMut::<u64>::zeroed(len.div_ceil(64));
201 for idx in indices {
202 assert!(idx < len, "index {idx} exceeds len {len}");
203 buffer.as_mut_slice()[idx / 64] |= 1 << (idx % 64);
204 }
205
206 let mut buffer = buffer.into_byte_buffer();
207 buffer.truncate(len.div_ceil(8));
208
209 Self {
210 buffer,
211 offset: 0,
212 len,
213 }
214 }
215
216 #[inline]
220 pub fn collect_bool<F: FnMut(usize) -> bool>(len: usize, f: F) -> Self {
221 Self::collect_words(len, |words| collect_bool_words(words, len, f))
222 }
223
224 #[inline]
228 pub fn collect_bool_multiversioned<F: FnMut(usize) -> bool>(len: usize, f: F) -> Self {
229 Self::collect_words(len, |words| {
230 collect_bool_words_multiversioned(words, len, f)
231 })
232 }
233
234 #[inline]
237 fn collect_words(len: usize, fill: impl FnOnce(&mut [u64])) -> Self {
238 let num_words = len.div_ceil(64);
239 let mut buffer: BufferMut<u64> = BufferMut::with_capacity(num_words);
240 unsafe { buffer.set_len(num_words) };
244 fill(buffer.as_mut_slice());
245
246 let mut bytes = buffer.into_byte_buffer();
247 bytes.truncate(len.div_ceil(8));
248
249 Self {
250 buffer: bytes,
251 offset: 0,
252 len,
253 }
254 }
255
256 #[inline]
258 pub fn inner(&self) -> &ByteBufferMut {
259 &self.buffer
260 }
261
262 #[inline]
264 pub fn into_inner(self) -> ByteBufferMut {
265 self.buffer
266 }
267
268 #[allow(clippy::inline_always)]
270 #[inline(always)]
271 pub fn len(&self) -> usize {
272 self.len
273 }
274
275 #[allow(clippy::inline_always)]
277 #[inline(always)]
278 pub fn is_empty(&self) -> bool {
279 self.len == 0
280 }
281
282 #[allow(clippy::inline_always)]
284 #[inline(always)]
285 pub fn offset(&self) -> usize {
286 self.offset
287 }
288
289 #[allow(clippy::inline_always)]
291 #[inline(always)]
292 pub fn value(&self, index: usize) -> bool {
293 assert!(index < self.len);
294 unsafe { self.value_unchecked(index) }
296 }
297
298 #[allow(clippy::inline_always)]
304 #[inline(always)]
305 pub unsafe fn value_unchecked(&self, index: usize) -> bool {
306 unsafe { get_bit_unchecked(self.buffer.as_ptr(), self.offset + index) }
307 }
308
309 #[allow(clippy::inline_always)]
311 #[inline(always)]
312 pub fn capacity(&self) -> usize {
313 (self.buffer.capacity() * 8) - self.offset
314 }
315
316 #[inline]
318 pub fn reserve(&mut self, additional: usize) {
319 let required_bits = self.offset + self.len + additional;
320 let required_bytes = required_bits.div_ceil(8); let additional_bytes = required_bytes.saturating_sub(self.buffer.len());
323 self.buffer.reserve(additional_bytes);
324 }
325
326 #[inline]
328 pub fn clear(&mut self) {
329 self.buffer.clear();
332 self.len = 0;
333 self.offset = 0;
334 }
335
336 #[inline]
340 pub fn set_to(&mut self, index: usize, value: bool) {
341 if value {
342 self.set(index);
343 } else {
344 self.unset(index);
345 }
346 }
347
348 #[inline]
354 pub unsafe fn set_to_unchecked(&mut self, index: usize, value: bool) {
355 if value {
356 unsafe { self.set_unchecked(index) }
358 } else {
359 unsafe { self.unset_unchecked(index) }
361 }
362 }
363
364 #[inline]
368 pub fn set(&mut self, index: usize) {
369 assert!(index < self.len, "index {index} exceeds len {}", self.len);
370
371 unsafe { self.set_unchecked(index) };
373 }
374
375 #[inline]
379 pub fn unset(&mut self, index: usize) {
380 assert!(index < self.len, "index {index} exceeds len {}", self.len);
381
382 unsafe { self.unset_unchecked(index) };
384 }
385
386 #[inline]
394 pub unsafe fn set_unchecked(&mut self, index: usize) {
395 unsafe { set_bit_unchecked(self.buffer.as_mut_ptr(), self.offset + index) }
397 }
398
399 #[inline]
407 pub unsafe fn unset_unchecked(&mut self, index: usize) {
408 unsafe { unset_bit_unchecked(self.buffer.as_mut_ptr(), self.offset + index) }
410 }
411
412 #[allow(clippy::inline_always)]
419 #[inline(always)]
420 pub unsafe fn set_len(&mut self, new_len: usize) {
421 debug_assert!(
422 new_len <= self.capacity(),
423 "`set_len` requires that new_len <= capacity()"
424 );
425
426 let bytes_len = (self.offset + new_len).div_ceil(8);
428 unsafe { self.buffer.set_len(bytes_len) };
429
430 self.len = new_len;
431 }
432
433 #[inline]
437 pub fn truncate(&mut self, len: usize) {
438 if len > self.len {
439 return;
440 }
441
442 assert!(
443 self.offset <= usize::MAX - len,
444 "Truncate on BitBufferMut overflowed"
445 );
446 let end_bit = self.offset + len;
447 let new_len_bytes = end_bit.div_ceil(8);
448 self.buffer.truncate(new_len_bytes);
449 self.len = len;
450
451 if !end_bit.is_multiple_of(8) {
454 let keep = (1u8 << (end_bit % 8)) - 1;
455 self.buffer.as_mut_slice()[new_len_bytes - 1] &= keep;
456 }
457 }
458
459 #[inline]
461 pub fn append(&mut self, value: bool) {
462 if value {
463 self.append_true()
464 } else {
465 self.append_false()
466 }
467 }
468
469 #[inline]
471 pub fn append_true(&mut self) {
472 let bit_pos = self.offset + self.len;
473 let byte_pos = bit_pos / 8;
474 let bit_in_byte = bit_pos % 8;
475
476 if byte_pos >= self.buffer.len() {
478 self.buffer.push(0u8);
479 }
480
481 self.buffer.as_mut_slice()[byte_pos] |= 1 << bit_in_byte;
483 self.len += 1;
484 }
485
486 #[inline]
488 pub fn append_false(&mut self) {
489 let bit_pos = self.offset + self.len;
490 let byte_pos = bit_pos / 8;
491
492 if byte_pos >= self.buffer.len() {
494 self.buffer.push(0u8);
495 }
496
497 self.len += 1;
500 }
501
502 #[inline]
507 pub fn append_n(&mut self, value: bool, n: usize) {
508 if n == 0 {
509 return;
510 }
511
512 assert!(
513 self.offset
514 .checked_add(self.len)
515 .and_then(|v| v.checked_add(n))
516 .is_some(),
517 "Append on BitBufferMut overflowed"
518 );
519 let end_bit_pos = self.offset + self.len + n;
520 let required_bytes = end_bit_pos.div_ceil(8);
521
522 if required_bytes > self.buffer.len() {
524 self.buffer.push_n(0x00, required_bytes - self.buffer.len());
525 }
526
527 let start = self.len;
528 self.len += n;
529 self.fill_range(start, self.len, value);
530 }
531
532 #[allow(clippy::inline_always)]
537 #[inline(always)]
538 pub fn fill_range(&mut self, start: usize, end: usize, value: bool) {
539 assert!(end <= self.len, "end {end} exceeds len {}", self.len);
540 assert!(start <= end, "start {start} exceeds end {end}");
541
542 unsafe { self.fill_range_unchecked(start, end, value) }
545 }
546
547 #[allow(clippy::inline_always)]
553 #[inline(always)]
554 pub unsafe fn fill_range_unchecked(&mut self, start: usize, end: usize, value: bool) {
555 fill_bits(
556 self.buffer.as_mut_slice(),
557 self.offset + start,
558 self.offset + end,
559 value,
560 );
561 }
562
563 pub fn append_buffer(&mut self, buffer: &BitBuffer) {
567 let bit_len = buffer.len();
568 if bit_len == 0 {
569 return;
570 }
571
572 let start_bit_pos = self.offset + self.len;
573 let end_bit_pos = start_bit_pos + bit_len;
574 let required_bytes = end_bit_pos.div_ceil(8);
575
576 if required_bytes > self.buffer.len() {
578 self.buffer.push_n(0x00, required_bytes - self.buffer.len());
579 }
580
581 let dst_bit_offset = start_bit_pos % 8;
582 let src_bit_offset = buffer.offset();
583
584 if dst_bit_offset == 0 && src_bit_offset == 0 {
585 let dst_byte = start_bit_pos / 8;
587 let src_bytes = buffer.inner().as_slice();
588 let full_bytes = bit_len / 8;
589 self.buffer.as_mut_slice()[dst_byte..dst_byte + full_bytes]
590 .copy_from_slice(&src_bytes[..full_bytes]);
591 let rem = bit_len % 8;
592 if rem != 0 {
593 let mask = (1u8 << rem) - 1;
594 self.buffer.as_mut_slice()[dst_byte + full_bytes] |= src_bytes[full_bytes] & mask;
595 }
596 } else {
597 let self_slice = self
599 .buffer
600 .as_mut_slice()
601 .view_bits_mut::<bitvec::prelude::Lsb0>();
602 let other_slice = buffer
603 .inner()
604 .as_slice()
605 .view_bits::<bitvec::prelude::Lsb0>();
606 let source_range = src_bit_offset..src_bit_offset + bit_len;
607 self_slice[start_bit_pos..end_bit_pos].copy_from_bitslice(&other_slice[source_range]);
608 }
609
610 self.len += bit_len;
611 }
612
613 #[inline]
615 pub fn freeze(self) -> BitBuffer {
616 BitBuffer::new_with_offset(self.buffer.freeze(), self.len, self.offset)
617 }
618
619 #[inline]
621 pub fn as_slice(&self) -> &[u8] {
622 self.buffer.as_slice()
623 }
624
625 #[inline]
627 pub fn as_mut_slice(&mut self) -> &mut [u8] {
628 self.buffer.as_mut_slice()
629 }
630}
631
632impl Default for BitBufferMut {
633 fn default() -> Self {
634 Self::with_capacity(0)
635 }
636}
637
638impl Not for BitBufferMut {
640 type Output = BitBufferMut;
641
642 #[inline]
643 fn not(mut self) -> Self::Output {
644 ops::bitwise_unary_op_mut(&mut self, |b| !b);
645 self
646 }
647}
648
649impl From<&[bool]> for BitBufferMut {
650 fn from(value: &[bool]) -> Self {
651 BitBufferMut::collect_bool_multiversioned(value.len(), |i| unsafe {
654 *value.get_unchecked(i)
655 })
656 }
657}
658
659impl From<&[u8]> for BitBufferMut {
661 fn from(value: &[u8]) -> Self {
662 BitBufferMut::collect_bool_multiversioned(
665 value.len(),
666 |i| unsafe { *value.get_unchecked(i) } > 0,
667 )
668 }
669}
670
671impl From<Vec<bool>> for BitBufferMut {
672 fn from(value: Vec<bool>) -> Self {
673 value.as_slice().into()
674 }
675}
676
677impl FromIterator<bool> for BitBufferMut {
678 #[inline]
679 fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
680 let mut iter = iter.into_iter();
681
682 let (lower_bound, _) = iter.size_hint();
685
686 let mut buf = BitBufferMut::new_unset(lower_bound);
691 assert_eq!(buf.offset, 0);
692
693 let ptr = buf.buffer.as_mut_ptr();
695 for i in 0..lower_bound {
696 let Some(v) = iter.next() else {
697 unsafe { buf.set_len(i) };
700 return buf;
701 };
702
703 if v {
704 unsafe { set_bit_unchecked(ptr, i) }
706 }
707 }
708
709 for v in iter {
712 buf.append(v);
713 }
714
715 buf
716 }
717}
718
719#[cfg(test)]
720mod tests {
721 use rstest::rstest;
722
723 use crate::BufferMut;
724 use crate::bit::buf_mut::BitBufferMut;
725 use crate::bitbuffer;
726 use crate::bitbuffer_mut;
727 use crate::buffer_mut;
728
729 #[test]
730 fn test_bits_mut() {
731 let mut bools = bitbuffer_mut![false; 10];
732 bools.set_to(0, true);
733 bools.set_to(9, true);
734
735 let bools = bools.freeze();
736 assert!(bools.value(0));
737 for i in 1..=8 {
738 assert!(!bools.value(i));
739 }
740 assert!(bools.value(9));
741 }
742
743 #[test]
744 fn test_append_n() {
745 let mut bools = BitBufferMut::with_capacity(10);
746 assert_eq!(bools.len(), 0);
747 assert!(bools.is_empty());
748
749 bools.append(true);
750 bools.append_n(false, 8);
751 bools.append_n(true, 1);
752
753 let bools = bools.freeze();
754
755 assert_eq!(bools.true_count(), 2);
756 assert!(bools.value(0));
757 assert!(bools.value(9));
758 }
759
760 #[test]
761 fn append_false_after_truncate_reads_back_false() {
762 let mut bools = BitBufferMut::new_set(16);
765 bools.truncate(12);
766 bools.append_false();
767 bools.append_true();
768
769 let bools = bools.freeze();
770 assert_eq!(bools.len(), 14);
771 assert!(
772 !bools.value(12),
773 "appended false must read back false after truncate"
774 );
775 assert!(bools.value(13));
776 }
777
778 #[test]
779 fn test_reserve_ensures_len_plus_additional() {
780 let mut bits = BitBufferMut::with_capacity(10);
784 assert_eq!(bits.len(), 0);
785
786 bits.reserve(100);
787
788 assert!(bits.capacity() >= 100);
790
791 bits.append_n(true, 50);
792 assert_eq!(bits.len(), 50);
793
794 bits.reserve(100);
795
796 assert!(bits.capacity() >= 150);
798 }
799
800 #[test]
801 fn test_with_offset_zero() {
802 let buf = BufferMut::zeroed(2);
804 let mut bit_buf = BitBufferMut::from_buffer(buf, 0, 16);
805
806 bit_buf.set(0);
808 bit_buf.set(7);
809 bit_buf.set(8);
810 bit_buf.set(15);
811
812 assert!(bit_buf.value(0));
814 assert!(bit_buf.value(7));
815 assert!(bit_buf.value(8));
816 assert!(bit_buf.value(15));
817 assert!(!bit_buf.value(1));
818 assert!(!bit_buf.value(9));
819
820 assert_eq!(bit_buf.as_slice()[0], 0b10000001);
822 assert_eq!(bit_buf.as_slice()[1], 0b10000001);
823 }
824
825 #[test]
826 fn test_with_offset_within_byte() {
827 let buf = buffer_mut![0b11111111, 0b00000000, 0b00000000];
829 let mut bit_buf = BitBufferMut::from_buffer(buf, 3, 10);
830
831 assert!(bit_buf.value(0)); assert!(bit_buf.value(4)); assert!(!bit_buf.value(5)); bit_buf.set(7);
839 assert!(bit_buf.value(7));
840
841 bit_buf.unset(0);
843 assert!(!bit_buf.value(0));
844 }
845
846 #[test]
847 fn test_with_offset_byte_boundary() {
848 let buf = buffer_mut![0xFF, 0x00, 0xFF];
850 let mut bit_buf = BitBufferMut::from_buffer(buf, 8, 16);
851
852 for i in 0..8 {
854 assert!(!bit_buf.value(i));
855 }
856 for i in 8..16 {
858 assert!(bit_buf.value(i));
859 }
860
861 bit_buf.set(0);
863 bit_buf.set(3);
864 assert!(bit_buf.value(0));
865 assert!(bit_buf.value(3));
866 }
867
868 #[test]
869 fn test_with_large_offset() {
870 let buf = buffer_mut![0xFF, 0xFF, 0xFF, 0xFF];
872 let mut bit_buf = BitBufferMut::from_buffer(buf, 13, 10);
873
874 for i in 0..10 {
876 assert!(bit_buf.value(i));
877 }
878
879 bit_buf.unset(0);
881 bit_buf.unset(5);
882 bit_buf.unset(9);
883
884 assert!(!bit_buf.value(0));
885 assert!(bit_buf.value(1));
886 assert!(!bit_buf.value(5));
887 assert!(!bit_buf.value(9));
888 }
889
890 #[test]
891 fn test_append_with_offset() {
892 let buf = buffer_mut![0b11100000]; let mut bit_buf = BitBufferMut::from_buffer(buf, 3, 0); bit_buf.append(false); bit_buf.append(true); bit_buf.append(true); assert_eq!(bit_buf.len(), 3);
902 assert!(!bit_buf.value(0));
903 assert!(bit_buf.value(1));
904 assert!(bit_buf.value(2));
905 }
906
907 #[test]
908 fn test_append_n_with_offset_crossing_boundary() {
909 let buf = BufferMut::zeroed(4);
911 let mut bit_buf = BitBufferMut::from_buffer(buf, 5, 0);
912
913 bit_buf.append_n(true, 10); assert_eq!(bit_buf.len(), 10);
917 for i in 0..10 {
918 assert!(bit_buf.value(i));
919 }
920
921 assert_eq!(bit_buf.as_slice()[0], 0b11100000);
925 assert_eq!(bit_buf.as_slice()[1], 0b01111111);
926 }
927
928 #[test]
929 fn test_truncate_with_offset() {
930 let buf = buffer_mut![0xFF, 0xFF];
931 let mut bit_buf = BitBufferMut::from_buffer(buf, 4, 12);
932
933 assert_eq!(bit_buf.len(), 12);
934
935 bit_buf.truncate(8);
937 assert_eq!(bit_buf.len(), 8);
938
939 bit_buf.truncate(3);
941 assert_eq!(bit_buf.len(), 3);
942
943 bit_buf.truncate(10);
945 assert_eq!(bit_buf.len(), 3);
946 }
947
948 #[test]
949 fn test_capacity_with_offset() {
950 let buf = buffer_mut![0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; let bit_buf = BitBufferMut::from_buffer(buf, 5, 0);
953
954 assert!(bit_buf.capacity() >= 75);
957 assert_eq!(bit_buf.capacity() % 8, (80 - 5) % 8);
959 }
960
961 #[test]
962 fn test_reserve_with_offset() {
963 let buf = buffer_mut![0, 0]; let mut bit_buf = BitBufferMut::from_buffer(buf, 3, 0);
966
967 let initial_capacity = bit_buf.capacity();
969 assert!(initial_capacity >= 13);
970
971 bit_buf.reserve(20);
973
974 assert!(bit_buf.capacity() >= 20);
976 }
977
978 #[test]
979 fn test_freeze_with_offset() {
980 let buf = buffer_mut![0b11110000, 0b00001111];
981 let mut bit_buf = BitBufferMut::from_buffer(buf, 4, 8);
982
983 bit_buf.set(0);
985 bit_buf.set(7);
986
987 let frozen = bit_buf.freeze();
989 assert_eq!(frozen.offset(), 4);
990 assert_eq!(frozen.len(), 8);
991
992 assert!(frozen.value(0));
994 assert!(frozen.value(7));
995 }
996
997 #[cfg_attr(miri, ignore)] #[test]
999 fn append_after_clear_reads_back_false() {
1000 let mut bools = BitBufferMut::new_set(16);
1003 bools.clear();
1004 bools.append_false();
1005 bools.append_buffer(&crate::BitBuffer::new_unset(8));
1006
1007 let bools = bools.freeze();
1008 assert_eq!(bools.len(), 9);
1009 assert_eq!(bools.true_count(), 0);
1010 }
1011
1012 #[cfg_attr(miri, ignore)] #[test]
1014 fn test_append_buffer_after_truncate() {
1015 let mut buf = BitBufferMut::new_set(16);
1018 buf.truncate(3);
1019 buf.append_buffer(&crate::BitBuffer::new_unset(8));
1020
1021 let frozen = buf.freeze();
1022 assert_eq!(frozen.len(), 11);
1023 for i in 0..3 {
1024 assert!(frozen.value(i), "bit {i} should be set");
1025 }
1026 for i in 3..11 {
1027 assert!(!frozen.value(i), "bit {i} should be unset");
1028 }
1029 }
1030
1031 #[rstest]
1032 #[case::both_aligned(0, 0)]
1033 #[case::dst_unaligned(3, 0)]
1034 #[case::src_unaligned(0, 5)]
1035 #[case::mismatched(3, 5)]
1036 #[case::equal_nonzero(5, 5)]
1037 #[cfg_attr(miri, ignore)] fn test_append_buffer_long(#[case] dst_prefix: usize, #[case] src_start: usize) {
1039 let source = crate::BitBuffer::from_iter((0..301).map(|i| i % 3 == 0));
1041 let source = source.slice(src_start..301);
1042
1043 let mut dest = BitBufferMut::with_capacity(512);
1044 dest.append_n(true, dst_prefix);
1045 dest.append_buffer(&source);
1046
1047 assert_eq!(dest.len(), dst_prefix + source.len());
1048 for i in 0..dst_prefix {
1049 assert!(dest.value(i), "prefix bit {i}");
1050 }
1051 for i in 0..source.len() {
1052 assert_eq!(dest.value(dst_prefix + i), source.value(i), "bit {i}");
1053 }
1054 }
1055
1056 #[cfg_attr(miri, ignore)] #[test]
1058 fn test_append_buffer_with_offsets() {
1059 let source = bitbuffer![false, false, true, true, false, true];
1061
1062 let buf = BufferMut::zeroed(4);
1064 let mut dest = BitBufferMut::from_buffer(buf, 3, 0);
1065
1066 dest.append(true);
1068 dest.append(false);
1069
1070 dest.append_buffer(&source);
1072
1073 assert_eq!(dest.len(), 8);
1074 assert!(dest.value(0)); assert!(!dest.value(1)); assert!(!dest.value(2)); assert!(!dest.value(3)); assert!(dest.value(4)); assert!(dest.value(5)); assert!(!dest.value(6)); assert!(dest.value(7)); }
1083
1084 #[test]
1085 fn test_set_unset_unchecked_with_offset() {
1086 let buf = BufferMut::zeroed(3);
1087 let mut bit_buf = BitBufferMut::from_buffer(buf, 7, 10);
1088
1089 unsafe {
1090 bit_buf.set_unchecked(0);
1091 bit_buf.set_unchecked(5);
1092 bit_buf.set_unchecked(9);
1093 }
1094
1095 assert!(bit_buf.value(0));
1096 assert!(bit_buf.value(5));
1097 assert!(bit_buf.value(9));
1098
1099 unsafe {
1100 bit_buf.unset_unchecked(5);
1101 }
1102
1103 assert!(!bit_buf.value(5));
1104 }
1105
1106 #[test]
1107 fn test_value_unchecked_with_offset() {
1108 let buf = buffer_mut![0b11110000, 0b00001111];
1109 let bit_buf = BitBufferMut::from_buffer(buf, 4, 8);
1110
1111 unsafe {
1112 assert!(bit_buf.value_unchecked(0));
1114 assert!(bit_buf.value_unchecked(3));
1115
1116 assert!(bit_buf.value_unchecked(4));
1118 assert!(bit_buf.value_unchecked(7));
1119 }
1120 }
1121
1122 #[test]
1123 fn test_append_alternating_with_offset() {
1124 let buf = BufferMut::zeroed(4);
1125 let mut bit_buf = BitBufferMut::from_buffer(buf, 2, 0);
1126
1127 for i in 0..20 {
1129 bit_buf.append(i % 2 == 0);
1130 }
1131
1132 assert_eq!(bit_buf.len(), 20);
1133 for i in 0..20 {
1134 assert_eq!(bit_buf.value(i), i % 2 == 0);
1135 }
1136 }
1137
1138 #[test]
1139 fn test_new_set_new_unset() {
1140 let set_buf = bitbuffer_mut![true; 10];
1141 let unset_buf = bitbuffer_mut![false; 10];
1142
1143 for i in 0..10 {
1144 assert!(set_buf.value(i));
1145 assert!(!unset_buf.value(i));
1146 }
1147
1148 assert_eq!(set_buf.len(), 10);
1149 assert_eq!(unset_buf.len(), 10);
1150 }
1151
1152 #[test]
1153 fn test_append_n_false_with_offset() {
1154 let buf = BufferMut::zeroed(4);
1155 let mut bit_buf = BitBufferMut::from_buffer(buf, 5, 0);
1156
1157 bit_buf.append_n(false, 15);
1158
1159 assert_eq!(bit_buf.len(), 15);
1160 for i in 0..15 {
1161 assert!(!bit_buf.value(i));
1162 }
1163 }
1164
1165 #[test]
1166 fn test_append_n_true_with_offset() {
1167 let buf = BufferMut::zeroed(4);
1168 let mut bit_buf = BitBufferMut::from_buffer(buf, 5, 0);
1169
1170 bit_buf.append_n(true, 15);
1171
1172 assert_eq!(bit_buf.len(), 15);
1173 for i in 0..15 {
1174 assert!(bit_buf.value(i));
1175 }
1176 }
1177
1178 #[test]
1179 fn test_mixed_operations_with_offset() {
1180 let buf = BufferMut::zeroed(5);
1182 let mut bit_buf = BitBufferMut::from_buffer(buf, 3, 0);
1183
1184 bit_buf.append_n(true, 5);
1186 bit_buf.append_n(false, 3);
1187 bit_buf.append(true);
1188
1189 assert_eq!(bit_buf.len(), 9);
1190
1191 bit_buf.set(6); bit_buf.unset(2); assert!(bit_buf.value(0));
1197 assert!(bit_buf.value(1));
1198 assert!(!bit_buf.value(2)); assert!(bit_buf.value(3));
1200 assert!(bit_buf.value(4));
1201 assert!(!bit_buf.value(5));
1202 assert!(bit_buf.value(6)); assert!(!bit_buf.value(7));
1204 assert!(bit_buf.value(8));
1205
1206 bit_buf.truncate(6);
1208 assert_eq!(bit_buf.len(), 6);
1209
1210 let frozen = bit_buf.freeze();
1212 assert_eq!(frozen.offset(), 3);
1213 assert_eq!(frozen.len(), 6);
1214 }
1215
1216 #[test]
1217 fn test_from_iterator_with_incorrect_size_hint() {
1218 struct LyingIterator {
1225 values: Vec<bool>,
1226 index: usize,
1227 }
1228
1229 impl Iterator for LyingIterator {
1230 type Item = bool;
1231
1232 fn next(&mut self) -> Option<Self::Item> {
1233 (self.index < self.values.len()).then(|| {
1234 let val = self.values[self.index];
1235 self.index += 1;
1236 val
1237 })
1238 }
1239
1240 fn size_hint(&self) -> (usize, Option<usize>) {
1241 let remaining = self.values.len() - self.index;
1244 let lower = remaining.min(5); let upper = Some(5); (lower, upper)
1247 }
1248 }
1249
1250 let lying_iter = LyingIterator {
1252 values: vec![
1253 true, false, true, false, true, false, true, false, true, false,
1254 ],
1255 index: 0,
1256 };
1257
1258 let bit_buf: BitBufferMut = lying_iter.collect();
1261
1262 assert_eq!(bit_buf.len(), 10);
1264 for i in 0..10 {
1265 assert_eq!(bit_buf.value(i), i % 2 == 0);
1266 }
1267 }
1268}