use core::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub};
c0nst::c0nst! {
pub c0nst trait CheckedAdd: Sized + [c0nst] Add<Self> {
fn checked_add(self, v: Self) -> Option<<Self as Add<Self>>::Output>;
}
}
macro_rules! checked_impl {
($trait_name:ident, $method:ident, $t:ty) => {
c0nst::c0nst! {
c0nst impl $trait_name for $t {
#[inline]
fn $method(self, v: $t) -> Option<$t> {
<$t>::$method(self, v)
}
}
}
};
}
checked_impl!(CheckedAdd, checked_add, u8);
checked_impl!(CheckedAdd, checked_add, u16);
checked_impl!(CheckedAdd, checked_add, u32);
checked_impl!(CheckedAdd, checked_add, u64);
checked_impl!(CheckedAdd, checked_add, usize);
checked_impl!(CheckedAdd, checked_add, u128);
checked_impl!(CheckedAdd, checked_add, i8);
checked_impl!(CheckedAdd, checked_add, i16);
checked_impl!(CheckedAdd, checked_add, i32);
checked_impl!(CheckedAdd, checked_add, i64);
checked_impl!(CheckedAdd, checked_add, isize);
checked_impl!(CheckedAdd, checked_add, i128);
c0nst::c0nst! {
pub c0nst trait CheckedSub: Sized + [c0nst] Sub<Self> {
fn checked_sub(self, v: Self) -> Option<<Self as Sub<Self>>::Output>;
}
}
checked_impl!(CheckedSub, checked_sub, u8);
checked_impl!(CheckedSub, checked_sub, u16);
checked_impl!(CheckedSub, checked_sub, u32);
checked_impl!(CheckedSub, checked_sub, u64);
checked_impl!(CheckedSub, checked_sub, usize);
checked_impl!(CheckedSub, checked_sub, u128);
checked_impl!(CheckedSub, checked_sub, i8);
checked_impl!(CheckedSub, checked_sub, i16);
checked_impl!(CheckedSub, checked_sub, i32);
checked_impl!(CheckedSub, checked_sub, i64);
checked_impl!(CheckedSub, checked_sub, isize);
checked_impl!(CheckedSub, checked_sub, i128);
c0nst::c0nst! {
pub c0nst trait CheckedMul: Sized + [c0nst] Mul<Self> {
fn checked_mul(self, v: Self) -> Option<<Self as Mul<Self>>::Output>;
}
}
checked_impl!(CheckedMul, checked_mul, u8);
checked_impl!(CheckedMul, checked_mul, u16);
checked_impl!(CheckedMul, checked_mul, u32);
checked_impl!(CheckedMul, checked_mul, u64);
checked_impl!(CheckedMul, checked_mul, usize);
checked_impl!(CheckedMul, checked_mul, u128);
checked_impl!(CheckedMul, checked_mul, i8);
checked_impl!(CheckedMul, checked_mul, i16);
checked_impl!(CheckedMul, checked_mul, i32);
checked_impl!(CheckedMul, checked_mul, i64);
checked_impl!(CheckedMul, checked_mul, isize);
checked_impl!(CheckedMul, checked_mul, i128);
c0nst::c0nst! {
pub c0nst trait CheckedDiv: Sized + [c0nst] Div<Self> {
fn checked_div(self, v: Self) -> Option<<Self as Div<Self>>::Output>;
}
}
checked_impl!(CheckedDiv, checked_div, u8);
checked_impl!(CheckedDiv, checked_div, u16);
checked_impl!(CheckedDiv, checked_div, u32);
checked_impl!(CheckedDiv, checked_div, u64);
checked_impl!(CheckedDiv, checked_div, usize);
checked_impl!(CheckedDiv, checked_div, u128);
checked_impl!(CheckedDiv, checked_div, i8);
checked_impl!(CheckedDiv, checked_div, i16);
checked_impl!(CheckedDiv, checked_div, i32);
checked_impl!(CheckedDiv, checked_div, i64);
checked_impl!(CheckedDiv, checked_div, isize);
checked_impl!(CheckedDiv, checked_div, i128);
c0nst::c0nst! {
pub c0nst trait CheckedRem: Sized + [c0nst] Rem<Self> {
fn checked_rem(self, v: Self) -> Option<<Self as Rem<Self>>::Output>;
}
}
checked_impl!(CheckedRem, checked_rem, u8);
checked_impl!(CheckedRem, checked_rem, u16);
checked_impl!(CheckedRem, checked_rem, u32);
checked_impl!(CheckedRem, checked_rem, u64);
checked_impl!(CheckedRem, checked_rem, usize);
checked_impl!(CheckedRem, checked_rem, u128);
checked_impl!(CheckedRem, checked_rem, i8);
checked_impl!(CheckedRem, checked_rem, i16);
checked_impl!(CheckedRem, checked_rem, i32);
checked_impl!(CheckedRem, checked_rem, i64);
checked_impl!(CheckedRem, checked_rem, isize);
checked_impl!(CheckedRem, checked_rem, i128);
macro_rules! checked_impl_unary {
($trait_name:ident, $method:ident, $t:ty) => {
c0nst::c0nst! {
c0nst impl $trait_name for $t {
#[inline]
fn $method(self) -> Option<$t> {
<$t>::$method(self)
}
}
}
};
}
c0nst::c0nst! {
pub c0nst trait CheckedNeg: Sized {
type Output;
fn checked_neg(self) -> Option<Self::Output>;
}
}
macro_rules! checked_neg_impl {
($($t:ty)*) => {$(
c0nst::c0nst! {
c0nst impl CheckedNeg for $t {
type Output = $t;
#[inline]
fn checked_neg(self) -> Option<$t> {
<$t>::checked_neg(self)
}
}
}
)*};
}
checked_neg_impl!(u8 u16 u32 u64 usize u128 i8 i16 i32 i64 isize i128);
c0nst::c0nst! {
pub c0nst trait CheckedShl: Sized + [c0nst] Shl<u32> {
fn checked_shl(self, rhs: u32) -> Option<<Self as Shl<u32>>::Output>;
}
}
macro_rules! checked_shift_impl {
($trait_name:ident, $method:ident, $t:ty) => {
c0nst::c0nst! {
c0nst impl $trait_name for $t {
#[inline]
fn $method(self, rhs: u32) -> Option<$t> {
<$t>::$method(self, rhs)
}
}
}
};
}
checked_shift_impl!(CheckedShl, checked_shl, u8);
checked_shift_impl!(CheckedShl, checked_shl, u16);
checked_shift_impl!(CheckedShl, checked_shl, u32);
checked_shift_impl!(CheckedShl, checked_shl, u64);
checked_shift_impl!(CheckedShl, checked_shl, usize);
checked_shift_impl!(CheckedShl, checked_shl, u128);
checked_shift_impl!(CheckedShl, checked_shl, i8);
checked_shift_impl!(CheckedShl, checked_shl, i16);
checked_shift_impl!(CheckedShl, checked_shl, i32);
checked_shift_impl!(CheckedShl, checked_shl, i64);
checked_shift_impl!(CheckedShl, checked_shl, isize);
checked_shift_impl!(CheckedShl, checked_shl, i128);
c0nst::c0nst! {
pub c0nst trait CheckedShr: Sized + [c0nst] Shr<u32> {
fn checked_shr(self, rhs: u32) -> Option<<Self as Shr<u32>>::Output>;
}
}
checked_shift_impl!(CheckedShr, checked_shr, u8);
checked_shift_impl!(CheckedShr, checked_shr, u16);
checked_shift_impl!(CheckedShr, checked_shr, u32);
checked_shift_impl!(CheckedShr, checked_shr, u64);
checked_shift_impl!(CheckedShr, checked_shr, usize);
checked_shift_impl!(CheckedShr, checked_shr, u128);
checked_shift_impl!(CheckedShr, checked_shr, i8);
checked_shift_impl!(CheckedShr, checked_shr, i16);
checked_shift_impl!(CheckedShr, checked_shr, i32);
checked_shift_impl!(CheckedShr, checked_shr, i64);
checked_shift_impl!(CheckedShr, checked_shr, isize);
checked_shift_impl!(CheckedShr, checked_shr, i128);
c0nst::c0nst! {
pub c0nst trait CheckedAbs: Sized + [c0nst] Neg {
fn checked_abs(self) -> Option<<Self as Neg>::Output>;
}
}
checked_impl_unary!(CheckedAbs, checked_abs, i8);
checked_impl_unary!(CheckedAbs, checked_abs, i16);
checked_impl_unary!(CheckedAbs, checked_abs, i32);
checked_impl_unary!(CheckedAbs, checked_abs, i64);
checked_impl_unary!(CheckedAbs, checked_abs, isize);
checked_impl_unary!(CheckedAbs, checked_abs, i128);
c0nst::c0nst! {
pub c0nst trait CheckedPow: Sized + [c0nst] Mul<Self> {
fn checked_pow(self, exp: u32) -> Option<<Self as Mul<Self>>::Output>;
}
}
checked_shift_impl!(CheckedPow, checked_pow, u8);
checked_shift_impl!(CheckedPow, checked_pow, u16);
checked_shift_impl!(CheckedPow, checked_pow, u32);
checked_shift_impl!(CheckedPow, checked_pow, u64);
checked_shift_impl!(CheckedPow, checked_pow, usize);
checked_shift_impl!(CheckedPow, checked_pow, u128);
checked_shift_impl!(CheckedPow, checked_pow, i8);
checked_shift_impl!(CheckedPow, checked_pow, i16);
checked_shift_impl!(CheckedPow, checked_pow, i32);
checked_shift_impl!(CheckedPow, checked_pow, i64);
checked_shift_impl!(CheckedPow, checked_pow, isize);
checked_shift_impl!(CheckedPow, checked_pow, i128);
#[test]
fn test_checked_abs_pow() {
fn checked_abs<T: CheckedAbs + core::ops::Neg<Output = T>>(a: T) -> Option<T> {
a.checked_abs()
}
fn checked_pow<T: CheckedPow + core::ops::Mul<Output = T>>(a: T, exp: u32) -> Option<T> {
a.checked_pow(exp)
}
assert_eq!(checked_abs(-5i16), Some(5));
assert_eq!(checked_abs(i16::MIN), None);
assert_eq!(checked_pow(3u8, 5), Some(243));
assert_eq!(checked_pow(2u8, 8), None);
assert_eq!(checked_pow(-3i32, 3), Some(-27));
}