1use std::ops::Bound;
5use std::ops::RangeBounds;
6
7use crate::BitBuffer;
8use crate::BitBufferMeta;
9use crate::BitBufferMut;
10use crate::ByteBuffer;
11use crate::bit::BitChunks;
12use crate::bit::BitIndexIterator;
13use crate::bit::BitIterator;
14use crate::bit::BitSliceIterator;
15use crate::bit::UnalignedBitChunk;
16use crate::bit::buf_mut::fill_bits;
17use crate::bit::count_ones::count_ones;
18use crate::bit::get_bit_unchecked;
19use crate::bit::select::bit_select;
20use crate::bit::set_bit_unchecked;
21use crate::bit::unset_bit_unchecked;
22
23#[inline]
25fn resolve_range(range: impl RangeBounds<usize>, len: usize) -> (usize, usize) {
26 let start = match range.start_bound() {
27 Bound::Included(&s) => s,
28 Bound::Excluded(&s) => s + 1,
29 Bound::Unbounded => 0,
30 };
31 let end = match range.end_bound() {
32 Bound::Included(&e) => e + 1,
33 Bound::Excluded(&e) => e,
34 Bound::Unbounded => len,
35 };
36
37 assert!(start <= end);
38 assert!(start <= len);
39 assert!(end <= len);
40 (start, end)
41}
42
43#[inline]
45fn normalize(buffer: &[u8], offset: usize) -> (&[u8], usize) {
46 let byte_offset = offset / 8;
47 (&buffer[byte_offset..], offset % 8)
48}
49
50#[derive(Debug, Clone, Copy)]
56pub struct BitBufferView<'a> {
57 buffer: &'a [u8],
58 offset: usize,
59 len: usize,
60}
61
62impl<'a> BitBufferView<'a> {
63 #[inline]
67 pub fn new(buffer: &'a [u8], len: usize) -> Self {
68 Self::new_with_offset(buffer, len, 0)
69 }
70
71 #[inline]
75 pub fn new_with_offset(buffer: &'a [u8], len: usize, offset: usize) -> Self {
76 assert!(
77 len.saturating_add(offset) <= buffer.len().saturating_mul(8),
78 "provided slice (len={}) not large enough to back BitBufferView with offset {offset} len {len}",
79 buffer.len()
80 );
81
82 let (buffer, offset) = normalize(buffer, offset);
83 Self {
84 buffer,
85 offset,
86 len,
87 }
88 }
89
90 #[inline]
92 pub fn from_meta(buffer: &'a [u8], meta: BitBufferMeta) -> Self {
93 Self::new_with_offset(buffer, meta.len(), meta.offset())
94 }
95
96 #[inline]
98 pub fn meta(&self) -> BitBufferMeta {
99 BitBufferMeta::new(self.offset, self.len)
100 }
101
102 #[inline]
104 pub fn len(&self) -> usize {
105 self.len
106 }
107
108 #[inline]
110 pub fn is_empty(&self) -> bool {
111 self.len == 0
112 }
113
114 #[inline(always)]
116 pub fn offset(&self) -> usize {
117 self.offset
118 }
119
120 #[inline(always)]
122 pub fn inner(&self) -> &'a [u8] {
123 self.buffer
124 }
125
126 #[inline]
130 pub fn value(&self, index: usize) -> bool {
131 assert!(index < self.len);
132 unsafe { self.value_unchecked(index) }
134 }
135
136 #[inline]
142 pub unsafe fn value_unchecked(&self, index: usize) -> bool {
143 unsafe { get_bit_unchecked(self.buffer.as_ptr(), index + self.offset) }
144 }
145
146 #[inline]
150 pub fn slice(&self, range: impl RangeBounds<usize>) -> BitBufferView<'a> {
151 let (start, end) = resolve_range(range, self.len);
152 BitBufferView::new_with_offset(self.buffer, end - start, self.offset + start)
153 }
154
155 #[inline]
158 pub fn unaligned_chunks(&self) -> UnalignedBitChunk<'a> {
159 UnalignedBitChunk::new(self.buffer, self.offset, self.len)
160 }
161
162 #[inline]
164 pub fn chunks(&self) -> BitChunks<'a> {
165 BitChunks::new(self.buffer, self.offset, self.len)
166 }
167
168 #[inline]
170 pub fn true_count(&self) -> usize {
171 count_ones(self.buffer, self.offset, self.len)
172 }
173
174 #[inline]
176 pub fn false_count(&self) -> usize {
177 self.len - self.true_count()
178 }
179
180 #[inline]
182 pub fn select(&self, nth: usize) -> Option<usize> {
183 bit_select(self.buffer, self.offset, self.len, nth)
184 }
185
186 #[inline]
188 pub fn iter(&self) -> BitIterator<'a> {
189 BitIterator::new(self.buffer, self.offset, self.len)
190 }
191
192 #[inline]
194 pub fn set_indices(&self) -> BitIndexIterator<'a> {
195 BitIndexIterator::new(self.buffer, self.offset, self.len)
196 }
197
198 #[inline]
200 pub fn set_slices(&self) -> BitSliceIterator<'a> {
201 BitSliceIterator::new(self.buffer, self.offset, self.len)
202 }
203
204 pub fn to_bit_buffer(&self) -> BitBuffer {
206 let bytes = (self.offset + self.len).div_ceil(8);
207 BitBuffer::new_with_offset(
208 ByteBuffer::copy_from(&self.buffer[..bytes]),
209 self.len,
210 self.offset,
211 )
212 }
213}
214
215impl<'a> IntoIterator for BitBufferView<'a> {
216 type Item = bool;
217 type IntoIter = BitIterator<'a>;
218
219 fn into_iter(self) -> Self::IntoIter {
220 self.iter()
221 }
222}
223
224impl PartialEq for BitBufferView<'_> {
225 fn eq(&self, other: &Self) -> bool {
226 if self.len != other.len {
227 return false;
228 }
229
230 self.chunks()
231 .iter_padded()
232 .zip(other.chunks().iter_padded())
233 .all(|(a, b)| a == b)
234 }
235}
236
237impl Eq for BitBufferView<'_> {}
238
239#[derive(Debug)]
246pub struct BitBufferMutView<'a> {
247 buffer: &'a mut [u8],
248 offset: usize,
249 len: usize,
250}
251
252impl<'a> BitBufferMutView<'a> {
253 #[inline]
257 pub fn new(buffer: &'a mut [u8], len: usize) -> Self {
258 Self::new_with_offset(buffer, len, 0)
259 }
260
261 #[inline]
265 pub fn new_with_offset(buffer: &'a mut [u8], len: usize, offset: usize) -> Self {
266 assert!(
267 len.saturating_add(offset) <= buffer.len().saturating_mul(8),
268 "provided slice (len={}) not large enough to back BitBufferMutView with offset {offset} len {len}",
269 buffer.len()
270 );
271
272 let byte_offset = offset / 8;
273 let offset = offset % 8;
274 Self {
275 buffer: &mut buffer[byte_offset..],
276 offset,
277 len,
278 }
279 }
280
281 #[inline]
283 pub fn as_view(&self) -> BitBufferView<'_> {
284 BitBufferView {
285 buffer: self.buffer,
286 offset: self.offset,
287 len: self.len,
288 }
289 }
290
291 #[inline]
293 pub fn len(&self) -> usize {
294 self.len
295 }
296
297 #[inline]
299 pub fn is_empty(&self) -> bool {
300 self.len == 0
301 }
302
303 #[inline(always)]
305 pub fn offset(&self) -> usize {
306 self.offset
307 }
308
309 #[inline]
311 pub fn as_slice(&self) -> &[u8] {
312 self.buffer
313 }
314
315 #[inline]
317 pub fn as_mut_slice(&mut self) -> &mut [u8] {
318 self.buffer
319 }
320
321 #[inline]
325 pub fn value(&self, index: usize) -> bool {
326 assert!(index < self.len);
327 unsafe { self.value_unchecked(index) }
329 }
330
331 #[inline]
337 pub unsafe fn value_unchecked(&self, index: usize) -> bool {
338 unsafe { get_bit_unchecked(self.buffer.as_ptr(), index + self.offset) }
339 }
340
341 #[inline]
343 pub fn true_count(&self) -> usize {
344 self.as_view().true_count()
345 }
346
347 #[inline]
349 pub fn false_count(&self) -> usize {
350 self.as_view().false_count()
351 }
352
353 #[inline]
355 pub fn iter(&self) -> BitIterator<'_> {
356 self.as_view().iter()
357 }
358
359 #[inline]
363 pub fn set_to(&mut self, index: usize, value: bool) {
364 if value {
365 self.set(index);
366 } else {
367 self.unset(index);
368 }
369 }
370
371 #[inline]
377 pub unsafe fn set_to_unchecked(&mut self, index: usize, value: bool) {
378 if value {
379 unsafe { self.set_unchecked(index) }
381 } else {
382 unsafe { self.unset_unchecked(index) }
384 }
385 }
386
387 #[inline]
391 pub fn set(&mut self, index: usize) {
392 assert!(index < self.len, "index {index} exceeds len {}", self.len);
393 unsafe { self.set_unchecked(index) };
395 }
396
397 #[inline]
401 pub fn unset(&mut self, index: usize) {
402 assert!(index < self.len, "index {index} exceeds len {}", self.len);
403 unsafe { self.unset_unchecked(index) };
405 }
406
407 #[inline]
413 pub unsafe fn set_unchecked(&mut self, index: usize) {
414 unsafe { set_bit_unchecked(self.buffer.as_mut_ptr(), self.offset + index) }
416 }
417
418 #[inline]
424 pub unsafe fn unset_unchecked(&mut self, index: usize) {
425 unsafe { unset_bit_unchecked(self.buffer.as_mut_ptr(), self.offset + index) }
427 }
428
429 #[inline(always)]
433 pub fn fill_range(&mut self, start: usize, end: usize, value: bool) {
434 assert!(end <= self.len, "end {end} exceeds len {}", self.len);
435 assert!(start <= end, "start {start} exceeds end {end}");
436 unsafe { self.fill_range_unchecked(start, end, value) }
438 }
439
440 #[inline(always)]
446 pub unsafe fn fill_range_unchecked(&mut self, start: usize, end: usize, value: bool) {
447 fill_bits(self.buffer, self.offset + start, self.offset + end, value);
448 }
449
450 pub fn to_bit_buffer(&self) -> BitBuffer {
452 self.as_view().to_bit_buffer()
453 }
454}
455
456impl BitBuffer {
457 #[inline]
459 pub fn as_view(&self) -> BitBufferView<'_> {
460 BitBufferView {
461 buffer: self.inner().as_slice(),
462 offset: self.offset(),
463 len: self.len(),
464 }
465 }
466}
467
468impl BitBufferMut {
469 #[inline]
471 pub fn as_view(&self) -> BitBufferView<'_> {
472 BitBufferView {
473 buffer: self.as_slice(),
474 offset: self.offset(),
475 len: self.len(),
476 }
477 }
478
479 #[inline]
481 pub fn as_mut_view(&mut self) -> BitBufferMutView<'_> {
482 let offset = self.offset();
483 let len = self.len();
484 BitBufferMutView {
485 buffer: self.as_mut_slice(),
486 offset,
487 len,
488 }
489 }
490}
491
492#[cfg(test)]
493mod tests {
494 use crate::BitBuffer;
495 use crate::BitBufferMut;
496 use crate::bitbuffer;
497
498 #[test]
499 fn view_reads_match_buffer() {
500 let buffer = bitbuffer![true, false, true, true, false, true, false, false];
501 let view = buffer.as_view();
502
503 assert_eq!(view.len(), buffer.len());
504 assert_eq!(view.true_count(), buffer.true_count());
505 assert_eq!(view.false_count(), buffer.false_count());
506 for i in 0..buffer.len() {
507 assert_eq!(view.value(i), buffer.value(i));
508 }
509 assert_eq!(
510 view.iter().collect::<Vec<_>>(),
511 buffer.iter().collect::<Vec<_>>()
512 );
513 }
514
515 #[test]
516 fn view_slice_preserves_offset() {
517 let buffer = BitBuffer::new_set(20);
518 let sliced = buffer.slice(5..17);
519 let view = buffer.as_view().slice(5..17);
520
521 assert_eq!(view.len(), sliced.len());
522 assert_eq!(view.true_count(), sliced.true_count());
523 assert_eq!(view.to_bit_buffer(), sliced);
524 }
525
526 #[test]
527 fn view_offset_buffer() {
528 let buffer = BitBuffer::new_set(64).slice(3..40);
529 let view = buffer.as_view();
530 assert_eq!(view.offset(), buffer.offset());
531 assert_eq!(view.len(), buffer.len());
532 assert_eq!(view.to_bit_buffer(), buffer);
533 }
534
535 #[test]
536 fn mut_view_set_unset() {
537 let mut buffer = BitBufferMut::new_unset(16);
538 {
539 let mut view = buffer.as_mut_view();
540 view.set(0);
541 view.set(15);
542 view.set_to(7, true);
543 view.fill_range(2, 5, true);
544 assert!(view.value(0));
545 assert_eq!(view.true_count(), 6);
546 view.unset(0);
547 }
548 let frozen = buffer.freeze();
549 assert!(!frozen.value(0));
550 assert!(frozen.value(2));
551 assert!(frozen.value(4));
552 assert!(frozen.value(7));
553 assert!(frozen.value(15));
554 assert_eq!(frozen.true_count(), 5);
555 }
556
557 #[test]
558 fn mut_view_with_offset() {
559 let mut buffer = BitBufferMut::from_buffer(crate::buffer_mut![0u8; 4], 3, 20);
560 {
561 let mut view = buffer.as_mut_view();
562 assert_eq!(view.offset(), 3);
563 view.fill_range(0, 20, true);
564 }
565 let frozen = buffer.freeze();
566 assert_eq!(frozen.true_count(), 20);
567 }
568}