Skip to main content

rbatis_codegen/
ops_shr.rs

1use crate::ops::{AsProxy, BitShr};
2use crate::ops_macros::{impl_numeric_binary_op, impl_same_type_shift_op, impl_value_binary_op};
3use rbs::Value;
4
5fn op_shr_value(left: Value, rhs: Value) -> Value {
6    match left {
7        Value::I32(s) => {
8            let rhs = rhs.i64();
9            if !(0..i32::BITS as i64).contains(&rhs) {
10                return Value::I32(0);
11            }
12            Value::I32(s >> rhs)
13        }
14        Value::I64(s) => {
15            let rhs = rhs.i64();
16            if !(0..i64::BITS as i64).contains(&rhs) {
17                return Value::I64(0);
18            }
19            Value::I64(s >> rhs)
20        }
21        Value::U32(s) => {
22            let rhs = rhs.u64();
23            if rhs >= u32::BITS as u64 {
24                return Value::U32(0);
25            }
26            Value::U32(s >> rhs)
27        }
28        Value::U64(s) => {
29            let rhs = rhs.u64();
30            if rhs >= u64::BITS as u64 {
31                return Value::U64(0);
32            }
33            Value::U64(s >> rhs)
34        }
35        Value::Ext(_, e) => op_shr_value(*e, rhs),
36        _ => Value::Null,
37    }
38}
39
40fn op_shr_u64(value: &Value, other: u64) -> u64 {
41    if other >= u64::BITS as u64 {
42        return 0;
43    }
44    value.u64() >> other
45}
46
47fn op_shr_i64(value: &Value, other: i64) -> i64 {
48    if !(0..i64::BITS as i64).contains(&other) {
49        return 0;
50    }
51    value.i64() >> other
52}
53
54fn op_shr_u64_value(value: &Value, other: u64) -> u64 {
55    let rhs = value.u64();
56    if rhs >= u64::BITS as u64 {
57        return 0;
58    }
59    other >> rhs
60}
61
62fn op_shr_i64_value(value: &Value, other: i64) -> i64 {
63    let rhs = value.i64();
64    if !(0..i64::BITS as i64).contains(&rhs) {
65        return 0;
66    }
67    other >> rhs
68}
69
70impl_value_binary_op!(BitShr, op_shr, op_shr_value);
71impl_numeric_binary_op!(
72    BitShr,
73    op_shr,
74    op_shr_u64,
75    op_shr_u64_value,
76    [u8, u16, u32, u64],
77    u64
78);
79impl_numeric_binary_op!(
80    BitShr,
81    op_shr,
82    op_shr_i64,
83    op_shr_i64_value,
84    [i8, i16, i32, i64, isize, usize],
85    i64
86);
87impl_same_type_shift_op!(
88    BitShr,
89    op_shr,
90    checked_shr,
91    [u8, u16, u32, u64, i8, i16, i32, i64, isize, usize]
92);
93
94#[cfg(test)]
95mod test {
96    use crate::ops::BitShr;
97    use rbs::Value;
98
99    #[test]
100    fn test_shr() {
101        assert_eq!(Value::I32(8).op_shr(2i64), 2i64);
102        assert_eq!((&Value::I32(8)).op_shr(&2i64), 2i64);
103        assert_eq!(Value::I32(8).op_shr(&&Value::I32(2)), Value::I32(2));
104        assert_eq!(8i64.op_shr(&Value::I32(2)), 2i64);
105    }
106
107    #[test]
108    fn test_shr_out_of_range() {
109        assert_eq!(Value::I32(8).op_shr(32i64), 0i64);
110        assert_eq!(Value::I32(8).op_shr(&&Value::I32(32)), Value::I32(0));
111    }
112}