rhdl_bits/
shl.rs

1use std::ops::Shl;
2use std::ops::ShlAssign;
3
4use crate::bits::Bits;
5use crate::signed_bits::SignedBits;
6
7impl<const N: usize> Shl<u128> for Bits<N> {
8    type Output = Self;
9    fn shl(self, rhs: u128) -> Self::Output {
10        self << Bits::<8>::from(rhs)
11    }
12}
13
14impl<const N: usize> Shl<Bits<N>> for u128 {
15    type Output = Bits<N>;
16    fn shl(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> Shl<Bits<M>> for Bits<N> {
23    type Output = Self;
24    fn shl(self, rhs: Bits<M>) -> Self::Output {
25        assert!(M <= 8, "Shift amount must be less than 8 bits");
26        Self(u128::wrapping_shl(self.0, rhs.0 as u32) & Self::mask().0)
27    }
28}
29
30impl<const M: usize, const N: usize> ShlAssign<Bits<M>> for Bits<N> {
31    fn shl_assign(&mut self, rhs: Bits<M>) {
32        *self = *self << rhs;
33    }
34}
35
36impl<const N: usize> ShlAssign<u128> for Bits<N> {
37    fn shl_assign(&mut self, rhs: u128) {
38        *self = *self << rhs;
39    }
40}
41
42impl<const N: usize> Shl<u128> for SignedBits<N> {
43    type Output = Self;
44    fn shl(self, rhs: u128) -> Self::Output {
45        self << Bits::<8>::from(rhs)
46    }
47}
48
49impl<const N: usize> Shl<Bits<N>> for i128 {
50    type Output = SignedBits<N>;
51    fn shl(self, rhs: Bits<N>) -> Self::Output {
52        assert!(N <= 8, "Shift amount must be less than 8 bits");
53        SignedBits::<N>::from(self) << rhs
54    }
55}
56
57impl<const M: usize, const N: usize> Shl<Bits<M>> for SignedBits<N> {
58    type Output = Self;
59    fn shl(self, rhs: Bits<M>) -> Self::Output {
60        assert!(M <= 8, "Shift amount must be less than 8 bits");
61        (self.as_unsigned() << rhs).as_signed()
62    }
63}
64
65impl<const M: usize, const N: usize> ShlAssign<Bits<M>> for SignedBits<N> {
66    fn shl_assign(&mut self, rhs: Bits<M>) {
67        *self = *self << rhs;
68    }
69}
70
71impl<const N: usize> ShlAssign<u128> for SignedBits<N> {
72    fn shl_assign(&mut self, rhs: u128) {
73        *self = *self << rhs;
74    }
75}
76
77#[cfg(test)]
78mod test {
79    use super::*;
80
81    #[test]
82    fn test_shl_bits() {
83        let bits: Bits<8> = 0b1101_1010.into();
84        let result = bits << 4;
85        assert_eq!(result.0, 0b1010_0000_u128);
86        let bits: Bits<16> = 0b0000_0000_1101_1010.into();
87        let result = bits << 8;
88        assert_eq!(result.0, 0b1101_1010_0000_0000_u128);
89        let shift: Bits<8> = 8.into();
90        let result = bits << shift;
91        assert_eq!(result.0, 0b1101_1010_0000_0000_u128);
92    }
93
94    #[test]
95    fn test_shl_signed_bits() {
96        let bits: SignedBits<8> = (-38).into();
97        let result = bits << 1;
98        assert_eq!(result.0, -76_i128);
99        for shift in 0..10 {
100            let bits: SignedBits<8> = (-38).into();
101            let result = bits << shift;
102            assert_eq!(result.0, ((-38_i128 << shift) as i8).into());
103            let shift_as_bits: Bits<8> = shift.into();
104            let result = bits << shift_as_bits;
105            assert_eq!(result.0, ((-38_i128 << shift) as i8).into());
106        }
107    }
108
109    #[test]
110    fn test_shl_assign_signed_bits() {
111        let mut bits: SignedBits<8> = (-38).into();
112        bits <<= 1;
113        assert_eq!(bits.0, -76_i128);
114        for shift in 0..10 {
115            let mut bits: SignedBits<8> = (-38).into();
116            bits <<= shift;
117            assert_eq!(bits.0, ((-38_i128 << shift) as i8).into());
118            let shift_as_bits: Bits<8> = shift.into();
119            let mut bits: SignedBits<8> = (-38).into();
120            bits <<= shift_as_bits;
121            assert_eq!(bits.0, ((-38_i128 << shift) as i8).into());
122        }
123    }
124}