use core::ops::Neg;
use multitype::Integral;
pub unsafe trait Signed
where
Self:
Integral<Signed = Self, Unsigned: Integral<Signed = Self>>
+ Neg<Output = Self>,
{
#[must_use]
fn abs(self) -> Self;
#[must_use]
fn cast_unsigned(self) -> Self::Unsigned;
#[must_use]
fn checked_abs(self) -> Option<Self>;
#[must_use]
fn checked_add_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
#[must_use]
fn checked_sub_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
#[must_use]
fn is_negative(self) -> bool;
#[must_use]
fn is_positive(self) -> bool;
#[must_use]
fn overflowing_abs(self) -> (Self, bool);
#[must_use]
fn overflowing_add_unsigned(self, rhs: Self::Unsigned) -> (Self, bool);
#[must_use]
fn overflowing_sub_unsigned(self, rhs: Self::Unsigned) -> (Self, bool);
#[must_use]
fn saturating_abs(self) -> Self;
#[must_use]
fn saturating_add_unsigned(self, rhs: Self::Unsigned) -> Self;
#[must_use]
fn saturating_neg(self) -> Self;
#[must_use]
fn saturating_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
#[must_use]
fn signum(self) -> Self;
#[must_use]
fn strict_abs(self) -> Self;
#[must_use]
fn strict_add_unsigned(self, rhs: Self::Unsigned) -> Self;
#[must_use]
fn strict_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
#[expect(clippy::missing_safety_doc)]
#[must_use]
unsafe fn unchecked_neg(self) -> Self;
#[must_use]
fn unsigned_abs(self) -> Self::Unsigned;
#[must_use]
fn wrapping_abs(self) -> Self;
#[must_use]
fn wrapping_add_unsigned(self, rhs: Self::Unsigned) -> Self;
#[must_use]
fn wrapping_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
}
macro_rules! impl_signed {
{
$(
$(#[$attr:meta])?
$Ty:ty { Unsigned = $Unsigned:ty$(,)? }
),*$(,)?
} => {$(
$(#[$attr])?
unsafe impl ::multitype::Integral for $Ty {
type Signed = Self;
type Unsigned = $Unsigned;
const BITS: ::core::primitive::u32 = Self::BITS;
const MAX: Self = Self::MAX;
const MIN: Self = Self::MIN;
#[inline(always)]
#[track_caller]
fn abs_diff(self, rhs: Self) -> <Self as ::multitype::Integral>::Unsigned {
self.abs_diff(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_add(self, rhs: Self) -> ::core::option::Option<Self> {
self.checked_add(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_div(self, rhs: Self) -> ::core::option::Option<Self> {
self.checked_div(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
self.checked_div_euclid(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_ilog(self, rhs: Self) -> ::core::option::Option<::core::primitive::u32> {
self.checked_ilog(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_ilog10(self) -> ::core::option::Option<::core::primitive::u32> {
self.checked_ilog10()
}
#[inline(always)]
#[track_caller]
fn checked_ilog2(self) -> ::core::option::Option<::core::primitive::u32> {
self.checked_ilog2()
}
#[inline(always)]
#[track_caller]
fn checked_mul(self, rhs: Self) -> ::core::option::Option<Self> {
self.checked_mul(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_neg(self) -> ::core::option::Option<Self> {
self.checked_neg()
}
#[inline(always)]
#[track_caller]
fn checked_pow(self, rhs: ::core::primitive::u32) -> ::core::option::Option<Self> {
self.checked_pow(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_rem(self, rhs: Self) -> ::core::option::Option<Self> {
self.checked_rem(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
self.checked_rem_euclid(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_shl(self, rhs: ::core::primitive::u32) -> ::core::option::Option<Self> {
self.checked_shl(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_shr(self, rhs: ::core::primitive::u32) -> ::core::option::Option<Self> {
self.checked_shr(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_sub(self, rhs: Self) -> ::core::option::Option<Self> {
self.checked_sub(rhs)
}
#[inline(always)]
#[track_caller]
fn count_ones(self) -> ::core::primitive::u32 {
self.count_ones()
}
#[inline(always)]
#[track_caller]
fn count_zeros(self) -> ::core::primitive::u32 {
self.count_zeros()
}
#[inline(always)]
#[track_caller]
fn div_euclid(self, rhs: Self) -> Self {
self.div_euclid(rhs)
}
#[inline(always)]
#[track_caller]
fn from_be(value: Self) -> Self {
Self::from_be(value)
}
#[inline(always)]
#[track_caller]
fn from_le(value: Self) -> Self {
Self::from_le(value)
}
#[inline]
fn highest_one(self) -> ::core::option::Option<::core::primitive::u32> {
match self {
0 => ::core::option::Option::None,
_ => ::core::option::Option::Some(Self::BITS - 1 - self.leading_zeros()),
}
}
#[inline(always)]
#[track_caller]
fn ilog(self, rhs: Self) -> ::core::primitive::u32 {
self.ilog(rhs)
}
#[inline(always)]
#[track_caller]
fn ilog10(self) -> ::core::primitive::u32 {
self.ilog10()
}
#[inline(always)]
#[track_caller]
fn ilog2(self) -> ::core::primitive::u32 {
self.ilog2()
}
#[inline]
fn isolate_highest_one(self) -> Self {
let one: Self = 1;
let mask = (one << <$Ty>::BITS - 1).wrapping_shr(self.leading_zeros());
self & mask
}
#[inline]
fn isolate_lowest_one(self) -> Self {
let mask = self.wrapping_neg();
self & mask
}
#[inline(always)]
#[track_caller]
fn isqrt(self) -> Self {
self.isqrt()
}
#[inline(always)]
#[track_caller]
fn leading_ones(self) -> ::core::primitive::u32 {
self.leading_ones()
}
#[inline(always)]
#[track_caller]
fn leading_zeros(self) -> ::core::primitive::u32 {
self.leading_zeros()
}
#[inline]
fn lowest_one(self) -> ::core::option::Option<::core::primitive::u32> {
match self {
0 => ::core::option::Option::None,
_ => ::core::option::Option::Some(self.trailing_zeros()),
}
}
#[inline]
fn midpoint(self, rhs: Self) -> Self {
let floor = ((self & rhs) + ((self ^ rhs) >> 1));
let offset = self.is_negative() as $Ty & (self ^ rhs);
floor + offset
}
#[inline(always)]
#[track_caller]
fn overflowing_add(self, rhs: Self) -> (Self, ::core::primitive::bool) {
self.overflowing_add(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_div(self, rhs: Self) -> (Self, ::core::primitive::bool) {
self.overflowing_div(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_div_euclid(self, rhs: Self) -> (Self, ::core::primitive::bool) {
self.overflowing_div_euclid(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_mul(self, rhs: Self) -> (Self, ::core::primitive::bool) {
self.overflowing_mul(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_neg(self) -> (Self, ::core::primitive::bool) {
self.overflowing_neg()
}
#[inline(always)]
#[track_caller]
fn overflowing_pow(self, rhs: ::core::primitive::u32) -> (Self, ::core::primitive::bool) {
self.overflowing_pow(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_rem(self, rhs: Self) -> (Self, ::core::primitive::bool) {
self.overflowing_rem(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_rem_euclid(self, rhs: Self) -> (Self, ::core::primitive::bool) {
self.overflowing_rem_euclid(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_shl(self, rhs: ::core::primitive::u32) -> (Self, ::core::primitive::bool) {
self.overflowing_shl(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_shr(self, rhs: ::core::primitive::u32) -> (Self, ::core::primitive::bool) {
self.overflowing_shr(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_sub(self, rhs: Self) -> (Self, ::core::primitive::bool) {
self.overflowing_sub(rhs)
}
#[inline(always)]
#[track_caller]
fn pow(self, rhs: ::core::primitive::u32) -> Self {
self.pow(rhs)
}
#[inline(always)]
#[track_caller]
fn rem_euclid(self, rhs: Self) -> Self {
self.rem_euclid(rhs)
}
#[inline(always)]
#[track_caller]
fn reverse_bits(self) -> Self {
self.reverse_bits()
}
#[inline(always)]
#[track_caller]
fn rotate_left(self, rhs: ::core::primitive::u32) -> Self {
self.rotate_left(rhs)
}
#[inline(always)]
#[track_caller]
fn rotate_right(self, rhs: ::core::primitive::u32) -> Self {
self.rotate_right(rhs)
}
#[inline(always)]
#[track_caller]
fn saturating_add(self, rhs: Self) -> Self {
self.saturating_add(rhs)
}
#[inline(always)]
#[track_caller]
fn saturating_div(self, rhs: Self) -> Self {
self.saturating_div(rhs)
}
#[inline(always)]
#[track_caller]
fn saturating_mul(self, rhs: Self) -> Self {
self.saturating_mul(rhs)
}
#[inline(always)]
#[track_caller]
fn saturating_pow(self, rhs: ::core::primitive::u32) -> Self {
self.saturating_pow(rhs)
}
#[inline(always)]
#[track_caller]
fn saturating_sub(self, rhs: Self) -> Self {
self.saturating_sub(rhs)
}
#[inline]
#[track_caller]
fn strict_add(self, rhs: Self) -> Self {
self.checked_add(rhs).expect("attempt to add with overflow")
}
#[inline]
#[track_caller]
fn strict_div(self, rhs: Self) -> Self {
self.checked_div(rhs).expect("attempt to divide with overflow")
}
#[inline]
#[track_caller]
fn strict_div_euclid(self, rhs: Self) -> Self {
self.checked_div_euclid(rhs).expect("attempt to divide with overflow")
}
#[inline]
#[track_caller]
fn strict_mul(self, rhs: Self) -> Self {
self.checked_mul(rhs).expect("attempt to multiply with overflow")
}
#[inline]
#[track_caller]
fn strict_neg(self) -> Self {
self.checked_neg().expect("attempt to negate with overflow")
}
#[inline]
#[track_caller]
fn strict_pow(self, rhs: ::core::primitive::u32) -> Self {
self.checked_pow(rhs).expect("attempt to multiply with overflow")
}
#[inline]
#[track_caller]
fn strict_rem(self, rhs: Self) -> Self {
self.checked_rem(rhs).expect("attempt to calculate the remainder with overflow")
}
#[inline]
#[track_caller]
fn strict_rem_euclid(self, rhs: Self) -> Self {
self.checked_rem_euclid(rhs).expect("attempt to calculate the remainder with overflow")
}
#[inline]
#[track_caller]
fn strict_shl(self, rhs: ::core::primitive::u32) -> Self {
self.checked_shl(rhs).expect("attempt to shift left with overflow")
}
#[inline]
#[track_caller]
fn strict_shr(self, rhs: ::core::primitive::u32) -> Self {
self.checked_shr(rhs).expect("attempt to shift right with overflow")
}
#[inline]
#[track_caller]
fn strict_sub(self, rhs: Self) -> Self {
self.checked_sub(rhs).expect("attempt to subtract with overflow")
}
#[inline(always)]
#[track_caller]
fn swap_bytes(self) -> Self {
self.swap_bytes()
}
#[inline(always)]
#[track_caller]
fn to_be(self) -> Self {
self.to_be()
}
#[inline(always)]
#[track_caller]
fn to_le(self) -> Self {
self.to_le()
}
#[inline(always)]
#[track_caller]
fn trailing_ones(self) -> ::core::primitive::u32 {
self.trailing_ones()
}
#[inline(always)]
#[track_caller]
fn trailing_zeros(self) -> ::core::primitive::u32 {
self.trailing_zeros()
}
#[inline]
fn unbounded_shl(self, rhs: ::core::primitive::u32) -> Self {
if rhs < Self::BITS {
self << rhs
} else {
0
}
}
#[inline]
fn unbounded_shr(self, rhs: ::core::primitive::u32) -> Self {
if rhs < Self::BITS {
self >> rhs
} else {
self >> (Self::BITS - 1)
}
}
#[inline(always)]
#[track_caller]
unsafe fn unchecked_add(self, rhs: Self) -> Self {
unsafe { self.unchecked_add(rhs) }
}
#[inline(always)]
#[track_caller]
unsafe fn unchecked_mul(self, rhs: Self) -> Self {
unsafe { self.unchecked_mul(rhs) }
}
#[inline(always)]
#[track_caller]
unsafe fn unchecked_shl(self, rhs: ::core::primitive::u32) -> Self {
unsafe { self.checked_shl(rhs).unwrap_unchecked() }
}
#[inline(always)]
#[track_caller]
unsafe fn unchecked_shr(self, rhs: ::core::primitive::u32) -> Self {
unsafe { self.checked_shr(rhs).unwrap_unchecked() }
}
#[inline(always)]
#[track_caller]
unsafe fn unchecked_sub(self, rhs: Self) -> Self {
unsafe { self.unchecked_sub(rhs) }
}
#[inline(always)]
#[track_caller]
fn wrapping_add(self, rhs: Self) -> Self {
self.wrapping_add(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_div(self, rhs: Self) -> Self {
self.wrapping_div(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_div_euclid(self, rhs: Self) -> Self {
self.wrapping_div_euclid(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_mul(self, rhs: Self) -> Self {
self.wrapping_mul(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_neg(self) -> Self {
self.wrapping_neg()
}
#[inline(always)]
#[track_caller]
fn wrapping_pow(self, rhs: ::core::primitive::u32) -> Self {
self.wrapping_pow(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_rem(self, rhs: Self) -> Self {
self.wrapping_rem(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_rem_euclid(self, rhs: Self) -> Self {
self.wrapping_rem_euclid(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_shl(self, rhs: ::core::primitive::u32) -> Self {
self.wrapping_shl(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_shr(self, rhs: ::core::primitive::u32) -> Self {
self.wrapping_shr(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_sub(self, rhs: Self) -> Self {
self.wrapping_sub(rhs)
}
}
$(#[$attr])?
unsafe impl ::multitype::Signed for $Ty {
#[inline(always)]
#[track_caller]
fn abs(self) -> Self {
self.abs()
}
#[inline(always)]
fn cast_unsigned(self) -> <Self as ::multitype::Integral>::Unsigned {
self as $Unsigned
}
#[inline(always)]
#[track_caller]
fn checked_abs(self) -> ::core::option::Option<Self> {
self.checked_abs()
}
#[inline(always)]
#[track_caller]
fn checked_add_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> ::core::option::Option<Self> {
self.checked_add_unsigned(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_sub_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> ::core::option::Option<Self> {
self.checked_sub_unsigned(rhs)
}
#[inline(always)]
#[track_caller]
fn is_negative(self) -> ::core::primitive::bool {
self.is_negative()
}
#[inline(always)]
#[track_caller]
fn is_positive(self) -> ::core::primitive::bool {
self.is_positive()
}
#[inline(always)]
#[track_caller]
fn overflowing_abs(self) -> (Self, ::core::primitive::bool) {
self.overflowing_abs()
}
#[inline(always)]
#[track_caller]
fn overflowing_add_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> (Self, ::core::primitive::bool) {
self.overflowing_add_unsigned(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_sub_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> (Self, ::core::primitive::bool) {
self.overflowing_sub_unsigned(rhs)
}
#[inline(always)]
#[track_caller]
fn signum(self) -> Self {
self.signum()
}
#[inline(always)]
#[track_caller]
fn saturating_abs(self) -> Self {
self.saturating_abs()
}
#[inline(always)]
#[track_caller]
fn saturating_add_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> Self {
self.saturating_add_unsigned(rhs)
}
#[inline(always)]
#[track_caller]
fn saturating_neg(self) -> Self {
self.saturating_neg()
}
#[inline(always)]
#[track_caller]
fn saturating_sub_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> Self {
self.saturating_sub_unsigned(rhs)
}
#[inline]
#[track_caller]
fn strict_abs(self) -> Self {
self.checked_abs().expect("attempt to negate with overflow")
}
#[inline]
#[track_caller]
fn strict_add_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> Self {
self.checked_add_unsigned(rhs).expect("attempt to add with overflow")
}
#[inline]
#[track_caller]
fn strict_sub_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> Self {
self.checked_sub_unsigned(rhs).expect("attempt to subtract with overflow")
}
#[inline(always)]
#[track_caller]
unsafe fn unchecked_neg(self) -> Self {
unsafe { self.checked_neg().unwrap_unchecked() }
}
#[inline(always)]
#[track_caller]
fn unsigned_abs(self) -> <Self as ::multitype::Integral>::Unsigned {
self.unsigned_abs()
}
#[inline(always)]
#[track_caller]
fn wrapping_abs(self) -> Self {
self.wrapping_abs()
}
#[inline(always)]
#[track_caller]
fn wrapping_add_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> Self {
self.wrapping_add_unsigned(rhs)
}
#[inline(always)]
#[track_caller]
fn wrapping_sub_unsigned(self, rhs: <Self as ::multitype::Integral>::Unsigned) -> Self {
self.wrapping_sub_unsigned(rhs)
}
}
)*};
}
impl_signed! {
i128 { Unsigned = u128 },
i16 { Unsigned = u16 },
i32 { Unsigned = u32 },
i64 { Unsigned = u64 },
i8 { Unsigned = u8 },
isize { Unsigned = usize },
}