c0nst::c0nst! {
pub c0nst trait Saturating {
type Output;
fn saturating_add(self, v: Self) -> Self::Output;
fn saturating_sub(self, v: Self) -> Self::Output;
}
}
macro_rules! deprecated_saturating_impl {
($trait_name:ident for $($t:ty)*) => {$(
c0nst::c0nst! {
c0nst impl $trait_name for $t {
type Output = $t;
#[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);
deprecated_saturating_impl!(Saturating for usize u8 u16 u32 u64 u128);
macro_rules! saturating_impl {
($trait_name:ident, $method:ident, $t:ty) => {
c0nst::c0nst! {
c0nst impl $trait_name for $t {
type Output = $t;
#[inline]
fn $method(self, v: Self) -> Self {
<$t>::$method(self, v)
}
}
}
};
}
c0nst::c0nst! {
pub c0nst trait SaturatingAdd: Sized {
type Output;
fn saturating_add(self, v: Self) -> Self::Output;
}
}
saturating_impl!(SaturatingAdd, saturating_add, u8);
saturating_impl!(SaturatingAdd, saturating_add, u16);
saturating_impl!(SaturatingAdd, saturating_add, u32);
saturating_impl!(SaturatingAdd, saturating_add, u64);
saturating_impl!(SaturatingAdd, saturating_add, usize);
saturating_impl!(SaturatingAdd, saturating_add, u128);
saturating_impl!(SaturatingAdd, saturating_add, i8);
saturating_impl!(SaturatingAdd, saturating_add, i16);
saturating_impl!(SaturatingAdd, saturating_add, i32);
saturating_impl!(SaturatingAdd, saturating_add, i64);
saturating_impl!(SaturatingAdd, saturating_add, isize);
saturating_impl!(SaturatingAdd, saturating_add, i128);
c0nst::c0nst! {
pub c0nst trait SaturatingSub: Sized {
type Output;
fn saturating_sub(self, v: Self) -> Self::Output;
}
}
saturating_impl!(SaturatingSub, saturating_sub, u8);
saturating_impl!(SaturatingSub, saturating_sub, u16);
saturating_impl!(SaturatingSub, saturating_sub, u32);
saturating_impl!(SaturatingSub, saturating_sub, u64);
saturating_impl!(SaturatingSub, saturating_sub, usize);
saturating_impl!(SaturatingSub, saturating_sub, u128);
saturating_impl!(SaturatingSub, saturating_sub, i8);
saturating_impl!(SaturatingSub, saturating_sub, i16);
saturating_impl!(SaturatingSub, saturating_sub, i32);
saturating_impl!(SaturatingSub, saturating_sub, i64);
saturating_impl!(SaturatingSub, saturating_sub, isize);
saturating_impl!(SaturatingSub, saturating_sub, i128);
c0nst::c0nst! {
pub c0nst trait SaturatingMul: Sized {
type Output;
fn saturating_mul(self, v: Self) -> Self::Output;
}
}
saturating_impl!(SaturatingMul, saturating_mul, u8);
saturating_impl!(SaturatingMul, saturating_mul, u16);
saturating_impl!(SaturatingMul, saturating_mul, u32);
saturating_impl!(SaturatingMul, saturating_mul, u64);
saturating_impl!(SaturatingMul, saturating_mul, usize);
saturating_impl!(SaturatingMul, saturating_mul, u128);
saturating_impl!(SaturatingMul, saturating_mul, i8);
saturating_impl!(SaturatingMul, saturating_mul, i16);
saturating_impl!(SaturatingMul, saturating_mul, i32);
saturating_impl!(SaturatingMul, saturating_mul, i64);
saturating_impl!(SaturatingMul, saturating_mul, isize);
saturating_impl!(SaturatingMul, saturating_mul, i128);
c0nst::c0nst! {
pub c0nst trait SaturatingDiv: Sized {
type Output;
fn saturating_div(self, v: Self) -> Self::Output;
}
}
saturating_impl!(SaturatingDiv, saturating_div, u8);
saturating_impl!(SaturatingDiv, saturating_div, u16);
saturating_impl!(SaturatingDiv, saturating_div, u32);
saturating_impl!(SaturatingDiv, saturating_div, u64);
saturating_impl!(SaturatingDiv, saturating_div, usize);
saturating_impl!(SaturatingDiv, saturating_div, u128);
saturating_impl!(SaturatingDiv, saturating_div, i8);
saturating_impl!(SaturatingDiv, saturating_div, i16);
saturating_impl!(SaturatingDiv, saturating_div, i32);
saturating_impl!(SaturatingDiv, saturating_div, i64);
saturating_impl!(SaturatingDiv, saturating_div, isize);
saturating_impl!(SaturatingDiv, saturating_div, i128);
macro_rules! saturating_unary_impl {
($trait_name:ident, $method:ident, $t:ty) => {
c0nst::c0nst! {
c0nst impl $trait_name for $t {
type Output = $t;
#[inline]
fn $method(self) -> $t {
<$t>::$method(self)
}
}
}
};
}
c0nst::c0nst! {
pub c0nst trait SaturatingNeg: Sized {
type Output;
fn saturating_neg(self) -> Self::Output;
}
}
saturating_unary_impl!(SaturatingNeg, saturating_neg, i8);
saturating_unary_impl!(SaturatingNeg, saturating_neg, i16);
saturating_unary_impl!(SaturatingNeg, saturating_neg, i32);
saturating_unary_impl!(SaturatingNeg, saturating_neg, i64);
saturating_unary_impl!(SaturatingNeg, saturating_neg, isize);
saturating_unary_impl!(SaturatingNeg, saturating_neg, i128);
c0nst::c0nst! {
pub c0nst trait SaturatingAbs: Sized {
type Output;
fn saturating_abs(self) -> Self::Output;
}
}
saturating_unary_impl!(SaturatingAbs, saturating_abs, i8);
saturating_unary_impl!(SaturatingAbs, saturating_abs, i16);
saturating_unary_impl!(SaturatingAbs, saturating_abs, i32);
saturating_unary_impl!(SaturatingAbs, saturating_abs, i64);
saturating_unary_impl!(SaturatingAbs, saturating_abs, isize);
saturating_unary_impl!(SaturatingAbs, saturating_abs, i128);
macro_rules! saturating_pow_impl {
($t:ty) => {
c0nst::c0nst! {
c0nst impl SaturatingPow for $t {
type Output = $t;
#[inline]
fn saturating_pow(self, exp: u32) -> $t {
<$t>::saturating_pow(self, exp)
}
}
}
};
}
c0nst::c0nst! {
pub c0nst trait SaturatingPow: Sized {
type Output;
fn saturating_pow(self, exp: u32) -> Self::Output;
}
}
saturating_pow_impl!(u8);
saturating_pow_impl!(u16);
saturating_pow_impl!(u32);
saturating_pow_impl!(u64);
saturating_pow_impl!(usize);
saturating_pow_impl!(u128);
saturating_pow_impl!(i8);
saturating_pow_impl!(i16);
saturating_pow_impl!(i32);
saturating_pow_impl!(i64);
saturating_pow_impl!(isize);
saturating_pow_impl!(i128);
#[test]
fn test_saturating_div_neg_abs_pow() {
assert_eq!(SaturatingDiv::saturating_div(i8::MIN, -1), i8::MAX);
assert_eq!(SaturatingDiv::saturating_div(100u8, 7), 14);
assert_eq!(SaturatingNeg::saturating_neg(i16::MIN), i16::MAX);
assert_eq!(SaturatingNeg::saturating_neg(7i16), -7);
assert_eq!(SaturatingAbs::saturating_abs(i16::MIN), i16::MAX);
assert_eq!(SaturatingAbs::saturating_abs(-7i16), 7);
assert_eq!(SaturatingPow::saturating_pow(2u16, 17), u16::MAX);
assert_eq!(SaturatingPow::saturating_pow(-2i16, 15), i16::MIN);
}
#[test]
fn test_saturating_traits() {
fn saturating_add<T: SaturatingAdd<Output = T>>(a: T, b: T) -> T {
a.saturating_add(b)
}
fn saturating_sub<T: SaturatingSub<Output = T>>(a: T, b: T) -> T {
a.saturating_sub(b)
}
fn saturating_mul<T: SaturatingMul<Output = T>>(a: T, b: T) -> T {
a.saturating_mul(b)
}
assert_eq!(saturating_add(255, 1), 255u8);
assert_eq!(saturating_add(127, 1), 127i8);
assert_eq!(saturating_add(-128, -1), -128i8);
assert_eq!(saturating_sub(0, 1), 0u8);
assert_eq!(saturating_sub(-128, 1), -128i8);
assert_eq!(saturating_sub(127, -1), 127i8);
assert_eq!(saturating_mul(255, 2), 255u8);
assert_eq!(saturating_mul(127, 2), 127i8);
assert_eq!(saturating_mul(-128, 2), -128i8);
}