-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbits.rs
112 lines (100 loc) · 3.16 KB
/
bits.rs
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use rand::distributions::{Distribution, Standard};
use rand::Rng;
use serde::{Deserialize, Serialize};
use std::fmt;
pub trait BitArray
where
Self: Sized,
{
fn set_bit_in_place(&mut self, i: usize, s: bool);
fn set_bit(mut self, i: usize, s: bool) -> Self {
self.set_bit_in_place(i, s);
self
}
fn get_bit(&self, i: usize) -> bool;
}
macro_rules! for_uints {
($b_type:ident, $u_type:ty, $len:expr, $format_string:expr) => {
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Serialize, Deserialize)]
pub struct $b_type(pub $u_type);
impl $b_type {
pub const ZEROS: $b_type = $b_type(0);
#[inline(always)]
pub fn count_ones(self) -> u32 {
self.0.count_ones()
}
#[inline(always)]
pub fn get_bit(self, index: usize) -> bool {
//dbg!(index);
((self.0 >> (($len - 1) - index)) & 1) == 1
}
#[inline(always)]
pub fn get_bit_u8(self, index: usize) -> u8 {
((self.0 >> (($len - 1) - index)) & 1) as u8
}
#[inline(always)]
pub fn set_bit_in_place(&mut self, index: usize, value: bool) {
self.0 &= !(1 << (($len - 1) - index));
self.0 |= ((value as $u_type) << (($len - 1) - index));
}
#[inline(always)]
pub fn set_bit(mut self, index: usize, value: bool) -> Self {
self.0 &= !(1 << (($len - 1) - index));
self.0 |= ((value as $u_type) << (($len - 1) - index));
self
}
}
impl<const L: usize> BitArray for [$b_type; L] {
fn set_bit_in_place(&mut self, i: usize, s: bool) {
self[i / $len].set_bit_in_place(i % $len, s);
}
fn get_bit(&self, i: usize) -> bool {
self[i / $len].get_bit(i % $len)
}
}
impl Default for $b_type {
fn default() -> Self {
$b_type(0)
}
}
impl fmt::Debug for $b_type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, $format_string, self.0)
}
}
impl fmt::Display for $b_type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, $format_string, self.0)
}
}
impl PartialEq for $b_type {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl Eq for $b_type {}
impl Distribution<$b_type> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $b_type {
$b_type(rng.gen())
}
}
};
}
for_uints!(b32, u32, 32, "{:032b}");
for_uints!(b64, u64, 64, "{:064b}");
pub trait GetBit {
fn bit(self, i: usize) -> bool;
}
impl GetBit for usize {
#[inline(always)]
fn bit(self, i: usize) -> bool {
((self >> i) & 1) == 1
}
}
impl GetBit for u8 {
#[inline(always)]
fn bit(self, i: usize) -> bool {
((self >> i) & 1) == 1
}
}