//! **Ignore me!** This module is for things that are conceptually private but that must //! be made public for typenum to work correctly. //! //! Unless you are working on typenum itself, **there is no need to view anything here**. //! //! Certainly don't implement any of the traits here for anything. //! //! //! Just look away. //! //! //! Loooooooooooooooooooooooooooooooooook awaaaaaaaaaaaayyyyyyyyyyyyyyyyyyyyyyyyyyyyy... //! //! //! If you do manage to find something of use in here, please let me know. If you can make a //! compelling case, it may be moved out of __private. //! //! Note: Aliases for private type operators will all be named simply that operator followed //! by an abbreviated name of its associated type. #![doc(hidden)] use crate::{ bit::{Bit, B0, B1}, uint::{UInt, UTerm, Unsigned}, }; /// A marker for restricting a method on a public trait to internal use only. pub(crate) enum Internal {} pub trait InternalMarker {} impl InternalMarker for Internal {} /// Convenience trait. Calls `Invert` -> `TrimTrailingZeros` -> `Invert` pub trait Trim { type Output; fn trim(self) -> Self::Output; } pub type TrimOut = ::Output; /// Gets rid of all zeros until it hits a one. // ONLY IMPLEMENT FOR INVERTED NUMBERS! pub trait TrimTrailingZeros { type Output; fn trim_trailing_zeros(self) -> Self::Output; } pub type TrimTrailingZerosOut = ::Output; /// Converts between standard numbers and inverted ones that have the most significant /// digit on the outside. pub trait Invert { type Output; fn invert(self) -> Self::Output; } pub type InvertOut = ::Output; /// Doubly private! Called by invert to make the magic happen once its done the first step. /// The Rhs is what we've got so far. pub trait PrivateInvert { type Output; fn private_invert(self, rhs: Rhs) -> Self::Output; } pub type PrivateInvertOut = >::Output; /// Terminating character for `InvertedUInt`s pub struct InvertedUTerm; /// Inverted `UInt` (has most significant digit on the outside) pub struct InvertedUInt { msb: IU, lsb: B, } /// Does the real anding for `UInt`s; `And` just calls this and then `Trim`. pub trait PrivateAnd { type Output; fn private_and(self, rhs: Rhs) -> Self::Output; } pub type PrivateAndOut = >::Output; /// Does the real xoring for `UInt`s; `Xor` just calls this and then `Trim`. pub trait PrivateXor { type Output; fn private_xor(self, rhs: Rhs) -> Self::Output; } pub type PrivateXorOut = >::Output; /// Does the real subtraction for `UInt`s; `Sub` just calls this and then `Trim`. pub trait PrivateSub { type Output; fn private_sub(self, rhs: Rhs) -> Self::Output; } pub type PrivateSubOut = >::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; }