1use crate::result::BitError;
2use alloc::fmt::Debug;
3use core::{convert::{TryFrom, TryInto}, hash::{Hash, Hasher}, mem, ops::*};
4
5macro_rules! bit_count_one {
6 ( $bit:expr) => {
7 if $bit.count_ones() != 1 {
8 return Err(BitError::CountNotEqualToOne);
9 }
10 };
11}
12
13macro_rules! bit_found {
14 ( $self:expr, $bit:expr) => {
15 bit_count_one!($bit);
16 if $self & $bit == 0 {
17 return Err(BitError::NotFound);
18 }
19 };
20}
21
22macro_rules! bit_not_found {
23 ( $self:expr, $bit:expr) => {
24 bit_count_one!($bit);
25 if $self & $bit == 1 {
26 return Err(BitError::Found);
27 }
28 };
29}
30
31macro_rules! bit_in_range {
32 ( $type:ty, $index:expr) => {
33 if $index >= <$type>::max_ones() {
34 return Err(BitError::Range);
35 }
36 };
37}
38
39pub trait AsUsize {
41 #[must_use]
43 fn as_usize(&self) -> usize;
44}
45impl AsUsize for u8 { fn as_usize(&self) -> usize {*self as usize} }
46impl AsUsize for u16 { fn as_usize(&self) -> usize {*self as usize} }
47impl AsUsize for u32 { fn as_usize(&self) -> usize {*self as usize} }
48impl AsUsize for u64 { fn as_usize(&self) -> usize {*self as usize} }
49impl AsUsize for u128 { fn as_usize(&self) -> usize {*self as usize} }
50impl AsUsize for usize { fn as_usize(&self) -> usize {*self} }
51
52pub trait BitContains {
54 fn bit_contains(&self, bit: Self) -> Result<bool, BitError>;
58}
59impl BitContains for u8 { fn bit_contains(&self, bit: Self) -> Result<bool, BitError> {bit_count_one!(bit); Ok((self & bit) != 0)} }
60impl BitContains for u16 { fn bit_contains(&self, bit: Self) -> Result<bool, BitError> {bit_count_one!(bit); Ok((self & bit) != 0)} }
61impl BitContains for u32 { fn bit_contains(&self, bit: Self) -> Result<bool, BitError> {bit_count_one!(bit); Ok((self & bit) != 0)} }
62impl BitContains for u64 { fn bit_contains(&self, bit: Self) -> Result<bool, BitError> {bit_count_one!(bit); Ok((self & bit) != 0)} }
63impl BitContains for u128 { fn bit_contains(&self, bit: Self) -> Result<bool, BitError> {bit_count_one!(bit); Ok((self & bit) != 0)} }
64impl BitContains for usize { fn bit_contains(&self, bit: Self) -> Result<bool, BitError> {bit_count_one!(bit); Ok((self & bit) != 0)} }
65
66pub trait BitIndex {
68 fn bit_index(&self, bit: Self) -> Result<usize, BitError>;
72}
73impl BitIndex for u8 { fn bit_index(&self, bit: Self) -> Result<usize, BitError> {bit_found!(self, bit); Ok((self & (bit - 1)).count_ones() as usize)} }
74impl BitIndex for u16 { fn bit_index(&self, bit: Self) -> Result<usize, BitError> {bit_found!(self, bit); Ok((self & (bit - 1)).count_ones() as usize)} }
75impl BitIndex for u32 { fn bit_index(&self, bit: Self) -> Result<usize, BitError> {bit_found!(self, bit); Ok((self & (bit - 1)).count_ones() as usize)} }
76impl BitIndex for u64 { fn bit_index(&self, bit: Self) -> Result<usize, BitError> {bit_found!(self, bit); Ok((self & (bit - 1)).count_ones() as usize)} }
77impl BitIndex for u128 { fn bit_index(&self, bit: Self) -> Result<usize, BitError> {bit_found!(self, bit); Ok((self & (bit - 1)).count_ones() as usize)} }
78impl BitIndex for usize { fn bit_index(&self, bit: Self) -> Result<usize, BitError> {bit_found!(self, bit); Ok((self & (bit - 1)).count_ones() as usize)} }
79
80pub trait BitInsert {
82 fn bit_insert(&self, bit: Self) -> Result<Self, BitError> where Self: Sized;
86}
87impl BitInsert for u8 { fn bit_insert(&self, bit: Self) -> Result<Self, BitError> {bit_not_found!(self, bit); Ok(self | bit)} }
88impl BitInsert for u16 { fn bit_insert(&self, bit: Self) -> Result<Self, BitError> {bit_not_found!(self, bit); Ok(self | bit)} }
89impl BitInsert for u32 { fn bit_insert(&self, bit: Self) -> Result<Self, BitError> {bit_not_found!(self, bit); Ok(self | bit)} }
90impl BitInsert for u64 { fn bit_insert(&self, bit: Self) -> Result<Self, BitError> {bit_not_found!(self, bit); Ok(self | bit)} }
91impl BitInsert for u128 { fn bit_insert(&self, bit: Self) -> Result<Self, BitError> {bit_not_found!(self, bit); Ok(self | bit)} }
92impl BitInsert for usize { fn bit_insert(&self, bit: Self) -> Result<Self, BitError> {bit_not_found!(self, bit); Ok(self | bit)} }
93
94pub trait BitRemove {
96 fn bit_remove(&self, bit: Self) -> Result<Self, BitError> where Self: Sized;
100}
101impl BitRemove for u8 { fn bit_remove(&self, bit: Self) -> Result<Self, BitError> {bit_found!(self, bit); Ok(self ^ bit)} }
102impl BitRemove for u16 { fn bit_remove(&self, bit: Self) -> Result<Self, BitError> {bit_found!(self, bit); Ok(self ^ bit)} }
103impl BitRemove for u32 { fn bit_remove(&self, bit: Self) -> Result<Self, BitError> {bit_found!(self, bit); Ok(self ^ bit)} }
104impl BitRemove for u64 { fn bit_remove(&self, bit: Self) -> Result<Self, BitError> {bit_found!(self, bit); Ok(self ^ bit)} }
105impl BitRemove for u128 { fn bit_remove(&self, bit: Self) -> Result<Self, BitError> {bit_found!(self, bit); Ok(self ^ bit)} }
106impl BitRemove for usize { fn bit_remove(&self, bit: Self) -> Result<Self, BitError> {bit_found!(self, bit); Ok(self ^ bit)} }
107
108pub trait CountOnes {
110 #[must_use]
114 fn count_ones_t(&self) -> usize;
115}
116impl CountOnes for u8 { fn count_ones_t(&self) -> usize {self.count_ones() as usize} }
117impl CountOnes for u16 { fn count_ones_t(&self) -> usize {self.count_ones() as usize} }
118impl CountOnes for u32 { fn count_ones_t(&self) -> usize {self.count_ones() as usize} }
119impl CountOnes for u64 { fn count_ones_t(&self) -> usize {self.count_ones() as usize} }
120impl CountOnes for u128 { fn count_ones_t(&self) -> usize {self.count_ones() as usize} }
121impl CountOnes for usize { fn count_ones_t(&self) -> usize {self.count_ones() as usize} }
122
123pub trait LogB {
125 #[must_use]
129 fn log_b() -> usize;
130}
131impl LogB for u8 { fn log_b() -> usize {3} }
132impl LogB for u16 { fn log_b() -> usize {4} }
133impl LogB for u32 { fn log_b() -> usize {5} }
134impl LogB for u64 { fn log_b() -> usize {6} }
135impl LogB for u128 { fn log_b() -> usize {7} }
136impl LogB for usize {
137 fn log_b() -> usize {
138 match mem::size_of::<usize>() {
139 1 => 3,
140 2 => 4,
141 4 => 5,
142 8 => 6,
143 16 => 7,
144 _ => panic!()
145 }
146 }
147}
148
149pub trait MaskLogB<T> {
151 #[must_use]
155 fn mask_log_b() -> T;
156}
157impl <T: From<u8>> MaskLogB<T> for u8 { fn mask_log_b() -> T {0b111.into()} }
158impl <T: From<u8>> MaskLogB<T> for u16 { fn mask_log_b() -> T {0b1111.into()} }
159impl <T: From<u16>> MaskLogB<T> for u32 { fn mask_log_b() -> T {0b11111.into()} }
160impl <T: From<u16>> MaskLogB<T> for u64 { fn mask_log_b() -> T {0b111111.into()} }
161impl <T: From<u16>> MaskLogB<T> for u128 { fn mask_log_b() -> T {0b1111111.into()} }
162impl <T: From<u16>> MaskLogB<T> for usize {
163 fn mask_log_b() -> T {
164 match mem::size_of::<usize>() {
165 1 => 0b111,
166 2 => 0b1111,
167 4 => 0b11111,
168 8 => 0b111111,
169 16 => 0b1111111,
170 _ => panic!()
171 }.into()
172 }
173}
174
175pub trait MaxOnes {
177 #[must_use]
181 fn max_ones() -> usize;
182}
183impl MaxOnes for u8 { fn max_ones() -> usize {8} }
184impl MaxOnes for u16 { fn max_ones() -> usize {16} }
185impl MaxOnes for u32 { fn max_ones() -> usize {32} }
186impl MaxOnes for u64 { fn max_ones() -> usize {64} }
187impl MaxOnes for u128 { fn max_ones() -> usize {128} }
188impl MaxOnes for usize { fn max_ones() -> usize {8 * mem::size_of::<usize>()} }
189
190pub trait NthBit {
192 fn nth_bit(n: usize) -> Result<Self, BitError> where Self: Sized;
196}
197impl NthBit for u8 { fn nth_bit(n: usize) -> Result<Self, BitError> {bit_in_range!(u8, n); Ok(1_u8 << n)} }
198impl NthBit for u16 { fn nth_bit(n: usize) -> Result<Self, BitError> {bit_in_range!(u16, n); Ok(1_u16 << n)} }
199impl NthBit for u32 { fn nth_bit(n: usize) -> Result<Self, BitError> {bit_in_range!(u32, n); Ok(1_u32 << n)} }
200impl NthBit for u64 { fn nth_bit(n: usize) -> Result<Self, BitError> {bit_in_range!(u64, n); Ok(1_u64 << n)} }
201impl NthBit for u128 { fn nth_bit(n: usize) -> Result<Self, BitError> {bit_in_range!(u128, n); Ok(1_u128 << n)} }
202impl NthBit for usize { fn nth_bit(n: usize) -> Result<Self, BitError> {bit_in_range!(usize, n); Ok(1_usize << n)} }
203
204pub trait Hashword: BitAnd + Clone + Debug + From<<Self as Shr<usize>>::Output> + MaxOnes + PartialEq + Shr<usize> + 'static {}
206impl <H: BitAnd + Clone + Debug + From<<Self as Shr<usize>>::Output> + MaxOnes + PartialEq + Shr<usize>> Hashword
207for H where H: BitAnd + Clone + Debug + From<<Self as Shr<usize>>::Output> + MaxOnes + PartialEq + Shr<usize> + 'static {}
208
209pub trait Flagword<H: Hashword>: AsUsize + BitContains + BitIndex + BitInsert + BitRemove + Clone + CountOnes + Debug + Default + TryFrom<<H as BitAnd>::Output> + LogB + MaskLogB<H> + MaxOnes + NthBit + PartialEq + 'static {}
211impl <H: Hashword, F: AsUsize + BitContains + BitIndex + BitInsert + BitRemove + Clone + CountOnes + Debug + Default + TryFrom<<H as BitAnd>::Output> + LogB + MaskLogB<H> + MaxOnes + NthBit + PartialEq> Flagword<H>
212for F where F: AsUsize + BitContains + BitIndex + BitInsert + BitRemove + Clone + CountOnes + Debug + Default + TryFrom<<H as BitAnd>::Output> + LogB + MaskLogB<H> + MaxOnes + NthBit + PartialEq + 'static {}
213
214pub trait Key: Clone + Debug + Eq + PartialEq + Hash + Send + Sync + 'static {}
216impl <T: Clone + Debug + Eq + PartialEq + Hash + Send + Sync + 'static> Key
217for T where T: Clone + Debug + Eq + PartialEq + Hash + Send + Sync + 'static {}
218
219pub trait Value: Clone + Debug + Send + Sync + 'static {}
221impl <T: Clone + Debug + Send + Sync + 'static> Value
222for T where T: Clone + Debug + Send + Sync + 'static {}
223
224pub trait HashLike<T> {}
226impl <T> HashLike<T> for T {}
227
228pub trait HasherBv<B, V>: Default + 'static {
230 #[must_use]
231 fn hash(&self, value: &V) -> B;
232}
233macro_rules! hasher_bv_impl {
234 ( $type:ty ) => {
235 impl <V: Default + Hash + 'static, H: Default + Hasher + 'static> HasherBv<$type, V> for H {
236 fn hash(&self, value: &V) -> $type {
237 let mut hasher = H::default();
238 value.hash(&mut hasher);
239 hasher.finish().try_into().unwrap()
240 }
241 }
242 };
243}
244hasher_bv_impl!(u8);
245hasher_bv_impl!(u16);
246hasher_bv_impl!(u32);
247hasher_bv_impl!(u64);