use core::{num::Saturating, ops::Neg};
use crate::{
define_wrapper, scalars,
su::{Su8, Su16, Su32, Su64, Su128},
};
define_wrapper!(Si);
scalars! {
Si, Si8, si8, i8;
Si, Si16, si16, i16;
Si, Si32, si32, i32;
Si, Si64, si64, i64;
Si, Si128, si128, i128;
}
impl<T> Neg for Si<T>
where
Saturating<T>: Neg<Output = Saturating<T>>,
{
type Output = Self;
#[inline]
fn neg(self) -> Self::Output {
Self(self.0.neg())
}
}
macro_rules! signed_scalar_methods {
($($alias:ident, $ctor:ident, $primitive:ty, $unsigned_alias:ty, $unsigned_ctor:path);+ $(;)?) => {
$(
impl $alias {
#[inline]
#[must_use]
pub const fn abs(self) -> Self {
$ctor(self.into_inner().saturating_abs())
}
#[inline]
#[must_use]
pub const fn unsigned_abs(self) -> $unsigned_alias {
$unsigned_ctor(self.into_inner().unsigned_abs())
}
#[inline]
#[must_use]
pub const fn abs_diff(self, rhs: Self) -> $unsigned_alias {
$unsigned_ctor(self.into_inner().abs_diff(rhs.into_inner()))
}
#[inline]
#[must_use]
pub const fn checked_abs(self) -> Option<Self> {
match self.into_inner().checked_abs() {
Some(v) => Some($ctor(v)),
None => None,
}
}
#[inline]
#[must_use]
pub const fn signum(self) -> Self {
$ctor(self.into_inner().signum())
}
#[inline]
#[must_use]
pub const fn is_positive(self) -> bool {
self.into_inner().is_positive()
}
#[inline]
#[must_use]
pub const fn is_negative(self) -> bool {
self.into_inner().is_negative()
}
#[inline]
#[must_use]
pub const fn checked_isqrt(self) -> Option<Self> {
match self.into_inner().checked_isqrt() {
Some(v) => Some($ctor(v)),
None => None,
}
}
}
)+
};
}
signed_scalar_methods! {
Si8, si8, i8, Su8, crate::su8;
Si16, si16, i16, Su16, crate::su16;
Si32, si32, i32, Su32, crate::su32;
Si64, si64, i64, Su64, crate::su64;
Si128, si128, i128, Su128, crate::su128;
}