1use crate::signed_bits::SignedBits;
2use derive_more::{
3 Binary, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Display, LowerHex,
4 UpperHex,
5};
6
7#[derive(
26 Clone,
27 Debug,
28 Copy,
29 PartialEq,
30 Eq,
31 PartialOrd,
32 Ord,
33 Hash,
34 BitAnd,
35 BitAndAssign,
36 BitOr,
37 BitOrAssign,
38 BitXor,
39 BitXorAssign,
40 Display,
41 LowerHex,
42 UpperHex,
43 Binary,
44)]
45#[repr(transparent)]
46pub struct Bits<const N: usize>(pub(crate) u128);
47
48pub const fn bits<const N: usize>(value: u128) -> Bits<N> {
62 assert!(N <= 128);
63 assert!(value <= Bits::<N>::mask().0);
64 Bits(value)
65}
66
67impl<const N: usize> Bits<N> {
68 pub const MASK: Self = Self::mask();
70 pub const fn mask() -> Self {
77 if N < 128 {
80 Self((1 << N) - 1)
81 } else {
82 Self(u128::MAX)
83 }
84 }
85 pub fn set_bit(&mut self, bit: usize, value: bool) {
97 assert!(bit < N);
98 if value {
99 self.0 |= 1 << bit;
100 } else {
101 self.0 &= !(1 << bit);
102 }
103 }
104 pub fn get_bit(&self, bit: usize) -> bool {
115 assert!(bit < N);
116 (self.0 & (1 << bit)) != 0
117 }
118 pub fn any(self) -> bool {
127 (self.0 & Self::mask().0) != 0
128 }
129 pub fn all(self) -> bool {
138 (self.0 & Self::mask().0) == Self::mask().0
139 }
140 pub fn xor(self) -> bool {
142 let mut x = self.0 & Self::mask().0;
143 x ^= x >> 64;
144 x ^= x >> 32;
145 x ^= x >> 16;
146 x ^= x >> 8;
147 x ^= x >> 4;
148 x ^= x >> 2;
149 x ^= x >> 1;
150 x & 1 == 1
151 }
152 pub fn slice<const M: usize>(&self, start: usize) -> Bits<M> {
154 Bits((self.0 >> start) & Bits::<M>::mask().0)
155 }
156 pub fn as_signed(self) -> SignedBits<N> {
158 if self.get_bit(N - 1) {
160 SignedBits((self.0 | !(Self::mask().0)) as i128)
161 } else {
162 SignedBits(self.0 as i128)
163 }
164 }
165}
166
167impl<const N: usize> Default for Bits<N> {
169 fn default() -> Self {
170 Self(0)
171 }
172}
173
174impl<const N: usize> From<u128> for Bits<N> {
178 fn from(value: u128) -> Self {
179 assert!(N <= 128);
180 assert!(value <= Self::mask().0);
181 Self(value)
182 }
183}
184
185impl<const N: usize> PartialEq<u128> for Bits<N> {
186 fn eq(&self, other: &u128) -> bool {
187 self == &Self::from(*other)
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194
195 #[test]
196 fn test_mask() {
197 let bits = Bits::<128>::mask();
198 assert_eq!(bits.0, u128::MAX);
199 let bits = Bits::<32>::mask();
200 assert_eq!(bits.0, 0xFFFF_FFFF_u128);
201 }
202
203 #[test]
204 fn test_xor() {
205 let bits = Bits::<128>::mask();
206 assert!(!bits.xor());
207 let bits = Bits::<32>::mask();
208 assert!(!bits.xor());
209 let bits = Bits::<1>::mask();
210 assert!(bits.xor());
211 let bits: Bits<5> = 0b11010.into();
212 assert!(bits.xor());
213 }
214
215 #[test]
216 fn test_all() {
217 let bits = Bits::<128>::mask();
218 assert!(bits.all());
219 let bits = Bits::<32>::mask();
220 assert!(bits.all());
221 let bits = Bits::<1>::mask();
222 assert!(bits.all());
223 let bits: Bits<5> = 0b11111.into();
224 assert!(bits.all());
225 let bits: Bits<5> = 0b11110.into();
226 assert!(!bits.all());
227 }
228
229 #[test]
230 fn test_any() {
231 let bits = Bits::<128>::mask();
232 assert!(bits.any());
233 let bits = Bits::<32>::mask();
234 assert!(bits.any());
235 let bits = Bits::<1>::mask();
236 assert!(bits.any());
237 let bits: Bits<5> = 0b11111.into();
238 assert!(bits.any());
239 let bits: Bits<5> = 0b00000.into();
240 assert!(!bits.any());
241 }
242
243 #[test]
244 fn test_set_bit() {
245 let mut bits = Bits::<128>::mask();
246 bits.set_bit(0, false);
247 assert_eq!(bits.0, u128::MAX - 1);
248 bits.set_bit(0, true);
249 assert_eq!(bits.0, u128::MAX);
250 bits.set_bit(127, false);
251 assert_eq!(bits.0, u128::MAX - (1 << 127));
252 bits.set_bit(127, true);
253 assert_eq!(bits.0, u128::MAX);
254 bits.set_bit(64, false);
255 assert_eq!(bits.0, u128::MAX - (1 << 64));
256 bits.set_bit(64, true);
257 assert_eq!(bits.0, u128::MAX);
258 bits.set_bit(32, false);
259 assert_eq!(bits.0, u128::MAX - (1 << 32));
260 bits.set_bit(32, true);
261 assert_eq!(bits.0, u128::MAX);
262 bits.set_bit(16, false);
263 assert_eq!(bits.0, u128::MAX - (1 << 16));
264 bits.set_bit(16, true);
265 assert_eq!(bits.0, u128::MAX);
266 bits.set_bit(8, false);
267 assert_eq!(bits.0, u128::MAX - (1 << 8));
268 bits.set_bit(8, true);
269 assert_eq!(bits.0, u128::MAX);
270 bits.set_bit(4, false);
271 assert_eq!(bits.0, u128::MAX - (1 << 4));
272 bits.set_bit(4, true);
273 assert_eq!(bits.0, u128::MAX);
274 bits.set_bit(2, false);
275 assert_eq!(bits.0, u128::MAX - (1 << 2));
276 bits.set_bit(2, true);
277 assert_eq!(bits.0, u128::MAX);
278 bits.set_bit(1, false);
279 assert_eq!(bits.0, u128::MAX - (1 << 1));
280 bits.set_bit(1, true);
281 assert_eq!(bits.0, u128::MAX);
282 }
283
284 #[test]
285 fn test_get_bit() {
286 let bits = Bits::<128>::mask();
287 assert!(bits.get_bit(0));
288 assert!(bits.get_bit(127));
289 assert!(bits.get_bit(64));
290 assert!(bits.get_bit(32));
291 assert!(bits.get_bit(16));
292 assert!(bits.get_bit(8));
293 assert!(bits.get_bit(4));
294 assert!(bits.get_bit(2));
295 assert!(bits.get_bit(1));
296 let bits = Bits::<32>::mask();
297 assert!(bits.get_bit(0));
298 assert!(bits.get_bit(31));
299 assert!(bits.get_bit(16));
300 assert!(bits.get_bit(8));
301 assert!(bits.get_bit(4));
302 assert!(bits.get_bit(2));
303 assert!(bits.get_bit(1));
304 let bits = Bits::<1>::mask();
305 assert!(bits.get_bit(0));
306 let bits: Bits<5> = 0b11010.into();
307 assert!(bits.get_bit(4));
308 assert!(bits.get_bit(3));
309 assert!(!bits.get_bit(2));
310 assert!(bits.get_bit(1));
311 assert!(!bits.get_bit(0));
312 }
313
314 #[test]
315 fn test_binary_format() {
316 let bits: Bits<8> = 0b1101_1010.into();
317 assert_eq!(format!("{:b}", bits), "11011010");
318 }
319
320 #[test]
321 fn test_hex_format() {
322 let bits: Bits<8> = 0b1101_1010.into();
323 assert_eq!(format!("{:x}", bits), "da");
324 assert_eq!(format!("{:X}", bits), "DA");
325 }
326
327 #[test]
328 fn test_slice_function() {
329 let bits: Bits<8> = 0b1101_1010.into();
330 let result = bits.slice::<4>(0);
331 assert_eq!(result.0, 0b1010);
332 let result = bits.slice::<4>(4);
333 assert_eq!(result.0, 0b1101);
334 let result = bits.slice::<2>(6);
335 assert_eq!(result.0, 0b11);
336 }
337
338 #[test]
339 fn test_round_trip_unsigned_signed() {
340 let bits: Bits<8> = 0b1101_1010.into();
341 let signed = bits.as_signed();
342 println!("{}", signed);
343 assert!(signed.is_negative());
344 let unsigned = signed.as_unsigned();
345 assert_eq!(bits.0, unsigned.0);
346 let signed = unsigned.as_signed();
347 assert!(signed.is_negative());
348 }
349}