1use core::ops::{Add, Mul, Sub};
2
3pub trait Saturating {
6 fn saturating_add(self, v: Self) -> Self;
9
10 fn saturating_sub(self, v: Self) -> Self;
13}
14
15macro_rules! deprecated_saturating_impl {
16 ($trait_name:ident for $($t:ty)*) => {$(
17 impl $trait_name for $t {
18 #[inline]
19 fn saturating_add(self, v: Self) -> Self {
20 Self::saturating_add(self, v)
21 }
22
23 #[inline]
24 fn saturating_sub(self, v: Self) -> Self {
25 Self::saturating_sub(self, v)
26 }
27 }
28 )*}
29}
30
31impl Saturating for i128 {
#[inline]
fn saturating_add(self, v: Self) -> Self { Self::saturating_add(self, v) }
#[inline]
fn saturating_sub(self, v: Self) -> Self { Self::saturating_sub(self, v) }
}deprecated_saturating_impl!(Saturating for isize i8 i16 i32 i64 i128);
32impl Saturating for u128 {
#[inline]
fn saturating_add(self, v: Self) -> Self { Self::saturating_add(self, v) }
#[inline]
fn saturating_sub(self, v: Self) -> Self { Self::saturating_sub(self, v) }
}deprecated_saturating_impl!(Saturating for usize u8 u16 u32 u64 u128);
33
34macro_rules! saturating_impl {
35 ($trait_name:ident, $method:ident, $t:ty) => {
36 impl $trait_name for $t {
37 #[inline]
38 fn $method(&self, v: &Self) -> Self {
39 <$t>::$method(*self, *v)
40 }
41 }
42 };
43}
44
45pub trait SaturatingAdd: Sized + Add<Self, Output = Self> {
47 fn saturating_add(&self, v: &Self) -> Self;
50}
51
52impl SaturatingAdd for u8 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<u8>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, u8);
53impl SaturatingAdd for u16 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<u16>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, u16);
54impl SaturatingAdd for u32 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<u32>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, u32);
55impl SaturatingAdd for u64 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<u64>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, u64);
56impl SaturatingAdd for usize {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<usize>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, usize);
57impl SaturatingAdd for u128 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<u128>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, u128);
58
59impl SaturatingAdd for i8 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<i8>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, i8);
60impl SaturatingAdd for i16 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<i16>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, i16);
61impl SaturatingAdd for i32 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<i32>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, i32);
62impl SaturatingAdd for i64 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<i64>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, i64);
63impl SaturatingAdd for isize {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<isize>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, isize);
64impl SaturatingAdd for i128 {
#[inline]
fn saturating_add(&self, v: &Self) -> Self {
<i128>::saturating_add(*self, *v)
}
}saturating_impl!(SaturatingAdd, saturating_add, i128);
65
66pub trait SaturatingSub: Sized + Sub<Self, Output = Self> {
68 fn saturating_sub(&self, v: &Self) -> Self;
71}
72
73impl SaturatingSub for u8 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<u8>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, u8);
74impl SaturatingSub for u16 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<u16>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, u16);
75impl SaturatingSub for u32 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<u32>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, u32);
76impl SaturatingSub for u64 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<u64>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, u64);
77impl SaturatingSub for usize {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<usize>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, usize);
78impl SaturatingSub for u128 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<u128>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, u128);
79
80impl SaturatingSub for i8 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<i8>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, i8);
81impl SaturatingSub for i16 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<i16>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, i16);
82impl SaturatingSub for i32 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<i32>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, i32);
83impl SaturatingSub for i64 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<i64>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, i64);
84impl SaturatingSub for isize {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<isize>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, isize);
85impl SaturatingSub for i128 {
#[inline]
fn saturating_sub(&self, v: &Self) -> Self {
<i128>::saturating_sub(*self, *v)
}
}saturating_impl!(SaturatingSub, saturating_sub, i128);
86
87pub trait SaturatingMul: Sized + Mul<Self, Output = Self> {
89 fn saturating_mul(&self, v: &Self) -> Self;
92}
93
94impl SaturatingMul for u8 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<u8>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, u8);
95impl SaturatingMul for u16 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<u16>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, u16);
96impl SaturatingMul for u32 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<u32>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, u32);
97impl SaturatingMul for u64 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<u64>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, u64);
98impl SaturatingMul for usize {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<usize>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, usize);
99impl SaturatingMul for u128 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<u128>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, u128);
100
101impl SaturatingMul for i8 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<i8>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, i8);
102impl SaturatingMul for i16 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<i16>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, i16);
103impl SaturatingMul for i32 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<i32>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, i32);
104impl SaturatingMul for i64 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<i64>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, i64);
105impl SaturatingMul for isize {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<isize>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, isize);
106impl SaturatingMul for i128 {
#[inline]
fn saturating_mul(&self, v: &Self) -> Self {
<i128>::saturating_mul(*self, *v)
}
}saturating_impl!(SaturatingMul, saturating_mul, i128);
107
108#[test]
111fn test_saturating_traits() {
112 fn saturating_add<T: SaturatingAdd>(a: T, b: T) -> T {
113 a.saturating_add(&b)
114 }
115 fn saturating_sub<T: SaturatingSub>(a: T, b: T) -> T {
116 a.saturating_sub(&b)
117 }
118 fn saturating_mul<T: SaturatingMul>(a: T, b: T) -> T {
119 a.saturating_mul(&b)
120 }
121 assert_eq!(saturating_add(255, 1), 255u8);
122 assert_eq!(saturating_add(127, 1), 127i8);
123 assert_eq!(saturating_add(-128, -1), -128i8);
124 assert_eq!(saturating_sub(0, 1), 0u8);
125 assert_eq!(saturating_sub(-128, 1), -128i8);
126 assert_eq!(saturating_sub(127, -1), 127i8);
127 assert_eq!(saturating_mul(255, 2), 255u8);
128 assert_eq!(saturating_mul(127, 2), 127i8);
129 assert_eq!(saturating_mul(-128, 2), -128i8);
130}