1use std::ops::Shr;
2use std::ops::ShrAssign;
3
4use crate::bits::Bits;
5use crate::signed_bits::SignedBits;
6
7impl<const N: usize> Shr<u128> for Bits<N> {
8 type Output = Self;
9 fn shr(self, rhs: u128) -> Self::Output {
10 self >> Bits::<8>::from(rhs)
11 }
12}
13
14impl<const N: usize> Shr<Bits<N>> for u128 {
15 type Output = Bits<N>;
16 fn shr(self, rhs: Bits<N>) -> Self::Output {
17 assert!(N <= 8, "Shift amount must be less than 8 bits");
18 Bits::<N>::from(self) >> rhs
19 }
20}
21
22impl<const M: usize, const N: usize> Shr<Bits<M>> for Bits<N> {
23 type Output = Self;
24 fn shr(self, rhs: Bits<M>) -> Self::Output {
25 assert!(M <= 8, "Shift amount must be less than 8 bits");
26 Self(u128::wrapping_shr(self.0, rhs.0 as u32) & Self::mask().0)
27 }
28}
29
30impl<const M: usize, const N: usize> ShrAssign<Bits<M>> for Bits<N> {
31 fn shr_assign(&mut self, rhs: Bits<M>) {
32 *self = *self >> rhs;
33 }
34}
35
36impl<const N: usize> ShrAssign<u128> for Bits<N> {
37 fn shr_assign(&mut self, rhs: u128) {
38 *self = *self >> rhs;
39 }
40}
41
42impl<const M: usize, const N: usize> Shr<Bits<M>> for SignedBits<N> {
43 type Output = Self;
44 fn shr(self, rhs: Bits<M>) -> Self::Output {
45 assert!(M <= 8, "Shift amount must be less than 8 bits");
46 Self(i128::wrapping_shr(self.0, rhs.0 as u32))
47 }
48}
49
50impl<const N: usize> Shr<u128> for SignedBits<N> {
51 type Output = Self;
52 fn shr(self, rhs: u128) -> Self::Output {
53 self >> Bits::<8>::from(rhs)
54 }
55}
56
57impl<const M: usize, const N: usize> ShrAssign<Bits<M>> for SignedBits<N> {
58 fn shr_assign(&mut self, rhs: Bits<M>) {
59 *self = *self >> rhs;
60 }
61}
62
63impl<const N: usize> ShrAssign<u128> for SignedBits<N> {
64 fn shr_assign(&mut self, rhs: u128) {
65 *self = *self >> rhs;
66 }
67}
68
69#[cfg(test)]
70mod test {
71 use super::*;
72
73 #[test]
74 fn test_shr_bits() {
75 let bits: Bits<8> = 0b1101_1010.into();
76 let result = bits >> 4;
77 assert_eq!(result.0, 0b0000_1101_u128);
78 let bits: Bits<16> = 0b1101_1010_0000_0000.into();
79 let result = bits >> 8;
80 assert_eq!(result.0, 0b0000_0000_1101_1010_u128);
81 let shift: Bits<8> = 8.into();
82 let result = bits >> shift;
83 assert_eq!(result.0, 0b0000_0000_1101_1010_u128);
84 let bits: Bits<8> = 0b1101_1010.into();
85 let result = bits >> 8;
86 assert_eq!(result.0, 0);
87 }
88
89 #[test]
90 fn test_shr_signed_i8_sane() {
91 let i = -128_i8;
92 let j = i >> 1;
93 assert_eq!(j, -64_i8);
94 let j = i8::wrapping_shr(i, 1);
95 assert_eq!(j, -64_i8);
96 }
97
98 #[test]
99 fn test_shr_signed() {
100 for i in i8::MIN..i8::MAX {
101 for shift in 0..10_u32 {
102 let bits: SignedBits<8> = (i as i128).into();
103 let result = bits >> (shift as u128);
104 assert_eq!(
105 result.0,
106 i128::wrapping_shr(i as i128, shift),
107 "i = {:b}, shift = {}",
108 i,
109 shift
110 );
111 let shift_as_bits: Bits<8> = (shift as u128).into();
112 let result = bits >> shift_as_bits;
113 assert_eq!(result.0, i128::wrapping_shr(i as i128, shift));
114 }
115 }
116 }
117}