use core::ops;
mod specialized_div_rem;
pub mod addsub;
pub mod leading_zeros;
pub mod mul;
pub mod sdiv;
pub mod shift;
pub mod udiv;
pub use self::leading_zeros::__clzsi2;
#[doc(hidden)]
pub trait Int:
Copy
+ PartialEq
+ PartialOrd
+ ops::AddAssign
+ ops::BitAndAssign
+ ops::BitOrAssign
+ ops::BitXorAssign
+ ops::ShlAssign<i32>
+ ops::ShrAssign<u32>
+ ops::Add<Output = Self>
+ ops::Sub<Output = Self>
+ ops::Div<Output = Self>
+ ops::Shl<u32, Output = Self>
+ ops::Shr<u32, Output = Self>
+ ops::BitOr<Output = Self>
+ ops::BitXor<Output = Self>
+ ops::BitAnd<Output = Self>
+ ops::Not<Output = Self>
{
type OtherSign: Int;
type UnsignedInt: Int;
const BITS: u32;
const ZERO: Self;
const ONE: Self;
const MIN: Self;
const FUZZ_LENGTHS: [u8; 20];
const FUZZ_NUM: usize;
fn extract_sign(self) -> (bool, Self::UnsignedInt);
fn unsigned(self) -> Self::UnsignedInt;
fn from_unsigned(unsigned: Self::UnsignedInt) -> Self;
fn from_bool(b: bool) -> Self;
fn logical_shr(self, other: u32) -> Self;
fn abs_diff(self, other: Self) -> Self::UnsignedInt;
fn is_zero(self) -> bool;
fn max_value() -> Self;
fn min_value() -> Self;
fn wrapping_neg(self) -> Self;
fn wrapping_add(self, other: Self) -> Self;
fn wrapping_mul(self, other: Self) -> Self;
fn wrapping_sub(self, other: Self) -> Self;
fn wrapping_shl(self, other: u32) -> Self;
fn wrapping_shr(self, other: u32) -> Self;
fn rotate_left(self, other: u32) -> Self;
fn overflowing_add(self, other: Self) -> (Self, bool);
fn aborting_div(self, other: Self) -> Self;
fn aborting_rem(self, other: Self) -> Self;
fn leading_zeros(self) -> u32;
fn count_ones(self) -> u32;
}
fn unwrap<T>(t: Option<T>) -> T {
match t {
Some(t) => t,
None => ::abort(),
}
}
macro_rules! int_impl_common {
($ty:ty, $bits:expr) => {
const BITS: u32 = $bits;
const ZERO: Self = 0;
const ONE: Self = 1;
const MIN: Self = <Self>::MIN;
const FUZZ_LENGTHS: [u8; 20] = {
let bits = <Self as Int>::BITS;
let mut v = [0u8; 20];
v[0] = 0;
v[1] = 1;
v[2] = 2; let mut i = 3;
let mut l = 8;
loop {
if l >= ((bits / 2) as u8) {
break;
}
v[i] = l - 1;
i += 1;
v[i] = l;
i += 1;
l *= 2;
}
if bits != 8 {
v[i] = ((bits / 2) - 1) as u8;
i += 1;
}
let mid = i;
let mut j = 1;
loop {
v[i] = (bits as u8) - (v[mid - j]) - 1;
if j == mid {
break;
}
i += 1;
j += 1;
}
v
};
const FUZZ_NUM: usize = {
let log2 = (<Self as Int>::BITS - 1).count_ones() as usize;
if log2 == 3 {
6
} else {
8 + (4 * (log2 - 4))
}
};
fn from_bool(b: bool) -> Self {
b as $ty
}
fn logical_shr(self, other: u32) -> Self {
Self::from_unsigned(self.unsigned().wrapping_shr(other))
}
fn is_zero(self) -> bool {
self == Self::ZERO
}
fn max_value() -> Self {
<Self>::max_value()
}
fn min_value() -> Self {
<Self>::min_value()
}
fn wrapping_neg(self) -> Self {
<Self>::wrapping_neg(self)
}
fn wrapping_add(self, other: Self) -> Self {
<Self>::wrapping_add(self, other)
}
fn wrapping_mul(self, other: Self) -> Self {
<Self>::wrapping_mul(self, other)
}
fn wrapping_sub(self, other: Self) -> Self {
<Self>::wrapping_sub(self, other)
}
fn wrapping_shl(self, other: u32) -> Self {
<Self>::wrapping_shl(self, other)
}
fn wrapping_shr(self, other: u32) -> Self {
<Self>::wrapping_shr(self, other)
}
fn rotate_left(self, other: u32) -> Self {
<Self>::rotate_left(self, other)
}
fn overflowing_add(self, other: Self) -> (Self, bool) {
<Self>::overflowing_add(self, other)
}
fn aborting_div(self, other: Self) -> Self {
unwrap(<Self>::checked_div(self, other))
}
fn aborting_rem(self, other: Self) -> Self {
unwrap(<Self>::checked_rem(self, other))
}
fn leading_zeros(self) -> u32 {
<Self>::leading_zeros(self)
}
fn count_ones(self) -> u32 {
<Self>::count_ones(self)
}
};
}
macro_rules! int_impl {
($ity:ty, $uty:ty, $bits:expr) => {
impl Int for $uty {
type OtherSign = $ity;
type UnsignedInt = $uty;
fn extract_sign(self) -> (bool, $uty) {
(false, self)
}
fn unsigned(self) -> $uty {
self
}
fn from_unsigned(me: $uty) -> Self {
me
}
fn abs_diff(self, other: Self) -> Self {
(self.wrapping_sub(other) as $ity).wrapping_abs() as $uty
}
int_impl_common!($uty, $bits);
}
impl Int for $ity {
type OtherSign = $uty;
type UnsignedInt = $uty;
fn extract_sign(self) -> (bool, $uty) {
if self < 0 {
(true, (!(self as $uty)).wrapping_add(1))
} else {
(false, self as $uty)
}
}
fn unsigned(self) -> $uty {
self as $uty
}
fn from_unsigned(me: $uty) -> Self {
me as $ity
}
fn abs_diff(self, other: Self) -> $uty {
self.wrapping_sub(other).wrapping_abs() as $uty
}
int_impl_common!($ity, $bits);
}
};
}
int_impl!(isize, usize, usize::MAX.count_ones());
int_impl!(i8, u8, 8);
int_impl!(i16, u16, 16);
int_impl!(i32, u32, 32);
int_impl!(i64, u64, 64);
int_impl!(i128, u128, 128);
#[doc(hidden)]
pub trait DInt: Int {
type H: HInt<D = Self> + Int;
fn lo(self) -> Self::H;
fn hi(self) -> Self::H;
fn lo_hi(self) -> (Self::H, Self::H);
fn from_lo_hi(lo: Self::H, hi: Self::H) -> Self;
}
#[doc(hidden)]
pub trait HInt: Int {
type D: DInt<H = Self> + Int;
fn widen(self) -> Self::D;
fn zero_widen(self) -> Self::D;
fn widen_hi(self) -> Self::D;
fn zero_widen_mul(self, rhs: Self) -> Self::D;
fn widen_mul(self, rhs: Self) -> Self::D;
}
macro_rules! impl_d_int {
($($X:ident $D:ident),*) => {
$(
impl DInt for $D {
type H = $X;
fn lo(self) -> Self::H {
self as $X
}
fn hi(self) -> Self::H {
(self >> <$X as Int>::BITS) as $X
}
fn lo_hi(self) -> (Self::H, Self::H) {
(self.lo(), self.hi())
}
fn from_lo_hi(lo: Self::H, hi: Self::H) -> Self {
lo.zero_widen() | hi.widen_hi()
}
}
)*
};
}
macro_rules! impl_h_int {
($($H:ident $uH:ident $X:ident),*) => {
$(
impl HInt for $H {
type D = $X;
fn widen(self) -> Self::D {
self as $X
}
fn zero_widen(self) -> Self::D {
(self as $uH) as $X
}
fn widen_hi(self) -> Self::D {
(self as $X) << <$H as Int>::BITS
}
fn zero_widen_mul(self, rhs: Self) -> Self::D {
self.zero_widen().wrapping_mul(rhs.zero_widen())
}
fn widen_mul(self, rhs: Self) -> Self::D {
self.widen().wrapping_mul(rhs.widen())
}
}
)*
};
}
impl_d_int!(u8 u16, u16 u32, u32 u64, u64 u128, i8 i16, i16 i32, i32 i64, i64 i128);
impl_h_int!(
u8 u8 u16,
u16 u16 u32,
u32 u32 u64,
u64 u64 u128,
i8 u8 i16,
i16 u16 i32,
i32 u32 i64,
i64 u64 i128
);
pub(crate) trait CastInto<T: Copy>: Copy {
fn cast(self) -> T;
}
macro_rules! cast_into {
($ty:ty) => {
cast_into!($ty; usize, isize, u32, i32, u64, i64, u128, i128);
};
($ty:ty; $($into:ty),*) => {$(
impl CastInto<$into> for $ty {
fn cast(self) -> $into {
self as $into
}
}
)*};
}
cast_into!(u32);
cast_into!(i32);
cast_into!(u64);
cast_into!(i64);
cast_into!(u128);
cast_into!(i128);