grit_bitvec/
proto_proxy.rs

1use 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 {}