typenum/
int.rs

1//! Type-level signed integers.
2//!
3//!
4//! Type **operators** implemented:
5//!
6//! From `core::ops`: `Add`, `Sub`, `Mul`, `Div`, and `Rem`.
7//! From `typenum`: `Same`, `Cmp`, and `Pow`.
8//!
9//! Rather than directly using the structs defined in this module, it is recommended that
10//! you import and use the relevant aliases from the [consts](../consts/index.html) module.
11//!
12//! Note that operators that work on the underlying structure of the number are
13//! intentionally not implemented. This is because this implementation of signed integers
14//! does *not* use twos-complement, and implementing them would require making arbitrary
15//! choices, causing the results of such operators to be difficult to reason about.
16//!
17//! # Example
18//! ```rust
19//! use std::ops::{Add, Div, Mul, Rem, Sub};
20//! use typenum::{Integer, N3, P2};
21//!
22//! assert_eq!(<N3 as Add<P2>>::Output::to_i32(), -1);
23//! assert_eq!(<N3 as Sub<P2>>::Output::to_i32(), -5);
24//! assert_eq!(<N3 as Mul<P2>>::Output::to_i32(), -6);
25//! assert_eq!(<N3 as Div<P2>>::Output::to_i32(), -1);
26//! assert_eq!(<N3 as Rem<P2>>::Output::to_i32(), -1);
27//! ```
28
29pub use crate::marker_traits::Integer;
30use crate::{
31    bit::{Bit, B0, B1},
32    consts::{N1, P1, U0, U1},
33    private::{Internal, InternalMarker, PrivateDivInt, PrivateIntegerAdd, PrivateRem},
34    uint::{UInt, Unsigned},
35    Cmp, Equal, Greater, Less, NonZero, Pow, PowerOfTwo, ToInt, Zero,
36};
37use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
38
39/// Type-level signed integers with positive sign.
40#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
41#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
42pub struct PInt<U: Unsigned + NonZero> {
43    pub(crate) n: U,
44}
45
46/// Type-level signed integers with negative sign.
47#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
48#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
49pub struct NInt<U: Unsigned + NonZero> {
50    pub(crate) n: U,
51}
52
53impl<U: Unsigned + NonZero> PInt<U> {
54    /// Instantiates a singleton representing this strictly positive integer.
55    #[inline]
56    pub fn new() -> PInt<U> {
57        PInt::default()
58    }
59}
60
61impl<U: Unsigned + NonZero> NInt<U> {
62    /// Instantiates a singleton representing this strictly negative integer.
63    #[inline]
64    pub fn new() -> NInt<U> {
65        NInt::default()
66    }
67}
68
69/// The type-level signed integer 0.
70#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
71#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
72pub struct Z0;
73
74impl Z0 {
75    /// Instantiates a singleton representing the integer 0.
76    #[inline]
77    pub fn new() -> Z0 {
78        Z0
79    }
80}
81
82impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
83impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
84impl Zero for Z0 {}
85
86impl<U: Unsigned + NonZero + PowerOfTwo> PowerOfTwo for PInt<U> {}
87
88impl Integer for Z0 {
89    const I8: i8 = 0;
90    const I16: i16 = 0;
91    const I32: i32 = 0;
92    const I64: i64 = 0;
93    #[cfg(feature = "i128")]
94    const I128: i128 = 0;
95    const ISIZE: isize = 0;
96
97    #[inline]
98    fn to_i8() -> i8 {
99        0
100    }
101    #[inline]
102    fn to_i16() -> i16 {
103        0
104    }
105    #[inline]
106    fn to_i32() -> i32 {
107        0
108    }
109    #[inline]
110    fn to_i64() -> i64 {
111        0
112    }
113    #[cfg(feature = "i128")]
114    #[inline]
115    fn to_i128() -> i128 {
116        0
117    }
118    #[inline]
119    fn to_isize() -> isize {
120        0
121    }
122}
123
124impl<U: Unsigned + NonZero> Integer for PInt<U> {
125    const I8: i8 = U::I8;
126    const I16: i16 = U::I16;
127    const I32: i32 = U::I32;
128    const I64: i64 = U::I64;
129    #[cfg(feature = "i128")]
130    const I128: i128 = U::I128;
131    const ISIZE: isize = U::ISIZE;
132
133    #[inline]
134    fn to_i8() -> i8 {
135        <U as Unsigned>::to_i8()
136    }
137    #[inline]
138    fn to_i16() -> i16 {
139        <U as Unsigned>::to_i16()
140    }
141    #[inline]
142    fn to_i32() -> i32 {
143        <U as Unsigned>::to_i32()
144    }
145    #[inline]
146    fn to_i64() -> i64 {
147        <U as Unsigned>::to_i64()
148    }
149    #[cfg(feature = "i128")]
150    #[inline]
151    fn to_i128() -> i128 {
152        <U as Unsigned>::to_i128()
153    }
154    #[inline]
155    fn to_isize() -> isize {
156        <U as Unsigned>::to_isize()
157    }
158}
159
160// Simply negating the result of e.g. `U::I8` will result in overflow for `std::i8::MIN`. Instead,
161// we use the fact that `U: NonZero` by subtracting one from the `U::U8` before negating.
162impl<U: Unsigned + NonZero> Integer for NInt<U> {
163    const I8: i8 = -((U::U8 - 1) as i8) - 1;
164    const I16: i16 = -((U::U16 - 1) as i16) - 1;
165    const I32: i32 = -((U::U32 - 1) as i32) - 1;
166    const I64: i64 = -((U::U64 - 1) as i64) - 1;
167    #[cfg(feature = "i128")]
168    const I128: i128 = -((U::U128 - 1) as i128) - 1;
169    const ISIZE: isize = -((U::USIZE - 1) as isize) - 1;
170
171    #[inline]
172    fn to_i8() -> i8 {
173        Self::I8
174    }
175    #[inline]
176    fn to_i16() -> i16 {
177        Self::I16
178    }
179    #[inline]
180    fn to_i32() -> i32 {
181        Self::I32
182    }
183    #[inline]
184    fn to_i64() -> i64 {
185        Self::I64
186    }
187    #[cfg(feature = "i128")]
188    #[inline]
189    fn to_i128() -> i128 {
190        Self::I128
191    }
192    #[inline]
193    fn to_isize() -> isize {
194        Self::ISIZE
195    }
196}
197
198// ---------------------------------------------------------------------------------------
199// Neg
200
201/// `-Z0 = Z0`
202impl Neg for Z0 {
203    type Output = Z0;
204    #[inline]
205    fn neg(self) -> Self::Output {
206        Z0
207    }
208}
209
210/// `-PInt = NInt`
211impl<U: Unsigned + NonZero> Neg for PInt<U> {
212    type Output = NInt<U>;
213    #[inline]
214    fn neg(self) -> Self::Output {
215        NInt::new()
216    }
217}
218
219/// `-NInt = PInt`
220impl<U: Unsigned + NonZero> Neg for NInt<U> {
221    type Output = PInt<U>;
222    #[inline]
223    fn neg(self) -> Self::Output {
224        PInt::new()
225    }
226}
227
228// ---------------------------------------------------------------------------------------
229// Add
230
231/// `Z0 + I = I`
232impl<I: Integer> Add<I> for Z0 {
233    type Output = I;
234    #[inline]
235    fn add(self, rhs: I) -> Self::Output {
236        rhs
237    }
238}
239
240/// `PInt + Z0 = PInt`
241impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
242    type Output = PInt<U>;
243    #[inline]
244    fn add(self, _: Z0) -> Self::Output {
245        PInt::new()
246    }
247}
248
249/// `NInt + Z0 = NInt`
250impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
251    type Output = NInt<U>;
252    #[inline]
253    fn add(self, _: Z0) -> Self::Output {
254        NInt::new()
255    }
256}
257
258/// `P(Ul) + P(Ur) = P(Ul + Ur)`
259impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul>
260where
261    Ul: Add<Ur>,
262    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
263{
264    type Output = PInt<<Ul as Add<Ur>>::Output>;
265    #[inline]
266    fn add(self, _: PInt<Ur>) -> Self::Output {
267        PInt::new()
268    }
269}
270
271/// `N(Ul) + N(Ur) = N(Ul + Ur)`
272impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul>
273where
274    Ul: Add<Ur>,
275    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
276{
277    type Output = NInt<<Ul as Add<Ur>>::Output>;
278    #[inline]
279    fn add(self, _: NInt<Ur>) -> Self::Output {
280        NInt::new()
281    }
282}
283
284/// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
285impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul>
286where
287    Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
288{
289    type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
290    #[inline]
291    fn add(self, rhs: NInt<Ur>) -> Self::Output {
292        let lhs = self.n;
293        let rhs = rhs.n;
294        let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
295        lhs.private_integer_add(lhs_cmp_rhs, rhs)
296    }
297}
298
299/// `N(Ul) + P(Ur)`: We resolve this with our `PrivateAdd`
300// We just do the same thing as above, swapping Lhs and Rhs
301impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul>
302where
303    Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
304{
305    type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
306    #[inline]
307    fn add(self, rhs: PInt<Ur>) -> Self::Output {
308        let lhs = self.n;
309        let rhs = rhs.n;
310        let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
311        rhs.private_integer_add(rhs_cmp_lhs, lhs)
312    }
313}
314
315/// `P + N = 0` where `P == N`
316impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
317    type Output = Z0;
318
319    #[inline]
320    fn private_integer_add(self, _: Equal, _: N) -> Self::Output {
321        Z0
322    }
323}
324
325/// `P + N = Positive` where `P > N`
326impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P
327where
328    P: Sub<N>,
329    <P as Sub<N>>::Output: Unsigned + NonZero,
330{
331    type Output = PInt<<P as Sub<N>>::Output>;
332
333    #[inline]
334    fn private_integer_add(self, _: Greater, n: N) -> Self::Output {
335        PInt { n: self - n }
336    }
337}
338
339/// `P + N = Negative` where `P < N`
340impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P
341where
342    N: Sub<P>,
343    <N as Sub<P>>::Output: Unsigned + NonZero,
344{
345    type Output = NInt<<N as Sub<P>>::Output>;
346
347    #[inline]
348    fn private_integer_add(self, _: Less, n: N) -> Self::Output {
349        NInt { n: n - self }
350    }
351}
352
353// ---------------------------------------------------------------------------------------
354// Sub
355
356/// `Z0 - Z0 = Z0`
357impl Sub<Z0> for Z0 {
358    type Output = Z0;
359    #[inline]
360    fn sub(self, _: Z0) -> Self::Output {
361        Z0
362    }
363}
364
365/// `Z0 - P = N`
366impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
367    type Output = NInt<U>;
368    #[inline]
369    fn sub(self, _: PInt<U>) -> Self::Output {
370        NInt::new()
371    }
372}
373
374/// `Z0 - N = P`
375impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 {
376    type Output = PInt<U>;
377    #[inline]
378    fn sub(self, _: NInt<U>) -> Self::Output {
379        PInt::new()
380    }
381}
382
383/// `PInt - Z0 = PInt`
384impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> {
385    type Output = PInt<U>;
386    #[inline]
387    fn sub(self, _: Z0) -> Self::Output {
388        PInt::new()
389    }
390}
391
392/// `NInt - Z0 = NInt`
393impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
394    type Output = NInt<U>;
395    #[inline]
396    fn sub(self, _: Z0) -> Self::Output {
397        NInt::new()
398    }
399}
400
401/// `P(Ul) - N(Ur) = P(Ul + Ur)`
402impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul>
403where
404    Ul: Add<Ur>,
405    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
406{
407    type Output = PInt<<Ul as Add<Ur>>::Output>;
408    #[inline]
409    fn sub(self, _: NInt<Ur>) -> Self::Output {
410        PInt::new()
411    }
412}
413
414/// `N(Ul) - P(Ur) = N(Ul + Ur)`
415impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul>
416where
417    Ul: Add<Ur>,
418    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
419{
420    type Output = NInt<<Ul as Add<Ur>>::Output>;
421    #[inline]
422    fn sub(self, _: PInt<Ur>) -> Self::Output {
423        NInt::new()
424    }
425}
426
427/// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
428impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul>
429where
430    Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
431{
432    type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
433    #[inline]
434    fn sub(self, rhs: PInt<Ur>) -> Self::Output {
435        let lhs = self.n;
436        let rhs = rhs.n;
437        let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
438        lhs.private_integer_add(lhs_cmp_rhs, rhs)
439    }
440}
441
442/// `N(Ul) - N(Ur)`: We resolve this with our `PrivateAdd`
443// We just do the same thing as above, swapping Lhs and Rhs
444impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul>
445where
446    Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
447{
448    type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
449    #[inline]
450    fn sub(self, rhs: NInt<Ur>) -> Self::Output {
451        let lhs = self.n;
452        let rhs = rhs.n;
453        let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
454        rhs.private_integer_add(rhs_cmp_lhs, lhs)
455    }
456}
457
458// ---------------------------------------------------------------------------------------
459// Mul
460
461/// `Z0 * I = Z0`
462impl<I: Integer> Mul<I> for Z0 {
463    type Output = Z0;
464    #[inline]
465    fn mul(self, _: I) -> Self::Output {
466        Z0
467    }
468}
469
470/// `P * Z0 = Z0`
471impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
472    type Output = Z0;
473    #[inline]
474    fn mul(self, _: Z0) -> Self::Output {
475        Z0
476    }
477}
478
479/// `N * Z0 = Z0`
480impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
481    type Output = Z0;
482    #[inline]
483    fn mul(self, _: Z0) -> Self::Output {
484        Z0
485    }
486}
487
488/// P(Ul) * P(Ur) = P(Ul * Ur)
489impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul>
490where
491    Ul: Mul<Ur>,
492    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
493{
494    type Output = PInt<<Ul as Mul<Ur>>::Output>;
495    #[inline]
496    fn mul(self, _: PInt<Ur>) -> Self::Output {
497        PInt::new()
498    }
499}
500
501/// N(Ul) * N(Ur) = P(Ul * Ur)
502impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul>
503where
504    Ul: Mul<Ur>,
505    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
506{
507    type Output = PInt<<Ul as Mul<Ur>>::Output>;
508    #[inline]
509    fn mul(self, _: NInt<Ur>) -> Self::Output {
510        PInt::new()
511    }
512}
513
514/// P(Ul) * N(Ur) = N(Ul * Ur)
515impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul>
516where
517    Ul: Mul<Ur>,
518    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
519{
520    type Output = NInt<<Ul as Mul<Ur>>::Output>;
521    #[inline]
522    fn mul(self, _: NInt<Ur>) -> Self::Output {
523        NInt::new()
524    }
525}
526
527/// N(Ul) * P(Ur) = N(Ul * Ur)
528impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul>
529where
530    Ul: Mul<Ur>,
531    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
532{
533    type Output = NInt<<Ul as Mul<Ur>>::Output>;
534    #[inline]
535    fn mul(self, _: PInt<Ur>) -> Self::Output {
536        NInt::new()
537    }
538}
539
540// ---------------------------------------------------------------------------------------
541// Div
542
543/// `Z0 / I = Z0` where `I != 0`
544impl<I: Integer + NonZero> Div<I> for Z0 {
545    type Output = Z0;
546    #[inline]
547    fn div(self, _: I) -> Self::Output {
548        Z0
549    }
550}
551
552macro_rules! impl_int_div {
553    ($A:ident, $B:ident, $R:ident) => {
554        /// `$A<Ul> / $B<Ur> = $R<Ul / Ur>`
555        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Div<$B<Ur>> for $A<Ul>
556        where
557            Ul: Cmp<Ur>,
558            $A<Ul>: PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>,
559        {
560            type Output = <$A<Ul> as PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>>::Output;
561            #[inline]
562            fn div(self, rhs: $B<Ur>) -> Self::Output {
563                let lhs_cmp_rhs = self.n.compare::<Internal>(&rhs.n);
564                self.private_div_int(lhs_cmp_rhs, rhs)
565            }
566        }
567        impl<Ul, Ur> PrivateDivInt<Less, $B<Ur>> for $A<Ul>
568        where
569            Ul: Unsigned + NonZero,
570            Ur: Unsigned + NonZero,
571        {
572            type Output = Z0;
573
574            #[inline]
575            fn private_div_int(self, _: Less, _: $B<Ur>) -> Self::Output {
576                Z0
577            }
578        }
579        impl<Ul, Ur> PrivateDivInt<Equal, $B<Ur>> for $A<Ul>
580        where
581            Ul: Unsigned + NonZero,
582            Ur: Unsigned + NonZero,
583        {
584            type Output = $R<U1>;
585
586            #[inline]
587            fn private_div_int(self, _: Equal, _: $B<Ur>) -> Self::Output {
588                $R { n: U1::new() }
589            }
590        }
591        impl<Ul, Ur> PrivateDivInt<Greater, $B<Ur>> for $A<Ul>
592        where
593            Ul: Unsigned + NonZero + Div<Ur>,
594            Ur: Unsigned + NonZero,
595            <Ul as Div<Ur>>::Output: Unsigned + NonZero,
596        {
597            type Output = $R<<Ul as Div<Ur>>::Output>;
598
599            #[inline]
600            fn private_div_int(self, _: Greater, d: $B<Ur>) -> Self::Output {
601                $R { n: self.n / d.n }
602            }
603        }
604    };
605}
606
607impl_int_div!(PInt, PInt, PInt);
608impl_int_div!(PInt, NInt, NInt);
609impl_int_div!(NInt, PInt, NInt);
610impl_int_div!(NInt, NInt, PInt);
611
612// ---------------------------------------------------------------------------------------
613// PartialDiv
614
615use crate::{PartialDiv, Quot};
616
617impl<M, N> PartialDiv<N> for M
618where
619    M: Integer + Div<N> + Rem<N, Output = Z0>,
620{
621    type Output = Quot<M, N>;
622    #[inline]
623    fn partial_div(self, rhs: N) -> Self::Output {
624        self / rhs
625    }
626}
627
628// ---------------------------------------------------------------------------------------
629// Cmp
630
631/// 0 == 0
632impl Cmp<Z0> for Z0 {
633    type Output = Equal;
634
635    #[inline]
636    fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
637        Equal
638    }
639}
640
641/// 0 > -X
642impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
643    type Output = Greater;
644
645    #[inline]
646    fn compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output {
647        Greater
648    }
649}
650
651/// 0 < X
652impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
653    type Output = Less;
654
655    #[inline]
656    fn compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output {
657        Less
658    }
659}
660
661/// X > 0
662impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
663    type Output = Greater;
664
665    #[inline]
666    fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
667        Greater
668    }
669}
670
671/// -X < 0
672impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
673    type Output = Less;
674
675    #[inline]
676    fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
677        Less
678    }
679}
680
681/// -X < Y
682impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
683    type Output = Less;
684
685    #[inline]
686    fn compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output {
687        Less
688    }
689}
690
691/// X > - Y
692impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
693    type Output = Greater;
694
695    #[inline]
696    fn compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output {
697        Greater
698    }
699}
700
701/// X <==> Y
702impl<Pl: Cmp<Pr> + Unsigned + NonZero, Pr: Unsigned + NonZero> Cmp<PInt<Pr>> for PInt<Pl> {
703    type Output = <Pl as Cmp<Pr>>::Output;
704
705    #[inline]
706    fn compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output {
707        self.n.compare::<Internal>(&rhs.n)
708    }
709}
710
711/// -X <==> -Y
712impl<Nl: Unsigned + NonZero, Nr: Cmp<Nl> + Unsigned + NonZero> Cmp<NInt<Nr>> for NInt<Nl> {
713    type Output = <Nr as Cmp<Nl>>::Output;
714
715    #[inline]
716    fn compare<IM: InternalMarker>(&self, rhs: &NInt<Nr>) -> Self::Output {
717        rhs.n.compare::<Internal>(&self.n)
718    }
719}
720
721// ---------------------------------------------------------------------------------------
722// Rem
723
724/// `Z0 % I = Z0` where `I != 0`
725impl<I: Integer + NonZero> Rem<I> for Z0 {
726    type Output = Z0;
727    #[inline]
728    fn rem(self, _: I) -> Self::Output {
729        Z0
730    }
731}
732
733macro_rules! impl_int_rem {
734    ($A:ident, $B:ident, $R:ident) => {
735        /// `$A<Ul> % $B<Ur> = $R<Ul % Ur>`
736        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Rem<$B<Ur>> for $A<Ul>
737        where
738            Ul: Rem<Ur>,
739            $A<Ul>: PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>,
740        {
741            type Output = <$A<Ul> as PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>>::Output;
742            #[inline]
743            fn rem(self, rhs: $B<Ur>) -> Self::Output {
744                self.private_rem(self.n % rhs.n, rhs)
745            }
746        }
747        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> PrivateRem<U0, $B<Ur>> for $A<Ul> {
748            type Output = Z0;
749
750            #[inline]
751            fn private_rem(self, _: U0, _: $B<Ur>) -> Self::Output {
752                Z0
753            }
754        }
755        impl<Ul, Ur, U, B> PrivateRem<UInt<U, B>, $B<Ur>> for $A<Ul>
756        where
757            Ul: Unsigned + NonZero,
758            Ur: Unsigned + NonZero,
759            U: Unsigned,
760            B: Bit,
761        {
762            type Output = $R<UInt<U, B>>;
763
764            #[inline]
765            fn private_rem(self, urem: UInt<U, B>, _: $B<Ur>) -> Self::Output {
766                $R { n: urem }
767            }
768        }
769    };
770}
771
772impl_int_rem!(PInt, PInt, PInt);
773impl_int_rem!(PInt, NInt, PInt);
774impl_int_rem!(NInt, PInt, NInt);
775impl_int_rem!(NInt, NInt, NInt);
776
777// ---------------------------------------------------------------------------------------
778// Pow
779
780/// 0^0 = 1
781impl Pow<Z0> for Z0 {
782    type Output = P1;
783    #[inline]
784    fn powi(self, _: Z0) -> Self::Output {
785        P1::new()
786    }
787}
788
789/// 0^P = 0
790impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
791    type Output = Z0;
792    #[inline]
793    fn powi(self, _: PInt<U>) -> Self::Output {
794        Z0
795    }
796}
797
798/// 0^N = 0
799impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
800    type Output = Z0;
801    #[inline]
802    fn powi(self, _: NInt<U>) -> Self::Output {
803        Z0
804    }
805}
806
807/// 1^N = 1
808impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
809    type Output = P1;
810    #[inline]
811    fn powi(self, _: NInt<U>) -> Self::Output {
812        P1::new()
813    }
814}
815
816/// (-1)^N = 1 if N is even
817impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 {
818    type Output = P1;
819    #[inline]
820    fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output {
821        P1::new()
822    }
823}
824
825/// (-1)^N = -1 if N is odd
826impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 {
827    type Output = N1;
828    #[inline]
829    fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output {
830        N1::new()
831    }
832}
833
834/// P^0 = 1
835impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> {
836    type Output = P1;
837    #[inline]
838    fn powi(self, _: Z0) -> Self::Output {
839        P1::new()
840    }
841}
842
843/// N^0 = 1
844impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
845    type Output = P1;
846    #[inline]
847    fn powi(self, _: Z0) -> Self::Output {
848        P1::new()
849    }
850}
851
852/// P(Ul)^P(Ur) = P(Ul^Ur)
853impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul>
854where
855    Ul: Pow<Ur>,
856    <Ul as Pow<Ur>>::Output: Unsigned + NonZero,
857{
858    type Output = PInt<<Ul as Pow<Ur>>::Output>;
859    #[inline]
860    fn powi(self, _: PInt<Ur>) -> Self::Output {
861        PInt::new()
862    }
863}
864
865/// N(Ul)^P(Ur) = P(Ul^Ur) if Ur is even
866impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul>
867where
868    Ul: Pow<UInt<Ur, B0>>,
869    <Ul as Pow<UInt<Ur, B0>>>::Output: Unsigned + NonZero,
870{
871    type Output = PInt<<Ul as Pow<UInt<Ur, B0>>>::Output>;
872    #[inline]
873    fn powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output {
874        PInt::new()
875    }
876}
877
878/// N(Ul)^P(Ur) = N(Ul^Ur) if Ur is odd
879impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul>
880where
881    Ul: Pow<UInt<Ur, B1>>,
882    <Ul as Pow<UInt<Ur, B1>>>::Output: Unsigned + NonZero,
883{
884    type Output = NInt<<Ul as Pow<UInt<Ur, B1>>>::Output>;
885    #[inline]
886    fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
887        NInt::new()
888    }
889}
890
891// ---------------------------------------------------------------------------------------
892// Gcd
893use crate::{Gcd, Gcf};
894
895impl Gcd<Z0> for Z0 {
896    type Output = Z0;
897}
898
899impl<U> Gcd<PInt<U>> for Z0
900where
901    U: Unsigned + NonZero,
902{
903    type Output = PInt<U>;
904}
905
906impl<U> Gcd<Z0> for PInt<U>
907where
908    U: Unsigned + NonZero,
909{
910    type Output = PInt<U>;
911}
912
913impl<U> Gcd<NInt<U>> for Z0
914where
915    U: Unsigned + NonZero,
916{
917    type Output = PInt<U>;
918}
919
920impl<U> Gcd<Z0> for NInt<U>
921where
922    U: Unsigned + NonZero,
923{
924    type Output = PInt<U>;
925}
926
927impl<U1, U2> Gcd<PInt<U2>> for PInt<U1>
928where
929    U1: Unsigned + NonZero + Gcd<U2>,
930    U2: Unsigned + NonZero,
931    Gcf<U1, U2>: Unsigned + NonZero,
932{
933    type Output = PInt<Gcf<U1, U2>>;
934}
935
936impl<U1, U2> Gcd<PInt<U2>> for NInt<U1>
937where
938    U1: Unsigned + NonZero + Gcd<U2>,
939    U2: Unsigned + NonZero,
940    Gcf<U1, U2>: Unsigned + NonZero,
941{
942    type Output = PInt<Gcf<U1, U2>>;
943}
944
945impl<U1, U2> Gcd<NInt<U2>> for PInt<U1>
946where
947    U1: Unsigned + NonZero + Gcd<U2>,
948    U2: Unsigned + NonZero,
949    Gcf<U1, U2>: Unsigned + NonZero,
950{
951    type Output = PInt<Gcf<U1, U2>>;
952}
953
954impl<U1, U2> Gcd<NInt<U2>> for NInt<U1>
955where
956    U1: Unsigned + NonZero + Gcd<U2>,
957    U2: Unsigned + NonZero,
958    Gcf<U1, U2>: Unsigned + NonZero,
959{
960    type Output = PInt<Gcf<U1, U2>>;
961}
962
963// ---------------------------------------------------------------------------------------
964// Min
965use crate::{Max, Maximum, Min, Minimum};
966
967impl Min<Z0> for Z0 {
968    type Output = Z0;
969    #[inline]
970    fn min(self, _: Z0) -> Self::Output {
971        self
972    }
973}
974
975impl<U> Min<PInt<U>> for Z0
976where
977    U: Unsigned + NonZero,
978{
979    type Output = Z0;
980    #[inline]
981    fn min(self, _: PInt<U>) -> Self::Output {
982        self
983    }
984}
985
986impl<U> Min<NInt<U>> for Z0
987where
988    U: Unsigned + NonZero,
989{
990    type Output = NInt<U>;
991    #[inline]
992    fn min(self, rhs: NInt<U>) -> Self::Output {
993        rhs
994    }
995}
996
997impl<U> Min<Z0> for PInt<U>
998where
999    U: Unsigned + NonZero,
1000{
1001    type Output = Z0;
1002    #[inline]
1003    fn min(self, rhs: Z0) -> Self::Output {
1004        rhs
1005    }
1006}
1007
1008impl<U> Min<Z0> for NInt<U>
1009where
1010    U: Unsigned + NonZero,
1011{
1012    type Output = NInt<U>;
1013    #[inline]
1014    fn min(self, _: Z0) -> Self::Output {
1015        self
1016    }
1017}
1018
1019impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul>
1020where
1021    Ul: Unsigned + NonZero + Min<Ur>,
1022    Ur: Unsigned + NonZero,
1023    Minimum<Ul, Ur>: Unsigned + NonZero,
1024{
1025    type Output = PInt<Minimum<Ul, Ur>>;
1026    #[inline]
1027    fn min(self, rhs: PInt<Ur>) -> Self::Output {
1028        PInt {
1029            n: self.n.min(rhs.n),
1030        }
1031    }
1032}
1033
1034impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
1035where
1036    Ul: Unsigned + NonZero,
1037    Ur: Unsigned + NonZero,
1038{
1039    type Output = NInt<Ul>;
1040    #[inline]
1041    fn min(self, _: PInt<Ur>) -> Self::Output {
1042        self
1043    }
1044}
1045
1046impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul>
1047where
1048    Ul: Unsigned + NonZero,
1049    Ur: Unsigned + NonZero,
1050{
1051    type Output = NInt<Ur>;
1052    #[inline]
1053    fn min(self, rhs: NInt<Ur>) -> Self::Output {
1054        rhs
1055    }
1056}
1057
1058impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul>
1059where
1060    Ul: Unsigned + NonZero + Max<Ur>,
1061    Ur: Unsigned + NonZero,
1062    Maximum<Ul, Ur>: Unsigned + NonZero,
1063{
1064    type Output = NInt<Maximum<Ul, Ur>>;
1065    #[inline]
1066    fn min(self, rhs: NInt<Ur>) -> Self::Output {
1067        NInt {
1068            n: self.n.max(rhs.n),
1069        }
1070    }
1071}
1072
1073// ---------------------------------------------------------------------------------------
1074// Max
1075
1076impl Max<Z0> for Z0 {
1077    type Output = Z0;
1078    #[inline]
1079    fn max(self, _: Z0) -> Self::Output {
1080        self
1081    }
1082}
1083
1084impl<U> Max<PInt<U>> for Z0
1085where
1086    U: Unsigned + NonZero,
1087{
1088    type Output = PInt<U>;
1089    #[inline]
1090    fn max(self, rhs: PInt<U>) -> Self::Output {
1091        rhs
1092    }
1093}
1094
1095impl<U> Max<NInt<U>> for Z0
1096where
1097    U: Unsigned + NonZero,
1098{
1099    type Output = Z0;
1100    #[inline]
1101    fn max(self, _: NInt<U>) -> Self::Output {
1102        self
1103    }
1104}
1105
1106impl<U> Max<Z0> for PInt<U>
1107where
1108    U: Unsigned + NonZero,
1109{
1110    type Output = PInt<U>;
1111    #[inline]
1112    fn max(self, _: Z0) -> Self::Output {
1113        self
1114    }
1115}
1116
1117impl<U> Max<Z0> for NInt<U>
1118where
1119    U: Unsigned + NonZero,
1120{
1121    type Output = Z0;
1122    #[inline]
1123    fn max(self, rhs: Z0) -> Self::Output {
1124        rhs
1125    }
1126}
1127
1128impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul>
1129where
1130    Ul: Unsigned + NonZero + Max<Ur>,
1131    Ur: Unsigned + NonZero,
1132    Maximum<Ul, Ur>: Unsigned + NonZero,
1133{
1134    type Output = PInt<Maximum<Ul, Ur>>;
1135    #[inline]
1136    fn max(self, rhs: PInt<Ur>) -> Self::Output {
1137        PInt {
1138            n: self.n.max(rhs.n),
1139        }
1140    }
1141}
1142
1143impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
1144where
1145    Ul: Unsigned + NonZero,
1146    Ur: Unsigned + NonZero,
1147{
1148    type Output = PInt<Ur>;
1149    #[inline]
1150    fn max(self, rhs: PInt<Ur>) -> Self::Output {
1151        rhs
1152    }
1153}
1154
1155impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul>
1156where
1157    Ul: Unsigned + NonZero,
1158    Ur: Unsigned + NonZero,
1159{
1160    type Output = PInt<Ul>;
1161    #[inline]
1162    fn max(self, _: NInt<Ur>) -> Self::Output {
1163        self
1164    }
1165}
1166
1167impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul>
1168where
1169    Ul: Unsigned + NonZero + Min<Ur>,
1170    Ur: Unsigned + NonZero,
1171    Minimum<Ul, Ur>: Unsigned + NonZero,
1172{
1173    type Output = NInt<Minimum<Ul, Ur>>;
1174    #[inline]
1175    fn max(self, rhs: NInt<Ur>) -> Self::Output {
1176        NInt {
1177            n: self.n.min(rhs.n),
1178        }
1179    }
1180}
1181
1182// -----------------------------------------
1183// ToInt
1184
1185impl ToInt<i8> for Z0 {
1186    #[inline]
1187    fn to_int() -> i8 {
1188        Self::I8
1189    }
1190    const INT: i8 = Self::I8;
1191}
1192
1193impl ToInt<i16> for Z0 {
1194    #[inline]
1195    fn to_int() -> i16 {
1196        Self::I16
1197    }
1198    const INT: i16 = Self::I16;
1199}
1200
1201impl ToInt<i32> for Z0 {
1202    #[inline]
1203    fn to_int() -> i32 {
1204        Self::I32
1205    }
1206    const INT: i32 = Self::I32;
1207}
1208
1209impl ToInt<i64> for Z0 {
1210    #[inline]
1211    fn to_int() -> i64 {
1212        Self::I64
1213    }
1214    const INT: i64 = Self::I64;
1215}
1216
1217// negative numbers
1218
1219impl<U> ToInt<i8> for NInt<U>
1220where
1221    U: Unsigned + NonZero,
1222{
1223    #[inline]
1224    fn to_int() -> i8 {
1225        Self::I8
1226    }
1227    const INT: i8 = Self::I8;
1228}
1229
1230impl<U> ToInt<i16> for NInt<U>
1231where
1232    U: Unsigned + NonZero,
1233{
1234    #[inline]
1235    fn to_int() -> i16 {
1236        Self::I16
1237    }
1238    const INT: i16 = Self::I16;
1239}
1240
1241impl<U> ToInt<i32> for NInt<U>
1242where
1243    U: Unsigned + NonZero,
1244{
1245    #[inline]
1246    fn to_int() -> i32 {
1247        Self::I32
1248    }
1249    const INT: i32 = Self::I32;
1250}
1251
1252impl<U> ToInt<i64> for NInt<U>
1253where
1254    U: Unsigned + NonZero,
1255{
1256    #[inline]
1257    fn to_int() -> i64 {
1258        Self::I64
1259    }
1260    const INT: i64 = Self::I64;
1261}
1262
1263// positive numbers
1264
1265impl<U> ToInt<i8> for PInt<U>
1266where
1267    U: Unsigned + NonZero,
1268{
1269    #[inline]
1270    fn to_int() -> i8 {
1271        Self::I8
1272    }
1273    const INT: i8 = Self::I8;
1274}
1275
1276impl<U> ToInt<i16> for PInt<U>
1277where
1278    U: Unsigned + NonZero,
1279{
1280    #[inline]
1281    fn to_int() -> i16 {
1282        Self::I16
1283    }
1284    const INT: i16 = Self::I16;
1285}
1286
1287impl<U> ToInt<i32> for PInt<U>
1288where
1289    U: Unsigned + NonZero,
1290{
1291    #[inline]
1292    fn to_int() -> i32 {
1293        Self::I32
1294    }
1295    const INT: i32 = Self::I32;
1296}
1297
1298impl<U> ToInt<i64> for PInt<U>
1299where
1300    U: Unsigned + NonZero,
1301{
1302    #[inline]
1303    fn to_int() -> i64 {
1304        Self::I64
1305    }
1306    const INT: i64 = Self::I64;
1307}
1308
1309#[cfg(test)]
1310mod tests {
1311    use crate::{consts::*, Integer, ToInt};
1312
1313    #[test]
1314    fn to_ix_min() {
1315        assert_eq!(N128::to_i8(), ::core::i8::MIN);
1316        assert_eq!(N32768::to_i16(), ::core::i16::MIN);
1317    }
1318
1319    #[test]
1320    fn int_toint_test() {
1321        // i8
1322        assert_eq!(0_i8, Z0::to_int());
1323        assert_eq!(1_i8, P1::to_int());
1324        assert_eq!(2_i8, P2::to_int());
1325        assert_eq!(3_i8, P3::to_int());
1326        assert_eq!(4_i8, P4::to_int());
1327        assert_eq!(-1_i8, N1::to_int());
1328        assert_eq!(-2_i8, N2::to_int());
1329        assert_eq!(-3_i8, N3::to_int());
1330        assert_eq!(-4_i8, N4::to_int());
1331        assert_eq!(0_i8, Z0::INT);
1332        assert_eq!(1_i8, P1::INT);
1333        assert_eq!(2_i8, P2::INT);
1334        assert_eq!(3_i8, P3::INT);
1335        assert_eq!(4_i8, P4::INT);
1336        assert_eq!(-1_i8, N1::INT);
1337        assert_eq!(-2_i8, N2::INT);
1338        assert_eq!(-3_i8, N3::INT);
1339        assert_eq!(-4_i8, N4::INT);
1340
1341        // i16
1342        assert_eq!(0_i16, Z0::to_int());
1343        assert_eq!(1_i16, P1::to_int());
1344        assert_eq!(2_i16, P2::to_int());
1345        assert_eq!(3_i16, P3::to_int());
1346        assert_eq!(4_i16, P4::to_int());
1347        assert_eq!(-1_i16, N1::to_int());
1348        assert_eq!(-2_i16, N2::to_int());
1349        assert_eq!(-3_i16, N3::to_int());
1350        assert_eq!(-4_i16, N4::to_int());
1351        assert_eq!(0_i16, Z0::INT);
1352        assert_eq!(1_i16, P1::INT);
1353        assert_eq!(2_i16, P2::INT);
1354        assert_eq!(3_i16, P3::INT);
1355        assert_eq!(4_i16, P4::INT);
1356        assert_eq!(-1_i16, N1::INT);
1357        assert_eq!(-2_i16, N2::INT);
1358        assert_eq!(-3_i16, N3::INT);
1359        assert_eq!(-4_i16, N4::INT);
1360
1361        // i32
1362        assert_eq!(0_i32, Z0::to_int());
1363        assert_eq!(1_i32, P1::to_int());
1364        assert_eq!(2_i32, P2::to_int());
1365        assert_eq!(3_i32, P3::to_int());
1366        assert_eq!(4_i32, P4::to_int());
1367        assert_eq!(-1_i32, N1::to_int());
1368        assert_eq!(-2_i32, N2::to_int());
1369        assert_eq!(-3_i32, N3::to_int());
1370        assert_eq!(-4_i32, N4::to_int());
1371        assert_eq!(0_i32, Z0::INT);
1372        assert_eq!(1_i32, P1::INT);
1373        assert_eq!(2_i32, P2::INT);
1374        assert_eq!(3_i32, P3::INT);
1375        assert_eq!(4_i32, P4::INT);
1376        assert_eq!(-1_i32, N1::INT);
1377        assert_eq!(-2_i32, N2::INT);
1378        assert_eq!(-3_i32, N3::INT);
1379        assert_eq!(-4_i32, N4::INT);
1380
1381        // i64
1382        assert_eq!(0_i64, Z0::to_int());
1383        assert_eq!(1_i64, P1::to_int());
1384        assert_eq!(2_i64, P2::to_int());
1385        assert_eq!(3_i64, P3::to_int());
1386        assert_eq!(4_i64, P4::to_int());
1387        assert_eq!(-1_i64, N1::to_int());
1388        assert_eq!(-2_i64, N2::to_int());
1389        assert_eq!(-3_i64, N3::to_int());
1390        assert_eq!(-4_i64, N4::to_int());
1391        assert_eq!(0_i64, Z0::INT);
1392        assert_eq!(1_i64, P1::INT);
1393        assert_eq!(2_i64, P2::INT);
1394        assert_eq!(3_i64, P3::INT);
1395        assert_eq!(4_i64, P4::INT);
1396        assert_eq!(-1_i64, N1::INT);
1397        assert_eq!(-2_i64, N2::INT);
1398        assert_eq!(-3_i64, N3::INT);
1399        assert_eq!(-4_i64, N4::INT);
1400    }
1401}