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 pub fn new(buffer: &'a [u8], len: usize) -> Self {
67 Self::new_with_offset(buffer, len, 0)
68 }
69
70 pub fn new_with_offset(buffer: &'a [u8], len: usize, offset: usize) -> Self {
74 assert!(
75 len.saturating_add(offset) <= buffer.len().saturating_mul(8),
76 "provided slice (len={}) not large enough to back BitBufferView with offset {offset} len {len}",
77 buffer.len()
78 );
79
80 let (buffer, offset) = normalize(buffer, offset);
81 Self {
82 buffer,
83 offset,
84 len,
85 }
86 }
87
88 pub fn from_meta(buffer: &'a [u8], meta: BitBufferMeta) -> Self {
90 Self::new_with_offset(buffer, meta.len(), meta.offset())
91 }
92
93 pub fn meta(&self) -> BitBufferMeta {
95 BitBufferMeta::new(self.offset, self.len)
96 }
97
98 #[inline]
100 pub fn len(&self) -> usize {
101 self.len
102 }
103
104 #[inline]
106 pub fn is_empty(&self) -> bool {
107 self.len == 0
108 }
109
110 #[inline(always)]
112 pub fn offset(&self) -> usize {
113 self.offset
114 }
115
116 #[inline(always)]
118 pub fn inner(&self) -> &'a [u8] {
119 self.buffer
120 }
121
122 #[inline]
126 pub fn value(&self, index: usize) -> bool {
127 assert!(index < self.len);
128 unsafe { self.value_unchecked(index) }
130 }
131
132 #[inline]
138 pub unsafe fn value_unchecked(&self, index: usize) -> bool {
139 unsafe { get_bit_unchecked(self.buffer.as_ptr(), index + self.offset) }
140 }
141
142 pub fn slice(&self, range: impl RangeBounds<usize>) -> BitBufferView<'a> {
146 let (start, end) = resolve_range(range, self.len);
147 BitBufferView::new_with_offset(self.buffer, end - start, self.offset + start)
148 }
149
150 pub fn unaligned_chunks(&self) -> UnalignedBitChunk<'a> {
153 UnalignedBitChunk::new(self.buffer, self.offset, self.len)
154 }
155
156 pub fn chunks(&self) -> BitChunks<'a> {
158 BitChunks::new(self.buffer, self.offset, self.len)
159 }
160
161 pub fn true_count(&self) -> usize {
163 count_ones(self.buffer, self.offset, self.len)
164 }
165
166 pub fn false_count(&self) -> usize {
168 self.len - self.true_count()
169 }
170
171 pub fn select(&self, nth: usize) -> Option<usize> {
173 bit_select(self.buffer, self.offset, self.len, nth)
174 }
175
176 pub fn iter(&self) -> BitIterator<'a> {
178 BitIterator::new(self.buffer, self.offset, self.len)
179 }
180
181 pub fn set_indices(&self) -> BitIndexIterator<'a> {
183 BitIndexIterator::new(self.buffer, self.offset, self.len)
184 }
185
186 pub fn set_slices(&self) -> BitSliceIterator<'a> {
188 BitSliceIterator::new(self.buffer, self.offset, self.len)
189 }
190
191 pub fn to_bit_buffer(&self) -> BitBuffer {
193 let bytes = (self.offset + self.len).div_ceil(8);
194 BitBuffer::new_with_offset(
195 ByteBuffer::copy_from(&self.buffer[..bytes]),
196 self.len,
197 self.offset,
198 )
199 }
200}
201
202impl<'a> IntoIterator for BitBufferView<'a> {
203 type Item = bool;
204 type IntoIter = BitIterator<'a>;
205
206 fn into_iter(self) -> Self::IntoIter {
207 self.iter()
208 }
209}
210
211impl PartialEq for BitBufferView<'_> {
212 fn eq(&self, other: &Self) -> bool {
213 if self.len != other.len {
214 return false;
215 }
216
217 self.chunks()
218 .iter_padded()
219 .zip(other.chunks().iter_padded())
220 .all(|(a, b)| a == b)
221 }
222}
223
224impl Eq for BitBufferView<'_> {}
225
226#[derive(Debug)]
233pub struct BitBufferMutView<'a> {
234 buffer: &'a mut [u8],
235 offset: usize,
236 len: usize,
237}
238
239impl<'a> BitBufferMutView<'a> {
240 pub fn new(buffer: &'a mut [u8], len: usize) -> Self {
244 Self::new_with_offset(buffer, len, 0)
245 }
246
247 pub fn new_with_offset(buffer: &'a mut [u8], len: usize, offset: usize) -> Self {
251 assert!(
252 len.saturating_add(offset) <= buffer.len().saturating_mul(8),
253 "provided slice (len={}) not large enough to back BitBufferMutView with offset {offset} len {len}",
254 buffer.len()
255 );
256
257 let byte_offset = offset / 8;
258 let offset = offset % 8;
259 Self {
260 buffer: &mut buffer[byte_offset..],
261 offset,
262 len,
263 }
264 }
265
266 #[inline]
268 pub fn as_view(&self) -> BitBufferView<'_> {
269 BitBufferView {
270 buffer: self.buffer,
271 offset: self.offset,
272 len: self.len,
273 }
274 }
275
276 #[inline]
278 pub fn len(&self) -> usize {
279 self.len
280 }
281
282 #[inline]
284 pub fn is_empty(&self) -> bool {
285 self.len == 0
286 }
287
288 #[inline(always)]
290 pub fn offset(&self) -> usize {
291 self.offset
292 }
293
294 #[inline]
296 pub fn as_slice(&self) -> &[u8] {
297 self.buffer
298 }
299
300 #[inline]
302 pub fn as_mut_slice(&mut self) -> &mut [u8] {
303 self.buffer
304 }
305
306 #[inline]
310 pub fn value(&self, index: usize) -> bool {
311 assert!(index < self.len);
312 unsafe { self.value_unchecked(index) }
314 }
315
316 #[inline]
322 pub unsafe fn value_unchecked(&self, index: usize) -> bool {
323 unsafe { get_bit_unchecked(self.buffer.as_ptr(), index + self.offset) }
324 }
325
326 pub fn true_count(&self) -> usize {
328 self.as_view().true_count()
329 }
330
331 pub fn false_count(&self) -> usize {
333 self.as_view().false_count()
334 }
335
336 pub fn iter(&self) -> BitIterator<'_> {
338 self.as_view().iter()
339 }
340
341 pub fn set_to(&mut self, index: usize, value: bool) {
345 if value {
346 self.set(index);
347 } else {
348 self.unset(index);
349 }
350 }
351
352 pub unsafe fn set_to_unchecked(&mut self, index: usize, value: bool) {
358 if value {
359 unsafe { self.set_unchecked(index) }
361 } else {
362 unsafe { self.unset_unchecked(index) }
364 }
365 }
366
367 pub fn set(&mut self, index: usize) {
371 assert!(index < self.len, "index {index} exceeds len {}", self.len);
372 unsafe { self.set_unchecked(index) };
374 }
375
376 pub fn unset(&mut self, index: usize) {
380 assert!(index < self.len, "index {index} exceeds len {}", self.len);
381 unsafe { self.unset_unchecked(index) };
383 }
384
385 #[inline]
391 pub unsafe fn set_unchecked(&mut self, index: usize) {
392 unsafe { set_bit_unchecked(self.buffer.as_mut_ptr(), self.offset + index) }
394 }
395
396 #[inline]
402 pub unsafe fn unset_unchecked(&mut self, index: usize) {
403 unsafe { unset_bit_unchecked(self.buffer.as_mut_ptr(), self.offset + index) }
405 }
406
407 #[inline(always)]
411 pub fn fill_range(&mut self, start: usize, end: usize, value: bool) {
412 assert!(end <= self.len, "end {end} exceeds len {}", self.len);
413 assert!(start <= end, "start {start} exceeds end {end}");
414 unsafe { self.fill_range_unchecked(start, end, value) }
416 }
417
418 #[inline(always)]
424 pub unsafe fn fill_range_unchecked(&mut self, start: usize, end: usize, value: bool) {
425 fill_bits(self.buffer, self.offset + start, self.offset + end, value);
426 }
427
428 pub fn to_bit_buffer(&self) -> BitBuffer {
430 self.as_view().to_bit_buffer()
431 }
432}
433
434impl BitBuffer {
435 #[inline]
437 pub fn as_view(&self) -> BitBufferView<'_> {
438 BitBufferView {
439 buffer: self.inner().as_slice(),
440 offset: self.offset(),
441 len: self.len(),
442 }
443 }
444}
445
446impl BitBufferMut {
447 #[inline]
449 pub fn as_view(&self) -> BitBufferView<'_> {
450 BitBufferView {
451 buffer: self.as_slice(),
452 offset: self.offset(),
453 len: self.len(),
454 }
455 }
456
457 #[inline]
459 pub fn as_mut_view(&mut self) -> BitBufferMutView<'_> {
460 let offset = self.offset();
461 let len = self.len();
462 BitBufferMutView {
463 buffer: self.as_mut_slice(),
464 offset,
465 len,
466 }
467 }
468}
469
470#[cfg(test)]
471mod tests {
472 use crate::BitBuffer;
473 use crate::BitBufferMut;
474 use crate::bitbuffer;
475
476 #[test]
477 fn view_reads_match_buffer() {
478 let buffer = bitbuffer![true, false, true, true, false, true, false, false];
479 let view = buffer.as_view();
480
481 assert_eq!(view.len(), buffer.len());
482 assert_eq!(view.true_count(), buffer.true_count());
483 assert_eq!(view.false_count(), buffer.false_count());
484 for i in 0..buffer.len() {
485 assert_eq!(view.value(i), buffer.value(i));
486 }
487 assert_eq!(
488 view.iter().collect::<Vec<_>>(),
489 buffer.iter().collect::<Vec<_>>()
490 );
491 }
492
493 #[test]
494 fn view_slice_preserves_offset() {
495 let buffer = BitBuffer::new_set(20);
496 let sliced = buffer.slice(5..17);
497 let view = buffer.as_view().slice(5..17);
498
499 assert_eq!(view.len(), sliced.len());
500 assert_eq!(view.true_count(), sliced.true_count());
501 assert_eq!(view.to_bit_buffer(), sliced);
502 }
503
504 #[test]
505 fn view_offset_buffer() {
506 let buffer = BitBuffer::new_set(64).slice(3..40);
507 let view = buffer.as_view();
508 assert_eq!(view.offset(), buffer.offset());
509 assert_eq!(view.len(), buffer.len());
510 assert_eq!(view.to_bit_buffer(), buffer);
511 }
512
513 #[test]
514 fn mut_view_set_unset() {
515 let mut buffer = BitBufferMut::new_unset(16);
516 {
517 let mut view = buffer.as_mut_view();
518 view.set(0);
519 view.set(15);
520 view.set_to(7, true);
521 view.fill_range(2, 5, true);
522 assert!(view.value(0));
523 assert_eq!(view.true_count(), 6);
524 view.unset(0);
525 }
526 let frozen = buffer.freeze();
527 assert!(!frozen.value(0));
528 assert!(frozen.value(2));
529 assert!(frozen.value(4));
530 assert!(frozen.value(7));
531 assert!(frozen.value(15));
532 assert_eq!(frozen.true_count(), 5);
533 }
534
535 #[test]
536 fn mut_view_with_offset() {
537 let mut buffer = BitBufferMut::from_buffer(crate::buffer_mut![0u8; 4], 3, 20);
538 {
539 let mut view = buffer.as_mut_view();
540 assert_eq!(view.offset(), 3);
541 view.fill_range(0, 20, true);
542 }
543 let frozen = buffer.freeze();
544 assert_eq!(frozen.true_count(), 20);
545 }
546}