blob: 856d579bad4876cbdc303d86a80249b27f94fa3d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
use contracts::requires;
use core::{fmt, mem::transmute};
/// A fixed-length vector of bits.
pub struct BitVec([usize]);
impl BitVec {
fn from_mut(words: &mut [usize]) -> &mut BitVec {
// SAFETY: The types have a newtype relationship.
unsafe { transmute(words) }
}
fn from_ref(words: &[usize]) -> &BitVec {
// SAFETY: The types have a newtype relationship.
unsafe { transmute(words) }
}
/// Retrieves the value of a bit from the BitVec.
#[requires(i < self.len())]
pub fn get(&self, i: usize) -> bool {
let word_index = i / usize::BITS as usize;
let subword_index = i % usize::BITS as usize;
let one_hot = 1 << subword_index;
(self.0[word_index] & one_hot) != 0
}
/// Returns whether the BitVec is empty.
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
/// Returns the number of bits in the BitVec.
pub fn len(&self) -> usize {
self.0.len() * usize::BITS as usize
}
/// Sets the value of a bit in the BitVec.
#[requires(i < self.len())]
pub fn set(&mut self, i: usize, value: bool) {
let word_index = i / usize::BITS as usize;
let subword_index = i % usize::BITS as usize;
let one_hot = 1 << subword_index;
if value {
self.0[word_index] |= one_hot;
} else {
self.0[word_index] &= !one_hot;
}
}
}
impl fmt::Debug for BitVec {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "BitVec(")?;
for word in &self.0 {
write!(fmt, "{word:064b}")?;
}
write!(fmt, ")")
}
}
|