ext_ops/
saturating_ops.rs1pub trait SaturatingAdd<Rhs = Self> {
12 type Output;
13 fn saturating_add(self, rhs: Rhs) -> Self::Output;
14}
15
16pub trait SaturatingMul<Rhs = Self> {
19 type Output;
20 fn saturating_mul(self, rhs: Rhs) -> Self::Output;
21}
22
23pub trait SaturatingNeg {
26 type Output;
27 fn saturating_neg(self) -> Self::Output;
28}
29
30pub trait SaturatingSub<Rhs = Self> {
33 type Output;
34 fn saturating_sub(self, rhs: Rhs) -> Self::Output;
35}
36
37macro_rules! impl_unary_ref_ops {
41 { $(impl $trait:ident::$fn:ident for $ty:ident;)* } => { $(
42 impl<'a> $trait for &'a $ty {
43 type Output = $ty;
44
45 fn $fn(self) -> $ty {
46 $trait::$fn(*self)
47 }
48 }
49 )* };
50}
51
52macro_rules! impl_binary_ops {
54 { $(impl $trait:ident::$fn:ident for $ty:ident;)* } => { $(
55 impl $trait for $ty {
56 type Output = $ty;
57
58 fn $fn(self, rhs: $ty) -> $ty {
59 self.$fn(rhs)
60 }
61 }
62
63 impl<'a> $trait<$ty> for &'a $ty {
64 type Output = $ty;
65
66 fn $fn(self, rhs: $ty) -> $ty {
67 $trait::$fn(*self, rhs)
68 }
69 }
70
71 impl<'r> $trait<&'r $ty> for $ty {
72 type Output = $ty;
73
74 fn $fn(self, rhs: &'r $ty) -> $ty {
75 $trait::$fn(self, *rhs)
76 }
77 }
78
79 impl<'a, 'r> $trait<&'r $ty> for &'a $ty {
80 type Output = $ty;
81
82 fn $fn(self, rhs: &'r $ty) -> $ty {
83 $trait::$fn(*self, *rhs)
84 }
85 }
86 )* };
87}
88
89macro_rules! impl_int_ops {
91 ($($ty:ident),*) => { $(
92 impl SaturatingNeg for $ty {
93 type Output = $ty;
94
95 fn saturating_neg(self) -> $ty {
96 self.saturating_neg()
97 }
98 }
99
100 impl_unary_ref_ops! {
101 impl SaturatingNeg::saturating_neg for $ty;
102 }
103
104 impl_binary_ops! {
105 impl SaturatingAdd::saturating_add for $ty;
106 impl SaturatingMul::saturating_mul for $ty;
107 impl SaturatingSub::saturating_sub for $ty;
108 }
109 )* };
110}
111
112impl_int_ops!(i8, i16, i32, i64, i128, isize);
113
114macro_rules! impl_uint_ops {
116 ($($ty:ident),*) => { $(
117 impl_binary_ops! {
118 impl SaturatingAdd::saturating_add for $ty;
119 impl SaturatingMul::saturating_mul for $ty;
120 impl SaturatingSub::saturating_sub for $ty;
121 }
122 )* };
123}
124
125impl_uint_ops!(u8, u16, u32, u64, u128, usize);
126
127#[test]
130fn test_saturating_add() {
131 assert_eq!(SaturatingAdd::saturating_add(100i8, 26), 126);
132 assert_eq!(SaturatingAdd::saturating_add(100i8, 27), 127);
133 assert_eq!(SaturatingAdd::saturating_add(100i8, 28), 127);
134 assert_eq!(SaturatingAdd::saturating_add(-100i8, -27), -127);
135 assert_eq!(SaturatingAdd::saturating_add(-100i8, -28), -128);
136 assert_eq!(SaturatingAdd::saturating_add(-100i8, -29), -128);
137 assert_eq!(SaturatingAdd::saturating_add(200u8, 54), 254);
138 assert_eq!(SaturatingAdd::saturating_add(200u8, 55), 255);
139 assert_eq!(SaturatingAdd::saturating_add(200u8, 56), 255);
140}
141
142#[test]
143fn test_saturating_mul() {
144 assert_eq!(SaturatingMul::saturating_mul(50i8, 2), 100);
145 assert_eq!(SaturatingMul::saturating_mul(50i8, 3), 127);
146 assert_eq!(SaturatingMul::saturating_mul(50i8, -2), -100);
147 assert_eq!(SaturatingMul::saturating_mul(50i8, -3), -128);
148 assert_eq!(SaturatingMul::saturating_mul(-50i8, -2), 100);
149 assert_eq!(SaturatingMul::saturating_mul(-50i8, -3), 127);
150 assert_eq!(SaturatingMul::saturating_mul(50u8, 5), 250);
151 assert_eq!(SaturatingMul::saturating_mul(50u8, 6), 255);
152}
153
154#[test]
155fn test_saturating_neg() {
156 assert_eq!(SaturatingNeg::saturating_neg(127i8), -127);
157 assert_eq!(SaturatingNeg::saturating_neg(-127i8), 127);
158 assert_eq!(SaturatingNeg::saturating_neg(-128i8), 127);
159}
160
161#[test]
162fn test_saturating_sub() {
163 assert_eq!(SaturatingSub::saturating_sub(100i8, -26), 126);
164 assert_eq!(SaturatingSub::saturating_sub(100i8, -27), 127);
165 assert_eq!(SaturatingSub::saturating_sub(100i8, -28), 127);
166 assert_eq!(SaturatingSub::saturating_sub(-100i8, 27), -127);
167 assert_eq!(SaturatingSub::saturating_sub(-100i8, 28), -128);
168 assert_eq!(SaturatingSub::saturating_sub(-100i8, 29), -128);
169 assert_eq!(SaturatingSub::saturating_sub(100u8, 99), 1);
170 assert_eq!(SaturatingSub::saturating_sub(100u8, 100), 0);
171 assert_eq!(SaturatingSub::saturating_sub(100u8, 101), 0);
172}