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);