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}