num.rsannotatednum.rssource159 lines · 3.3 KB · raw
1use std::ops::RangeInclusive;
2
3pub trait GetBit {
4    #[must_use]
5    fn bit(self, i: u8) -> bool;
6
7    #[must_use]
8    fn bits(self, range: RangeInclusive<u8>) -> Self;
9}
10
11macro_rules! impl_get_bit {
12    ($t:ty) => {
13        impl GetBit for $t {
14            #[inline]
15            fn bit(self, i: u8) -> bool {
16                debug_assert!(i < (<$t>::BITS as u8));
17                self & (1 << i) != 0
18            }
19
20            #[inline]
21            fn bits(self, range: RangeInclusive<u8>) -> Self {
22                let start = *range.start();
23                let end = *range.end();
24                debug_assert!(end < (<$t>::BITS as u8));
25
26                (self >> start) & ((1 << (end - start + 1)) - 1)
27            }
28        }
29    };
30}
31
32impl_get_bit!(u8);
33impl_get_bit!(u16);
34impl_get_bit!(u32);
35impl_get_bit!(u64);
36impl_get_bit!(usize);
37
38impl_get_bit!(i8);
39impl_get_bit!(i16);
40impl_get_bit!(i32);
41impl_get_bit!(i64);
42
43pub trait SignBit: Copy {
44    fn sign_bit(self) -> bool;
45}
46
47macro_rules! impl_sign_bit {
48    ($t:ty) => {
49        impl SignBit for $t {
50            #[inline]
51            fn sign_bit(self) -> bool {
52                self.bit((<$t>::BITS - 1) as u8)
53            }
54        }
55    };
56}
57
58impl_sign_bit!(u8);
59impl_sign_bit!(u16);
60impl_sign_bit!(u32);
61impl_sign_bit!(u64);
62
63impl_sign_bit!(i8);
64impl_sign_bit!(i16);
65impl_sign_bit!(i32);
66impl_sign_bit!(i64);
67
68pub trait U16Ext {
69    fn lsb(self) -> u8;
70
71    fn msb(self) -> u8;
72
73    fn set_lsb(&mut self, value: u8);
74
75    fn set_msb(&mut self, value: u8);
76
77    fn be_byte(self, i: u32) -> u8;
78}
79
80impl U16Ext for u16 {
81    #[inline(always)]
82    fn lsb(self) -> u8 {
83        self as u8
84    }
85
86    #[inline(always)]
87    fn msb(self) -> u8 {
88        (self >> 8) as u8
89    }
90
91    #[inline(always)]
92    fn set_lsb(&mut self, value: u8) {
93        *self = (*self & 0xFF00) | u16::from(value);
94    }
95
96    #[inline(always)]
97    fn set_msb(&mut self, value: u8) {
98        *self = (*self & 0x00FF) | (u16::from(value) << 8);
99    }
100
101    #[inline(always)]
102    fn be_byte(self, i: u32) -> u8 {
103        debug_assert!(i <= 1);
104        (self >> (8 * (i ^ 1))) as u8
105    }
106}
107
108pub trait U24Ext {
109    fn low_byte(self) -> u8;
110
111    fn mid_byte(self) -> u8;
112
113    fn high_byte(self) -> u8;
114
115    fn set_low_byte(&mut self, value: u8);
116
117    fn set_mid_byte(&mut self, value: u8);
118
119    fn set_high_byte(&mut self, value: u8);
120}
121
122macro_rules! impl_u24_ext {
123    ($t:ty) => {
124        impl U24Ext for $t {
125            #[inline(always)]
126            fn low_byte(self) -> u8 {
127                self as u8
128            }
129
130            #[inline(always)]
131            fn mid_byte(self) -> u8 {
132                (self >> 8) as u8
133            }
134
135            #[inline(always)]
136            fn high_byte(self) -> u8 {
137                (self >> 16) as u8
138            }
139
140            #[inline(always)]
141            fn set_low_byte(&mut self, value: u8) {
142                *self = (*self & 0xFFFF00) | <$t>::from(value);
143            }
144
145            #[inline(always)]
146            fn set_mid_byte(&mut self, value: u8) {
147                *self = (*self & 0xFF00FF) | (<$t>::from(value) << 8);
148            }
149
150            #[inline(always)]
151            fn set_high_byte(&mut self, value: u8) {
152                *self = (*self & 0x00FFFF) | (<$t>::from(value) << 16);
153            }
154        }
155    };
156}
157
158impl_u24_ext!(u32);
159impl_u24_ext!(i32);