1use core::ops::{Add, Div, Mul, Neg, Sub};
9
10c0nst::c0nst! {
11pub c0nst trait Saturating {
14 fn saturating_add(self, v: Self) -> Self;
17
18 fn saturating_sub(self, v: Self) -> Self;
21}
22}
23
24macro_rules! deprecated_saturating_impl {
25 ($trait_name:ident for $($t:ty)*) => {$(
26 c0nst::c0nst! {
27 c0nst impl $trait_name for $t {
28 #[inline]
29 fn saturating_add(self, v: Self) -> Self {
30 Self::saturating_add(self, v)
31 }
32
33 #[inline]
34 fn saturating_sub(self, v: Self) -> Self {
35 Self::saturating_sub(self, v)
36 }
37 }
38 }
39 )*}
40}
41
42deprecated_saturating_impl!(Saturating for isize i8 i16 i32 i64 i128);
43deprecated_saturating_impl!(Saturating for usize u8 u16 u32 u64 u128);
44
45macro_rules! saturating_impl {
46 ($trait_name:ident, $method:ident, $t:ty) => {
47 c0nst::c0nst! {
48 c0nst impl $trait_name for $t {
49 #[inline]
50 fn $method(self, v: Self) -> Self {
51 <$t>::$method(self, v)
52 }
53 }
54 }
55 };
56}
57
58c0nst::c0nst! {
59pub c0nst trait SaturatingAdd: Sized + [c0nst] Add<Self> {
61 fn saturating_add(self, v: Self) -> <Self as Add<Self>>::Output;
64}
65}
66
67saturating_impl!(SaturatingAdd, saturating_add, u8);
68saturating_impl!(SaturatingAdd, saturating_add, u16);
69saturating_impl!(SaturatingAdd, saturating_add, u32);
70saturating_impl!(SaturatingAdd, saturating_add, u64);
71saturating_impl!(SaturatingAdd, saturating_add, usize);
72saturating_impl!(SaturatingAdd, saturating_add, u128);
73
74saturating_impl!(SaturatingAdd, saturating_add, i8);
75saturating_impl!(SaturatingAdd, saturating_add, i16);
76saturating_impl!(SaturatingAdd, saturating_add, i32);
77saturating_impl!(SaturatingAdd, saturating_add, i64);
78saturating_impl!(SaturatingAdd, saturating_add, isize);
79saturating_impl!(SaturatingAdd, saturating_add, i128);
80
81c0nst::c0nst! {
82pub c0nst trait SaturatingSub: Sized + [c0nst] Sub<Self> {
84 fn saturating_sub(self, v: Self) -> <Self as Sub<Self>>::Output;
87}
88}
89
90saturating_impl!(SaturatingSub, saturating_sub, u8);
91saturating_impl!(SaturatingSub, saturating_sub, u16);
92saturating_impl!(SaturatingSub, saturating_sub, u32);
93saturating_impl!(SaturatingSub, saturating_sub, u64);
94saturating_impl!(SaturatingSub, saturating_sub, usize);
95saturating_impl!(SaturatingSub, saturating_sub, u128);
96
97saturating_impl!(SaturatingSub, saturating_sub, i8);
98saturating_impl!(SaturatingSub, saturating_sub, i16);
99saturating_impl!(SaturatingSub, saturating_sub, i32);
100saturating_impl!(SaturatingSub, saturating_sub, i64);
101saturating_impl!(SaturatingSub, saturating_sub, isize);
102saturating_impl!(SaturatingSub, saturating_sub, i128);
103
104c0nst::c0nst! {
105pub c0nst trait SaturatingMul: Sized + [c0nst] Mul<Self> {
107 fn saturating_mul(self, v: Self) -> <Self as Mul<Self>>::Output;
110}
111}
112
113saturating_impl!(SaturatingMul, saturating_mul, u8);
114saturating_impl!(SaturatingMul, saturating_mul, u16);
115saturating_impl!(SaturatingMul, saturating_mul, u32);
116saturating_impl!(SaturatingMul, saturating_mul, u64);
117saturating_impl!(SaturatingMul, saturating_mul, usize);
118saturating_impl!(SaturatingMul, saturating_mul, u128);
119
120saturating_impl!(SaturatingMul, saturating_mul, i8);
121saturating_impl!(SaturatingMul, saturating_mul, i16);
122saturating_impl!(SaturatingMul, saturating_mul, i32);
123saturating_impl!(SaturatingMul, saturating_mul, i64);
124saturating_impl!(SaturatingMul, saturating_mul, isize);
125saturating_impl!(SaturatingMul, saturating_mul, i128);
126
127c0nst::c0nst! {
128pub c0nst trait SaturatingDiv: Sized + [c0nst] Div<Self> {
130 fn saturating_div(self, v: Self) -> <Self as Div<Self>>::Output;
145}
146}
147
148saturating_impl!(SaturatingDiv, saturating_div, u8);
149saturating_impl!(SaturatingDiv, saturating_div, u16);
150saturating_impl!(SaturatingDiv, saturating_div, u32);
151saturating_impl!(SaturatingDiv, saturating_div, u64);
152saturating_impl!(SaturatingDiv, saturating_div, usize);
153saturating_impl!(SaturatingDiv, saturating_div, u128);
154
155saturating_impl!(SaturatingDiv, saturating_div, i8);
156saturating_impl!(SaturatingDiv, saturating_div, i16);
157saturating_impl!(SaturatingDiv, saturating_div, i32);
158saturating_impl!(SaturatingDiv, saturating_div, i64);
159saturating_impl!(SaturatingDiv, saturating_div, isize);
160saturating_impl!(SaturatingDiv, saturating_div, i128);
161
162macro_rules! saturating_unary_impl {
163 ($trait_name:ident, $method:ident, $t:ty) => {
164 c0nst::c0nst! {
165 c0nst impl $trait_name for $t {
166 #[inline]
167 fn $method(self) -> $t {
168 <$t>::$method(self)
169 }
170 }
171 }
172 };
173}
174
175c0nst::c0nst! {
176pub c0nst trait SaturatingNeg: Sized + [c0nst] Neg {
178 fn saturating_neg(self) -> <Self as Neg>::Output;
188}
189}
190
191saturating_unary_impl!(SaturatingNeg, saturating_neg, i8);
192saturating_unary_impl!(SaturatingNeg, saturating_neg, i16);
193saturating_unary_impl!(SaturatingNeg, saturating_neg, i32);
194saturating_unary_impl!(SaturatingNeg, saturating_neg, i64);
195saturating_unary_impl!(SaturatingNeg, saturating_neg, isize);
196saturating_unary_impl!(SaturatingNeg, saturating_neg, i128);
197
198c0nst::c0nst! {
199pub c0nst trait SaturatingAbs: Sized + [c0nst] Neg {
201 fn saturating_abs(self) -> <Self as Neg>::Output;
211}
212}
213
214saturating_unary_impl!(SaturatingAbs, saturating_abs, i8);
215saturating_unary_impl!(SaturatingAbs, saturating_abs, i16);
216saturating_unary_impl!(SaturatingAbs, saturating_abs, i32);
217saturating_unary_impl!(SaturatingAbs, saturating_abs, i64);
218saturating_unary_impl!(SaturatingAbs, saturating_abs, isize);
219saturating_unary_impl!(SaturatingAbs, saturating_abs, i128);
220
221macro_rules! saturating_pow_impl {
222 ($t:ty) => {
223 c0nst::c0nst! {
224 c0nst impl SaturatingPow for $t {
225 #[inline]
226 fn saturating_pow(self, exp: u32) -> $t {
227 <$t>::saturating_pow(self, exp)
228 }
229 }
230 }
231 };
232}
233
234c0nst::c0nst! {
235pub c0nst trait SaturatingPow: Sized + [c0nst] Mul<Self> {
237 fn saturating_pow(self, exp: u32) -> <Self as Mul<Self>>::Output;
248}
249}
250
251saturating_pow_impl!(u8);
252saturating_pow_impl!(u16);
253saturating_pow_impl!(u32);
254saturating_pow_impl!(u64);
255saturating_pow_impl!(usize);
256saturating_pow_impl!(u128);
257
258saturating_pow_impl!(i8);
259saturating_pow_impl!(i16);
260saturating_pow_impl!(i32);
261saturating_pow_impl!(i64);
262saturating_pow_impl!(isize);
263saturating_pow_impl!(i128);
264
265#[test]
266fn test_saturating_div_neg_abs_pow() {
267 assert_eq!(SaturatingDiv::saturating_div(i8::MIN, -1), i8::MAX);
268 assert_eq!(SaturatingDiv::saturating_div(100u8, 7), 14);
269 assert_eq!(SaturatingNeg::saturating_neg(i16::MIN), i16::MAX);
270 assert_eq!(SaturatingNeg::saturating_neg(7i16), -7);
271 assert_eq!(SaturatingAbs::saturating_abs(i16::MIN), i16::MAX);
272 assert_eq!(SaturatingAbs::saturating_abs(-7i16), 7);
273 assert_eq!(SaturatingPow::saturating_pow(2u16, 17), u16::MAX);
274 assert_eq!(SaturatingPow::saturating_pow(-2i16, 15), i16::MIN);
275}
276
277#[test]
278fn test_saturating_traits() {
279 fn saturating_add<T: SaturatingAdd<Output = T>>(a: T, b: T) -> T {
280 a.saturating_add(b)
281 }
282 fn saturating_sub<T: SaturatingSub<Output = T>>(a: T, b: T) -> T {
283 a.saturating_sub(b)
284 }
285 fn saturating_mul<T: SaturatingMul<Output = T>>(a: T, b: T) -> T {
286 a.saturating_mul(b)
287 }
288 assert_eq!(saturating_add(255, 1), 255u8);
289 assert_eq!(saturating_add(127, 1), 127i8);
290 assert_eq!(saturating_add(-128, -1), -128i8);
291 assert_eq!(saturating_sub(0, 1), 0u8);
292 assert_eq!(saturating_sub(-128, 1), -128i8);
293 assert_eq!(saturating_sub(127, -1), 127i8);
294 assert_eq!(saturating_mul(255, 2), 255u8);
295 assert_eq!(saturating_mul(127, 2), 127i8);
296 assert_eq!(saturating_mul(-128, 2), -128i8);
297}