pub trait SignOps {
fn abs(self) -> Self;
fn abs_diff(self, other: Self) -> Self;
fn signum(self) -> Self;
fn is_positive(self) -> bool;
fn is_negative(self) -> bool;
}
macro_rules! impl_sign_uint {
($($t:ty),*) => {
$(impl SignOps for $t {
#[inline] fn abs(self) -> Self { self }
#[inline] fn abs_diff(self, other: Self) -> Self { self.abs_diff(other) }
#[inline] fn signum(self) -> Self { if self == 0 { 0 } else { 1 } }
#[inline] fn is_positive(self) -> bool { self != 0 }
#[inline] fn is_negative(self) -> bool { false }
})*
};
}
impl_sign_uint!(u8, u16, u32, u64, u128, usize);
macro_rules! impl_sign_int {
($($t:ty),*) => {
$(impl SignOps for $t {
#[inline] fn abs(self) -> Self { self.abs() }
#[inline] fn signum(self) -> Self { self.signum() }
#[inline] fn is_positive(self) -> bool { self.is_positive() }
#[inline] fn is_negative(self) -> bool { self.is_negative() }
#[inline]
fn abs_diff(self, other: Self) -> Self {
if self < other {
other - self
} else {
self - other
}
}
})*
};
}
impl_sign_int!(i8, i16, i32, i64, i128, isize);
macro_rules! impl_sign_float {
($($t:ty),*) => {
$(impl SignOps for $t {
#[inline] fn abs(self) -> Self { self.abs() }
#[inline] fn signum(self) -> Self { self.signum() }
#[inline] fn is_positive(self) -> bool { self.is_sign_positive() }
#[inline] fn is_negative(self) -> bool { self.is_sign_negative() }
#[inline]
fn abs_diff(self, other: Self) -> Self {
if self < other {
other - self
} else {
self - other
}
}
})*
};
}
impl_sign_float!(f32, f64);