use bytemuck::Pod;
use const_default::ConstDefault;
use crate::{Array, repr::ConvertEndian};
use core::{
fmt::{Binary, Debug, Display, LowerExp, LowerHex, Octal, UpperExp, UpperHex},
hash::Hash,
ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl,
ShlAssign, Shr, ShrAssign, Sub, SubAssign,
},
};
pub use self::{bits_op::BitsOp, cint::CInt};
#[cfg(feature = "varint")]
pub use self::varint::VarInt;
#[cfg(feature = "ranged-int")]
pub mod ranged;
pub trait MaybeZeroableInt: Copy + sealed::Sealed {
type Underlying: PrimaryInt;
const ZEROABLE: bool = true;
}
pub trait CalcFitted: sealed::Sealed {
#[cfg(feature = "varint")]
type VarIntBuf: Copy;
}
pub trait BasicInt:
'static
+ sealed::Sealed
+ Add<Output = Self>
+ AddAssign
+ BitAnd<Output = Self>
+ BitAndAssign
+ BitOr<Output = Self>
+ BitOrAssign
+ BitXor<Output = Self>
+ BitXorAssign
+ Default
+ Div<Output = Self>
+ DivAssign
+ Eq
+ Mul<Output = Self>
+ MulAssign
+ Not<Output = Self>
+ Ord
+ Rem<Output = Self>
+ RemAssign
+ Shl<u32, Output = Self>
+ ShlAssign<u32>
+ Shr<u32, Output = Self>
+ ShrAssign<u32>
+ Shl<usize, Output = Self>
+ ShlAssign<usize>
+ Shr<usize, Output = Self>
+ ShrAssign<usize>
+ Sub<Output = Self>
+ SubAssign
+ BitsOp
+ Binary
+ Copy
+ Debug
+ Display
+ Hash
+ Octal
+ UpperHex
+ LowerHex
+ LowerExp
+ UpperExp
+ Unpin
+ ConstDefault
{
const BITS: u32;
const MIN: Self;
const MAX: Self;
const ZERO: Self;
const ONE: Self;
const ALL_ONE: Self;
const SIGNED: bool;
type Primary: PrimaryInt<SignedPrimary = <Self::Signed as BasicInt>::Primary, UnsignedPrimary = <Self::Unsigned as BasicInt>::Primary, CalcFitted = Self::CalcFitted>;
type Signed: BasicSInt<Signed = Self::Signed, Unsigned = Self::Unsigned>;
type Unsigned: BasicUInt<Signed = Self::Signed, Unsigned = Self::Unsigned>;
type CalcFitted: PrimaryInt<CalcFitted = Self::CalcFitted> + CalcFitted;
fn abs_diff(self, other: Self) -> Self::Unsigned;
fn checked_add(self, other: Self) -> Option<Self>;
fn checked_div(self, other: Self) -> Option<Self>;
fn checked_div_euclid(self, other: Self) -> Option<Self>;
fn checked_ilog(self, base: Self) -> Option<u32>;
fn checked_ilog2(self) -> Option<u32>;
fn checked_ilog10(self) -> Option<u32>;
fn checked_mul(self, other: Self) -> Option<Self>;
fn checked_neg(self) -> Option<Self>;
fn checked_pow(self, exp: u32) -> Option<Self>;
fn checked_rem(self, other: Self) -> Option<Self>;
fn checked_rem_euclid(self, other: Self) -> Option<Self>;
fn checked_shl(self, shift: u32) -> Option<Self>;
fn checked_shr(self, shift: u32) -> Option<Self>;
fn checked_sub(self, other: Self) -> Option<Self>;
fn count_ones(self) -> u32;
fn count_zeros(self) -> u32;
fn div_euclid(self, other: Self) -> Self;
fn ilog(self, base: Self) -> u32;
fn ilog2(self) -> u32;
fn ilog10(self) -> u32;
fn leading_zeros(self) -> u32;
fn leading_ones(self) -> u32;
fn midpoint(self, other: Self) -> Self;
fn overflowing_add(self, other: Self) -> (Self, bool);
fn overflowing_div(self, other: Self) -> (Self, bool);
fn overflowing_div_euclid(self, other: Self) -> (Self, bool);
fn overflowing_mul(self, other: Self) -> (Self, bool);
fn overflowing_neg(self) -> (Self, bool);
fn overflowing_pow(self, exp: u32) -> (Self, bool);
fn overflowing_rem(self, other: Self) -> (Self, bool);
fn overflowing_rem_euclid(self, other: Self) -> (Self, bool);
fn overflowing_shl(self, shift: u32) -> (Self, bool);
fn overflowing_shr(self, shift: u32) -> (Self, bool);
fn overflowing_sub(self, other: Self) -> (Self, bool);
fn pow(self, exp: u32) -> Self;
fn rem_euclid(self, other: Self) -> Self;
fn reverse_bits(self) -> Self;
fn rotate_left(self, shift: u32) -> Self;
fn rotate_right(self, shift: u32) -> Self;
fn saturating_add(self, other: Self) -> Self;
fn saturating_div(self, other: Self) -> Self;
fn saturating_mul(self, other: Self) -> Self;
fn saturating_pow(self, exp: u32) -> Self;
fn saturating_sub(self, other: Self) -> Self;
fn trailing_ones(self) -> u32;
fn trailing_zeros(self) -> u32;
fn unbounded_shl(self, shift: u32) -> Self;
fn unbounded_shr(self, shift: u32) -> Self;
unsafe fn unchecked_add(self, other: Self) -> Self;
unsafe fn unchecked_mul(self, other: Self) -> Self;
unsafe fn unchecked_sub(self, other: Self) -> Self;
fn wrapping_add(self, other: Self) -> Self;
fn wrapping_div(self, other: Self) -> Self;
fn wrapping_div_euclid(self, other: Self) -> Self;
fn wrapping_mul(self, other: Self) -> Self;
fn wrapping_neg(self) -> Self;
fn wrapping_pow(self, exp: u32) -> Self;
fn wrapping_rem(self, other: Self) -> Self;
fn wrapping_rem_euclid(self, other: Self) -> Self;
fn wrapping_shl(self, shift: u32) -> Self;
fn wrapping_shr(self, shift: u32) -> Self;
fn wrapping_sub(self, other: Self) -> Self;
#[inline(always)]
fn is_zero(self) -> bool {
self == Self::ZERO
}
fn cast_as_primary(self) -> Self::Primary;
fn cast_from_primary(src: Self::Primary) -> Self;
unsafe fn unchecked_from_primary(src: Self::Primary) -> Self;
fn cast_as_signed(self) -> Self::Signed;
fn cast_from_signed(src: Self::Signed) -> Self;
fn cast_as_unsigned(self) -> Self::Unsigned;
fn cast_from_unsigned(src: Self::Unsigned) -> Self;
fn cast_as_calc(self) -> Self::CalcFitted;
fn cast_from_calc(src: Self::CalcFitted) -> Self;
#[inline(always)]
fn cast_from_bool(src: bool) -> Self {
if Self::BITS != 0 && src { if Self::SIGNED && Self::BITS == 1 { Self::MIN } else { Self::ONE } } else { Self::ZERO }
}
#[inline(always)]
fn cast_as<Tgt: BasicInt>(self) -> Tgt {
base_impl::cast_as(self)
}
#[inline(always)]
fn checked_cast_as<Tgt: BasicInt>(self) -> Option<Tgt> {
base_impl::checked_cast_as(self)
}
#[inline(always)]
fn is_multiple_of(self, other: Self) -> bool {
other.cast_as_primary() > Self::Primary::ZERO && self.cast_as_primary() % other.cast_as_primary() == Self::Primary::ZERO
}
}
pub trait BasicUInt: BasicInt<Unsigned = Self, CalcFitted = Self::UnsignedCalcFitted> {
type UnsignedCalcFitted: PrimaryUInt<UnsignedCalcFitted = Self::UnsignedCalcFitted> + CalcFitted;
fn cast_signed(self) -> Self::Signed;
fn checked_add_signed(self, other: Self::Signed) -> Option<Self>;
fn checked_next_multiple_of(self, other: Self) -> Option<Self>;
fn checked_next_power_of_two(self) -> Option<Self>;
fn div_ceil(self, other: Self) -> Self;
fn is_power_of_two(self) -> bool;
fn next_multiple_of(self, other: Self) -> Self;
fn next_power_of_two(self) -> Self;
fn overflowing_add_signed(self, other: Self::Signed) -> (Self, bool);
fn saturating_add_signed(self, other: Self::Signed) -> Self;
fn wrapping_add_signed(self, other: Self::Signed) -> Self;
}
pub trait BasicSInt: BasicInt<Signed = Self, CalcFitted = Self::SignedCalcFitted> + Neg<Output = Self> {
type SignedCalcFitted: PrimarySInt<SignedCalcFitted = Self::SignedCalcFitted> + CalcFitted;
fn abs(self) -> Self;
fn cast_unsigned(self) -> Self::Unsigned;
fn checked_abs(self) -> Option<Self>;
fn checked_add_unsigned(self, other: Self::Unsigned) -> Option<Self>;
fn checked_sub_unsigned(self, other: Self::Unsigned) -> Option<Self>;
fn is_negative(self) -> bool;
fn is_positive(self) -> bool;
fn overflowing_abs(self) -> (Self, bool);
fn overflowing_add_unsigned(self, other: Self::Unsigned) -> (Self, bool);
fn overflowing_sub_unsigned(self, other: Self::Unsigned) -> (Self, bool);
fn saturating_abs(self) -> Self;
fn saturating_add_unsigned(self, other: Self::Unsigned) -> Self;
fn saturating_neg(self) -> Self;
fn saturating_sub_unsigned(self, other: Self::Unsigned) -> Self;
fn signum(self) -> Self::Primary;
fn unsigned_abs(self) -> Self::Unsigned;
fn wrapping_abs(self) -> Self;
fn wrapping_add_unsigned(self, other: Self::Unsigned) -> Self;
fn wrapping_sub_unsigned(self, other: Self::Unsigned) -> Self;
}
pub trait PrimaryInt:
BasicInt<Primary = Self, Signed = Self::SignedPrimary, Unsigned = Self::UnsignedPrimary> + Pod + MaybeZeroableInt<Underlying = Self> + ConvertEndian
{
type BytesArray: Pod + Array<E = u8>;
type SignedPrimary: PrimarySInt<SignedPrimary = Self::SignedPrimary, UnsignedPrimary = Self::UnsignedPrimary>;
type UnsignedPrimary: PrimaryUInt<SignedPrimary = Self::SignedPrimary, UnsignedPrimary = Self::UnsignedPrimary>;
fn swap_bytes(self) -> Self;
fn from_be(src: Self) -> Self;
fn from_be_bytes(bytes: Self::BytesArray) -> Self;
fn from_le(src: Self) -> Self;
fn from_le_bytes(bytes: Self::BytesArray) -> Self;
fn from_ne_bytes(bytes: Self::BytesArray) -> Self;
fn to_be(self) -> Self;
fn to_be_bytes(self) -> Self::BytesArray;
fn to_le(self) -> Self;
fn to_le_bytes(self) -> Self::BytesArray;
fn to_ne_bytes(self) -> Self::BytesArray;
}
pub trait PrimaryUInt: PrimaryInt<UnsignedPrimary = Self> + BasicUInt {}
pub trait PrimarySInt: PrimaryInt<SignedPrimary = Self> + BasicSInt {}
mod base_impl;
mod bits_op;
mod cint;
#[cfg(feature = "varint")]
mod varint;
mod sealed {
pub trait Sealed {}
impl<T: super::PrimaryInt, const BITS: u32> Sealed for crate::bitint::BitInt<T, BITS> {}
}