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