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,
103 len: usize,
104}
105
106impl BitBufferMut {
107 #[inline]
111 pub fn from_buffer(buffer: ByteBufferMut, offset: usize, len: usize) -> Self {
112 assert!(
113 len.saturating_add(offset) <= buffer.len().saturating_mul(8),
114 "Buffer len {} is too short for offset {offset} and length {len}",
115 buffer.len()
116 );
117 Self {
118 buffer,
119 offset,
120 len,
121 }
122 }
123
124 pub fn copy_from(bit_buffer: &BitBuffer) -> Self {
126 Self::copy_from_in(bit_buffer, bit_buffer.inner().allocator().clone())
127 }
128
129 pub fn copy_from_in(bit_buffer: &BitBuffer, allocator: BufferAllocatorRef) -> Self {
131 Self {
132 buffer: ByteBufferMut::copy_from_in(bit_buffer.inner(), allocator),
133 offset: bit_buffer.offset(),
134 len: bit_buffer.len(),
135 }
136 }
137
138 #[inline]
140 pub fn with_capacity(capacity: usize) -> Self {
141 Self::with_capacity_in(capacity, BufferAllocatorRef::statically_allocated())
142 }
143
144 #[inline]
146 pub fn with_capacity_in(capacity: usize, allocator: BufferAllocatorRef) -> Self {
147 Self {
148 buffer: BufferMut::with_capacity_in(capacity.div_ceil(8), allocator),
149 offset: 0,
150 len: 0,
151 }
152 }
153
154 #[inline]
156 pub fn new_set(len: usize) -> Self {
157 Self {
158 buffer: buffer_mut![0xFF; len.div_ceil(8)],
159 offset: 0,
160 len,
161 }
162 }
163
164 #[inline]
166 pub fn new_unset(len: usize) -> Self {
167 Self {
168 buffer: BufferMut::zeroed(len.div_ceil(8)),
169 offset: 0,
170 len,
171 }
172 }
173
174 #[allow(clippy::inline_always)]
176 #[inline(always)]
177 pub fn empty() -> Self {
178 Self::with_capacity(0)
179 }
180
181 pub fn empty_in(allocator: BufferAllocatorRef) -> Self {
183 Self::with_capacity_in(0, allocator)
184 }
185
186 #[cfg(test)]
187 pub(crate) fn allocator(&self) -> &BufferAllocatorRef {
188 self.buffer.allocator()
189 }
190
191 pub fn take(&mut self) -> Self {
193 Self {
194 buffer: self.buffer.take(),
195 offset: std::mem::take(&mut self.offset),
196 len: std::mem::take(&mut self.len),
197 }
198 }
199
200 #[inline]
202 pub fn full(value: bool, len: usize) -> Self {
203 if value {
204 Self::new_set(len)
205 } else {
206 Self::new_unset(len)
207 }
208 }
209
210 pub fn from_indices(len: usize, indices: impl IntoIterator<Item = usize>) -> BitBufferMut {
212 let mut buffer = BufferMut::<u64>::zeroed(len.div_ceil(64));
213 for idx in indices {
214 assert!(idx < len, "index {idx} exceeds len {len}");
215 buffer.as_mut_slice()[idx / 64] |= 1 << (idx % 64);
216 }
217
218 let mut buffer = buffer.into_byte_buffer();
219 buffer.truncate(len.div_ceil(8));
220
221 Self {
222 buffer,
223 offset: 0,
224 len,
225 }
226 }
227
228 #[inline]
232 pub fn collect_bool<F: FnMut(usize) -> bool>(len: usize, f: F) -> Self {
233 Self::collect_bool_in(len, f, BufferAllocatorRef::statically_allocated())
234 }
235
236 #[inline]
238 pub fn collect_bool_in<F: FnMut(usize) -> bool>(
239 len: usize,
240 f: F,
241 allocator: BufferAllocatorRef,
242 ) -> Self {
243 Self::collect_words_in(len, allocator, |words| collect_bool_words(words, len, f))
244 }
245
246 #[inline]
250 pub fn collect_bool_multiversioned<F: FnMut(usize) -> bool>(len: usize, f: F) -> Self {
251 Self::collect_bool_multiversioned_in(len, f, BufferAllocatorRef::statically_allocated())
252 }
253
254 #[inline]
256 pub fn collect_bool_multiversioned_in<F: FnMut(usize) -> bool>(
257 len: usize,
258 f: F,
259 allocator: BufferAllocatorRef,
260 ) -> Self {
261 Self::collect_words_in(len, allocator, |words| {
262 collect_bool_words_multiversioned(words, len, f)
263 })
264 }
265
266 #[inline]
267 fn collect_words_in(
268 len: usize,
269 allocator: BufferAllocatorRef,
270 fill: impl FnOnce(&mut [u64]),
271 ) -> Self {
272 let num_words = len.div_ceil(64);
273 let mut buffer = BufferMut::<u64>::with_capacity_in(num_words, allocator);
274 unsafe { buffer.set_len(num_words) };
278 fill(buffer.as_mut_slice());
279
280 let mut bytes = buffer.into_byte_buffer();
281 bytes.truncate(len.div_ceil(8));
282
283 Self {
284 buffer: bytes,
285 offset: 0,
286 len,
287 }
288 }
289
290 #[inline]
292 pub fn inner(&self) -> &ByteBufferMut {
293 &self.buffer
294 }
295
296 #[inline]
298 pub fn into_inner(self) -> ByteBufferMut {
299 self.buffer
300 }
301
302 #[allow(clippy::inline_always)]
304 #[inline(always)]
305 pub fn len(&self) -> usize {
306 self.len
307 }
308
309 #[allow(clippy::inline_always)]
311 #[inline(always)]
312 pub fn is_empty(&self) -> bool {
313 self.len == 0
314 }
315
316 #[allow(clippy::inline_always)]
318 #[inline(always)]
319 pub fn offset(&self) -> usize {
320 self.offset
321 }
322
323 #[allow(clippy::inline_always)]
325 #[inline(always)]
326 pub fn value(&self, index: usize) -> bool {
327 assert!(index < self.len);
328 unsafe { self.value_unchecked(index) }
330 }
331
332 #[allow(clippy::inline_always)]
338 #[inline(always)]
339 pub unsafe fn value_unchecked(&self, index: usize) -> bool {
340 unsafe { get_bit_unchecked(self.buffer.as_ptr(), self.offset + index) }
341 }
342
343 #[allow(clippy::inline_always)]
345 #[inline(always)]
346 pub fn capacity(&self) -> usize {
347 (self.buffer.capacity() * 8) - self.offset
348 }
349
350 #[inline]
352 pub fn reserve(&mut self, additional: usize) {
353 let required_bits = self.offset + self.len + additional;
354 let required_bytes = required_bits.div_ceil(8); let additional_bytes = required_bytes.saturating_sub(self.buffer.len());
357 self.buffer.reserve(additional_bytes);
358 }
359
360 #[inline]
362 pub fn clear(&mut self) {
363 self.buffer.clear();
366 self.len = 0;
367 self.offset = 0;
368 }
369
370 #[inline]
374 pub fn set_to(&mut self, index: usize, value: bool) {
375 if value {
376 self.set(index);
377 } else {
378 self.unset(index);
379 }
380 }
381
382 #[inline]
388 pub unsafe fn set_to_unchecked(&mut self, index: usize, value: bool) {
389 if value {
390 unsafe { self.set_unchecked(index) }
392 } else {
393 unsafe { self.unset_unchecked(index) }
395 }
396 }
397
398 #[inline]
402 pub fn set(&mut self, index: usize) {
403 assert!(index < self.len, "index {index} exceeds len {}", self.len);
404
405 unsafe { self.set_unchecked(index) };
407 }
408
409 #[inline]
413 pub fn unset(&mut self, index: usize) {
414 assert!(index < self.len, "index {index} exceeds len {}", self.len);
415
416 unsafe { self.unset_unchecked(index) };
418 }
419
420 #[inline]
428 pub unsafe fn set_unchecked(&mut self, index: usize) {
429 unsafe { set_bit_unchecked(self.buffer.as_mut_ptr(), self.offset + index) }
431 }
432
433 #[inline]
441 pub unsafe fn unset_unchecked(&mut self, index: usize) {
442 unsafe { unset_bit_unchecked(self.buffer.as_mut_ptr(), self.offset + index) }
444 }
445
446 #[allow(clippy::inline_always)]
453 #[inline(always)]
454 pub unsafe fn set_len(&mut self, new_len: usize) {
455 debug_assert!(
456 new_len <= self.capacity(),
457 "`set_len` requires that new_len <= capacity()"
458 );
459
460 let bytes_len = (self.offset + new_len).div_ceil(8);
462 unsafe { self.buffer.set_len(bytes_len) };
463
464 self.len = new_len;
465 }
466
467 #[inline]
471 pub fn truncate(&mut self, len: usize) {
472 if len > self.len {
473 return;
474 }
475
476 assert!(
477 self.offset <= usize::MAX - len,
478 "Truncate on BitBufferMut overflowed"
479 );
480 let end_bit = self.offset + len;
481 let new_len_bytes = end_bit.div_ceil(8);
482 self.buffer.truncate(new_len_bytes);
483 self.len = len;
484
485 if !end_bit.is_multiple_of(8) {
488 let keep = (1u8 << (end_bit % 8)) - 1;
489 self.buffer.as_mut_slice()[new_len_bytes - 1] &= keep;
490 }
491 }
492
493 #[inline]
495 pub fn append(&mut self, value: bool) {
496 if value {
497 self.append_true()
498 } else {
499 self.append_false()
500 }
501 }
502
503 #[inline]
505 pub fn append_true(&mut self) {
506 let bit_pos = self.offset + self.len;
507 let byte_pos = bit_pos / 8;
508 let bit_in_byte = bit_pos % 8;
509
510 if byte_pos >= self.buffer.len() {
512 self.buffer.push(0u8);
513 }
514
515 self.buffer.as_mut_slice()[byte_pos] |= 1 << bit_in_byte;
517 self.len += 1;
518 }
519
520 #[inline]
522 pub fn append_false(&mut self) {
523 let bit_pos = self.offset + self.len;
524 let byte_pos = bit_pos / 8;
525
526 if byte_pos >= self.buffer.len() {
528 self.buffer.push(0u8);
529 }
530
531 self.len += 1;
534 }
535
536 #[inline]
541 pub fn append_n(&mut self, value: bool, n: usize) {
542 if n == 0 {
543 return;
544 }
545
546 assert!(
547 self.offset
548 .checked_add(self.len)
549 .and_then(|v| v.checked_add(n))
550 .is_some(),
551 "Append on BitBufferMut overflowed"
552 );
553 let end_bit_pos = self.offset + self.len + n;
554 let required_bytes = end_bit_pos.div_ceil(8);
555
556 if required_bytes > self.buffer.len() {
558 self.buffer.push_n(0x00, required_bytes - self.buffer.len());
559 }
560
561 let start = self.len;
562 self.len += n;
563 self.fill_range(start, self.len, value);
564 }
565
566 #[allow(clippy::inline_always)]
571 #[inline(always)]
572 pub fn fill_range(&mut self, start: usize, end: usize, value: bool) {
573 assert!(end <= self.len, "end {end} exceeds len {}", self.len);
574 assert!(start <= end, "start {start} exceeds end {end}");
575
576 unsafe { self.fill_range_unchecked(start, end, value) }
579 }
580
581 #[allow(clippy::inline_always)]
587 #[inline(always)]
588 pub unsafe fn fill_range_unchecked(&mut self, start: usize, end: usize, value: bool) {
589 fill_bits(
590 self.buffer.as_mut_slice(),
591 self.offset + start,
592 self.offset + end,
593 value,
594 );
595 }
596
597 pub fn append_buffer(&mut self, buffer: &BitBuffer) {
601 let bit_len = buffer.len();
602 if bit_len == 0 {
603 return;
604 }
605
606 let start_bit_pos = self.offset + self.len;
607 let end_bit_pos = start_bit_pos + bit_len;
608 let required_bytes = end_bit_pos.div_ceil(8);
609
610 if required_bytes > self.buffer.len() {
612 self.buffer.push_n(0x00, required_bytes - self.buffer.len());
613 }
614
615 let dst_bit_offset = start_bit_pos % 8;
616 let src_bit_offset = buffer.offset();
617
618 if dst_bit_offset == 0 && src_bit_offset == 0 {
619 let dst_byte = start_bit_pos / 8;
621 let src_bytes = buffer.inner().as_slice();
622 let full_bytes = bit_len / 8;
623 self.buffer.as_mut_slice()[dst_byte..dst_byte + full_bytes]
624 .copy_from_slice(&src_bytes[..full_bytes]);
625 let rem = bit_len % 8;
626 if rem != 0 {
627 let mask = (1u8 << rem) - 1;
628 self.buffer.as_mut_slice()[dst_byte + full_bytes] |= src_bytes[full_bytes] & mask;
629 }
630 } else {
631 let self_slice = self
633 .buffer
634 .as_mut_slice()
635 .view_bits_mut::<bitvec::prelude::Lsb0>();
636 let other_slice = buffer
637 .inner()
638 .as_slice()
639 .view_bits::<bitvec::prelude::Lsb0>();
640 let source_range = src_bit_offset..src_bit_offset + bit_len;
641 self_slice[start_bit_pos..end_bit_pos].copy_from_bitslice(&other_slice[source_range]);
642 }
643
644 self.len += bit_len;
645 }
646
647 #[inline]
649 pub fn freeze(self) -> BitBuffer {
650 BitBuffer::new_with_offset(self.buffer.freeze(), self.len, self.offset)
651 }
652
653 #[inline]
655 pub fn as_slice(&self) -> &[u8] {
656 self.buffer.as_slice()
657 }
658
659 #[inline]
661 pub fn as_mut_slice(&mut self) -> &mut [u8] {
662 self.buffer.as_mut_slice()
663 }
664}
665
666impl Default for BitBufferMut {
667 fn default() -> Self {
668 Self::with_capacity(0)
669 }
670}
671
672impl Not for BitBufferMut {
674 type Output = BitBufferMut;
675
676 #[inline]
677 fn not(mut self) -> Self::Output {
678 ops::bitwise_unary_op_mut(&mut self, |b| !b);
679 self
680 }
681}
682
683impl From<&[bool]> for BitBufferMut {
684 fn from(value: &[bool]) -> Self {
685 BitBufferMut::collect_bool_multiversioned(value.len(), |i| unsafe {
688 *value.get_unchecked(i)
689 })
690 }
691}
692
693impl From<&[u8]> for BitBufferMut {
695 fn from(value: &[u8]) -> Self {
696 BitBufferMut::collect_bool_multiversioned(
699 value.len(),
700 |i| unsafe { *value.get_unchecked(i) } > 0,
701 )
702 }
703}
704
705impl From<Vec<bool>> for BitBufferMut {
706 fn from(value: Vec<bool>) -> Self {
707 value.as_slice().into()
708 }
709}
710
711impl FromIterator<bool> for BitBufferMut {
712 #[inline]
713 fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
714 let mut iter = iter.into_iter();
715
716 let (lower_bound, _) = iter.size_hint();
719
720 let mut buf = BitBufferMut::new_unset(lower_bound);
725 assert_eq!(buf.offset, 0);
726
727 let ptr = buf.buffer.as_mut_ptr();
729 for i in 0..lower_bound {
730 let Some(v) = iter.next() else {
731 unsafe { buf.set_len(i) };
734 return buf;
735 };
736
737 if v {
738 unsafe { set_bit_unchecked(ptr, i) }
740 }
741 }
742
743 for v in iter {
746 buf.append(v);
747 }
748
749 buf
750 }
751}
752
753#[cfg(test)]
754mod tests {
755 use allocator_api2::alloc::Global;
756 use rstest::rstest;
757
758 use crate::BufferAllocatorRef;
759 use crate::BufferMut;
760 use crate::bit::buf_mut::BitBufferMut;
761 use crate::bitbuffer;
762 use crate::bitbuffer_mut;
763 use crate::buffer_mut;
764
765 #[test]
766 fn test_bits_mut() {
767 let mut bools = bitbuffer_mut![false; 10];
768 bools.set_to(0, true);
769 bools.set_to(9, true);
770
771 let bools = bools.freeze();
772 assert!(bools.value(0));
773 for i in 1..=8 {
774 assert!(!bools.value(i));
775 }
776 assert!(bools.value(9));
777 }
778
779 #[test]
780 fn take_preserves_allocator() {
781 let allocator = BufferAllocatorRef::new(Global);
782 let mut buffer = BitBufferMut::with_capacity_in(4, allocator.clone());
783 buffer.append(true);
784 buffer.append(false);
785 buffer.append(true);
786
787 let taken = buffer.take();
788
789 assert_eq!(
790 (0..taken.len())
791 .map(|index| taken.value(index))
792 .collect::<Vec<_>>(),
793 [true, false, true]
794 );
795 assert!(taken.allocator().ptr_eq(&allocator));
796 assert!(buffer.is_empty());
797 assert!(buffer.allocator().ptr_eq(&allocator));
798 }
799
800 #[test]
801 fn test_append_n() {
802 let mut bools = BitBufferMut::with_capacity(10);
803 assert_eq!(bools.len(), 0);
804 assert!(bools.is_empty());
805
806 bools.append(true);
807 bools.append_n(false, 8);
808 bools.append_n(true, 1);
809
810 let bools = bools.freeze();
811
812 assert_eq!(bools.true_count(), 2);
813 assert!(bools.value(0));
814 assert!(bools.value(9));
815 }
816
817 #[test]
818 fn append_false_after_truncate_reads_back_false() {
819 let mut bools = BitBufferMut::new_set(16);
822 bools.truncate(12);
823 bools.append_false();
824 bools.append_true();
825
826 let bools = bools.freeze();
827 assert_eq!(bools.len(), 14);
828 assert!(
829 !bools.value(12),
830 "appended false must read back false after truncate"
831 );
832 assert!(bools.value(13));
833 }
834
835 #[test]
836 fn test_reserve_ensures_len_plus_additional() {
837 let mut bits = BitBufferMut::with_capacity(10);
841 assert_eq!(bits.len(), 0);
842
843 bits.reserve(100);
844
845 assert!(bits.capacity() >= 100);
847
848 bits.append_n(true, 50);
849 assert_eq!(bits.len(), 50);
850
851 bits.reserve(100);
852
853 assert!(bits.capacity() >= 150);
855 }
856
857 #[test]
858 fn test_with_offset_zero() {
859 let buf = BufferMut::zeroed(2);
861 let mut bit_buf = BitBufferMut::from_buffer(buf, 0, 16);
862
863 bit_buf.set(0);
865 bit_buf.set(7);
866 bit_buf.set(8);
867 bit_buf.set(15);
868
869 assert!(bit_buf.value(0));
871 assert!(bit_buf.value(7));
872 assert!(bit_buf.value(8));
873 assert!(bit_buf.value(15));
874 assert!(!bit_buf.value(1));
875 assert!(!bit_buf.value(9));
876
877 assert_eq!(bit_buf.as_slice()[0], 0b10000001);
879 assert_eq!(bit_buf.as_slice()[1], 0b10000001);
880 }
881
882 #[test]
883 fn test_with_offset_within_byte() {
884 let buf = buffer_mut![0b11111111, 0b00000000, 0b00000000];
886 let mut bit_buf = BitBufferMut::from_buffer(buf, 3, 10);
887
888 assert!(bit_buf.value(0)); assert!(bit_buf.value(4)); assert!(!bit_buf.value(5)); bit_buf.set(7);
896 assert!(bit_buf.value(7));
897
898 bit_buf.unset(0);
900 assert!(!bit_buf.value(0));
901 }
902
903 #[test]
904 fn test_with_offset_byte_boundary() {
905 let buf = buffer_mut![0xFF, 0x00, 0xFF];
907 let mut bit_buf = BitBufferMut::from_buffer(buf, 8, 16);
908
909 for i in 0..8 {
911 assert!(!bit_buf.value(i));
912 }
913 for i in 8..16 {
915 assert!(bit_buf.value(i));
916 }
917
918 bit_buf.set(0);
920 bit_buf.set(3);
921 assert!(bit_buf.value(0));
922 assert!(bit_buf.value(3));
923 }
924
925 #[test]
926 fn test_with_large_offset() {
927 let buf = buffer_mut![0xFF, 0xFF, 0xFF, 0xFF];
929 let mut bit_buf = BitBufferMut::from_buffer(buf, 13, 10);
930
931 for i in 0..10 {
933 assert!(bit_buf.value(i));
934 }
935
936 bit_buf.unset(0);
938 bit_buf.unset(5);
939 bit_buf.unset(9);
940
941 assert!(!bit_buf.value(0));
942 assert!(bit_buf.value(1));
943 assert!(!bit_buf.value(5));
944 assert!(!bit_buf.value(9));
945 }
946
947 #[test]
948 fn test_append_with_offset() {
949 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);
959 assert!(!bit_buf.value(0));
960 assert!(bit_buf.value(1));
961 assert!(bit_buf.value(2));
962 }
963
964 #[test]
965 fn test_append_n_with_offset_crossing_boundary() {
966 let buf = BufferMut::zeroed(4);
968 let mut bit_buf = BitBufferMut::from_buffer(buf, 5, 0);
969
970 bit_buf.append_n(true, 10); assert_eq!(bit_buf.len(), 10);
974 for i in 0..10 {
975 assert!(bit_buf.value(i));
976 }
977
978 assert_eq!(bit_buf.as_slice()[0], 0b11100000);
982 assert_eq!(bit_buf.as_slice()[1], 0b01111111);
983 }
984
985 #[test]
986 fn test_truncate_with_offset() {
987 let buf = buffer_mut![0xFF, 0xFF];
988 let mut bit_buf = BitBufferMut::from_buffer(buf, 4, 12);
989
990 assert_eq!(bit_buf.len(), 12);
991
992 bit_buf.truncate(8);
994 assert_eq!(bit_buf.len(), 8);
995
996 bit_buf.truncate(3);
998 assert_eq!(bit_buf.len(), 3);
999
1000 bit_buf.truncate(10);
1002 assert_eq!(bit_buf.len(), 3);
1003 }
1004
1005 #[test]
1006 fn test_capacity_with_offset() {
1007 let buf = buffer_mut![0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; let bit_buf = BitBufferMut::from_buffer(buf, 5, 0);
1010
1011 assert!(bit_buf.capacity() >= 75);
1014 assert_eq!(bit_buf.capacity() % 8, (80 - 5) % 8);
1016 }
1017
1018 #[test]
1019 fn test_reserve_with_offset() {
1020 let buf = buffer_mut![0, 0]; let mut bit_buf = BitBufferMut::from_buffer(buf, 3, 0);
1023
1024 let initial_capacity = bit_buf.capacity();
1026 assert!(initial_capacity >= 13);
1027
1028 bit_buf.reserve(20);
1030
1031 assert!(bit_buf.capacity() >= 20);
1033 }
1034
1035 #[test]
1036 fn test_freeze_with_offset() {
1037 let buf = buffer_mut![0b11110000, 0b00001111];
1038 let mut bit_buf = BitBufferMut::from_buffer(buf, 4, 8);
1039
1040 bit_buf.set(0);
1042 bit_buf.set(7);
1043
1044 let frozen = bit_buf.freeze();
1046 assert_eq!(frozen.offset(), 4);
1047 assert_eq!(frozen.len(), 8);
1048
1049 assert!(frozen.value(0));
1051 assert!(frozen.value(7));
1052 }
1053
1054 #[cfg_attr(miri, ignore)] #[test]
1056 fn append_after_clear_reads_back_false() {
1057 let mut bools = BitBufferMut::new_set(16);
1060 bools.clear();
1061 bools.append_false();
1062 bools.append_buffer(&crate::BitBuffer::new_unset(8));
1063
1064 let bools = bools.freeze();
1065 assert_eq!(bools.len(), 9);
1066 assert_eq!(bools.true_count(), 0);
1067 }
1068
1069 #[cfg_attr(miri, ignore)] #[test]
1071 fn test_append_buffer_after_truncate() {
1072 let mut buf = BitBufferMut::new_set(16);
1075 buf.truncate(3);
1076 buf.append_buffer(&crate::BitBuffer::new_unset(8));
1077
1078 let frozen = buf.freeze();
1079 assert_eq!(frozen.len(), 11);
1080 for i in 0..3 {
1081 assert!(frozen.value(i), "bit {i} should be set");
1082 }
1083 for i in 3..11 {
1084 assert!(!frozen.value(i), "bit {i} should be unset");
1085 }
1086 }
1087
1088 #[rstest]
1089 #[case::both_aligned(0, 0)]
1090 #[case::dst_unaligned(3, 0)]
1091 #[case::src_unaligned(0, 5)]
1092 #[case::mismatched(3, 5)]
1093 #[case::equal_nonzero(5, 5)]
1094 #[cfg_attr(miri, ignore)] fn test_append_buffer_long(#[case] dst_prefix: usize, #[case] src_start: usize) {
1096 let source = crate::BitBuffer::from_iter((0..301).map(|i| i % 3 == 0));
1098 let source = source.slice(src_start..301);
1099
1100 let mut dest = BitBufferMut::with_capacity(512);
1101 dest.append_n(true, dst_prefix);
1102 dest.append_buffer(&source);
1103
1104 assert_eq!(dest.len(), dst_prefix + source.len());
1105 for i in 0..dst_prefix {
1106 assert!(dest.value(i), "prefix bit {i}");
1107 }
1108 for i in 0..source.len() {
1109 assert_eq!(dest.value(dst_prefix + i), source.value(i), "bit {i}");
1110 }
1111 }
1112
1113 #[cfg_attr(miri, ignore)] #[test]
1115 fn test_append_buffer_with_offsets() {
1116 let source = bitbuffer![false, false, true, true, false, true];
1118
1119 let buf = BufferMut::zeroed(4);
1121 let mut dest = BitBufferMut::from_buffer(buf, 3, 0);
1122
1123 dest.append(true);
1125 dest.append(false);
1126
1127 dest.append_buffer(&source);
1129
1130 assert_eq!(dest.len(), 8);
1131 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)); }
1140
1141 #[test]
1142 fn test_set_unset_unchecked_with_offset() {
1143 let buf = BufferMut::zeroed(3);
1144 let mut bit_buf = BitBufferMut::from_buffer(buf, 7, 10);
1145
1146 unsafe {
1147 bit_buf.set_unchecked(0);
1148 bit_buf.set_unchecked(5);
1149 bit_buf.set_unchecked(9);
1150 }
1151
1152 assert!(bit_buf.value(0));
1153 assert!(bit_buf.value(5));
1154 assert!(bit_buf.value(9));
1155
1156 unsafe {
1157 bit_buf.unset_unchecked(5);
1158 }
1159
1160 assert!(!bit_buf.value(5));
1161 }
1162
1163 #[test]
1164 fn test_value_unchecked_with_offset() {
1165 let buf = buffer_mut![0b11110000, 0b00001111];
1166 let bit_buf = BitBufferMut::from_buffer(buf, 4, 8);
1167
1168 unsafe {
1169 assert!(bit_buf.value_unchecked(0));
1171 assert!(bit_buf.value_unchecked(3));
1172
1173 assert!(bit_buf.value_unchecked(4));
1175 assert!(bit_buf.value_unchecked(7));
1176 }
1177 }
1178
1179 #[test]
1180 fn test_append_alternating_with_offset() {
1181 let buf = BufferMut::zeroed(4);
1182 let mut bit_buf = BitBufferMut::from_buffer(buf, 2, 0);
1183
1184 for i in 0..20 {
1186 bit_buf.append(i % 2 == 0);
1187 }
1188
1189 assert_eq!(bit_buf.len(), 20);
1190 for i in 0..20 {
1191 assert_eq!(bit_buf.value(i), i % 2 == 0);
1192 }
1193 }
1194
1195 #[test]
1196 fn test_new_set_new_unset() {
1197 let set_buf = bitbuffer_mut![true; 10];
1198 let unset_buf = bitbuffer_mut![false; 10];
1199
1200 for i in 0..10 {
1201 assert!(set_buf.value(i));
1202 assert!(!unset_buf.value(i));
1203 }
1204
1205 assert_eq!(set_buf.len(), 10);
1206 assert_eq!(unset_buf.len(), 10);
1207 }
1208
1209 #[test]
1210 fn test_append_n_false_with_offset() {
1211 let buf = BufferMut::zeroed(4);
1212 let mut bit_buf = BitBufferMut::from_buffer(buf, 5, 0);
1213
1214 bit_buf.append_n(false, 15);
1215
1216 assert_eq!(bit_buf.len(), 15);
1217 for i in 0..15 {
1218 assert!(!bit_buf.value(i));
1219 }
1220 }
1221
1222 #[test]
1223 fn test_append_n_true_with_offset() {
1224 let buf = BufferMut::zeroed(4);
1225 let mut bit_buf = BitBufferMut::from_buffer(buf, 5, 0);
1226
1227 bit_buf.append_n(true, 15);
1228
1229 assert_eq!(bit_buf.len(), 15);
1230 for i in 0..15 {
1231 assert!(bit_buf.value(i));
1232 }
1233 }
1234
1235 #[test]
1236 fn test_mixed_operations_with_offset() {
1237 let buf = BufferMut::zeroed(5);
1239 let mut bit_buf = BitBufferMut::from_buffer(buf, 3, 0);
1240
1241 bit_buf.append_n(true, 5);
1243 bit_buf.append_n(false, 3);
1244 bit_buf.append(true);
1245
1246 assert_eq!(bit_buf.len(), 9);
1247
1248 bit_buf.set(6); bit_buf.unset(2); assert!(bit_buf.value(0));
1254 assert!(bit_buf.value(1));
1255 assert!(!bit_buf.value(2)); assert!(bit_buf.value(3));
1257 assert!(bit_buf.value(4));
1258 assert!(!bit_buf.value(5));
1259 assert!(bit_buf.value(6)); assert!(!bit_buf.value(7));
1261 assert!(bit_buf.value(8));
1262
1263 bit_buf.truncate(6);
1265 assert_eq!(bit_buf.len(), 6);
1266
1267 let frozen = bit_buf.freeze();
1269 assert_eq!(frozen.offset(), 3);
1270 assert_eq!(frozen.len(), 6);
1271 }
1272
1273 #[test]
1274 fn test_from_iterator_with_incorrect_size_hint() {
1275 struct LyingIterator {
1282 values: Vec<bool>,
1283 index: usize,
1284 }
1285
1286 impl Iterator for LyingIterator {
1287 type Item = bool;
1288
1289 fn next(&mut self) -> Option<Self::Item> {
1290 (self.index < self.values.len()).then(|| {
1291 let val = self.values[self.index];
1292 self.index += 1;
1293 val
1294 })
1295 }
1296
1297 fn size_hint(&self) -> (usize, Option<usize>) {
1298 let remaining = self.values.len() - self.index;
1301 let lower = remaining.min(5); let upper = Some(5); (lower, upper)
1304 }
1305 }
1306
1307 let lying_iter = LyingIterator {
1309 values: vec![
1310 true, false, true, false, true, false, true, false, true, false,
1311 ],
1312 index: 0,
1313 };
1314
1315 let bit_buf: BitBufferMut = lying_iter.collect();
1318
1319 assert_eq!(bit_buf.len(), 10);
1321 for i in 0..10 {
1322 assert_eq!(bit_buf.value(i), i % 2 == 0);
1323 }
1324 }
1325
1326 #[rstest]
1330 #[case(0, 8)]
1331 #[case(1, 7)]
1332 #[case(7, 1)]
1333 #[case(8, 0)]
1334 fn from_buffer_accepts_offset_plus_len_within_the_buffer(
1335 #[case] offset: usize,
1336 #[case] len: usize,
1337 ) {
1338 let bits = BitBufferMut::from_buffer(buffer_mut![0u8; 1], offset, len);
1339 assert_eq!(bits.len(), len);
1340 }
1341
1342 #[rstest]
1343 #[case::offset_pushes_past_the_end(1, 8)]
1344 #[case::offset_alone_past_the_end(9, 0)]
1345 #[case::len_alone_past_the_end(0, 9)]
1346 #[should_panic(expected = "is too short for offset")]
1347 fn from_buffer_rejects_offset_plus_len_past_the_buffer(
1348 #[case] offset: usize,
1349 #[case] len: usize,
1350 ) {
1351 BitBufferMut::from_buffer(buffer_mut![0u8; 1], offset, len);
1352 }
1353
1354 #[test]
1357 fn from_buffer_allows_offsets_beyond_one_byte() {
1358 let bits = BitBufferMut::from_buffer(buffer_mut![0u8; 128], 1000, 24);
1359 assert_eq!(bits.len(), 24);
1360 }
1361
1362 #[test]
1364 #[should_panic(expected = "is too short for offset")]
1365 fn from_buffer_does_not_wrap_on_a_huge_offset() {
1366 BitBufferMut::from_buffer(buffer_mut![0u8; 1], usize::MAX, 8);
1367 }
1368}