>::Output;
/// Used for addition of signed integers; `C = P.cmp(N)`
/// Assumes `P = Self` is positive and `N` is negative
/// where `P` and `N` are both passed as unsigned integers
pub trait PrivateIntegerAdd {
type Output;
fn private_integer_add(self, _: C, _: N) -> Self::Output;
}
pub type PrivateIntegerAddOut =
>::Output;
pub trait PrivatePow {
type Output;
fn private_pow(self, _: Y, _: N) -> Self::Output;
}
pub type PrivatePowOut = >::Output;
/// Performs `Shl` on `Lhs` so that `SizeOf(Lhs) = SizeOf(Rhs)`
/// Fails if `SizeOf(Lhs) > SizeOf(Rhs)`
pub trait ShiftDiff {
type Output;
}
pub type ShiftDiffOut = >::Output;
/// Gives `SizeOf(Lhs) - SizeOf(Rhs)`
pub trait BitDiff {
type Output;
}
pub type BitDiffOut = >::Output;
/// Inverted unsigned numbers
pub trait InvertedUnsigned {
fn to_u64() -> u64;
}
impl InvertedUnsigned for InvertedUTerm {
#[inline]
fn to_u64() -> u64 {
0
}
}
impl InvertedUnsigned for InvertedUInt {
#[inline]
fn to_u64() -> u64 {
u64::from(B::to_u8()) | IU::to_u64() << 1
}
}
impl Invert for UTerm {
type Output = InvertedUTerm;
#[inline]
fn invert(self) -> Self::Output {
InvertedUTerm
}
}
impl Invert for UInt
where
U: PrivateInvert>,
{
type Output = PrivateInvertOut>;
#[inline]
fn invert(self) -> Self::Output {
self.msb.private_invert(InvertedUInt {
msb: InvertedUTerm,
lsb: self.lsb,
})
}
}
impl PrivateInvert for UTerm {
type Output = IU;
#[inline]
fn private_invert(self, rhs: IU) -> Self::Output {
rhs
}
}
impl PrivateInvert for UInt
where
U: PrivateInvert>,
{
type Output = PrivateInvertOut>;
#[inline]
fn private_invert(self, rhs: IU) -> Self::Output {
self.msb.private_invert(InvertedUInt {
msb: rhs,
lsb: self.lsb,
})
}
}
#[test]
fn test_inversion() {
type Test4 = ::Output;
type Test5 = ::Output;
type Test12 = ::Output;
type Test16 = ::Output;
assert_eq!(1, ::to_u64());
assert_eq!(5, ::to_u64());
assert_eq!(3, ::to_u64());
assert_eq!(1, ::to_u64());
}
impl Invert for InvertedUTerm {
type Output = UTerm;
#[inline]
fn invert(self) -> Self::Output {
UTerm
}
}
impl Invert for InvertedUInt
where
IU: PrivateInvert>,
{
type Output = >>::Output;
#[inline]
fn invert(self) -> Self::Output {
self.msb.private_invert(UInt {
msb: UTerm,
lsb: self.lsb,
})
}
}
impl PrivateInvert for InvertedUTerm {
type Output = U;
#[inline]
fn private_invert(self, rhs: U) -> Self::Output {
rhs
}
}
impl PrivateInvert for InvertedUInt
where
IU: PrivateInvert>,
{
type Output = >>::Output;
#[inline]
fn private_invert(self, rhs: U) -> Self::Output {
self.msb.private_invert(UInt {
msb: rhs,
lsb: self.lsb,
})
}
}
#[test]
fn test_double_inversion() {
type Test4 = <::Output as Invert>::Output;
type Test5 = <::Output as Invert>::Output;
type Test12 = <::Output as Invert>::Output;
type Test16 = <::Output as Invert>::Output;
assert_eq!(4, ::to_u64());
assert_eq!(5, ::to_u64());
assert_eq!(12, ::to_u64());
assert_eq!(16, ::to_u64());
}
impl TrimTrailingZeros for InvertedUTerm {
type Output = InvertedUTerm;
#[inline]
fn trim_trailing_zeros(self) -> Self::Output {
InvertedUTerm
}
}
impl TrimTrailingZeros for InvertedUInt {
type Output = Self;
#[inline]
fn trim_trailing_zeros(self) -> Self::Output {
self
}
}
impl TrimTrailingZeros for InvertedUInt
where
IU: TrimTrailingZeros,
{
type Output = ::Output;
#[inline]
fn trim_trailing_zeros(self) -> Self::Output {
self.msb.trim_trailing_zeros()
}
}
impl Trim for U
where
U: Invert,
::Output: TrimTrailingZeros,
<::Output as TrimTrailingZeros>::Output: Invert,
{
type Output = <<::Output as TrimTrailingZeros>::Output as Invert>::Output;
#[inline]
fn trim(self) -> Self::Output {
self.invert().trim_trailing_zeros().invert()
}
}
// Note: Trimming is tested when we do subtraction.
pub trait PrivateCmp {
type Output;
fn private_cmp(&self, _: &Rhs, _: SoFar) -> Self::Output;
}
pub type PrivateCmpOut = >::Output;
// Set Bit
pub trait PrivateSetBit {
type Output;
fn private_set_bit(self, _: I, _: B) -> Self::Output;
}
pub type PrivateSetBitOut = >::Output;
// Div
pub trait PrivateDiv {
type Quotient;
type Remainder;
fn private_div_quotient(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Quotient;
fn private_div_remainder(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Remainder;
}
pub type PrivateDivQuot = <() as PrivateDiv>::Quotient;
pub type PrivateDivRem = <() as PrivateDiv>::Remainder;
pub trait PrivateDivIf {
type Quotient;
type Remainder;
fn private_div_if_quotient(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Quotient;
fn private_div_if_remainder(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Remainder;
}
pub type PrivateDivIfQuot =
<() as PrivateDivIf>::Quotient;
pub type PrivateDivIfRem =
<() as PrivateDivIf>::Remainder;
// Div for signed ints
pub trait PrivateDivInt {
type Output;
fn private_div_int(self, _: C, _: Divisor) -> Self::Output;
}
pub type PrivateDivIntOut = >::Output;
pub trait PrivateRem {
type Output;
fn private_rem(self, _: URem, _: Divisor) -> Self::Output;
}
pub type PrivateRemOut = >::Output;
// min max
pub trait PrivateMin {
type Output;
fn private_min(self, rhs: Rhs) -> Self::Output;
}
pub type PrivateMinOut = >::Output;
pub trait PrivateMax {
type Output;
fn private_max(self, rhs: Rhs) -> Self::Output;
}
pub type PrivateMaxOut = >::Output;
// Comparisons
use crate::{Equal, False, Greater, Less, True};
pub trait IsLessPrivate {
type Output: Bit;
fn is_less_private(self, _: Rhs, _: Cmp) -> Self::Output;
}
impl IsLessPrivate for A {
type Output = True;
#[inline]
fn is_less_private(self, _: B, _: Less) -> Self::Output {
B1
}
}
impl IsLessPrivate for A {
type Output = False;
#[inline]
fn is_less_private(self, _: B, _: Equal) -> Self::Output {
B0
}
}
impl IsLessPrivate for A {
type Output = False;
#[inline]
fn is_less_private(self, _: B, _: Greater) -> Self::Output {
B0
}
}
pub trait IsEqualPrivate {
type Output: Bit;
fn is_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
}
impl IsEqualPrivate for A {
type Output = False;
#[inline]
fn is_equal_private(self, _: B, _: Less) -> Self::Output {
B0
}
}
impl IsEqualPrivate for A {
type Output = True;
#[inline]
fn is_equal_private(self, _: B, _: Equal) -> Self::Output {
B1
}
}
impl IsEqualPrivate for A {
type Output = False;
#[inline]
fn is_equal_private(self, _: B, _: Greater) -> Self::Output {
B0
}
}
pub trait IsGreaterPrivate {
type Output: Bit;
fn is_greater_private(self, _: Rhs, _: Cmp) -> Self::Output;
}
impl IsGreaterPrivate for A {
type Output = False;
#[inline]
fn is_greater_private(self, _: B, _: Less) -> Self::Output {
B0
}
}
impl IsGreaterPrivate for A {
type Output = False;
#[inline]
fn is_greater_private(self, _: B, _: Equal) -> Self::Output {
B0
}
}
impl IsGreaterPrivate for A {
type Output = True;
#[inline]
fn is_greater_private(self, _: B, _: Greater) -> Self::Output {
B1
}
}
pub trait IsLessOrEqualPrivate {
type Output: Bit;
fn is_less_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
}
impl IsLessOrEqualPrivate for A {
type Output = True;
#[inline]
fn is_less_or_equal_private(self, _: B, _: Less) -> Self::Output {
B1
}
}
impl IsLessOrEqualPrivate for A {
type Output = True;
#[inline]
fn is_less_or_equal_private(self, _: B, _: Equal) -> Self::Output {
B1
}
}
impl IsLessOrEqualPrivate for A {
type Output = False;
#[inline]
fn is_less_or_equal_private(self, _: B, _: Greater) -> Self::Output {
B0
}
}
pub trait IsNotEqualPrivate {
type Output: Bit;
fn is_not_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
}
impl IsNotEqualPrivate for A {
type Output = True;
#[inline]
fn is_not_equal_private(self, _: B, _: Less) -> Self::Output {
B1
}
}
impl IsNotEqualPrivate for A {
type Output = False;
#[inline]
fn is_not_equal_private(self, _: B, _: Equal) -> Self::Output {
B0
}
}
impl IsNotEqualPrivate for A {
type Output = True;
#[inline]
fn is_not_equal_private(self, _: B, _: Greater) -> Self::Output {
B1
}
}
pub trait IsGreaterOrEqualPrivate {
type Output: Bit;
fn is_greater_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
}
impl IsGreaterOrEqualPrivate for A {
type Output = False;
#[inline]
fn is_greater_or_equal_private(self, _: B, _: Less) -> Self::Output {
B0
}
}
impl IsGreaterOrEqualPrivate for A {
type Output = True;
#[inline]
fn is_greater_or_equal_private(self, _: B, _: Equal) -> Self::Output {
B1
}
}
impl IsGreaterOrEqualPrivate for A {
type Output = True;
#[inline]
fn is_greater_or_equal_private(self, _: B, _: Greater) -> Self::Output {
B1
}
}
pub trait PrivateSquareRoot {
type Output;
}
pub trait PrivateLogarithm2 {
type Output;
}