use core::convert::Infallible;
use crate::{PrimitiveInteger, PrimitiveIntegerRef, PrimitiveUnsigned};
pub trait PrimitiveSigned:
PrimitiveInteger
+ core::convert::From<i8>
+ core::convert::TryFrom<i8, Error = Infallible>
+ core::ops::Neg<Output = Self>
{
type Unsigned: PrimitiveUnsigned;
fn abs(self) -> Self;
fn abs_diff(self, other: Self) -> Self::Unsigned;
fn cast_unsigned(self) -> Self::Unsigned;
fn checked_abs(self) -> Option<Self>;
fn checked_add_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
fn checked_isqrt(self) -> Option<Self>;
fn checked_sub_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
fn is_negative(self) -> bool;
fn is_positive(self) -> bool;
fn overflowing_abs(self) -> (Self, bool);
fn overflowing_add_unsigned(self, rhs: Self::Unsigned) -> (Self, bool);
fn overflowing_sub_unsigned(self, rhs: Self::Unsigned) -> (Self, bool);
fn saturating_abs(self) -> Self;
fn saturating_add_unsigned(self, rhs: Self::Unsigned) -> Self;
fn saturating_neg(self) -> Self;
fn saturating_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn signum(self) -> Self;
fn strict_abs(self) -> Self;
fn strict_add_unsigned(self, rhs: Self::Unsigned) -> Self;
fn strict_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn unsigned_abs(self) -> Self::Unsigned;
fn wrapping_abs(self) -> Self;
fn wrapping_add_unsigned(self, rhs: Self::Unsigned) -> Self;
fn wrapping_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
unsafe fn unchecked_neg(self) -> Self;
}
pub trait PrimitiveSignedRef<T>: PrimitiveIntegerRef<T> + core::ops::Neg<Output = T> {}
macro_rules! impl_signed {
($Signed:ident, $Unsigned:ty) => {
impl PrimitiveSigned for $Signed {
type Unsigned = $Unsigned;
forward! {
fn abs(self) -> Self;
fn abs_diff(self, other: Self) -> Self::Unsigned;
fn cast_unsigned(self) -> Self::Unsigned;
fn checked_abs(self) -> Option<Self>;
fn checked_add_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
fn checked_isqrt(self) -> Option<Self>;
fn checked_sub_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
fn is_negative(self) -> bool;
fn is_positive(self) -> bool;
fn overflowing_abs(self) -> (Self, bool);
fn overflowing_add_unsigned(self, rhs: Self::Unsigned) -> (Self, bool);
fn overflowing_sub_unsigned(self, rhs: Self::Unsigned) -> (Self, bool);
fn saturating_abs(self) -> Self;
fn saturating_add_unsigned(self, rhs: Self::Unsigned) -> Self;
fn saturating_neg(self) -> Self;
fn saturating_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn signum(self) -> Self;
fn strict_abs(self) -> Self;
fn strict_add_unsigned(self, rhs: Self::Unsigned) -> Self;
fn strict_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn unsigned_abs(self) -> Self::Unsigned;
fn wrapping_abs(self) -> Self;
fn wrapping_add_unsigned(self, rhs: Self::Unsigned) -> Self;
fn wrapping_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
}
forward! {
unsafe fn unchecked_neg(self) -> Self;
}
}
impl PrimitiveSignedRef<$Signed> for &$Signed {}
};
}
impl_signed!(i8, u8);
impl_signed!(i16, u16);
impl_signed!(i32, u32);
impl_signed!(i64, u64);
impl_signed!(i128, u128);
impl_signed!(isize, usize);