typenum/
uint.rs

1//! Type-level unsigned integers.
2//!
3//!
4//! **Type operators** implemented:
5//!
6//! From `::core::ops`: `BitAnd`, `BitOr`, `BitXor`, `Shl`, `Shr`, `Add`, `Sub`,
7//!                 `Mul`, `Div`, and `Rem`.
8//! From `typenum`: `Same`, `Cmp`, and `Pow`.
9//!
10//! Rather than directly using the structs defined in this module, it is recommended that
11//! you import and use the relevant aliases from the [consts](../consts/index.html) module.
12//!
13//! # Example
14//! ```rust
15//! use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub};
16//! use typenum::{Unsigned, U1, U2, U3, U4};
17//!
18//! assert_eq!(<U3 as BitAnd<U2>>::Output::to_u32(), 2);
19//! assert_eq!(<U3 as BitOr<U4>>::Output::to_u32(), 7);
20//! assert_eq!(<U3 as BitXor<U2>>::Output::to_u32(), 1);
21//! assert_eq!(<U3 as Shl<U1>>::Output::to_u32(), 6);
22//! assert_eq!(<U3 as Shr<U1>>::Output::to_u32(), 1);
23//! assert_eq!(<U3 as Add<U2>>::Output::to_u32(), 5);
24//! assert_eq!(<U3 as Sub<U2>>::Output::to_u32(), 1);
25//! assert_eq!(<U3 as Mul<U2>>::Output::to_u32(), 6);
26//! assert_eq!(<U3 as Div<U2>>::Output::to_u32(), 1);
27//! assert_eq!(<U3 as Rem<U2>>::Output::to_u32(), 1);
28//! ```
29
30use crate::{
31    bit::{Bit, B0, B1},
32    consts::{U0, U1},
33    private::{
34        BitDiff, BitDiffOut, Internal, InternalMarker, PrivateAnd, PrivateAndOut, PrivateCmp,
35        PrivateCmpOut, PrivateLogarithm2, PrivatePow, PrivatePowOut, PrivateSquareRoot, PrivateSub,
36        PrivateSubOut, PrivateXor, PrivateXorOut, Trim, TrimOut,
37    },
38    Add1, Cmp, Double, Equal, Gcd, Gcf, GrEq, Greater, IsGreaterOrEqual, Len, Length, Less, Log2,
39    Logarithm2, Maximum, Minimum, NonZero, Or, Ord, Pow, Prod, Shleft, Shright, Sqrt, Square,
40    SquareRoot, Sub1, Sum, ToInt, Zero,
41};
42use core::ops::{Add, BitAnd, BitOr, BitXor, Mul, Shl, Shr, Sub};
43
44pub use crate::marker_traits::{PowerOfTwo, Unsigned};
45
46/// The terminating type for `UInt`; it always comes after the most significant
47/// bit. `UTerm` by itself represents zero, which is aliased to `U0`.
48#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
49#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
50pub struct UTerm;
51
52impl UTerm {
53    /// Instantiates a singleton representing this unsigned integer.
54    #[inline]
55    pub fn new() -> UTerm {
56        UTerm
57    }
58}
59
60impl Unsigned for UTerm {
61    const U8: u8 = 0;
62    const U16: u16 = 0;
63    const U32: u32 = 0;
64    const U64: u64 = 0;
65    #[cfg(feature = "i128")]
66    const U128: u128 = 0;
67    const USIZE: usize = 0;
68
69    const I8: i8 = 0;
70    const I16: i16 = 0;
71    const I32: i32 = 0;
72    const I64: i64 = 0;
73    #[cfg(feature = "i128")]
74    const I128: i128 = 0;
75    const ISIZE: isize = 0;
76
77    #[inline]
78    fn to_u8() -> u8 {
79        0
80    }
81    #[inline]
82    fn to_u16() -> u16 {
83        0
84    }
85    #[inline]
86    fn to_u32() -> u32 {
87        0
88    }
89    #[inline]
90    fn to_u64() -> u64 {
91        0
92    }
93    #[cfg(feature = "i128")]
94    #[inline]
95    fn to_u128() -> u128 {
96        0
97    }
98    #[inline]
99    fn to_usize() -> usize {
100        0
101    }
102
103    #[inline]
104    fn to_i8() -> i8 {
105        0
106    }
107    #[inline]
108    fn to_i16() -> i16 {
109        0
110    }
111    #[inline]
112    fn to_i32() -> i32 {
113        0
114    }
115    #[inline]
116    fn to_i64() -> i64 {
117        0
118    }
119    #[cfg(feature = "i128")]
120    #[inline]
121    fn to_i128() -> i128 {
122        0
123    }
124    #[inline]
125    fn to_isize() -> isize {
126        0
127    }
128}
129
130/// `UInt` is defined recursively, where `B` is the least significant bit and `U` is the rest
131/// of the number. Conceptually, `U` should be bound by the trait `Unsigned` and `B` should
132/// be bound by the trait `Bit`, but enforcing these bounds causes linear instead of
133/// logrithmic scaling in some places, so they are left off for now. They may be enforced in
134/// future.
135///
136/// In order to keep numbers unique, leading zeros are not allowed, so `UInt<UTerm, B0>` is
137/// forbidden.
138///
139/// # Example
140/// ```rust
141/// use typenum::{UInt, UTerm, B0, B1};
142///
143/// # #[allow(dead_code)]
144/// type U6 = UInt<UInt<UInt<UTerm, B1>, B1>, B0>;
145/// ```
146#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
147#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
148pub struct UInt<U, B> {
149    /// The more significant bits of `Self`.
150    pub(crate) msb: U,
151    /// The least significant bit of `Self`.
152    pub(crate) lsb: B,
153}
154
155impl<U: Unsigned, B: Bit> UInt<U, B> {
156    /// Instantiates a singleton representing this unsigned integer.
157    #[inline]
158    pub fn new() -> UInt<U, B> {
159        UInt::default()
160    }
161}
162
163impl<U: Unsigned, B: Bit> Unsigned for UInt<U, B> {
164    const U8: u8 = B::U8 | U::U8 << 1;
165    const U16: u16 = B::U8 as u16 | U::U16 << 1;
166    const U32: u32 = B::U8 as u32 | U::U32 << 1;
167    const U64: u64 = B::U8 as u64 | U::U64 << 1;
168    #[cfg(feature = "i128")]
169    const U128: u128 = B::U8 as u128 | U::U128 << 1;
170    const USIZE: usize = B::U8 as usize | U::USIZE << 1;
171
172    const I8: i8 = B::U8 as i8 | U::I8 << 1;
173    const I16: i16 = B::U8 as i16 | U::I16 << 1;
174    const I32: i32 = B::U8 as i32 | U::I32 << 1;
175    const I64: i64 = B::U8 as i64 | U::I64 << 1;
176    #[cfg(feature = "i128")]
177    const I128: i128 = B::U8 as i128 | U::I128 << 1;
178    const ISIZE: isize = B::U8 as isize | U::ISIZE << 1;
179
180    #[inline]
181    fn to_u8() -> u8 {
182        B::to_u8() | U::to_u8() << 1
183    }
184    #[inline]
185    fn to_u16() -> u16 {
186        u16::from(B::to_u8()) | U::to_u16() << 1
187    }
188    #[inline]
189    fn to_u32() -> u32 {
190        u32::from(B::to_u8()) | U::to_u32() << 1
191    }
192    #[inline]
193    fn to_u64() -> u64 {
194        u64::from(B::to_u8()) | U::to_u64() << 1
195    }
196    #[cfg(feature = "i128")]
197    #[inline]
198    fn to_u128() -> u128 {
199        u128::from(B::to_u8()) | U::to_u128() << 1
200    }
201    #[inline]
202    fn to_usize() -> usize {
203        usize::from(B::to_u8()) | U::to_usize() << 1
204    }
205
206    #[inline]
207    fn to_i8() -> i8 {
208        B::to_u8() as i8 | U::to_i8() << 1
209    }
210    #[inline]
211    fn to_i16() -> i16 {
212        i16::from(B::to_u8()) | U::to_i16() << 1
213    }
214    #[inline]
215    fn to_i32() -> i32 {
216        i32::from(B::to_u8()) | U::to_i32() << 1
217    }
218    #[inline]
219    fn to_i64() -> i64 {
220        i64::from(B::to_u8()) | U::to_i64() << 1
221    }
222    #[cfg(feature = "i128")]
223    #[inline]
224    fn to_i128() -> i128 {
225        i128::from(B::to_u8()) | U::to_i128() << 1
226    }
227    #[inline]
228    fn to_isize() -> isize {
229        B::to_u8() as isize | U::to_isize() << 1
230    }
231}
232
233impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {}
234impl Zero for UTerm {}
235
236impl PowerOfTwo for UInt<UTerm, B1> {}
237impl<U: Unsigned + PowerOfTwo> PowerOfTwo for UInt<U, B0> {}
238
239// ---------------------------------------------------------------------------------------
240// Getting length of unsigned integers, which is defined as the number of bits before `UTerm`
241
242/// Length of `UTerm` by itself is 0
243impl Len for UTerm {
244    type Output = U0;
245    #[inline]
246    fn len(&self) -> Self::Output {
247        UTerm
248    }
249}
250
251/// Length of a bit is 1
252impl<U: Unsigned, B: Bit> Len for UInt<U, B>
253where
254    U: Len,
255    Length<U>: Add<B1>,
256    Add1<Length<U>>: Unsigned,
257{
258    type Output = Add1<Length<U>>;
259    #[inline]
260    fn len(&self) -> Self::Output {
261        self.msb.len() + B1
262    }
263}
264
265// ---------------------------------------------------------------------------------------
266// Adding bits to unsigned integers
267
268/// `UTerm + B0 = UTerm`
269impl Add<B0> for UTerm {
270    type Output = UTerm;
271    #[inline]
272    fn add(self, _: B0) -> Self::Output {
273        UTerm
274    }
275}
276
277/// `U + B0 = U`
278impl<U: Unsigned, B: Bit> Add<B0> for UInt<U, B> {
279    type Output = UInt<U, B>;
280    #[inline]
281    fn add(self, _: B0) -> Self::Output {
282        UInt::new()
283    }
284}
285
286/// `UTerm + B1 = UInt<UTerm, B1>`
287impl Add<B1> for UTerm {
288    type Output = UInt<UTerm, B1>;
289    #[inline]
290    fn add(self, _: B1) -> Self::Output {
291        UInt::new()
292    }
293}
294
295/// `UInt<U, B0> + B1 = UInt<U + B1>`
296impl<U: Unsigned> Add<B1> for UInt<U, B0> {
297    type Output = UInt<U, B1>;
298    #[inline]
299    fn add(self, _: B1) -> Self::Output {
300        UInt::new()
301    }
302}
303
304/// `UInt<U, B1> + B1 = UInt<U + B1, B0>`
305impl<U: Unsigned> Add<B1> for UInt<U, B1>
306where
307    U: Add<B1>,
308    Add1<U>: Unsigned,
309{
310    type Output = UInt<Add1<U>, B0>;
311    #[inline]
312    fn add(self, _: B1) -> Self::Output {
313        UInt::new()
314    }
315}
316
317// ---------------------------------------------------------------------------------------
318// Adding unsigned integers
319
320/// `UTerm + U = U`
321impl<U: Unsigned> Add<U> for UTerm {
322    type Output = U;
323    #[inline]
324    fn add(self, rhs: U) -> Self::Output {
325        rhs
326    }
327}
328
329/// `UInt<U, B> + UTerm = UInt<U, B>`
330impl<U: Unsigned, B: Bit> Add<UTerm> for UInt<U, B> {
331    type Output = UInt<U, B>;
332    #[inline]
333    fn add(self, _: UTerm) -> Self::Output {
334        UInt::new()
335    }
336}
337
338/// `UInt<Ul, B0> + UInt<Ur, B0> = UInt<Ul + Ur, B0>`
339impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B0>
340where
341    Ul: Add<Ur>,
342{
343    type Output = UInt<Sum<Ul, Ur>, B0>;
344    #[inline]
345    fn add(self, rhs: UInt<Ur, B0>) -> Self::Output {
346        UInt {
347            msb: self.msb + rhs.msb,
348            lsb: B0,
349        }
350    }
351}
352
353/// `UInt<Ul, B0> + UInt<Ur, B1> = UInt<Ul + Ur, B1>`
354impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B0>
355where
356    Ul: Add<Ur>,
357{
358    type Output = UInt<Sum<Ul, Ur>, B1>;
359    #[inline]
360    fn add(self, rhs: UInt<Ur, B1>) -> Self::Output {
361        UInt {
362            msb: self.msb + rhs.msb,
363            lsb: B1,
364        }
365    }
366}
367
368/// `UInt<Ul, B1> + UInt<Ur, B0> = UInt<Ul + Ur, B1>`
369impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B1>
370where
371    Ul: Add<Ur>,
372{
373    type Output = UInt<Sum<Ul, Ur>, B1>;
374    #[inline]
375    fn add(self, rhs: UInt<Ur, B0>) -> Self::Output {
376        UInt {
377            msb: self.msb + rhs.msb,
378            lsb: B1,
379        }
380    }
381}
382
383/// `UInt<Ul, B1> + UInt<Ur, B1> = UInt<(Ul + Ur) + B1, B0>`
384impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B1>
385where
386    Ul: Add<Ur>,
387    Sum<Ul, Ur>: Add<B1>,
388{
389    type Output = UInt<Add1<Sum<Ul, Ur>>, B0>;
390    #[inline]
391    fn add(self, rhs: UInt<Ur, B1>) -> Self::Output {
392        UInt {
393            msb: self.msb + rhs.msb + B1,
394            lsb: B0,
395        }
396    }
397}
398
399// ---------------------------------------------------------------------------------------
400// Subtracting bits from unsigned integers
401
402/// `UTerm - B0 = Term`
403impl Sub<B0> for UTerm {
404    type Output = UTerm;
405    #[inline]
406    fn sub(self, _: B0) -> Self::Output {
407        UTerm
408    }
409}
410
411/// `UInt - B0 = UInt`
412impl<U: Unsigned, B: Bit> Sub<B0> for UInt<U, B> {
413    type Output = UInt<U, B>;
414    #[inline]
415    fn sub(self, _: B0) -> Self::Output {
416        UInt::new()
417    }
418}
419
420/// `UInt<U, B1> - B1 = UInt<U, B0>`
421impl<U: Unsigned, B: Bit> Sub<B1> for UInt<UInt<U, B>, B1> {
422    type Output = UInt<UInt<U, B>, B0>;
423    #[inline]
424    fn sub(self, _: B1) -> Self::Output {
425        UInt::new()
426    }
427}
428
429/// `UInt<UTerm, B1> - B1 = UTerm`
430impl Sub<B1> for UInt<UTerm, B1> {
431    type Output = UTerm;
432    #[inline]
433    fn sub(self, _: B1) -> Self::Output {
434        UTerm
435    }
436}
437
438/// `UInt<U, B0> - B1 = UInt<U - B1, B1>`
439impl<U: Unsigned> Sub<B1> for UInt<U, B0>
440where
441    U: Sub<B1>,
442    Sub1<U>: Unsigned,
443{
444    type Output = UInt<Sub1<U>, B1>;
445    #[inline]
446    fn sub(self, _: B1) -> Self::Output {
447        UInt::new()
448    }
449}
450
451// ---------------------------------------------------------------------------------------
452// Subtracting unsigned integers
453
454/// `UTerm - UTerm = UTerm`
455impl Sub<UTerm> for UTerm {
456    type Output = UTerm;
457    #[inline]
458    fn sub(self, _: UTerm) -> Self::Output {
459        UTerm
460    }
461}
462
463/// Subtracting unsigned integers. We just do our `PrivateSub` and then `Trim` the output.
464impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> Sub<Ur> for UInt<Ul, Bl>
465where
466    UInt<Ul, Bl>: PrivateSub<Ur>,
467    PrivateSubOut<UInt<Ul, Bl>, Ur>: Trim,
468{
469    type Output = TrimOut<PrivateSubOut<UInt<Ul, Bl>, Ur>>;
470    #[inline]
471    fn sub(self, rhs: Ur) -> Self::Output {
472        self.private_sub(rhs).trim()
473    }
474}
475
476/// `U - UTerm = U`
477impl<U: Unsigned> PrivateSub<UTerm> for U {
478    type Output = U;
479
480    #[inline]
481    fn private_sub(self, _: UTerm) -> Self::Output {
482        self
483    }
484}
485
486/// `UInt<Ul, B0> - UInt<Ur, B0> = UInt<Ul - Ur, B0>`
487impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B0>
488where
489    Ul: PrivateSub<Ur>,
490{
491    type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
492
493    #[inline]
494    fn private_sub(self, rhs: UInt<Ur, B0>) -> Self::Output {
495        UInt {
496            msb: self.msb.private_sub(rhs.msb),
497            lsb: B0,
498        }
499    }
500}
501
502/// `UInt<Ul, B0> - UInt<Ur, B1> = UInt<(Ul - Ur) - B1, B1>`
503impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B0>
504where
505    Ul: PrivateSub<Ur>,
506    PrivateSubOut<Ul, Ur>: Sub<B1>,
507{
508    type Output = UInt<Sub1<PrivateSubOut<Ul, Ur>>, B1>;
509
510    #[inline]
511    fn private_sub(self, rhs: UInt<Ur, B1>) -> Self::Output {
512        UInt {
513            msb: self.msb.private_sub(rhs.msb) - B1,
514            lsb: B1,
515        }
516    }
517}
518
519/// `UInt<Ul, B1> - UInt<Ur, B0> = UInt<Ul - Ur, B1>`
520impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B1>
521where
522    Ul: PrivateSub<Ur>,
523{
524    type Output = UInt<PrivateSubOut<Ul, Ur>, B1>;
525
526    #[inline]
527    fn private_sub(self, rhs: UInt<Ur, B0>) -> Self::Output {
528        UInt {
529            msb: self.msb.private_sub(rhs.msb),
530            lsb: B1,
531        }
532    }
533}
534
535/// `UInt<Ul, B1> - UInt<Ur, B1> = UInt<Ul - Ur, B0>`
536impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B1>
537where
538    Ul: PrivateSub<Ur>,
539{
540    type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
541
542    #[inline]
543    fn private_sub(self, rhs: UInt<Ur, B1>) -> Self::Output {
544        UInt {
545            msb: self.msb.private_sub(rhs.msb),
546            lsb: B0,
547        }
548    }
549}
550
551// ---------------------------------------------------------------------------------------
552// And unsigned integers
553
554/// 0 & X = 0
555impl<Ur: Unsigned> BitAnd<Ur> for UTerm {
556    type Output = UTerm;
557    #[inline]
558    fn bitand(self, _: Ur) -> Self::Output {
559        UTerm
560    }
561}
562
563/// Anding unsigned integers.
564/// We use our `PrivateAnd` operator and then `Trim` the output.
565impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitAnd<Ur> for UInt<Ul, Bl>
566where
567    UInt<Ul, Bl>: PrivateAnd<Ur>,
568    PrivateAndOut<UInt<Ul, Bl>, Ur>: Trim,
569{
570    type Output = TrimOut<PrivateAndOut<UInt<Ul, Bl>, Ur>>;
571    #[inline]
572    fn bitand(self, rhs: Ur) -> Self::Output {
573        self.private_and(rhs).trim()
574    }
575}
576
577/// `UTerm & X = UTerm`
578impl<U: Unsigned> PrivateAnd<U> for UTerm {
579    type Output = UTerm;
580
581    #[inline]
582    fn private_and(self, _: U) -> Self::Output {
583        UTerm
584    }
585}
586
587/// `X & UTerm = UTerm`
588impl<B: Bit, U: Unsigned> PrivateAnd<UTerm> for UInt<U, B> {
589    type Output = UTerm;
590
591    #[inline]
592    fn private_and(self, _: UTerm) -> Self::Output {
593        UTerm
594    }
595}
596
597/// `UInt<Ul, B0> & UInt<Ur, B0> = UInt<Ul & Ur, B0>`
598impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B0>
599where
600    Ul: PrivateAnd<Ur>,
601{
602    type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
603
604    #[inline]
605    fn private_and(self, rhs: UInt<Ur, B0>) -> Self::Output {
606        UInt {
607            msb: self.msb.private_and(rhs.msb),
608            lsb: B0,
609        }
610    }
611}
612
613/// `UInt<Ul, B0> & UInt<Ur, B1> = UInt<Ul & Ur, B0>`
614impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B0>
615where
616    Ul: PrivateAnd<Ur>,
617{
618    type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
619
620    #[inline]
621    fn private_and(self, rhs: UInt<Ur, B1>) -> Self::Output {
622        UInt {
623            msb: self.msb.private_and(rhs.msb),
624            lsb: B0,
625        }
626    }
627}
628
629/// `UInt<Ul, B1> & UInt<Ur, B0> = UInt<Ul & Ur, B0>`
630impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B1>
631where
632    Ul: PrivateAnd<Ur>,
633{
634    type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
635
636    #[inline]
637    fn private_and(self, rhs: UInt<Ur, B0>) -> Self::Output {
638        UInt {
639            msb: self.msb.private_and(rhs.msb),
640            lsb: B0,
641        }
642    }
643}
644
645/// `UInt<Ul, B1> & UInt<Ur, B1> = UInt<Ul & Ur, B1>`
646impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B1>
647where
648    Ul: PrivateAnd<Ur>,
649{
650    type Output = UInt<PrivateAndOut<Ul, Ur>, B1>;
651
652    #[inline]
653    fn private_and(self, rhs: UInt<Ur, B1>) -> Self::Output {
654        UInt {
655            msb: self.msb.private_and(rhs.msb),
656            lsb: B1,
657        }
658    }
659}
660
661// ---------------------------------------------------------------------------------------
662// Or unsigned integers
663
664/// `UTerm | X = X`
665impl<U: Unsigned> BitOr<U> for UTerm {
666    type Output = U;
667    #[inline]
668    fn bitor(self, rhs: U) -> Self::Output {
669        rhs
670    }
671}
672
673///  `X | UTerm = X`
674impl<B: Bit, U: Unsigned> BitOr<UTerm> for UInt<U, B> {
675    type Output = Self;
676    #[inline]
677    fn bitor(self, _: UTerm) -> Self::Output {
678        UInt::new()
679    }
680}
681
682/// `UInt<Ul, B0> | UInt<Ur, B0> = UInt<Ul | Ur, B0>`
683impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B0>
684where
685    Ul: BitOr<Ur>,
686{
687    type Output = UInt<<Ul as BitOr<Ur>>::Output, B0>;
688    #[inline]
689    fn bitor(self, rhs: UInt<Ur, B0>) -> Self::Output {
690        UInt {
691            msb: self.msb.bitor(rhs.msb),
692            lsb: B0,
693        }
694    }
695}
696
697/// `UInt<Ul, B0> | UInt<Ur, B1> = UInt<Ul | Ur, B1>`
698impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B0>
699where
700    Ul: BitOr<Ur>,
701{
702    type Output = UInt<Or<Ul, Ur>, B1>;
703    #[inline]
704    fn bitor(self, rhs: UInt<Ur, B1>) -> Self::Output {
705        UInt {
706            msb: self.msb.bitor(rhs.msb),
707            lsb: self.lsb.bitor(rhs.lsb),
708        }
709    }
710}
711
712/// `UInt<Ul, B1> | UInt<Ur, B0> = UInt<Ul | Ur, B1>`
713impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B1>
714where
715    Ul: BitOr<Ur>,
716{
717    type Output = UInt<Or<Ul, Ur>, B1>;
718    #[inline]
719    fn bitor(self, rhs: UInt<Ur, B0>) -> Self::Output {
720        UInt {
721            msb: self.msb.bitor(rhs.msb),
722            lsb: self.lsb.bitor(rhs.lsb),
723        }
724    }
725}
726
727/// `UInt<Ul, B1> | UInt<Ur, B1> = UInt<Ul | Ur, B1>`
728impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B1>
729where
730    Ul: BitOr<Ur>,
731{
732    type Output = UInt<Or<Ul, Ur>, B1>;
733    #[inline]
734    fn bitor(self, rhs: UInt<Ur, B1>) -> Self::Output {
735        UInt {
736            msb: self.msb.bitor(rhs.msb),
737            lsb: self.lsb.bitor(rhs.lsb),
738        }
739    }
740}
741
742// ---------------------------------------------------------------------------------------
743// Xor unsigned integers
744
745/// 0 ^ X = X
746impl<Ur: Unsigned> BitXor<Ur> for UTerm {
747    type Output = Ur;
748    #[inline]
749    fn bitxor(self, rhs: Ur) -> Self::Output {
750        rhs
751    }
752}
753
754/// Xoring unsigned integers.
755/// We use our `PrivateXor` operator and then `Trim` the output.
756impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitXor<Ur> for UInt<Ul, Bl>
757where
758    UInt<Ul, Bl>: PrivateXor<Ur>,
759    PrivateXorOut<UInt<Ul, Bl>, Ur>: Trim,
760{
761    type Output = TrimOut<PrivateXorOut<UInt<Ul, Bl>, Ur>>;
762    #[inline]
763    fn bitxor(self, rhs: Ur) -> Self::Output {
764        self.private_xor(rhs).trim()
765    }
766}
767
768/// `UTerm ^ X = X`
769impl<U: Unsigned> PrivateXor<U> for UTerm {
770    type Output = U;
771
772    #[inline]
773    fn private_xor(self, rhs: U) -> Self::Output {
774        rhs
775    }
776}
777
778/// `X ^ UTerm = X`
779impl<B: Bit, U: Unsigned> PrivateXor<UTerm> for UInt<U, B> {
780    type Output = Self;
781
782    #[inline]
783    fn private_xor(self, _: UTerm) -> Self::Output {
784        self
785    }
786}
787
788/// `UInt<Ul, B0> ^ UInt<Ur, B0> = UInt<Ul ^ Ur, B0>`
789impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B0>
790where
791    Ul: PrivateXor<Ur>,
792{
793    type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
794
795    #[inline]
796    fn private_xor(self, rhs: UInt<Ur, B0>) -> Self::Output {
797        UInt {
798            msb: self.msb.private_xor(rhs.msb),
799            lsb: B0,
800        }
801    }
802}
803
804/// `UInt<Ul, B0> ^ UInt<Ur, B1> = UInt<Ul ^ Ur, B1>`
805impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B0>
806where
807    Ul: PrivateXor<Ur>,
808{
809    type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
810
811    #[inline]
812    fn private_xor(self, rhs: UInt<Ur, B1>) -> Self::Output {
813        UInt {
814            msb: self.msb.private_xor(rhs.msb),
815            lsb: B1,
816        }
817    }
818}
819
820/// `UInt<Ul, B1> ^ UInt<Ur, B0> = UInt<Ul ^ Ur, B1>`
821impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B1>
822where
823    Ul: PrivateXor<Ur>,
824{
825    type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
826
827    #[inline]
828    fn private_xor(self, rhs: UInt<Ur, B0>) -> Self::Output {
829        UInt {
830            msb: self.msb.private_xor(rhs.msb),
831            lsb: B1,
832        }
833    }
834}
835
836/// `UInt<Ul, B1> ^ UInt<Ur, B1> = UInt<Ul ^ Ur, B0>`
837impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B1>
838where
839    Ul: PrivateXor<Ur>,
840{
841    type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
842
843    #[inline]
844    fn private_xor(self, rhs: UInt<Ur, B1>) -> Self::Output {
845        UInt {
846            msb: self.msb.private_xor(rhs.msb),
847            lsb: B0,
848        }
849    }
850}
851
852// ---------------------------------------------------------------------------------------
853// Shl unsigned integers
854
855/// Shifting `UTerm` by a 0 bit: `UTerm << B0 = UTerm`
856impl Shl<B0> for UTerm {
857    type Output = UTerm;
858    #[inline]
859    fn shl(self, _: B0) -> Self::Output {
860        UTerm
861    }
862}
863
864/// Shifting `UTerm` by a 1 bit: `UTerm << B1 = UTerm`
865impl Shl<B1> for UTerm {
866    type Output = UTerm;
867    #[inline]
868    fn shl(self, _: B1) -> Self::Output {
869        UTerm
870    }
871}
872
873/// Shifting left any unsigned by a zero bit: `U << B0 = U`
874impl<U: Unsigned, B: Bit> Shl<B0> for UInt<U, B> {
875    type Output = UInt<U, B>;
876    #[inline]
877    fn shl(self, _: B0) -> Self::Output {
878        UInt::new()
879    }
880}
881
882/// Shifting left a `UInt` by a one bit: `UInt<U, B> << B1 = UInt<UInt<U, B>, B0>`
883impl<U: Unsigned, B: Bit> Shl<B1> for UInt<U, B> {
884    type Output = UInt<UInt<U, B>, B0>;
885    #[inline]
886    fn shl(self, _: B1) -> Self::Output {
887        UInt::new()
888    }
889}
890
891/// Shifting left `UInt` by `UTerm`: `UInt<U, B> << UTerm = UInt<U, B>`
892impl<U: Unsigned, B: Bit> Shl<UTerm> for UInt<U, B> {
893    type Output = UInt<U, B>;
894    #[inline]
895    fn shl(self, _: UTerm) -> Self::Output {
896        UInt::new()
897    }
898}
899
900/// Shifting left `UTerm` by an unsigned integer: `UTerm << U = UTerm`
901impl<U: Unsigned> Shl<U> for UTerm {
902    type Output = UTerm;
903    #[inline]
904    fn shl(self, _: U) -> Self::Output {
905        UTerm
906    }
907}
908
909/// Shifting left `UInt` by `UInt`: `X << Y` = `UInt(X, B0) << (Y - 1)`
910impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shl<UInt<Ur, Br>> for UInt<U, B>
911where
912    UInt<Ur, Br>: Sub<B1>,
913    UInt<UInt<U, B>, B0>: Shl<Sub1<UInt<Ur, Br>>>,
914{
915    type Output = Shleft<UInt<UInt<U, B>, B0>, Sub1<UInt<Ur, Br>>>;
916    #[inline]
917    fn shl(self, rhs: UInt<Ur, Br>) -> Self::Output {
918        #[allow(clippy::suspicious_arithmetic_impl)]
919        (UInt { msb: self, lsb: B0 }).shl(rhs - B1)
920    }
921}
922
923// ---------------------------------------------------------------------------------------
924// Shr unsigned integers
925
926/// Shifting right a `UTerm` by an unsigned integer: `UTerm >> U = UTerm`
927impl<U: Unsigned> Shr<U> for UTerm {
928    type Output = UTerm;
929    #[inline]
930    fn shr(self, _: U) -> Self::Output {
931        UTerm
932    }
933}
934
935/// Shifting right `UInt` by `UTerm`: `UInt<U, B> >> UTerm = UInt<U, B>`
936impl<U: Unsigned, B: Bit> Shr<UTerm> for UInt<U, B> {
937    type Output = UInt<U, B>;
938    #[inline]
939    fn shr(self, _: UTerm) -> Self::Output {
940        UInt::new()
941    }
942}
943
944/// Shifting right `UTerm` by a 0 bit: `UTerm >> B0 = UTerm`
945impl Shr<B0> for UTerm {
946    type Output = UTerm;
947    #[inline]
948    fn shr(self, _: B0) -> Self::Output {
949        UTerm
950    }
951}
952
953/// Shifting right `UTerm` by a 1 bit: `UTerm >> B1 = UTerm`
954impl Shr<B1> for UTerm {
955    type Output = UTerm;
956    #[inline]
957    fn shr(self, _: B1) -> Self::Output {
958        UTerm
959    }
960}
961
962/// Shifting right any unsigned by a zero bit: `U >> B0 = U`
963impl<U: Unsigned, B: Bit> Shr<B0> for UInt<U, B> {
964    type Output = UInt<U, B>;
965    #[inline]
966    fn shr(self, _: B0) -> Self::Output {
967        UInt::new()
968    }
969}
970
971/// Shifting right a `UInt` by a 1 bit: `UInt<U, B> >> B1 = U`
972impl<U: Unsigned, B: Bit> Shr<B1> for UInt<U, B> {
973    type Output = U;
974    #[inline]
975    fn shr(self, _: B1) -> Self::Output {
976        self.msb
977    }
978}
979
980/// Shifting right `UInt` by `UInt`: `UInt(U, B) >> Y` = `U >> (Y - 1)`
981impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shr<UInt<Ur, Br>> for UInt<U, B>
982where
983    UInt<Ur, Br>: Sub<B1>,
984    U: Shr<Sub1<UInt<Ur, Br>>>,
985{
986    type Output = Shright<U, Sub1<UInt<Ur, Br>>>;
987    #[inline]
988    fn shr(self, rhs: UInt<Ur, Br>) -> Self::Output {
989        #[allow(clippy::suspicious_arithmetic_impl)]
990        self.msb.shr(rhs - B1)
991    }
992}
993
994// ---------------------------------------------------------------------------------------
995// Multiply unsigned integers
996
997/// `UInt * B0 = UTerm`
998impl<U: Unsigned, B: Bit> Mul<B0> for UInt<U, B> {
999    type Output = UTerm;
1000    #[inline]
1001    fn mul(self, _: B0) -> Self::Output {
1002        UTerm
1003    }
1004}
1005
1006/// `UTerm * B0 = UTerm`
1007impl Mul<B0> for UTerm {
1008    type Output = UTerm;
1009    #[inline]
1010    fn mul(self, _: B0) -> Self::Output {
1011        UTerm
1012    }
1013}
1014
1015/// `UTerm * B1 = UTerm`
1016impl Mul<B1> for UTerm {
1017    type Output = UTerm;
1018    #[inline]
1019    fn mul(self, _: B1) -> Self::Output {
1020        UTerm
1021    }
1022}
1023
1024/// `UInt * B1 = UInt`
1025impl<U: Unsigned, B: Bit> Mul<B1> for UInt<U, B> {
1026    type Output = UInt<U, B>;
1027    #[inline]
1028    fn mul(self, _: B1) -> Self::Output {
1029        UInt::new()
1030    }
1031}
1032
1033/// `UInt<U, B> * UTerm = UTerm`
1034impl<U: Unsigned, B: Bit> Mul<UTerm> for UInt<U, B> {
1035    type Output = UTerm;
1036    #[inline]
1037    fn mul(self, _: UTerm) -> Self::Output {
1038        UTerm
1039    }
1040}
1041
1042/// `UTerm * U = UTerm`
1043impl<U: Unsigned> Mul<U> for UTerm {
1044    type Output = UTerm;
1045    #[inline]
1046    fn mul(self, _: U) -> Self::Output {
1047        UTerm
1048    }
1049}
1050
1051/// `UInt<Ul, B0> * UInt<Ur, B> = UInt<(Ul * UInt<Ur, B>), B0>`
1052impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B0>
1053where
1054    Ul: Mul<UInt<Ur, B>>,
1055{
1056    type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
1057    #[inline]
1058    fn mul(self, rhs: UInt<Ur, B>) -> Self::Output {
1059        UInt {
1060            msb: self.msb * rhs,
1061            lsb: B0,
1062        }
1063    }
1064}
1065
1066/// `UInt<Ul, B1> * UInt<Ur, B> = UInt<(Ul * UInt<Ur, B>), B0> + UInt<Ur, B>`
1067impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B1>
1068where
1069    Ul: Mul<UInt<Ur, B>>,
1070    UInt<Prod<Ul, UInt<Ur, B>>, B0>: Add<UInt<Ur, B>>,
1071{
1072    type Output = Sum<UInt<Prod<Ul, UInt<Ur, B>>, B0>, UInt<Ur, B>>;
1073    #[inline]
1074    fn mul(self, rhs: UInt<Ur, B>) -> Self::Output {
1075        UInt {
1076            msb: self.msb * rhs,
1077            lsb: B0,
1078        } + rhs
1079    }
1080}
1081
1082// ---------------------------------------------------------------------------------------
1083// Compare unsigned integers
1084
1085/// Zero == Zero
1086impl Cmp<UTerm> for UTerm {
1087    type Output = Equal;
1088
1089    #[inline]
1090    fn compare<IM: InternalMarker>(&self, _: &UTerm) -> Self::Output {
1091        Equal
1092    }
1093}
1094
1095/// Nonzero > Zero
1096impl<U: Unsigned, B: Bit> Cmp<UTerm> for UInt<U, B> {
1097    type Output = Greater;
1098
1099    #[inline]
1100    fn compare<IM: InternalMarker>(&self, _: &UTerm) -> Self::Output {
1101        Greater
1102    }
1103}
1104
1105/// Zero < Nonzero
1106impl<U: Unsigned, B: Bit> Cmp<UInt<U, B>> for UTerm {
1107    type Output = Less;
1108
1109    #[inline]
1110    fn compare<IM: InternalMarker>(&self, _: &UInt<U, B>) -> Self::Output {
1111        Less
1112    }
1113}
1114
1115/// `UInt<Ul, B0>` cmp with `UInt<Ur, B0>`: `SoFar` is `Equal`
1116impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B0>> for UInt<Ul, B0>
1117where
1118    Ul: PrivateCmp<Ur, Equal>,
1119{
1120    type Output = PrivateCmpOut<Ul, Ur, Equal>;
1121
1122    #[inline]
1123    fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B0>) -> Self::Output {
1124        self.msb.private_cmp(&rhs.msb, Equal)
1125    }
1126}
1127
1128/// `UInt<Ul, B1>` cmp with `UInt<Ur, B1>`: `SoFar` is `Equal`
1129impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B1>> for UInt<Ul, B1>
1130where
1131    Ul: PrivateCmp<Ur, Equal>,
1132{
1133    type Output = PrivateCmpOut<Ul, Ur, Equal>;
1134
1135    #[inline]
1136    fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B1>) -> Self::Output {
1137        self.msb.private_cmp(&rhs.msb, Equal)
1138    }
1139}
1140
1141/// `UInt<Ul, B0>` cmp with `UInt<Ur, B1>`: `SoFar` is `Less`
1142impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B1>> for UInt<Ul, B0>
1143where
1144    Ul: PrivateCmp<Ur, Less>,
1145{
1146    type Output = PrivateCmpOut<Ul, Ur, Less>;
1147
1148    #[inline]
1149    fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B1>) -> Self::Output {
1150        self.msb.private_cmp(&rhs.msb, Less)
1151    }
1152}
1153
1154/// `UInt<Ul, B1>` cmp with `UInt<Ur, B0>`: `SoFar` is `Greater`
1155impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B0>> for UInt<Ul, B1>
1156where
1157    Ul: PrivateCmp<Ur, Greater>,
1158{
1159    type Output = PrivateCmpOut<Ul, Ur, Greater>;
1160
1161    #[inline]
1162    fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B0>) -> Self::Output {
1163        self.msb.private_cmp(&rhs.msb, Greater)
1164    }
1165}
1166
1167/// Comparing non-terimal bits, with both having bit `B0`.
1168/// These are `Equal`, so we propagate `SoFar`.
1169impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B0>, SoFar> for UInt<Ul, B0>
1170where
1171    Ul: Unsigned,
1172    Ur: Unsigned,
1173    SoFar: Ord,
1174    Ul: PrivateCmp<Ur, SoFar>,
1175{
1176    type Output = PrivateCmpOut<Ul, Ur, SoFar>;
1177
1178    #[inline]
1179    fn private_cmp(&self, rhs: &UInt<Ur, B0>, so_far: SoFar) -> Self::Output {
1180        self.msb.private_cmp(&rhs.msb, so_far)
1181    }
1182}
1183
1184/// Comparing non-terimal bits, with both having bit `B1`.
1185/// These are `Equal`, so we propagate `SoFar`.
1186impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B1>, SoFar> for UInt<Ul, B1>
1187where
1188    Ul: Unsigned,
1189    Ur: Unsigned,
1190    SoFar: Ord,
1191    Ul: PrivateCmp<Ur, SoFar>,
1192{
1193    type Output = PrivateCmpOut<Ul, Ur, SoFar>;
1194
1195    #[inline]
1196    fn private_cmp(&self, rhs: &UInt<Ur, B1>, so_far: SoFar) -> Self::Output {
1197        self.msb.private_cmp(&rhs.msb, so_far)
1198    }
1199}
1200
1201/// Comparing non-terimal bits, with `Lhs` having bit `B0` and `Rhs` having bit `B1`.
1202/// `SoFar`, Lhs is `Less`.
1203impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B1>, SoFar> for UInt<Ul, B0>
1204where
1205    Ul: Unsigned,
1206    Ur: Unsigned,
1207    SoFar: Ord,
1208    Ul: PrivateCmp<Ur, Less>,
1209{
1210    type Output = PrivateCmpOut<Ul, Ur, Less>;
1211
1212    #[inline]
1213    fn private_cmp(&self, rhs: &UInt<Ur, B1>, _: SoFar) -> Self::Output {
1214        self.msb.private_cmp(&rhs.msb, Less)
1215    }
1216}
1217
1218/// Comparing non-terimal bits, with `Lhs` having bit `B1` and `Rhs` having bit `B0`.
1219/// `SoFar`, Lhs is `Greater`.
1220impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B0>, SoFar> for UInt<Ul, B1>
1221where
1222    Ul: Unsigned,
1223    Ur: Unsigned,
1224    SoFar: Ord,
1225    Ul: PrivateCmp<Ur, Greater>,
1226{
1227    type Output = PrivateCmpOut<Ul, Ur, Greater>;
1228
1229    #[inline]
1230    fn private_cmp(&self, rhs: &UInt<Ur, B0>, _: SoFar) -> Self::Output {
1231        self.msb.private_cmp(&rhs.msb, Greater)
1232    }
1233}
1234
1235/// Got to the end of just the `Lhs`. It's `Less`.
1236impl<U: Unsigned, B: Bit, SoFar: Ord> PrivateCmp<UInt<U, B>, SoFar> for UTerm {
1237    type Output = Less;
1238
1239    #[inline]
1240    fn private_cmp(&self, _: &UInt<U, B>, _: SoFar) -> Self::Output {
1241        Less
1242    }
1243}
1244
1245/// Got to the end of just the `Rhs`. `Lhs` is `Greater`.
1246impl<U: Unsigned, B: Bit, SoFar: Ord> PrivateCmp<UTerm, SoFar> for UInt<U, B> {
1247    type Output = Greater;
1248
1249    #[inline]
1250    fn private_cmp(&self, _: &UTerm, _: SoFar) -> Self::Output {
1251        Greater
1252    }
1253}
1254
1255/// Got to the end of both! Return `SoFar`
1256impl<SoFar: Ord> PrivateCmp<UTerm, SoFar> for UTerm {
1257    type Output = SoFar;
1258
1259    #[inline]
1260    fn private_cmp(&self, _: &UTerm, so_far: SoFar) -> Self::Output {
1261        so_far
1262    }
1263}
1264
1265// ---------------------------------------------------------------------------------------
1266// Getting difference in number of bits
1267
1268impl<Ul, Bl, Ur, Br> BitDiff<UInt<Ur, Br>> for UInt<Ul, Bl>
1269where
1270    Ul: Unsigned,
1271    Bl: Bit,
1272    Ur: Unsigned,
1273    Br: Bit,
1274    Ul: BitDiff<Ur>,
1275{
1276    type Output = BitDiffOut<Ul, Ur>;
1277}
1278
1279impl<Ul> BitDiff<UTerm> for Ul
1280where
1281    Ul: Unsigned + Len,
1282{
1283    type Output = Length<Ul>;
1284}
1285
1286// ---------------------------------------------------------------------------------------
1287// Shifting one number until it's the size of another
1288use crate::private::ShiftDiff;
1289impl<Ul: Unsigned, Ur: Unsigned> ShiftDiff<Ur> for Ul
1290where
1291    Ur: BitDiff<Ul>,
1292    Ul: Shl<BitDiffOut<Ur, Ul>>,
1293{
1294    type Output = Shleft<Ul, BitDiffOut<Ur, Ul>>;
1295}
1296
1297// ---------------------------------------------------------------------------------------
1298// Powers of unsigned integers
1299
1300/// X^N
1301impl<X: Unsigned, N: Unsigned> Pow<N> for X
1302where
1303    X: PrivatePow<U1, N>,
1304{
1305    type Output = PrivatePowOut<X, U1, N>;
1306    #[inline]
1307    fn powi(self, n: N) -> Self::Output {
1308        self.private_pow(U1::new(), n)
1309    }
1310}
1311
1312impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U0> for X {
1313    type Output = Y;
1314
1315    #[inline]
1316    fn private_pow(self, y: Y, _: U0) -> Self::Output {
1317        y
1318    }
1319}
1320
1321impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U1> for X
1322where
1323    X: Mul<Y>,
1324{
1325    type Output = Prod<X, Y>;
1326
1327    #[inline]
1328    fn private_pow(self, y: Y, _: U1) -> Self::Output {
1329        self * y
1330    }
1331}
1332
1333/// N is even
1334impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B0>> for X
1335where
1336    X: Mul,
1337    Square<X>: PrivatePow<Y, UInt<U, B>>,
1338{
1339    type Output = PrivatePowOut<Square<X>, Y, UInt<U, B>>;
1340
1341    #[inline]
1342    fn private_pow(self, y: Y, n: UInt<UInt<U, B>, B0>) -> Self::Output {
1343        (self * self).private_pow(y, n.msb)
1344    }
1345}
1346
1347/// N is odd
1348impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B1>> for X
1349where
1350    X: Mul + Mul<Y>,
1351    Square<X>: PrivatePow<Prod<X, Y>, UInt<U, B>>,
1352{
1353    type Output = PrivatePowOut<Square<X>, Prod<X, Y>, UInt<U, B>>;
1354
1355    #[inline]
1356    fn private_pow(self, y: Y, n: UInt<UInt<U, B>, B1>) -> Self::Output {
1357        (self * self).private_pow(self * y, n.msb)
1358    }
1359}
1360
1361//------------------------------------------
1362// Greatest Common Divisor
1363
1364/// The even number 2*N
1365#[allow(unused)] // Silence spurious warning on older versions of rust
1366type Even<N> = UInt<N, B0>;
1367
1368/// The odd number 2*N + 1
1369type Odd<N> = UInt<N, B1>;
1370
1371/// gcd(0, 0) = 0
1372impl Gcd<U0> for U0 {
1373    type Output = U0;
1374}
1375
1376/// gcd(x, 0) = x
1377impl<X> Gcd<U0> for X
1378where
1379    X: Unsigned + NonZero,
1380{
1381    type Output = X;
1382}
1383
1384/// gcd(0, y) = y
1385impl<Y> Gcd<Y> for U0
1386where
1387    Y: Unsigned + NonZero,
1388{
1389    type Output = Y;
1390}
1391
1392/// gcd(x, y) = 2*gcd(x/2, y/2) if both x and y even
1393impl<Xp, Yp> Gcd<Even<Yp>> for Even<Xp>
1394where
1395    Xp: Gcd<Yp>,
1396    Even<Xp>: NonZero,
1397    Even<Yp>: NonZero,
1398{
1399    type Output = UInt<Gcf<Xp, Yp>, B0>;
1400}
1401
1402/// gcd(x, y) = gcd(x, y/2) if x odd and y even
1403impl<Xp, Yp> Gcd<Even<Yp>> for Odd<Xp>
1404where
1405    Odd<Xp>: Gcd<Yp>,
1406    Even<Yp>: NonZero,
1407{
1408    type Output = Gcf<Odd<Xp>, Yp>;
1409}
1410
1411/// gcd(x, y) = gcd(x/2, y) if x even and y odd
1412impl<Xp, Yp> Gcd<Odd<Yp>> for Even<Xp>
1413where
1414    Xp: Gcd<Odd<Yp>>,
1415    Even<Xp>: NonZero,
1416{
1417    type Output = Gcf<Xp, Odd<Yp>>;
1418}
1419
1420/// gcd(x, y) = gcd([max(x, y) - min(x, y)], min(x, y)) if both x and y odd
1421///
1422/// This will immediately invoke the case for x even and y odd because the difference of two odd
1423/// numbers is an even number.
1424impl<Xp, Yp> Gcd<Odd<Yp>> for Odd<Xp>
1425where
1426    Odd<Xp>: Max<Odd<Yp>> + Min<Odd<Yp>>,
1427    Odd<Yp>: Max<Odd<Xp>> + Min<Odd<Xp>>,
1428    Maximum<Odd<Xp>, Odd<Yp>>: Sub<Minimum<Odd<Xp>, Odd<Yp>>>,
1429    Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>: Gcd<Minimum<Odd<Xp>, Odd<Yp>>>,
1430{
1431    type Output =
1432        Gcf<Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>, Minimum<Odd<Xp>, Odd<Yp>>>;
1433}
1434
1435#[cfg(test)]
1436mod gcd_tests {
1437    use super::*;
1438    use crate::consts::*;
1439
1440    macro_rules! gcd_test {
1441        (
1442            $( $a:ident, $b:ident => $c:ident ),* $(,)*
1443        ) => {
1444            $(
1445                assert_eq!(<Gcf<$a, $b> as Unsigned>::to_usize(), $c::to_usize());
1446                assert_eq!(<Gcf<$b, $a> as Unsigned>::to_usize(), $c::to_usize());
1447             )*
1448        }
1449    }
1450
1451    #[test]
1452    fn gcd() {
1453        gcd_test! {
1454            U0,   U0    => U0,
1455            U0,   U42   => U42,
1456            U12,  U8    => U4,
1457            U13,  U1013 => U1,  // Two primes
1458            U9,   U26   => U1,  // Not prime but coprime
1459            U143, U273  => U13,
1460            U117, U273  => U39,
1461        }
1462    }
1463}
1464
1465// -----------------------------------------
1466// GetBit
1467
1468#[allow(missing_docs)]
1469pub trait GetBit<I> {
1470    #[allow(missing_docs)]
1471    type Output;
1472
1473    #[doc(hidden)]
1474    fn get_bit<IM: InternalMarker>(&self, _: &I) -> Self::Output;
1475}
1476
1477#[allow(missing_docs)]
1478pub type GetBitOut<N, I> = <N as GetBit<I>>::Output;
1479
1480// Base case
1481impl<Un, Bn> GetBit<U0> for UInt<Un, Bn>
1482where
1483    Bn: Copy,
1484{
1485    type Output = Bn;
1486
1487    #[inline]
1488    fn get_bit<IM: InternalMarker>(&self, _: &U0) -> Self::Output {
1489        self.lsb
1490    }
1491}
1492
1493// Recursion case
1494impl<Un, Bn, Ui, Bi> GetBit<UInt<Ui, Bi>> for UInt<Un, Bn>
1495where
1496    UInt<Ui, Bi>: Copy + Sub<B1>,
1497    Un: GetBit<Sub1<UInt<Ui, Bi>>>,
1498{
1499    type Output = GetBitOut<Un, Sub1<UInt<Ui, Bi>>>;
1500
1501    #[inline]
1502    fn get_bit<IM: InternalMarker>(&self, i: &UInt<Ui, Bi>) -> Self::Output {
1503        self.msb.get_bit::<Internal>(&(*i - B1))
1504    }
1505}
1506
1507// Ran out of bits
1508impl<I> GetBit<I> for UTerm {
1509    type Output = B0;
1510
1511    #[inline]
1512    fn get_bit<IM: InternalMarker>(&self, _: &I) -> Self::Output {
1513        B0
1514    }
1515}
1516
1517#[test]
1518fn test_get_bit() {
1519    use crate::consts::*;
1520    use crate::Same;
1521    type T1 = <GetBitOut<U2, U0> as Same<B0>>::Output;
1522    type T2 = <GetBitOut<U2, U1> as Same<B1>>::Output;
1523    type T3 = <GetBitOut<U2, U2> as Same<B0>>::Output;
1524
1525    <T1 as Bit>::to_bool();
1526    <T2 as Bit>::to_bool();
1527    <T3 as Bit>::to_bool();
1528}
1529
1530// -----------------------------------------
1531// SetBit
1532
1533/// A **type operator** that, when implemented for unsigned integer `N`, sets the bit at position
1534/// `I` to `B`.
1535pub trait SetBit<I, B> {
1536    #[allow(missing_docs)]
1537    type Output;
1538
1539    #[doc(hidden)]
1540    fn set_bit<IM: InternalMarker>(self, _: I, _: B) -> Self::Output;
1541}
1542/// Alias for the result of calling `SetBit`: `SetBitOut<N, I, B> = <N as SetBit<I, B>>::Output`.
1543pub type SetBitOut<N, I, B> = <N as SetBit<I, B>>::Output;
1544
1545use crate::private::{PrivateSetBit, PrivateSetBitOut};
1546
1547// Call private one then trim it
1548impl<N, I, B> SetBit<I, B> for N
1549where
1550    N: PrivateSetBit<I, B>,
1551    PrivateSetBitOut<N, I, B>: Trim,
1552{
1553    type Output = TrimOut<PrivateSetBitOut<N, I, B>>;
1554
1555    #[inline]
1556    fn set_bit<IM: InternalMarker>(self, i: I, b: B) -> Self::Output {
1557        self.private_set_bit(i, b).trim()
1558    }
1559}
1560
1561// Base case
1562impl<Un, Bn, B> PrivateSetBit<U0, B> for UInt<Un, Bn> {
1563    type Output = UInt<Un, B>;
1564
1565    #[inline]
1566    fn private_set_bit(self, _: U0, b: B) -> Self::Output {
1567        UInt {
1568            msb: self.msb,
1569            lsb: b,
1570        }
1571    }
1572}
1573
1574// Recursion case
1575impl<Un, Bn, Ui, Bi, B> PrivateSetBit<UInt<Ui, Bi>, B> for UInt<Un, Bn>
1576where
1577    UInt<Ui, Bi>: Sub<B1>,
1578    Un: PrivateSetBit<Sub1<UInt<Ui, Bi>>, B>,
1579{
1580    type Output = UInt<PrivateSetBitOut<Un, Sub1<UInt<Ui, Bi>>, B>, Bn>;
1581
1582    #[inline]
1583    fn private_set_bit(self, i: UInt<Ui, Bi>, b: B) -> Self::Output {
1584        UInt {
1585            msb: self.msb.private_set_bit(i - B1, b),
1586            lsb: self.lsb,
1587        }
1588    }
1589}
1590
1591// Ran out of bits, setting B0
1592impl<I> PrivateSetBit<I, B0> for UTerm {
1593    type Output = UTerm;
1594
1595    #[inline]
1596    fn private_set_bit(self, _: I, _: B0) -> Self::Output {
1597        UTerm
1598    }
1599}
1600
1601// Ran out of bits, setting B1
1602impl<I> PrivateSetBit<I, B1> for UTerm
1603where
1604    U1: Shl<I>,
1605{
1606    type Output = Shleft<U1, I>;
1607
1608    #[inline]
1609    fn private_set_bit(self, i: I, _: B1) -> Self::Output {
1610        <U1 as Shl<I>>::shl(U1::new(), i)
1611    }
1612}
1613
1614#[test]
1615fn test_set_bit() {
1616    use crate::consts::*;
1617    use crate::Same;
1618    type T1 = <SetBitOut<U2, U0, B0> as Same<U2>>::Output;
1619    type T2 = <SetBitOut<U2, U0, B1> as Same<U3>>::Output;
1620    type T3 = <SetBitOut<U2, U1, B0> as Same<U0>>::Output;
1621    type T4 = <SetBitOut<U2, U1, B1> as Same<U2>>::Output;
1622    type T5 = <SetBitOut<U2, U2, B0> as Same<U2>>::Output;
1623    type T6 = <SetBitOut<U2, U2, B1> as Same<U6>>::Output;
1624    type T7 = <SetBitOut<U2, U3, B0> as Same<U2>>::Output;
1625    type T8 = <SetBitOut<U2, U3, B1> as Same<U10>>::Output;
1626    type T9 = <SetBitOut<U2, U4, B0> as Same<U2>>::Output;
1627    type T10 = <SetBitOut<U2, U4, B1> as Same<U18>>::Output;
1628
1629    type T11 = <SetBitOut<U3, U0, B0> as Same<U2>>::Output;
1630
1631    <T1 as Unsigned>::to_u32();
1632    <T2 as Unsigned>::to_u32();
1633    <T3 as Unsigned>::to_u32();
1634    <T4 as Unsigned>::to_u32();
1635    <T5 as Unsigned>::to_u32();
1636    <T6 as Unsigned>::to_u32();
1637    <T7 as Unsigned>::to_u32();
1638    <T8 as Unsigned>::to_u32();
1639    <T9 as Unsigned>::to_u32();
1640    <T10 as Unsigned>::to_u32();
1641    <T11 as Unsigned>::to_u32();
1642}
1643
1644// -----------------------------------------
1645
1646// Division algorithm:
1647// We have N / D:
1648// let Q = 0, R = 0
1649// NBits = len(N)
1650// for I in NBits-1..0:
1651//   R <<=1
1652//   R[0] = N[i]
1653//   let C = R.cmp(D)
1654//   if C == Equal or Greater:
1655//     R -= D
1656//     Q[i] = 1
1657
1658#[cfg(test)]
1659mod div_tests {
1660    use crate::Unsigned;
1661
1662    use super::SetBitOut;
1663
1664    macro_rules! test_div {
1665        ($a:ident / $b:ident = $c:ident) => {{
1666            type R = Quot<$a, $b>;
1667            assert_eq!(<R as Unsigned>::to_usize(), $c::to_usize());
1668        }};
1669    }
1670    #[test]
1671    fn test_div() {
1672        use crate::consts::*;
1673        use crate::{Quot, Same};
1674
1675        test_div!(U0 / U1 = U0);
1676        test_div!(U1 / U1 = U1);
1677        test_div!(U2 / U1 = U2);
1678        test_div!(U3 / U1 = U3);
1679        test_div!(U4 / U1 = U4);
1680
1681        test_div!(U0 / U2 = U0);
1682        test_div!(U1 / U2 = U0);
1683        test_div!(U2 / U2 = U1);
1684        test_div!(U3 / U2 = U1);
1685        test_div!(U4 / U2 = U2);
1686        test_div!(U6 / U2 = U3);
1687        test_div!(U7 / U2 = U3);
1688
1689        type T = <SetBitOut<U0, U1, B1> as Same<U2>>::Output;
1690        <T as Unsigned>::to_u32();
1691    }
1692}
1693// -----------------------------------------
1694// Div
1695use core::ops::Div;
1696
1697// 0 // N
1698impl<Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UTerm {
1699    type Output = UTerm;
1700    #[inline]
1701    fn div(self, _: UInt<Ur, Br>) -> Self::Output {
1702        UTerm
1703    }
1704}
1705
1706// M // N
1707impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UInt<Ul, Bl>
1708where
1709    UInt<Ul, Bl>: Len,
1710    Length<UInt<Ul, Bl>>: Sub<B1>,
1711    (): PrivateDiv<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>,
1712{
1713    type Output = PrivateDivQuot<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>;
1714    #[inline]
1715    fn div(self, rhs: UInt<Ur, Br>) -> Self::Output {
1716        #[allow(clippy::suspicious_arithmetic_impl)]
1717        ().private_div_quotient(self, rhs, U0::new(), U0::new(), self.len() - B1)
1718    }
1719}
1720
1721// -----------------------------------------
1722// Rem
1723use core::ops::Rem;
1724
1725// 0 % N
1726impl<Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UTerm {
1727    type Output = UTerm;
1728    #[inline]
1729    fn rem(self, _: UInt<Ur, Br>) -> Self::Output {
1730        UTerm
1731    }
1732}
1733
1734// M % N
1735impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UInt<Ul, Bl>
1736where
1737    UInt<Ul, Bl>: Len,
1738    Length<UInt<Ul, Bl>>: Sub<B1>,
1739    (): PrivateDiv<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>,
1740{
1741    type Output = PrivateDivRem<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>;
1742    #[inline]
1743    fn rem(self, rhs: UInt<Ur, Br>) -> Self::Output {
1744        #[allow(clippy::suspicious_arithmetic_impl)]
1745        ().private_div_remainder(self, rhs, UTerm, UTerm, self.len() - B1)
1746    }
1747}
1748
1749// -----------------------------------------
1750// PrivateDiv
1751use crate::private::{PrivateDiv, PrivateDivQuot, PrivateDivRem};
1752
1753use crate::Compare;
1754// R == 0: We set R = UInt<UTerm, N[i]>, then call out to PrivateDivIf for the if statement
1755impl<N, D, Q, I> PrivateDiv<N, D, Q, U0, I> for ()
1756where
1757    N: GetBit<I>,
1758    UInt<UTerm, GetBitOut<N, I>>: Trim,
1759    TrimOut<UInt<UTerm, GetBitOut<N, I>>>: Cmp<D>,
1760    (): PrivateDivIf<
1761        N,
1762        D,
1763        Q,
1764        TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
1765        I,
1766        Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>,
1767    >,
1768{
1769    type Quotient = PrivateDivIfQuot<
1770        N,
1771        D,
1772        Q,
1773        TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
1774        I,
1775        Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>,
1776    >;
1777    type Remainder = PrivateDivIfRem<
1778        N,
1779        D,
1780        Q,
1781        TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
1782        I,
1783        Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>,
1784    >;
1785
1786    #[inline]
1787    fn private_div_quotient(self, n: N, d: D, q: Q, _: U0, i: I) -> Self::Quotient
1788where {
1789        let r = (UInt {
1790            msb: UTerm,
1791            lsb: n.get_bit::<Internal>(&i),
1792        })
1793        .trim();
1794        let r_cmp_d = r.compare::<Internal>(&d);
1795        ().private_div_if_quotient(n, d, q, r, i, r_cmp_d)
1796    }
1797
1798    #[inline]
1799    fn private_div_remainder(self, n: N, d: D, q: Q, _: U0, i: I) -> Self::Remainder {
1800        let r = (UInt {
1801            msb: UTerm,
1802            lsb: n.get_bit::<Internal>(&i),
1803        })
1804        .trim();
1805        let r_cmp_d = r.compare::<Internal>(&d);
1806        ().private_div_if_remainder(n, d, q, r, i, r_cmp_d)
1807    }
1808}
1809
1810// R > 0: We perform R <<= 1 and R[0] = N[i], then call out to PrivateDivIf for the if statement
1811impl<N, D, Q, Ur, Br, I> PrivateDiv<N, D, Q, UInt<Ur, Br>, I> for ()
1812where
1813    N: GetBit<I>,
1814    UInt<UInt<Ur, Br>, GetBitOut<N, I>>: Cmp<D>,
1815    (): PrivateDivIf<
1816        N,
1817        D,
1818        Q,
1819        UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
1820        I,
1821        Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>,
1822    >,
1823{
1824    type Quotient = PrivateDivIfQuot<
1825        N,
1826        D,
1827        Q,
1828        UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
1829        I,
1830        Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>,
1831    >;
1832    type Remainder = PrivateDivIfRem<
1833        N,
1834        D,
1835        Q,
1836        UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
1837        I,
1838        Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>,
1839    >;
1840
1841    #[inline]
1842    fn private_div_quotient(self, n: N, d: D, q: Q, r: UInt<Ur, Br>, i: I) -> Self::Quotient {
1843        let r = UInt {
1844            msb: r,
1845            lsb: n.get_bit::<Internal>(&i),
1846        };
1847        let r_cmp_d = r.compare::<Internal>(&d);
1848        ().private_div_if_quotient(n, d, q, r, i, r_cmp_d)
1849    }
1850
1851    #[inline]
1852    fn private_div_remainder(self, n: N, d: D, q: Q, r: UInt<Ur, Br>, i: I) -> Self::Remainder {
1853        let r = UInt {
1854            msb: r,
1855            lsb: n.get_bit::<Internal>(&i),
1856        };
1857        let r_cmp_d = r.compare::<Internal>(&d);
1858        ().private_div_if_remainder(n, d, q, r, i, r_cmp_d)
1859    }
1860}
1861
1862// -----------------------------------------
1863// PrivateDivIf
1864
1865use crate::private::{PrivateDivIf, PrivateDivIfQuot, PrivateDivIfRem};
1866
1867// R < D, I > 0, we do nothing and recurse
1868impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Less> for ()
1869where
1870    UInt<Ui, Bi>: Sub<B1>,
1871    (): PrivateDiv<N, D, Q, R, Sub1<UInt<Ui, Bi>>>,
1872{
1873    type Quotient = PrivateDivQuot<N, D, Q, R, Sub1<UInt<Ui, Bi>>>;
1874    type Remainder = PrivateDivRem<N, D, Q, R, Sub1<UInt<Ui, Bi>>>;
1875
1876    #[inline]
1877    fn private_div_if_quotient(
1878        self,
1879        n: N,
1880        d: D,
1881        q: Q,
1882        r: R,
1883        i: UInt<Ui, Bi>,
1884        _: Less,
1885    ) -> Self::Quotient
1886where {
1887        ().private_div_quotient(n, d, q, r, i - B1)
1888    }
1889
1890    #[inline]
1891    fn private_div_if_remainder(
1892        self,
1893        n: N,
1894        d: D,
1895        q: Q,
1896        r: R,
1897        i: UInt<Ui, Bi>,
1898        _: Less,
1899    ) -> Self::Remainder
1900where {
1901        ().private_div_remainder(n, d, q, r, i - B1)
1902    }
1903}
1904
1905// R == D, I > 0, we set R = 0, Q[I] = 1 and recurse
1906impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Equal> for ()
1907where
1908    UInt<Ui, Bi>: Copy + Sub<B1>,
1909    Q: SetBit<UInt<Ui, Bi>, B1>,
1910    (): PrivateDiv<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>,
1911{
1912    type Quotient = PrivateDivQuot<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>;
1913    type Remainder = PrivateDivRem<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>;
1914
1915    #[inline]
1916    fn private_div_if_quotient(
1917        self,
1918        n: N,
1919        d: D,
1920        q: Q,
1921        _: R,
1922        i: UInt<Ui, Bi>,
1923        _: Equal,
1924    ) -> Self::Quotient
1925where {
1926        ().private_div_quotient(n, d, q.set_bit::<Internal>(i, B1), U0::new(), i - B1)
1927    }
1928
1929    #[inline]
1930    fn private_div_if_remainder(
1931        self,
1932        n: N,
1933        d: D,
1934        q: Q,
1935        _: R,
1936        i: UInt<Ui, Bi>,
1937        _: Equal,
1938    ) -> Self::Remainder
1939where {
1940        ().private_div_remainder(n, d, q.set_bit::<Internal>(i, B1), U0::new(), i - B1)
1941    }
1942}
1943
1944use crate::Diff;
1945// R > D, I > 0, we set R -= D, Q[I] = 1 and recurse
1946impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Greater> for ()
1947where
1948    D: Copy,
1949    UInt<Ui, Bi>: Copy + Sub<B1>,
1950    R: Sub<D>,
1951    Q: SetBit<UInt<Ui, Bi>, B1>,
1952    (): PrivateDiv<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>,
1953{
1954    type Quotient =
1955        PrivateDivQuot<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>;
1956    type Remainder =
1957        PrivateDivRem<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>;
1958
1959    #[inline]
1960    fn private_div_if_quotient(
1961        self,
1962        n: N,
1963        d: D,
1964        q: Q,
1965        r: R,
1966        i: UInt<Ui, Bi>,
1967        _: Greater,
1968    ) -> Self::Quotient
1969where {
1970        ().private_div_quotient(n, d, q.set_bit::<Internal>(i, B1), r - d, i - B1)
1971    }
1972
1973    #[inline]
1974    fn private_div_if_remainder(
1975        self,
1976        n: N,
1977        d: D,
1978        q: Q,
1979        r: R,
1980        i: UInt<Ui, Bi>,
1981        _: Greater,
1982    ) -> Self::Remainder
1983where {
1984        ().private_div_remainder(n, d, q.set_bit::<Internal>(i, B1), r - d, i - B1)
1985    }
1986}
1987
1988// R < D, I == 0: we do nothing, and return
1989impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Less> for () {
1990    type Quotient = Q;
1991    type Remainder = R;
1992
1993    #[inline]
1994    fn private_div_if_quotient(self, _: N, _: D, q: Q, _: R, _: U0, _: Less) -> Self::Quotient {
1995        q
1996    }
1997
1998    #[inline]
1999    fn private_div_if_remainder(self, _: N, _: D, _: Q, r: R, _: U0, _: Less) -> Self::Remainder {
2000        r
2001    }
2002}
2003
2004// R == D, I == 0: we set R = 0, Q[I] = 1, and return
2005impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Equal> for ()
2006where
2007    Q: SetBit<U0, B1>,
2008{
2009    type Quotient = SetBitOut<Q, U0, B1>;
2010    type Remainder = U0;
2011
2012    #[inline]
2013    fn private_div_if_quotient(self, _: N, _: D, q: Q, _: R, i: U0, _: Equal) -> Self::Quotient {
2014        q.set_bit::<Internal>(i, B1)
2015    }
2016
2017    #[inline]
2018    fn private_div_if_remainder(self, _: N, _: D, _: Q, _: R, i: U0, _: Equal) -> Self::Remainder {
2019        i
2020    }
2021}
2022
2023// R > D, I == 0: We set R -= D, Q[I] = 1, and return
2024impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Greater> for ()
2025where
2026    R: Sub<D>,
2027    Q: SetBit<U0, B1>,
2028{
2029    type Quotient = SetBitOut<Q, U0, B1>;
2030    type Remainder = Diff<R, D>;
2031
2032    #[inline]
2033    fn private_div_if_quotient(self, _: N, _: D, q: Q, _: R, i: U0, _: Greater) -> Self::Quotient {
2034        q.set_bit::<Internal>(i, B1)
2035    }
2036
2037    #[inline]
2038    fn private_div_if_remainder(
2039        self,
2040        _: N,
2041        d: D,
2042        _: Q,
2043        r: R,
2044        _: U0,
2045        _: Greater,
2046    ) -> Self::Remainder {
2047        r - d
2048    }
2049}
2050
2051// -----------------------------------------
2052// PartialDiv
2053use crate::{PartialDiv, Quot};
2054impl<Ur: Unsigned, Br: Bit> PartialDiv<UInt<Ur, Br>> for UTerm {
2055    type Output = UTerm;
2056    #[inline]
2057    fn partial_div(self, _: UInt<Ur, Br>) -> Self::Output {
2058        UTerm
2059    }
2060}
2061
2062// M / N
2063impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> PartialDiv<UInt<Ur, Br>> for UInt<Ul, Bl>
2064where
2065    UInt<Ul, Bl>: Div<UInt<Ur, Br>> + Rem<UInt<Ur, Br>, Output = U0>,
2066{
2067    type Output = Quot<UInt<Ul, Bl>, UInt<Ur, Br>>;
2068    #[inline]
2069    fn partial_div(self, rhs: UInt<Ur, Br>) -> Self::Output {
2070        self / rhs
2071    }
2072}
2073
2074// -----------------------------------------
2075// PrivateMin
2076use crate::private::{PrivateMin, PrivateMinOut};
2077
2078impl<U, B, Ur> PrivateMin<Ur, Equal> for UInt<U, B>
2079where
2080    Ur: Unsigned,
2081    U: Unsigned,
2082    B: Bit,
2083{
2084    type Output = UInt<U, B>;
2085    #[inline]
2086    fn private_min(self, _: Ur) -> Self::Output {
2087        self
2088    }
2089}
2090
2091impl<U, B, Ur> PrivateMin<Ur, Less> for UInt<U, B>
2092where
2093    Ur: Unsigned,
2094    U: Unsigned,
2095    B: Bit,
2096{
2097    type Output = UInt<U, B>;
2098    #[inline]
2099    fn private_min(self, _: Ur) -> Self::Output {
2100        self
2101    }
2102}
2103
2104impl<U, B, Ur> PrivateMin<Ur, Greater> for UInt<U, B>
2105where
2106    Ur: Unsigned,
2107    U: Unsigned,
2108    B: Bit,
2109{
2110    type Output = Ur;
2111    #[inline]
2112    fn private_min(self, rhs: Ur) -> Self::Output {
2113        rhs
2114    }
2115}
2116
2117// -----------------------------------------
2118// Min
2119use crate::Min;
2120
2121impl<U> Min<U> for UTerm
2122where
2123    U: Unsigned,
2124{
2125    type Output = UTerm;
2126    #[inline]
2127    fn min(self, _: U) -> Self::Output {
2128        self
2129    }
2130}
2131
2132impl<U, B, Ur> Min<Ur> for UInt<U, B>
2133where
2134    U: Unsigned,
2135    B: Bit,
2136    Ur: Unsigned,
2137    UInt<U, B>: Cmp<Ur> + PrivateMin<Ur, Compare<UInt<U, B>, Ur>>,
2138{
2139    type Output = PrivateMinOut<UInt<U, B>, Ur, Compare<UInt<U, B>, Ur>>;
2140    #[inline]
2141    fn min(self, rhs: Ur) -> Self::Output {
2142        self.private_min(rhs)
2143    }
2144}
2145
2146// -----------------------------------------
2147// PrivateMax
2148use crate::private::{PrivateMax, PrivateMaxOut};
2149
2150impl<U, B, Ur> PrivateMax<Ur, Equal> for UInt<U, B>
2151where
2152    Ur: Unsigned,
2153    U: Unsigned,
2154    B: Bit,
2155{
2156    type Output = UInt<U, B>;
2157    #[inline]
2158    fn private_max(self, _: Ur) -> Self::Output {
2159        self
2160    }
2161}
2162
2163impl<U, B, Ur> PrivateMax<Ur, Less> for UInt<U, B>
2164where
2165    Ur: Unsigned,
2166    U: Unsigned,
2167    B: Bit,
2168{
2169    type Output = Ur;
2170    #[inline]
2171    fn private_max(self, rhs: Ur) -> Self::Output {
2172        rhs
2173    }
2174}
2175
2176impl<U, B, Ur> PrivateMax<Ur, Greater> for UInt<U, B>
2177where
2178    Ur: Unsigned,
2179    U: Unsigned,
2180    B: Bit,
2181{
2182    type Output = UInt<U, B>;
2183    #[inline]
2184    fn private_max(self, _: Ur) -> Self::Output {
2185        self
2186    }
2187}
2188
2189// -----------------------------------------
2190// Max
2191use crate::Max;
2192
2193impl<U> Max<U> for UTerm
2194where
2195    U: Unsigned,
2196{
2197    type Output = U;
2198    #[inline]
2199    fn max(self, rhs: U) -> Self::Output {
2200        rhs
2201    }
2202}
2203
2204impl<U, B, Ur> Max<Ur> for UInt<U, B>
2205where
2206    U: Unsigned,
2207    B: Bit,
2208    Ur: Unsigned,
2209    UInt<U, B>: Cmp<Ur> + PrivateMax<Ur, Compare<UInt<U, B>, Ur>>,
2210{
2211    type Output = PrivateMaxOut<UInt<U, B>, Ur, Compare<UInt<U, B>, Ur>>;
2212    #[inline]
2213    fn max(self, rhs: Ur) -> Self::Output {
2214        self.private_max(rhs)
2215    }
2216}
2217
2218// -----------------------------------------
2219// SquareRoot
2220
2221impl<N> SquareRoot for N
2222where
2223    N: PrivateSquareRoot,
2224{
2225    type Output = <Self as PrivateSquareRoot>::Output;
2226}
2227
2228// sqrt(0) = 0.
2229impl PrivateSquareRoot for UTerm {
2230    type Output = UTerm;
2231}
2232
2233// sqrt(1) = 1.
2234impl PrivateSquareRoot for UInt<UTerm, B1> {
2235    type Output = UInt<UTerm, B1>;
2236}
2237
2238// General case of sqrt(Self) where Self >= 2. If a and b are
2239// bit-valued and Self = 4*u + 2*a + b, then the integer-valued
2240// (fractional part truncated) square root of Self is either 2*sqrt(u)
2241// or 2*sqrt(u)+1. Guess and check by comparing (2*sqrt(u)+1)^2
2242// against Self. Since the `typenum` result of that comparison is a
2243// bit, directly add that bit to 2*sqrt(u).
2244//
2245// Use `Sum<Double<Sqrt<U>>, GrEq<...>>` instead of `UInt<Sqrt<U>,
2246// GrEq<...>>` because `Sqrt<U>` can turn out to be `UTerm` and
2247// `GrEq<...>` can turn out to be `B0`, which would not be a valid
2248// UInt as leading zeros are disallowed.
2249impl<U, Ba, Bb> PrivateSquareRoot for UInt<UInt<U, Ba>, Bb>
2250where
2251    U: Unsigned,
2252    Ba: Bit,
2253    Bb: Bit,
2254    U: SquareRoot,
2255    Sqrt<U>: Shl<B1>,
2256    Double<Sqrt<U>>: Add<B1>,
2257    Add1<Double<Sqrt<U>>>: Mul,
2258    Self: IsGreaterOrEqual<Square<Add1<Double<Sqrt<U>>>>>,
2259    Double<Sqrt<U>>: Add<GrEq<Self, Square<Add1<Double<Sqrt<U>>>>>>,
2260{
2261    type Output = Sum<Double<Sqrt<U>>, GrEq<Self, Square<Add1<Double<Sqrt<U>>>>>>;
2262}
2263
2264#[test]
2265fn sqrt_test() {
2266    use crate::consts::*;
2267
2268    assert_eq!(0, <Sqrt<U0>>::to_u32());
2269
2270    assert_eq!(1, <Sqrt<U1>>::to_u32());
2271    assert_eq!(1, <Sqrt<U2>>::to_u32());
2272    assert_eq!(1, <Sqrt<U3>>::to_u32());
2273
2274    assert_eq!(2, <Sqrt<U4>>::to_u32());
2275    assert_eq!(2, <Sqrt<U5>>::to_u32());
2276    assert_eq!(2, <Sqrt<U6>>::to_u32());
2277    assert_eq!(2, <Sqrt<U7>>::to_u32());
2278    assert_eq!(2, <Sqrt<U8>>::to_u32());
2279
2280    assert_eq!(3, <Sqrt<U9>>::to_u32());
2281    assert_eq!(3, <Sqrt<U10>>::to_u32());
2282    assert_eq!(3, <Sqrt<U11>>::to_u32());
2283    assert_eq!(3, <Sqrt<U12>>::to_u32());
2284    assert_eq!(3, <Sqrt<U13>>::to_u32());
2285    assert_eq!(3, <Sqrt<U14>>::to_u32());
2286    assert_eq!(3, <Sqrt<U15>>::to_u32());
2287
2288    assert_eq!(4, <Sqrt<U16>>::to_u32());
2289    assert_eq!(4, <Sqrt<U17>>::to_u32());
2290    assert_eq!(4, <Sqrt<U18>>::to_u32());
2291    assert_eq!(4, <Sqrt<U19>>::to_u32());
2292    assert_eq!(4, <Sqrt<U20>>::to_u32());
2293    assert_eq!(4, <Sqrt<U21>>::to_u32());
2294    assert_eq!(4, <Sqrt<U22>>::to_u32());
2295    assert_eq!(4, <Sqrt<U23>>::to_u32());
2296    assert_eq!(4, <Sqrt<U24>>::to_u32());
2297
2298    assert_eq!(5, <Sqrt<U25>>::to_u32());
2299    assert_eq!(5, <Sqrt<U26>>::to_u32());
2300    // ...
2301}
2302
2303// -----------------------------------------
2304// Logarithm2
2305
2306impl<N> Logarithm2 for N
2307where
2308    N: PrivateLogarithm2,
2309{
2310    type Output = <Self as PrivateLogarithm2>::Output;
2311}
2312
2313// log2(1) = 0.
2314impl PrivateLogarithm2 for UInt<UTerm, B1> {
2315    type Output = U0;
2316}
2317
2318// General case of log2(Self) where Self >= 2.
2319impl<U, B> PrivateLogarithm2 for UInt<U, B>
2320where
2321    U: Unsigned + Logarithm2,
2322    B: Bit,
2323    Log2<U>: Add<B1>,
2324{
2325    type Output = Add1<Log2<U>>;
2326}
2327
2328// -----------------------------------------
2329// ToInt
2330
2331impl ToInt<i8> for UTerm {
2332    #[inline]
2333    fn to_int() -> i8 {
2334        Self::I8
2335    }
2336    const INT: i8 = Self::I8;
2337}
2338
2339impl ToInt<i16> for UTerm {
2340    #[inline]
2341    fn to_int() -> i16 {
2342        Self::I16
2343    }
2344    const INT: i16 = Self::I16;
2345}
2346
2347impl ToInt<i32> for UTerm {
2348    #[inline]
2349    fn to_int() -> i32 {
2350        Self::I32
2351    }
2352    const INT: i32 = Self::I32;
2353}
2354
2355impl ToInt<i64> for UTerm {
2356    #[inline]
2357    fn to_int() -> i64 {
2358        Self::I64
2359    }
2360    const INT: i64 = Self::I64;
2361}
2362
2363impl ToInt<u8> for UTerm {
2364    #[inline]
2365    fn to_int() -> u8 {
2366        Self::U8
2367    }
2368    const INT: u8 = Self::U8;
2369}
2370
2371impl ToInt<u16> for UTerm {
2372    #[inline]
2373    fn to_int() -> u16 {
2374        Self::U16
2375    }
2376    const INT: u16 = Self::U16;
2377}
2378
2379impl ToInt<u32> for UTerm {
2380    #[inline]
2381    fn to_int() -> u32 {
2382        Self::U32
2383    }
2384    const INT: u32 = Self::U32;
2385}
2386
2387impl ToInt<u64> for UTerm {
2388    #[inline]
2389    fn to_int() -> u64 {
2390        Self::U64
2391    }
2392    const INT: u64 = Self::U64;
2393}
2394
2395impl ToInt<usize> for UTerm {
2396    #[inline]
2397    fn to_int() -> usize {
2398        Self::USIZE
2399    }
2400    const INT: usize = Self::USIZE;
2401}
2402
2403impl<U, B> ToInt<i8> for UInt<U, B>
2404where
2405    U: Unsigned,
2406    B: Bit,
2407{
2408    #[inline]
2409    fn to_int() -> i8 {
2410        Self::I8
2411    }
2412    const INT: i8 = Self::I8;
2413}
2414
2415impl<U, B> ToInt<i16> for UInt<U, B>
2416where
2417    U: Unsigned,
2418    B: Bit,
2419{
2420    #[inline]
2421    fn to_int() -> i16 {
2422        Self::I16
2423    }
2424    const INT: i16 = Self::I16;
2425}
2426
2427impl<U, B> ToInt<i32> for UInt<U, B>
2428where
2429    U: Unsigned,
2430    B: Bit,
2431{
2432    #[inline]
2433    fn to_int() -> i32 {
2434        Self::I32
2435    }
2436    const INT: i32 = Self::I32;
2437}
2438
2439impl<U, B> ToInt<i64> for UInt<U, B>
2440where
2441    U: Unsigned,
2442    B: Bit,
2443{
2444    #[inline]
2445    fn to_int() -> i64 {
2446        Self::I64
2447    }
2448    const INT: i64 = Self::I64;
2449}
2450
2451impl<U, B> ToInt<u8> for UInt<U, B>
2452where
2453    U: Unsigned,
2454    B: Bit,
2455{
2456    #[inline]
2457    fn to_int() -> u8 {
2458        Self::U8
2459    }
2460    const INT: u8 = Self::U8;
2461}
2462
2463impl<U, B> ToInt<u16> for UInt<U, B>
2464where
2465    U: Unsigned,
2466    B: Bit,
2467{
2468    #[inline]
2469    fn to_int() -> u16 {
2470        Self::U16
2471    }
2472    const INT: u16 = Self::U16;
2473}
2474
2475impl<U, B> ToInt<u32> for UInt<U, B>
2476where
2477    U: Unsigned,
2478    B: Bit,
2479{
2480    #[inline]
2481    fn to_int() -> u32 {
2482        Self::U32
2483    }
2484    const INT: u32 = Self::U32;
2485}
2486
2487impl<U, B> ToInt<u64> for UInt<U, B>
2488where
2489    U: Unsigned,
2490    B: Bit,
2491{
2492    #[inline]
2493    fn to_int() -> u64 {
2494        Self::U64
2495    }
2496    const INT: u64 = Self::U64;
2497}
2498
2499impl<U, B> ToInt<usize> for UInt<U, B>
2500where
2501    U: Unsigned,
2502    B: Bit,
2503{
2504    #[inline]
2505    fn to_int() -> usize {
2506        Self::USIZE
2507    }
2508    const INT: usize = Self::USIZE;
2509}
2510
2511#[cfg(test)]
2512mod tests {
2513    use crate::consts::*;
2514    use crate::{Log2, ToInt, Unsigned};
2515
2516    #[test]
2517    fn log2_test() {
2518        assert_eq!(0, <Log2<U1>>::to_u32());
2519
2520        assert_eq!(1, <Log2<U2>>::to_u32());
2521        assert_eq!(1, <Log2<U3>>::to_u32());
2522
2523        assert_eq!(2, <Log2<U4>>::to_u32());
2524        assert_eq!(2, <Log2<U5>>::to_u32());
2525        assert_eq!(2, <Log2<U6>>::to_u32());
2526        assert_eq!(2, <Log2<U7>>::to_u32());
2527
2528        assert_eq!(3, <Log2<U8>>::to_u32());
2529        assert_eq!(3, <Log2<U9>>::to_u32());
2530        assert_eq!(3, <Log2<U10>>::to_u32());
2531        assert_eq!(3, <Log2<U11>>::to_u32());
2532        assert_eq!(3, <Log2<U12>>::to_u32());
2533        assert_eq!(3, <Log2<U13>>::to_u32());
2534        assert_eq!(3, <Log2<U14>>::to_u32());
2535        assert_eq!(3, <Log2<U15>>::to_u32());
2536
2537        assert_eq!(4, <Log2<U16>>::to_u32());
2538        assert_eq!(4, <Log2<U17>>::to_u32());
2539        assert_eq!(4, <Log2<U18>>::to_u32());
2540        assert_eq!(4, <Log2<U19>>::to_u32());
2541        assert_eq!(4, <Log2<U20>>::to_u32());
2542        assert_eq!(4, <Log2<U21>>::to_u32());
2543        assert_eq!(4, <Log2<U22>>::to_u32());
2544        assert_eq!(4, <Log2<U23>>::to_u32());
2545        assert_eq!(4, <Log2<U24>>::to_u32());
2546        assert_eq!(4, <Log2<U25>>::to_u32());
2547        assert_eq!(4, <Log2<U26>>::to_u32());
2548        assert_eq!(4, <Log2<U27>>::to_u32());
2549        assert_eq!(4, <Log2<U28>>::to_u32());
2550        assert_eq!(4, <Log2<U29>>::to_u32());
2551        assert_eq!(4, <Log2<U30>>::to_u32());
2552        assert_eq!(4, <Log2<U31>>::to_u32());
2553
2554        assert_eq!(5, <Log2<U32>>::to_u32());
2555        assert_eq!(5, <Log2<U33>>::to_u32());
2556
2557        // ...
2558    }
2559
2560    #[test]
2561    fn uint_toint_test() {
2562        // i8
2563        assert_eq!(0_i8, U0::to_int());
2564        assert_eq!(1_i8, U1::to_int());
2565        assert_eq!(2_i8, U2::to_int());
2566        assert_eq!(3_i8, U3::to_int());
2567        assert_eq!(4_i8, U4::to_int());
2568        assert_eq!(0_i8, U0::INT);
2569        assert_eq!(1_i8, U1::INT);
2570        assert_eq!(2_i8, U2::INT);
2571        assert_eq!(3_i8, U3::INT);
2572        assert_eq!(4_i8, U4::INT);
2573
2574        // i16
2575        assert_eq!(0_i16, U0::to_int());
2576        assert_eq!(1_i16, U1::to_int());
2577        assert_eq!(2_i16, U2::to_int());
2578        assert_eq!(3_i16, U3::to_int());
2579        assert_eq!(4_i16, U4::to_int());
2580        assert_eq!(0_i16, U0::INT);
2581        assert_eq!(1_i16, U1::INT);
2582        assert_eq!(2_i16, U2::INT);
2583        assert_eq!(3_i16, U3::INT);
2584        assert_eq!(4_i16, U4::INT);
2585
2586        // i32
2587        assert_eq!(0_i32, U0::to_int());
2588        assert_eq!(1_i32, U1::to_int());
2589        assert_eq!(2_i32, U2::to_int());
2590        assert_eq!(3_i32, U3::to_int());
2591        assert_eq!(4_i32, U4::to_int());
2592        assert_eq!(0_i32, U0::INT);
2593        assert_eq!(1_i32, U1::INT);
2594        assert_eq!(2_i32, U2::INT);
2595        assert_eq!(3_i32, U3::INT);
2596        assert_eq!(4_i32, U4::INT);
2597
2598        // i64
2599        assert_eq!(0_i64, U0::to_int());
2600        assert_eq!(1_i64, U1::to_int());
2601        assert_eq!(2_i64, U2::to_int());
2602        assert_eq!(3_i64, U3::to_int());
2603        assert_eq!(4_i64, U4::to_int());
2604        assert_eq!(0_i64, U0::INT);
2605        assert_eq!(1_i64, U1::INT);
2606        assert_eq!(2_i64, U2::INT);
2607        assert_eq!(3_i64, U3::INT);
2608        assert_eq!(4_i64, U4::INT);
2609
2610        // u8
2611        assert_eq!(0_u8, U0::to_int());
2612        assert_eq!(1_u8, U1::to_int());
2613        assert_eq!(2_u8, U2::to_int());
2614        assert_eq!(3_u8, U3::to_int());
2615        assert_eq!(4_u8, U4::to_int());
2616        assert_eq!(0_u8, U0::INT);
2617        assert_eq!(1_u8, U1::INT);
2618        assert_eq!(2_u8, U2::INT);
2619        assert_eq!(3_u8, U3::INT);
2620        assert_eq!(4_u8, U4::INT);
2621
2622        // u16
2623        assert_eq!(0_u16, U0::to_int());
2624        assert_eq!(1_u16, U1::to_int());
2625        assert_eq!(2_u16, U2::to_int());
2626        assert_eq!(3_u16, U3::to_int());
2627        assert_eq!(4_u16, U4::to_int());
2628        assert_eq!(0_u16, U0::INT);
2629        assert_eq!(1_u16, U1::INT);
2630        assert_eq!(2_u16, U2::INT);
2631        assert_eq!(3_u16, U3::INT);
2632        assert_eq!(4_u16, U4::INT);
2633
2634        // u32
2635        assert_eq!(0_u32, U0::to_int());
2636        assert_eq!(1_u32, U1::to_int());
2637        assert_eq!(2_u32, U2::to_int());
2638        assert_eq!(3_u32, U3::to_int());
2639        assert_eq!(4_u32, U4::to_int());
2640        assert_eq!(0_u32, U0::INT);
2641        assert_eq!(1_u32, U1::INT);
2642        assert_eq!(2_u32, U2::INT);
2643        assert_eq!(3_u32, U3::INT);
2644        assert_eq!(4_u32, U4::INT);
2645
2646        // u64
2647        assert_eq!(0_u64, U0::to_int());
2648        assert_eq!(1_u64, U1::to_int());
2649        assert_eq!(2_u64, U2::to_int());
2650        assert_eq!(3_u64, U3::to_int());
2651        assert_eq!(4_u64, U4::to_int());
2652        assert_eq!(0_u64, U0::INT);
2653        assert_eq!(1_u64, U1::INT);
2654        assert_eq!(2_u64, U2::INT);
2655        assert_eq!(3_u64, U3::INT);
2656        assert_eq!(4_u64, U4::INT);
2657
2658        // usize
2659        assert_eq!(0_usize, U0::to_int());
2660        assert_eq!(1_usize, U1::to_int());
2661        assert_eq!(2_usize, U2::to_int());
2662        assert_eq!(3_usize, U3::to_int());
2663        assert_eq!(4_usize, U4::to_int());
2664        assert_eq!(0_usize, U0::INT);
2665        assert_eq!(1_usize, U1::INT);
2666        assert_eq!(2_usize, U2::INT);
2667        assert_eq!(3_usize, U3::INT);
2668        assert_eq!(4_usize, U4::INT);
2669    }
2670}