mod test;
use multitype::Integral;
pub unsafe trait Unsigned
where
Self:
Integral<Unsigned = Self, Signed: Integral<Unsigned = Self>>,
{
#[must_use]
fn bit_width(self) -> u32;
#[must_use]
fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool);
#[must_use]
fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);
#[must_use]
fn carrying_mul(self, rhs: Self, carry: Self) -> (Self::Unsigned, Self);
#[must_use]
fn carrying_mul_add(self, mul: Self, add: Self, carry: Self) -> (Self::Unsigned, Self);
#[must_use]
fn cast_signed(self) -> Self::Signed;
#[must_use]
fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
#[must_use]
fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
#[must_use]
fn checked_next_power_of_two(self) -> Option<Self>;
#[must_use]
fn checked_signed_diff(self, rhs: Self) -> Option<Self::Signed>;
#[must_use]
fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
#[must_use]
fn div_ceil(self, rhs: Self) -> Self;
#[must_use]
fn is_power_of_two(self) -> bool;
#[must_use]
fn next_multiple_of(self, rhs: Self) -> Self;
#[must_use]
fn next_power_of_two(self) -> Self;
#[must_use]
fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool);
#[must_use]
fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool);
#[must_use]
fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn strict_add_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn strict_sub_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
#[must_use]
fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self;
}
macro_rules! impl_unsigned {
{
$(
$(#[$attr:meta])?
$Ty:ty { Signed = $Signed:ty$(,)? }
),*$(,)?
} => {$(
$(#[$attr])?
unsafe impl ::multitype::Integral for $Ty {
type Signed = $Signed;
type Unsigned = Self;
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 {
(self & rhs) + ((self ^ rhs) >> 1)
}
#[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 {
0
}
}
#[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::Unsigned for $Ty {
#[inline]
fn bit_width(self) -> ::core::primitive::u32 {
Self::BITS - self.leading_zeros()
}
#[inline]
fn borrowing_sub(self, rhs: Self, borrow: ::core::primitive::bool) -> (Self, ::core::primitive::bool) {
let (tmp, carry0) = self.overflowing_sub(rhs);
let (low, carry1) = tmp.overflowing_sub(borrow.into());
let high = carry0 | carry1;
(low, high)
}
#[inline]
fn carrying_add(self, rhs: Self, carry: ::core::primitive::bool) -> (Self, ::core::primitive::bool) {
let (tmp, carry0) = self.overflowing_add(rhs);
let (low, carry1) = tmp.overflowing_add(carry.into());
let high = carry0 | carry1;
(low, high)
}
#[inline]
fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
::multitype::Unsigned::carrying_mul_add(self, rhs, carry, 0)
}
#[inline(always)]
fn carrying_mul_add(self, mul: Self, add: Self, carry: Self) -> (Self, Self) {
<Self as ::multitype::CarryingMulAdd>::carrying_mul_add(self, mul, add, carry)
}
#[expect(clippy::cast_possible_wrap)]
#[inline(always)]
fn cast_signed(self) -> <Self as ::multitype::Integral>::Signed {
self as <Self as ::multitype::Integral>::Signed
}
#[inline(always)]
#[track_caller]
fn checked_add_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> ::core::option::Option<Self> {
self.checked_add_signed(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_next_multiple_of(self, rhs: Self) -> ::core::option::Option<Self> {
self.checked_next_multiple_of(rhs)
}
#[inline(always)]
#[track_caller]
fn checked_next_power_of_two(self) -> ::core::option::Option<Self> {
self.checked_next_power_of_two()
}
#[inline]
fn checked_signed_diff(self, rhs: Self) -> Option<<Self as ::multitype::Integral>::Signed> {
#[expect(clippy::cast_possible_wrap)]
let result = self.wrapping_sub(rhs) as <Self as ::multitype::Integral>::Signed;
let overflow = (self >= rhs) & result.is_negative();
overflow.then_some(result)
}
#[inline]
fn checked_sub_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> ::core::option::Option<Self> {
let (result, overflow) = ::multitype::Unsigned::overflowing_sub_signed(self, rhs);
overflow.then_some(result)
}
#[inline(always)]
#[track_caller]
fn div_ceil(self, rhs: Self) -> Self {
self.div_ceil(rhs)
}
#[inline(always)]
#[track_caller]
fn is_power_of_two(self) -> ::core::primitive::bool {
self.is_power_of_two()
}
#[inline(always)]
#[track_caller]
fn next_power_of_two(self) -> Self {
self.next_power_of_two()
}
#[inline(always)]
#[track_caller]
fn next_multiple_of(self, rhs: Self) -> Self {
self.next_multiple_of(rhs)
}
#[inline(always)]
#[track_caller]
fn overflowing_add_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> (Self, ::core::primitive::bool) {
self.overflowing_add_signed(rhs)
}
#[inline]
fn overflowing_sub_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> (Self, ::core::primitive::bool) {
let (result, mut overflow) = ::multitype::Integral::overflowing_sub(self, rhs as Self);
overflow ^= rhs.is_negative();
(result, overflow)
}
#[inline(always)]
#[track_caller]
fn saturating_add_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> Self {
self.saturating_add_signed(rhs)
}
#[inline]
fn saturating_sub_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> Self {
let (result, overflow) = ::multitype::Unsigned::overflowing_sub_signed(self, rhs);
if !overflow {
result
} else if rhs.is_negative() {
Self::MAX
} else {
Self::MIN
}
}
#[inline]
#[track_caller]
fn strict_add_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> Self {
self.checked_add_signed(rhs).expect("attempt to add with overflow")
}
#[inline]
#[track_caller]
fn strict_sub_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> Self {
::multitype::Unsigned::checked_sub_signed(self, rhs).expect("attempt to subtract with overflow")
}
#[inline(always)]
#[track_caller]
fn wrapping_add_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> Self {
self.wrapping_add_signed(rhs)
}
#[inline]
fn wrapping_sub_signed(self, rhs: <Self as ::multitype::Integral>::Signed) -> Self {
self.wrapping_sub(rhs as Self)
}
}
)*};
}
impl_unsigned! {
u128 { Signed = i128 },
u16 { Signed = i16 },
u32 { Signed = i32 },
u64 { Signed = i64 },
u8 { Signed = i8 },
usize { Signed = isize },
}