use core::convert::Infallible;
use core::num::NonZero;
use crate::{
NonZeroPrimitiveInteger, NonZeroPrimitiveSigned, PrimitiveInteger, PrimitiveIntegerRef,
PrimitiveSigned,
};
pub trait PrimitiveUnsigned:
PrimitiveInteger
+ core::convert::From<u8>
+ core::convert::TryFrom<u8, Error = Infallible>
+ core::ops::Div<Self::NonZero, Output = Self>
+ core::ops::DivAssign<Self::NonZero>
+ core::ops::Rem<Self::NonZero, Output = Self>
+ core::ops::RemAssign<Self::NonZero>
{
type Signed: PrimitiveSigned;
fn abs_diff(self, other: Self) -> Self;
fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool);
fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);
fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self);
fn carrying_mul_add(self, rhs: Self, carry: Self, add: Self) -> (Self, Self);
fn cast_signed(self) -> Self::Signed;
fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
fn checked_next_power_of_two(self) -> Option<Self>;
fn checked_signed_diff(self, rhs: Self) -> Option<Self::Signed>;
fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
fn div_ceil(self, rhs: Self) -> Self;
fn is_multiple_of(self, rhs: Self) -> bool;
fn is_power_of_two(self) -> bool;
fn next_multiple_of(self, rhs: Self) -> Self;
fn next_power_of_two(self) -> Self;
fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool);
fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool);
fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;
fn strict_add_signed(self, rhs: Self::Signed) -> Self;
fn strict_sub_signed(self, rhs: Self::Signed) -> Self;
fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self;
}
pub trait PrimitiveUnsignedRef<T>: PrimitiveIntegerRef<T> {}
pub trait NonZeroPrimitiveUnsigned:
NonZeroPrimitiveInteger<Integer: PrimitiveUnsigned> + core::convert::From<NonZero<u8>>
{
type NonZeroSigned: NonZeroPrimitiveSigned;
fn cast_signed(self) -> Self::NonZeroSigned;
fn checked_add(self, other: Self::Integer) -> Option<Self>;
fn checked_next_power_of_two(self) -> Option<Self>;
fn div_ceil(self, rhs: Self) -> Self;
fn ilog10(self) -> u32;
fn ilog2(self) -> u32;
fn is_power_of_two(self) -> bool;
fn isqrt(self) -> Self;
fn midpoint(self, rhs: Self) -> Self;
fn saturating_add(self, other: Self::Integer) -> Self;
}
macro_rules! impl_unsigned {
($Unsigned:ident, $Signed:ty) => {
impl PrimitiveUnsigned for $Unsigned {
type Signed = $Signed;
forward! {
fn abs_diff(self, other: Self) -> Self;
fn borrowing_sub(self, rhs: Self, borrow: bool) -> (Self, bool);
fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool);
fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self);
fn carrying_mul_add(self, rhs: Self, carry: Self, add: Self) -> (Self, Self);
fn cast_signed(self) -> Self::Signed;
fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
fn checked_next_power_of_two(self) -> Option<Self>;
fn checked_signed_diff(self, rhs: Self) -> Option<Self::Signed>;
fn checked_sub_signed(self, rhs: Self::Signed) -> Option<Self>;
fn div_ceil(self, rhs: Self) -> Self;
fn is_multiple_of(self, rhs: Self) -> bool;
fn is_power_of_two(self) -> bool;
fn next_multiple_of(self, rhs: Self) -> Self;
fn next_power_of_two(self) -> Self;
fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool);
fn overflowing_sub_signed(self, rhs: Self::Signed) -> (Self, bool);
fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
fn saturating_sub_signed(self, rhs: Self::Signed) -> Self;
fn strict_add_signed(self, rhs: Self::Signed) -> Self;
fn strict_sub_signed(self, rhs: Self::Signed) -> Self;
fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
fn wrapping_sub_signed(self, rhs: Self::Signed) -> Self;
}
}
impl PrimitiveUnsignedRef<$Unsigned> for &$Unsigned {}
impl NonZeroPrimitiveUnsigned for NonZero<$Unsigned> {
type NonZeroSigned = NonZero<$Signed>;
forward! {
fn cast_signed(self) -> Self::NonZeroSigned;
fn checked_add(self, other: Self::Integer) -> Option<Self>;
fn checked_next_power_of_two(self) -> Option<Self>;
fn div_ceil(self, rhs: Self) -> Self;
fn ilog10(self) -> u32;
fn ilog2(self) -> u32;
fn is_power_of_two(self) -> bool;
fn isqrt(self) -> Self;
fn midpoint(self, rhs: Self) -> Self;
fn saturating_add(self, other: Self::Integer) -> Self;
}
}
};
}
impl_unsigned!(u8, i8);
impl_unsigned!(u16, i16);
impl_unsigned!(u32, i32);
impl_unsigned!(u64, i64);
impl_unsigned!(u128, i128);
impl_unsigned!(usize, isize);