1use core::mem;
4use core::ops::Index;
5use core::ops::Range;
6
7use super::{FALSE, TRUE};
8use crate::local_prelude::*;
9use crate::util::div_rem;
10
11pub struct BitSlice {
13 pub(crate) slice: [Block],
14}
15
16impl BitSlice {
17 #[inline]
19 pub fn new(slice: &[Block]) -> &Self {
20 unsafe { mem::transmute(slice) }
21 }
22
23 #[inline]
25 pub fn new_mut(slice: &mut [Block]) -> &mut Self {
26 unsafe { mem::transmute(slice) }
27 }
28
29 #[inline]
31 pub fn iter_bits(&self, len: usize) -> Iter {
32 Iter {
33 bit_slice: self,
34 range: 0..len,
35 }
36 }
37
38 pub fn iter_blocks(&self) -> impl Iterator<Item = &Block> {
40 self.slice.iter()
41 }
42
43 pub fn iter_blocks_mut(&mut self) -> impl Iterator<Item = &mut Block> {
45 self.slice.iter_mut()
46 }
47
48 #[inline]
50 pub fn get(&self, bit: usize) -> bool {
51 let (block, i) = div_rem(bit, BITS);
52 match self.slice.get(block) {
53 None => false,
54 Some(b) => (b & (1 << i)) != 0,
55 }
56 }
57
58 #[inline]
60 pub fn small_slice_aligned(&self, bit: usize, len: u8) -> u32 {
61 let (block, i) = div_rem(bit, BITS);
62 match self.slice.get(block) {
63 None => 0,
64 Some(&b) => {
65 let len_mask = (1 << len) - 1;
66 (b >> i) & len_mask
67 }
68 }
69 }
70}
71
72impl Index<usize> for BitSlice {
74 type Output = bool;
75
76 #[inline]
77 fn index(&self, bit: usize) -> &bool {
78 let (block, i) = div_rem(bit, BITS);
79 match self.slice.get(block) {
80 None => &FALSE,
81 Some(b) => {
82 if (b & (1 << i)) != 0 {
83 &TRUE
84 } else {
85 &FALSE
86 }
87 }
88 }
89 }
90}
91
92#[derive(Clone)]
94pub struct Iter<'a> {
95 bit_slice: &'a BitSlice,
96 range: Range<usize>,
97}
98
99impl<'a> Iterator for Iter<'a> {
100 type Item = bool;
101
102 #[inline]
103 fn next(&mut self) -> Option<bool> {
104 self.range.next().map(|i| self.bit_slice[i])
105 }
106
107 fn size_hint(&self) -> (usize, Option<usize>) {
108 self.range.size_hint()
109 }
110}