use core::marker::PhantomData;
use core::ops::{BitAnd, BitOr, BitXor, Shl, Shr, Add, Sub, Mul, Div, Rem};
use {NonZero, Ord, Greater, Equal, Less, Cmp, Pow};
use bit::{Bit, B0, B1};
use private::{Trim, SizeOf, PrivateAnd, PrivateXor, PrivateSub, PrivateCmp, PrivateSizeOf,
ShiftDiff, PrivateDiv, PrivateDivFirstStep, PrivatePow, BitDiff};
use private::{TrimOut, SizeOfOut, PrivateAndOut, PrivateXorOut, PrivateSubOut, PrivateCmpOut,
PrivateSizeOfOut, PrivatePowOut, BitDiffOut};
use consts::{U0, U1};
use {Or, Shleft, Shright, Sum, Prod, Add1, Sub1, Square};
pub use marker_traits::Unsigned;
pub enum UTerm {}
impl_derivable!{UTerm}
impl Unsigned for UTerm {
#[inline]
fn to_u8() -> u8 {
0
}
#[inline]
fn to_u16() -> u16 {
0
}
#[inline]
fn to_u32() -> u32 {
0
}
#[inline]
fn to_u64() -> u64 {
0
}
#[inline]
fn to_usize() -> usize {
0
}
#[inline]
fn to_i8() -> i8 {
0
}
#[inline]
fn to_i16() -> i16 {
0
}
#[inline]
fn to_i32() -> i32 {
0
}
#[inline]
fn to_i64() -> i64 {
0
}
#[inline]
fn to_isize() -> isize {
0
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
pub struct UInt<U, B> {
_marker: PhantomData<(U, B)>,
}
impl<U: Unsigned, B: Bit> Unsigned for UInt<U, B> {
#[inline]
fn to_u8() -> u8 {
B::to_u8() | U::to_u8() << 1
}
#[inline]
fn to_u16() -> u16 {
B::to_u8() as u16 | U::to_u16() << 1
}
#[inline]
fn to_u32() -> u32 {
B::to_u8() as u32 | U::to_u32() << 1
}
#[inline]
fn to_u64() -> u64 {
B::to_u8() as u64 | U::to_u64() << 1
}
#[inline]
fn to_usize() -> usize {
B::to_u8() as usize | U::to_usize() << 1
}
#[inline]
fn to_i8() -> i8 {
B::to_u8() as i8 | U::to_i8() << 1
}
#[inline]
fn to_i16() -> i16 {
B::to_u8() as i16 | U::to_i16() << 1
}
#[inline]
fn to_i32() -> i32 {
B::to_u8() as i32 | U::to_i32() << 1
}
#[inline]
fn to_i64() -> i64 {
B::to_u8() as i64 | U::to_i64() << 1
}
#[inline]
fn to_isize() -> isize {
B::to_u8() as isize | U::to_isize() << 1
}
}
impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {}
macro_rules! test_uint_op {
($op:ident $Lhs:ident = $Answer:ident) => (
{
type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
assert_eq!(<$Answer as Unsigned>::to_u64(), <Test as Unsigned>::to_u64());
}
);
($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => (
{
type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
assert_eq!(<$Answer as Unsigned>::to_u64(), <Test as Unsigned>::to_u64());
}
);
}
impl SizeOf for UTerm {
type Output = U0;
}
impl<U: Unsigned, B: Bit> SizeOf for UInt<U, B> where UInt<U, B>: PrivateSizeOf
{
type Output = PrivateSizeOfOut<UInt<U, B>>;
}
impl PrivateSizeOf for UTerm {
type Output = U0;
}
impl<U: Unsigned, B: Bit> PrivateSizeOf for UInt<U, B>
where U: PrivateSizeOf,
PrivateSizeOfOut<U>: Add<B1>
{
type Output = Add1<PrivateSizeOfOut<U>>;
}
impl Add<B0> for UTerm {
type Output = UTerm;
fn add(self, _: B0) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Add<B0> for UInt<U, B> {
type Output = UInt<U, B>;
fn add(self, _: B0) -> Self::Output {
unreachable!()
}
}
impl Add<B1> for UTerm {
type Output = UInt<UTerm, B1>;
fn add(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned> Add<B1> for UInt<U, B0> {
type Output = UInt<U, B1>;
fn add(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned> Add<B1> for UInt<U, B1>
where U: Add<B1>,
Sum<U, B1>: Unsigned
{
type Output = UInt<Add1<U>, B0>;
fn add(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl Add<UTerm> for UTerm {
type Output = UTerm;
fn add(self, _: UTerm) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Add<UInt<U, B>> for UTerm {
type Output = UInt<U, B>;
fn add(self, _: UInt<U, B>) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Add<UTerm> for UInt<U, B> {
type Output = UInt<U, B>;
fn add(self, _: UTerm) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B0> where Ul: Add<Ur>
{
type Output = UInt<Sum<Ul, Ur>, B0>;
fn add(self, _: UInt<Ur, B0>) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B0> where Ul: Add<Ur>
{
type Output = UInt<Sum<Ul, Ur>, B1>;
fn add(self, _: UInt<Ur, B1>) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B1> where Ul: Add<Ur>
{
type Output = UInt<Sum<Ul, Ur>, B1>;
fn add(self, _: UInt<Ur, B0>) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B1>
where Ul: Add<Ur>,
Sum<Ul, Ur>: Add<B1>
{
type Output = UInt<Add1<Sum<Ul, Ur>>, B0>;
fn add(self, _: UInt<Ur, B1>) -> Self::Output {
unreachable!()
}
}
impl Sub<B0> for UTerm {
type Output = UTerm;
fn sub(self, _: B0) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Sub<B0> for UInt<U, B> {
type Output = UInt<U, B>;
fn sub(self, _: B0) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Sub<B1> for UInt<UInt<U, B>, B1> {
type Output = UInt<UInt<U, B>, B0>;
fn sub(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl Sub<B1> for UInt<UTerm, B1> {
type Output = UTerm;
fn sub(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned> Sub<B1> for UInt<U, B0>
where U: Sub<B1>,
Sub1<U>: Unsigned
{
type Output = UInt<Sub1<U>, B1>;
fn sub(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl Sub<UTerm> for UTerm {
type Output = UTerm;
fn sub(self, _: UTerm) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> Sub<Ur> for UInt<Ul, Bl>
where UInt<Ul, Bl>: PrivateSub<Ur>,
PrivateSubOut<UInt<Ul, Bl>, Ur>: Trim
{
type Output = TrimOut<PrivateSubOut<UInt<Ul, Bl>, Ur>>;
fn sub(self, _: Ur) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned> PrivateSub<UTerm> for U {
type Output = U;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B0> where Ul: PrivateSub<Ur>
{
type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B0>
where Ul: PrivateSub<Ur>,
PrivateSubOut<Ul, Ur>: Sub<B1>
{
type Output = UInt<Sub1<PrivateSubOut<Ul, Ur>>, B1>;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B1> where Ul: PrivateSub<Ur>
{
type Output = UInt<PrivateSubOut<Ul, Ur>, B1>;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B1> where Ul: PrivateSub<Ur>
{
type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
}
impl<U: Unsigned> PrivateAnd<U> for UTerm {
type Output = UTerm;
}
impl<B: Bit, U: Unsigned> PrivateAnd<UTerm> for UInt<U, B> {
type Output = UTerm;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B0> where Ul: PrivateAnd<Ur>
{
type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B0> where Ul: PrivateAnd<Ur>
{
type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B1> where Ul: PrivateAnd<Ur>
{
type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B1> where Ul: PrivateAnd<Ur>
{
type Output = UInt<PrivateAndOut<Ul, Ur>, B1>;
}
impl<Ur: Unsigned> BitAnd<Ur> for UTerm {
type Output = UTerm;
fn bitand(self, _: Ur) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitAnd<Ur> for UInt<Ul, Bl>
where UInt<Ul, Bl>: PrivateAnd<Ur>,
PrivateAndOut<UInt<Ul, Bl>, Ur>: Trim
{
type Output = TrimOut<PrivateAndOut<UInt<Ul, Bl>, Ur>>;
fn bitand(self, _: Ur) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned> BitOr<U> for UTerm {
type Output = U;
fn bitor(self, _: U) -> Self::Output {
unreachable!()
}
}
impl<B: Bit, U: Unsigned> BitOr<UTerm> for UInt<U, B> {
type Output = Self;
fn bitor(self, _: UTerm) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B0> where Ul: BitOr<Ur>
{
type Output = UInt<<Ul as BitOr<Ur>>::Output, B0>;
fn bitor(self, _: UInt<Ur, B0>) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B0> where Ul: BitOr<Ur>
{
type Output = UInt<Or<Ul, Ur>, B1>;
fn bitor(self, _: UInt<Ur, B1>) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B1> where Ul: BitOr<Ur>
{
type Output = UInt<Or<Ul, Ur>, B1>;
fn bitor(self, _: UInt<Ur, B0>) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B1> where Ul: BitOr<Ur>
{
type Output = UInt<Or<Ul, Ur>, B1>;
fn bitor(self, _: UInt<Ur, B1>) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned> PrivateXor<U> for UTerm {
type Output = U;
}
impl<B: Bit, U: Unsigned> PrivateXor<UTerm> for UInt<U, B> {
type Output = Self;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B0> where Ul: PrivateXor<Ur>
{
type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B0> where Ul: PrivateXor<Ur>
{
type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B1> where Ul: PrivateXor<Ur>
{
type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
}
impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B1> where Ul: PrivateXor<Ur>
{
type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
}
impl<Ur: Unsigned> BitXor<Ur> for UTerm {
type Output = Ur;
fn bitxor(self, _: Ur) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitXor<Ur> for UInt<Ul, Bl>
where UInt<Ul, Bl>: PrivateXor<Ur>,
PrivateXorOut<UInt<Ul, Bl>, Ur>: Trim
{
type Output = TrimOut<PrivateXorOut<UInt<Ul, Bl>, Ur>>;
fn bitxor(self, _: Ur) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned> Shl<U> for UTerm {
type Output = UTerm;
fn shl(self, _: U) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Shl<UTerm> for UInt<U, B> {
type Output = UInt<U, B>;
fn shl(self, _: UTerm) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Shl<B0> for UInt<U, B> {
type Output = UInt<U, B>;
fn shl(self, _: B0) -> Self::Output {
unreachable!()
}
}
impl Shl<B0> for UTerm {
type Output = UTerm;
fn shl(self, _: B0) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Shl<B1> for UInt<U, B> {
type Output = UInt<UInt<U, B>, B0>;
fn shl(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl Shl<B1> for UTerm {
type Output = UTerm;
fn shl(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shl<UInt<Ur, Br>> for UInt<U, B>
where UInt<Ur, Br>: Sub<B1>,
UInt<UInt<U, B>, B0>: Shl<Sub1<UInt<Ur, Br>>>
{
type Output = Shleft<UInt<UInt<U, B>, B0>, Sub1<UInt<Ur, Br>>>;
fn shl(self, _: UInt<Ur, Br>) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned> Shr<U> for UTerm {
type Output = UTerm;
fn shr(self, _: U) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Shr<UTerm> for UInt<U, B> {
type Output = UInt<U, B>;
fn shr(self, _: UTerm) -> Self::Output {
unreachable!()
}
}
impl Shr<B0> for UTerm {
type Output = UTerm;
fn shr(self, _: B0) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Shr<B0> for UInt<U, B> {
type Output = UInt<U, B>;
fn shr(self, _: B0) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Shr<B1> for UInt<U, B> {
type Output = U;
fn shr(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl Shr<B1> for UTerm {
type Output = UTerm;
fn shr(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shr<UInt<Ur, Br>> for UInt<U, B>
where UInt<Ur, Br>: Sub<B1>,
U: Shr<Sub1<UInt<Ur, Br>>>
{
type Output = Shright<U, Sub1<UInt<Ur, Br>>>;
fn shr(self, _: UInt<Ur, Br>) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Mul<B0> for UInt<U, B> {
type Output = UTerm;
fn mul(self, _: B0) -> Self::Output {
unreachable!()
}
}
impl<B: Bit> Mul<B> for UTerm {
type Output = UTerm;
fn mul(self, _: B) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Mul<B1> for UInt<U, B> {
type Output = UInt<U, B>;
fn mul(self, _: B1) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Mul<UTerm> for UInt<U, B> {
type Output = UTerm;
fn mul(self, _: UTerm) -> Self::Output {
unreachable!()
}
}
impl<U: Unsigned, B: Bit> Mul<UInt<U, B>> for UTerm {
type Output = UTerm;
fn mul(self, _: UInt<U, B>) -> Self::Output {
unreachable!()
}
}
impl Mul<UTerm> for UTerm {
type Output = UTerm;
fn mul(self, _: UTerm) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B0>
where Ul: Mul<UInt<Ur, B>>
{
type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
fn mul(self, _: UInt<Ur, B>) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B1>
where Ul: Mul<UInt<Ur, B>>,
UInt<Prod<Ul, UInt<Ur, B>>, B0>: Add<UInt<Ur, B>>
{
type Output = Sum<UInt<Prod<Ul, UInt<Ur, B>>, B0>, UInt<Ur, B>>;
fn mul(self, _: UInt<Ur, B>) -> Self::Output {
unreachable!()
}
}
impl Cmp<UTerm> for UTerm {
type Output = Equal;
}
impl<U: Unsigned, B: Bit> Cmp<UTerm> for UInt<U, B> {
type Output = Greater;
}
impl<U: Unsigned, B: Bit> Cmp<UInt<U, B>> for UTerm {
type Output = Less;
}
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Cmp<UInt<Ur, Br>> for UInt<Ul, Bl>
where UInt<Ul, Bl>: PrivateCmp<UInt<Ur, Br>, Equal>
{
type Output = PrivateCmpOut<UInt<Ul, Bl>, UInt<Ur, Br>, Equal>;
}
impl<Ul, Bl, Ur, Br, S> PrivateCmp<UInt<UInt<Ur, Br>, B0>, S> for UInt<UInt<Ul, Bl>, B0>
where Ul: Unsigned,
Bl: Bit,
Ur: Unsigned,
Br: Bit,
S: Ord,
UInt<Ul, Bl>: PrivateCmp<UInt<Ur, Br>, S>
{
type Output = PrivateCmpOut<UInt<Ul, Bl>, UInt<Ur, Br>, S>;
}
impl<Ul, Bl, Ur, Br, S> PrivateCmp<UInt<UInt<Ur, Br>, B1>, S> for UInt<UInt<Ul, Bl>, B1>
where Ul: Unsigned,
Bl: Bit,
Ur: Unsigned,
Br: Bit,
S: Ord,
UInt<Ul, Bl>: PrivateCmp<UInt<Ur, Br>, S>
{
type Output = PrivateCmpOut<UInt<Ul, Bl>, UInt<Ur, Br>, S>;
}
impl<Ul, Bl, Ur, Br, S> PrivateCmp<UInt<UInt<Ur, Br>, B1>, S> for UInt<UInt<Ul, Bl>, B0>
where Ul: Unsigned,
Bl: Bit,
Ur: Unsigned,
Br: Bit,
S: Ord,
UInt<Ul, Bl>: PrivateCmp<UInt<Ur, Br>, Less>
{
type Output = PrivateCmpOut<UInt<Ul, Bl>, UInt<Ur, Br>, Less>;
}
impl<Ul, Bl, Ur, Br, S> PrivateCmp<UInt<UInt<Ur, Br>, B0>, S> for UInt<UInt<Ul, Bl>, B1>
where Ul: Unsigned,
Bl: Bit,
Ur: Unsigned,
Br: Bit,
S: Ord,
UInt<Ul, Bl>: PrivateCmp<UInt<Ur, Br>, Greater>
{
type Output = PrivateCmpOut<UInt<Ul, Bl>, UInt<Ur, Br>, Greater>;
}
impl<Ul, Bl1, Bl2, Br, S> PrivateCmp<UInt<UTerm, Br>, S> for UInt<UInt<Ul, Bl2>, Bl1>
where Ul: Unsigned,
Bl1: Bit,
Bl2: Bit,
Br: Bit,
S: Ord
{
type Output = Greater;
}
impl<Bl, Ur, Br1, Br2, S> PrivateCmp<UInt<UInt<Ur, Br2>, Br1>, S> for UInt<UTerm, Bl>
where Bl: Bit,
Ur: Unsigned,
Br1: Bit,
Br2: Bit,
S: Ord
{
type Output = Less;
}
impl<S: Ord> PrivateCmp<UInt<UTerm, B0>, S> for UInt<UTerm, B0> {
type Output = S;
}
impl<S: Ord> PrivateCmp<UInt<UTerm, B1>, S> for UInt<UTerm, B1> {
type Output = S;
}
impl<S: Ord> PrivateCmp<UInt<UTerm, B1>, S> for UInt<UTerm, B0> {
type Output = Less;
}
impl<S: Ord> PrivateCmp<UInt<UTerm, B0>, S> for UInt<UTerm, B1> {
type Output = Greater;
}
macro_rules! test_ord {
($Lhs:ident > $Rhs:ident) => (
{
type Test = <$Lhs as Cmp<$Rhs>>::Output;
assert_eq!(::core::cmp::Ordering::Greater, <Test as Ord>::to_ordering());
}
);
($Lhs:ident == $Rhs:ident) => (
{
type Test = <$Lhs as Cmp<$Rhs>>::Output;
assert_eq!(::core::cmp::Ordering::Equal, <Test as Ord>::to_ordering());
}
);
($Lhs:ident < $Rhs:ident) => (
{
type Test = <$Lhs as Cmp<$Rhs>>::Output;
assert_eq!(::core::cmp::Ordering::Less, <Test as Ord>::to_ordering());
}
);
}
impl<Ul, Bl, Ur, Br> BitDiff<UInt<Ur, Br>> for UInt<Ul, Bl>
where Ul: Unsigned,
Bl: Bit,
Ur: Unsigned,
Br: Bit,
Ul: BitDiff<Ur>
{
type Output = BitDiffOut<Ul, Ur>;
}
impl<Ul> BitDiff<UTerm> for Ul where Ul: Unsigned + SizeOf
{
type Output = SizeOfOut<Ul>;
}
impl<Ul: Unsigned, Ur: Unsigned> ShiftDiff<Ur> for Ul
where Ur: BitDiff<Ul>,
Ul: Shl<BitDiffOut<Ur, Ul>>
{
type Output = Shleft<Ul, BitDiffOut<Ur, Ul>>;
}
impl<X: Unsigned, N: Unsigned> Pow<N> for X where X: PrivatePow<U1, N>
{
type Output = PrivatePowOut<X, U1, N>;
}
impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U0> for X {
type Output = Y;
}
impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U1> for X where X: Mul<Y>
{
type Output = Prod<X, Y>;
}
impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B0>> for X
where X: Mul,
Square<X>: PrivatePow<Y, UInt<U, B>>
{
type Output = PrivatePowOut<Square<X>, Y, UInt<U, B>>;
}
impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B1>> for X
where X: Mul + Mul<Y>,
Square<X>: PrivatePow<Prod<X, Y>, UInt<U, B>>
{
type Output = PrivatePowOut<Square<X>, Prod<X, Y>, UInt<U, B>>;
}
impl<Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UTerm {
type Output = UTerm;
fn div(self, _: UInt<Ur, Br>) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UInt<Ul, Bl>
where UInt<Ul, Bl>: Cmp<UInt<Ur, Br>>,
UInt<Ul, Bl>: PrivateDivFirstStep<<UInt<Ul, Bl> as Cmp<UInt<Ur, Br>>>::Output,
UInt<Ur, Br>>
{
type Output = <UInt<Ul, Bl> as PrivateDivFirstStep<
<UInt<Ul, Bl> as Cmp<UInt<Ur, Br>>>::Output,
UInt<Ur, Br>
>>::Quotient;
fn div(self, _: UInt<Ur, Br>) -> Self::Output { unreachable!() }
}
impl<Divisor: Unsigned, Numerator: Unsigned> PrivateDivFirstStep<Less, Divisor> for Numerator {
type Quotient = U0;
type Remainder = Numerator;
}
impl<Divisor: Unsigned, Numerator: Unsigned> PrivateDivFirstStep<Equal, Divisor> for Numerator {
type Quotient = U1;
type Remainder = U0;
}
impl<Divisor: Unsigned, Numerator: Unsigned> PrivateDivFirstStep<Greater, Divisor> for Numerator
where Numerator: BitDiff<Divisor> + Cmp<<Divisor as Shl<<Numerator as BitDiff<Divisor>>::Output>>::Output>,
Divisor: Shl<<Numerator as BitDiff<Divisor>>::Output>,
Numerator: PrivateDiv<
<Numerator as Cmp<<Divisor as ShiftDiff<Numerator>>::Output>>::Output,
<Numerator as BitDiff<Divisor>>::Output,
U0,
<Divisor as ShiftDiff<Numerator>>::Output
>
{
type Quotient = <Numerator as PrivateDiv<
<Numerator as Cmp<<Divisor as ShiftDiff<Numerator>>::Output>>::Output,
<Numerator as BitDiff<Divisor>>::Output, U0, <Divisor as ShiftDiff<Numerator>>::Output >>::Quotient;
type Remainder = <Numerator as PrivateDiv<
<Numerator as Cmp<<Divisor as ShiftDiff<Numerator>>::Output>>::Output,
<Numerator as BitDiff<Divisor>>::Output, U0, <Divisor as ShiftDiff<Numerator>>::Output >>::Remainder;
}
impl<Q, Divisor, Remainder> PrivateDiv<Less, U0, Q, Divisor> for Remainder
where Q: Unsigned,
Divisor: Unsigned,
Remainder: Unsigned
{
type Quotient = Q;
type Remainder = Remainder;
}
impl<Q, Divisor, Remainder> PrivateDiv<Equal, U0, Q, Divisor> for Remainder
where Q: Unsigned,
Divisor: Unsigned,
Remainder: Unsigned,
Q: Add<U1>
{
type Quotient = <Q as Add<U1>>::Output;
type Remainder = U0;
}
impl<Q, Divisor, Remainder> PrivateDiv<Greater, U0, Q, Divisor> for Remainder
where Q: Unsigned,
Divisor: Unsigned,
Remainder: Unsigned,
Q: Add<U1>,
Remainder: Sub<Divisor>
{
type Quotient = <Q as Add<U1>>::Output;
type Remainder = <Remainder as Sub<Divisor>>::Output;
}
impl<Ui, Bi, Q, Divisor, Remainder> PrivateDiv<Equal, UInt<Ui, Bi>, Q, Divisor> for Remainder
where Ui: Unsigned,
Bi: Bit,
Q: Unsigned,
Divisor: Unsigned,
Remainder: Unsigned,
U1: Shl<UInt<Ui, Bi>>,
Q: Add<<U1 as Shl<UInt<Ui, Bi>>>::Output>
{
type Quotient = <Q as Add<<U1 as Shl<UInt<Ui, Bi>>>::Output>>::Output;
type Remainder = U0;
}
impl<Ui, Bi, Q, Divisor, Remainder> PrivateDiv<Less, UInt<Ui, Bi>, Q, Divisor> for Remainder
where Ui: Unsigned, Bi: Bit, Q: Unsigned, Divisor: Unsigned, Remainder: Unsigned,
Divisor: Shr<B1>,
Remainder: Cmp<<Divisor as Shr<B1>>::Output>,
UInt<Ui, Bi>: Sub<U1>,
Remainder: PrivateDiv<
<Remainder as Cmp<<Divisor as Shr<B1>>::Output>>::Output,
<UInt<Ui, Bi> as Sub<U1>>::Output,
Q,
<Divisor as Shr<B1>>::Output
>
{
type Quotient = <Remainder as PrivateDiv<
<Remainder as Cmp<<Divisor as Shr<B1>>::Output>>::Output, <UInt<Ui, Bi> as Sub<U1>>::Output,
Q,
<Divisor as Shr<B1>>::Output
>>::Quotient;
type Remainder = <Remainder as PrivateDiv<
<Remainder as Cmp<<Divisor as Shr<B1>>::Output>>::Output,
<UInt<Ui, Bi> as Sub<U1>>::Output,
Q,
<Divisor as Shr<B1>>::Output
>>::Remainder;
}
impl<Ui, Bi, Q, Divisor, Remainder> PrivateDiv<Greater, UInt<Ui, Bi>, Q, Divisor> for Remainder
where Ui: Unsigned, Bi: Bit, Q: Unsigned, Divisor: Unsigned, Remainder: Unsigned,
Divisor: Shr<B1>,
Remainder: Sub<Divisor>,
<Remainder as Sub<Divisor>>::Output: Cmp<<Divisor as Shr<B1>>::Output>,
UInt<Ui, Bi>: Sub<U1>,
U1: Shl<UInt<Ui, Bi>>,
Q: Add<<U1 as Shl<UInt<Ui, Bi>>>::Output>,
<Remainder as Sub<Divisor>>::Output: PrivateDiv<
<<Remainder as Sub<Divisor>>::Output as Cmp<<Divisor as Shr<B1>>::Output>>::Output,
<UInt<Ui, Bi> as Sub<U1>>::Output,
<Q as Add<<U1 as Shl<UInt<Ui, Bi>>>::Output>>::Output,
<Divisor as Shr<B1>>::Output
>
{
type Quotient = <<Remainder as Sub<Divisor>>::Output as PrivateDiv<
<<Remainder as Sub<Divisor>>::Output as Cmp<<Divisor as Shr<B1>>::Output>>::Output,
<UInt<Ui, Bi> as Sub<U1>>::Output,
<Q as Add<<U1 as Shl<UInt<Ui, Bi>>>::Output>>::Output,
<Divisor as Shr<B1>>::Output
>>::Quotient;
type Remainder = <<Remainder as Sub<Divisor>>::Output as PrivateDiv<
<<Remainder as Sub<Divisor>>::Output as Cmp<<Divisor as Shr<B1>>::Output>>::Output,
<UInt<Ui, Bi> as Sub<U1>>::Output,
<Q as Add<<U1 as Shl<UInt<Ui, Bi>>>::Output>>::Output,
<Divisor as Shr<B1>>::Output
>>::Remainder;
}
impl<Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UTerm {
type Output = UTerm;
fn rem(self, _: UInt<Ur, Br>) -> Self::Output {
unreachable!()
}
}
impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UInt<Ul, Bl>
where UInt<Ul, Bl>: Cmp<UInt<Ur, Br>>,
UInt<Ul, Bl>: PrivateDivFirstStep<<UInt<Ul, Bl> as Cmp<UInt<Ur, Br>>>::Output,
UInt<Ur, Br>>
{
type Output = <UInt<Ul, Bl> as PrivateDivFirstStep<
<UInt<Ul, Bl> as Cmp<UInt<Ur, Br>>>::Output,
UInt<Ur, Br>
>>::Remainder;
fn rem(self, _: UInt<Ur, Br>) -> Self::Output { unreachable!() }
}