grit_bitvec/
proto_proxy.rs1use crate::{
2 BitUtil,
3 Ordering
4};
5
6#[allow(non_snake_case)]
7#[derive(Debug, Clone, Copy)]
8pub struct BitProto {
9 pub(crate) MASK: usize,
10 pub(crate) BITS: usize,
11 pub(crate) MAX_CAPACITY: usize
12}
13
14impl BitProto {
15 pub(crate) const MAX_TRUE_CAP: usize = (usize::MAX / usize::BITS as usize);
16 pub(crate) const MAX_TRUE_BITS: usize = Self::MAX_TRUE_CAP * usize::BITS as usize;
17
18 #[inline(always)]
19 pub const fn create(bit_width: usize) -> Self {
20 if bit_width == 0 {
21 panic!("bit_width cannot be 0 (use a zero-typed Vec instead)");
22 }
23 if bit_width > usize::BITS as usize {
24 panic!("bit_width cannot be greater than usize::BITS");
25 }
26 let mask = if bit_width == usize::BITS as usize {
27 usize::MAX
28 } else {
29 (1 << bit_width) - 1
30 };
31 Self {
32 MASK: mask,
33 BITS: bit_width,
34 MAX_CAPACITY: Self::MAX_TRUE_BITS / bit_width,
35 }
36 }
37
38 #[inline(always)]
39 pub const fn create_from_state_count(posible_states: usize) -> Self {
40 if posible_states == 0 {
41 panic!("bit_width cannot be 0 (use a zero-typed Vec instead)");
42 }
43 let mut current_max_states: usize = 1;
44 let mut current_bits: usize = 0;
45 loop {
46 current_max_states <<= 1;
47 current_bits += 1;
48 if current_max_states >= posible_states || current_bits == usize::BITS as usize {
49 break;
50 }
51 }
52 Self::create(current_bits)
53 }
54
55 #[inline(always)]
56 pub const fn idx_proxy(proto: BitProto, bitwise_idx: usize) -> IdxProxy {
57 let total_bits = bitwise_idx * proto.BITS;
58 let (real_idx, first_offset) = match BitUtil::USIZE_BITS {
59 64 => (total_bits >> 6, total_bits & 0b_00111111),
60 32 => (total_bits >> 5, total_bits & 0b_00011111),
61 16 => (total_bits >> 4, total_bits & 0b_00001111),
62 _ => (total_bits / BitUtil::USIZE_BITS, total_bits % BitUtil::USIZE_BITS)
63 };
64 let second_offset = BitUtil::USIZE_BITS - first_offset;
65 let first_mask = proto.MASK << first_offset;
66 let second_mask = BitUtil::right_shift_discard_if_ubits(proto.MASK, second_offset);
67 IdxProxy {
68 bitwise_idx,
69 real_idx,
70 first_offset,
71 first_mask,
72 second_offset,
73 second_mask
74 }
75 }
76
77 #[inline(always)]
78 pub(crate) const fn calc_block_count_from_bitwise_count(proto: BitProto, bitwise_count: usize) -> usize {
79 let total_bits = bitwise_count * proto.BITS;
80 let (real_count, bit_offset) = match BitUtil::USIZE_BITS {
81 64 => (total_bits >> 6, total_bits & 0b_00111111),
82 32 => (total_bits >> 5, total_bits & 0b_00011111),
83 16 => (total_bits >> 4, total_bits & 0b_00001111),
84 _ => (total_bits / BitUtil::USIZE_BITS, total_bits % BitUtil::USIZE_BITS)
85 };
86 real_count + BitUtil::one_if_val_isnt_zero(bit_offset)
87 }
88
89 #[inline(always)]
90 pub(crate) const fn calc_bitwise_count_from_block_count(proto: BitProto, block_count: usize) -> usize {
91 BitUtil::calc_total_bits_in_num_usize(block_count) / proto.BITS
92 }
93
94 #[inline(always)]
95 pub(crate) fn check_value(proto: BitProto, val: usize) -> Result<(), String> {
96 match val > proto.MASK {
97 true => Err(format!("value cannot be represented in {} bits:\nmax bits = {:064b}\nval bits = {:064b}", proto.BITS, proto.MASK, val)),
98 false => Ok(())
99 }
100 }
101}
102
103#[derive(Clone, Copy, Debug)]
104pub struct IdxProxy {
105 pub(crate) bitwise_idx: usize,
106 pub(crate) real_idx: usize,
107 pub(crate) first_offset: usize,
108 pub(crate) first_mask: usize,
109 pub(crate) second_offset: usize,
110 pub(crate) second_mask: usize
111}
112
113impl IdxProxy {
114 #[inline(always)]
115 pub fn idx(&self) -> usize {
116 self.bitwise_idx
117 }
118}
119
120impl Ord for IdxProxy {
121 #[inline(always)]
122 fn cmp(&self, other: &Self) -> Ordering {
123 self.bitwise_idx.cmp(&other.bitwise_idx)
124 }
125}
126
127impl PartialOrd<Self> for IdxProxy {
128 #[inline(always)]
129 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
130 Some(self.cmp(other))
131 }
132}
133
134impl PartialEq<Self> for IdxProxy {
135 #[inline(always)]
136 fn eq(&self, other: &Self) -> bool {
137 self.bitwise_idx == other.bitwise_idx
138 }
139}
140impl Eq for IdxProxy {}