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// Formatting as binary
200
201impl core::fmt::Binary for Z0 {
202    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
203        write!(f, "0")
204    }
205}
206
207impl<U: Unsigned + NonZero + core::fmt::Binary> core::fmt::Binary for PInt<U> {
208    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
209        write!(f, "+{:b}", self.n)
210    }
211}
212
213impl<U: Unsigned + NonZero + core::fmt::Binary> core::fmt::Binary for NInt<U> {
214    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
215        write!(f, "-{:b}", self.n)
216    }
217}
218
219// ---------------------------------------------------------------------------------------
220// Neg
221
222/// `-Z0 = Z0`
223impl Neg for Z0 {
224    type Output = Z0;
225    #[inline]
226    fn neg(self) -> Self::Output {
227        Z0
228    }
229}
230
231/// `-PInt = NInt`
232impl<U: Unsigned + NonZero> Neg for PInt<U> {
233    type Output = NInt<U>;
234    #[inline]
235    fn neg(self) -> Self::Output {
236        NInt::new()
237    }
238}
239
240/// `-NInt = PInt`
241impl<U: Unsigned + NonZero> Neg for NInt<U> {
242    type Output = PInt<U>;
243    #[inline]
244    fn neg(self) -> Self::Output {
245        PInt::new()
246    }
247}
248
249// ---------------------------------------------------------------------------------------
250// Add
251
252/// `Z0 + I = I`
253impl<I: Integer> Add<I> for Z0 {
254    type Output = I;
255    #[inline]
256    fn add(self, rhs: I) -> Self::Output {
257        rhs
258    }
259}
260
261/// `PInt + Z0 = PInt`
262impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
263    type Output = PInt<U>;
264    #[inline]
265    fn add(self, _: Z0) -> Self::Output {
266        PInt::new()
267    }
268}
269
270/// `NInt + Z0 = NInt`
271impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
272    type Output = NInt<U>;
273    #[inline]
274    fn add(self, _: Z0) -> Self::Output {
275        NInt::new()
276    }
277}
278
279/// `P(Ul) + P(Ur) = P(Ul + Ur)`
280impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul>
281where
282    Ul: Add<Ur>,
283    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
284{
285    type Output = PInt<<Ul as Add<Ur>>::Output>;
286    #[inline]
287    fn add(self, _: PInt<Ur>) -> Self::Output {
288        PInt::new()
289    }
290}
291
292/// `N(Ul) + N(Ur) = N(Ul + Ur)`
293impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul>
294where
295    Ul: Add<Ur>,
296    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
297{
298    type Output = NInt<<Ul as Add<Ur>>::Output>;
299    #[inline]
300    fn add(self, _: NInt<Ur>) -> Self::Output {
301        NInt::new()
302    }
303}
304
305/// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
306impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul>
307where
308    Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
309{
310    type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
311    #[inline]
312    fn add(self, rhs: NInt<Ur>) -> Self::Output {
313        let lhs = self.n;
314        let rhs = rhs.n;
315        let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
316        lhs.private_integer_add(lhs_cmp_rhs, rhs)
317    }
318}
319
320/// `N(Ul) + P(Ur)`: We resolve this with our `PrivateAdd`
321// We just do the same thing as above, swapping Lhs and Rhs
322impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul>
323where
324    Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
325{
326    type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
327    #[inline]
328    fn add(self, rhs: PInt<Ur>) -> Self::Output {
329        let lhs = self.n;
330        let rhs = rhs.n;
331        let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
332        rhs.private_integer_add(rhs_cmp_lhs, lhs)
333    }
334}
335
336/// `P + N = 0` where `P == N`
337impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
338    type Output = Z0;
339
340    #[inline]
341    fn private_integer_add(self, _: Equal, _: N) -> Self::Output {
342        Z0
343    }
344}
345
346/// `P + N = Positive` where `P > N`
347impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P
348where
349    P: Sub<N>,
350    <P as Sub<N>>::Output: Unsigned + NonZero,
351{
352    type Output = PInt<<P as Sub<N>>::Output>;
353
354    #[inline]
355    fn private_integer_add(self, _: Greater, n: N) -> Self::Output {
356        PInt { n: self - n }
357    }
358}
359
360/// `P + N = Negative` where `P < N`
361impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P
362where
363    N: Sub<P>,
364    <N as Sub<P>>::Output: Unsigned + NonZero,
365{
366    type Output = NInt<<N as Sub<P>>::Output>;
367
368    #[inline]
369    fn private_integer_add(self, _: Less, n: N) -> Self::Output {
370        NInt { n: n - self }
371    }
372}
373
374// ---------------------------------------------------------------------------------------
375// Sub
376
377/// `Z0 - Z0 = Z0`
378impl Sub<Z0> for Z0 {
379    type Output = Z0;
380    #[inline]
381    fn sub(self, _: Z0) -> Self::Output {
382        Z0
383    }
384}
385
386/// `Z0 - P = N`
387impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
388    type Output = NInt<U>;
389    #[inline]
390    fn sub(self, _: PInt<U>) -> Self::Output {
391        NInt::new()
392    }
393}
394
395/// `Z0 - N = P`
396impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 {
397    type Output = PInt<U>;
398    #[inline]
399    fn sub(self, _: NInt<U>) -> Self::Output {
400        PInt::new()
401    }
402}
403
404/// `PInt - Z0 = PInt`
405impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> {
406    type Output = PInt<U>;
407    #[inline]
408    fn sub(self, _: Z0) -> Self::Output {
409        PInt::new()
410    }
411}
412
413/// `NInt - Z0 = NInt`
414impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
415    type Output = NInt<U>;
416    #[inline]
417    fn sub(self, _: Z0) -> Self::Output {
418        NInt::new()
419    }
420}
421
422/// `P(Ul) - N(Ur) = P(Ul + Ur)`
423impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul>
424where
425    Ul: Add<Ur>,
426    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
427{
428    type Output = PInt<<Ul as Add<Ur>>::Output>;
429    #[inline]
430    fn sub(self, _: NInt<Ur>) -> Self::Output {
431        PInt::new()
432    }
433}
434
435/// `N(Ul) - P(Ur) = N(Ul + Ur)`
436impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul>
437where
438    Ul: Add<Ur>,
439    <Ul as Add<Ur>>::Output: Unsigned + NonZero,
440{
441    type Output = NInt<<Ul as Add<Ur>>::Output>;
442    #[inline]
443    fn sub(self, _: PInt<Ur>) -> Self::Output {
444        NInt::new()
445    }
446}
447
448/// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
449impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul>
450where
451    Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
452{
453    type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
454    #[inline]
455    fn sub(self, rhs: PInt<Ur>) -> Self::Output {
456        let lhs = self.n;
457        let rhs = rhs.n;
458        let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
459        lhs.private_integer_add(lhs_cmp_rhs, rhs)
460    }
461}
462
463/// `N(Ul) - N(Ur)`: We resolve this with our `PrivateAdd`
464// We just do the same thing as above, swapping Lhs and Rhs
465impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul>
466where
467    Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
468{
469    type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
470    #[inline]
471    fn sub(self, rhs: NInt<Ur>) -> Self::Output {
472        let lhs = self.n;
473        let rhs = rhs.n;
474        let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
475        rhs.private_integer_add(rhs_cmp_lhs, lhs)
476    }
477}
478
479// ---------------------------------------------------------------------------------------
480// Mul
481
482/// `Z0 * I = Z0`
483impl<I: Integer> Mul<I> for Z0 {
484    type Output = Z0;
485    #[inline]
486    fn mul(self, _: I) -> Self::Output {
487        Z0
488    }
489}
490
491/// `P * Z0 = Z0`
492impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
493    type Output = Z0;
494    #[inline]
495    fn mul(self, _: Z0) -> Self::Output {
496        Z0
497    }
498}
499
500/// `N * Z0 = Z0`
501impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
502    type Output = Z0;
503    #[inline]
504    fn mul(self, _: Z0) -> Self::Output {
505        Z0
506    }
507}
508
509/// P(Ul) * P(Ur) = P(Ul * Ur)
510impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul>
511where
512    Ul: Mul<Ur>,
513    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
514{
515    type Output = PInt<<Ul as Mul<Ur>>::Output>;
516    #[inline]
517    fn mul(self, _: PInt<Ur>) -> Self::Output {
518        PInt::new()
519    }
520}
521
522/// N(Ul) * N(Ur) = P(Ul * Ur)
523impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul>
524where
525    Ul: Mul<Ur>,
526    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
527{
528    type Output = PInt<<Ul as Mul<Ur>>::Output>;
529    #[inline]
530    fn mul(self, _: NInt<Ur>) -> Self::Output {
531        PInt::new()
532    }
533}
534
535/// P(Ul) * N(Ur) = N(Ul * Ur)
536impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul>
537where
538    Ul: Mul<Ur>,
539    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
540{
541    type Output = NInt<<Ul as Mul<Ur>>::Output>;
542    #[inline]
543    fn mul(self, _: NInt<Ur>) -> Self::Output {
544        NInt::new()
545    }
546}
547
548/// N(Ul) * P(Ur) = N(Ul * Ur)
549impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul>
550where
551    Ul: Mul<Ur>,
552    <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
553{
554    type Output = NInt<<Ul as Mul<Ur>>::Output>;
555    #[inline]
556    fn mul(self, _: PInt<Ur>) -> Self::Output {
557        NInt::new()
558    }
559}
560
561// ---------------------------------------------------------------------------------------
562// Div
563
564/// `Z0 / I = Z0` where `I != 0`
565impl<I: Integer + NonZero> Div<I> for Z0 {
566    type Output = Z0;
567    #[inline]
568    fn div(self, _: I) -> Self::Output {
569        Z0
570    }
571}
572
573macro_rules! impl_int_div {
574    ($A:ident, $B:ident, $R:ident) => {
575        /// `$A<Ul> / $B<Ur> = $R<Ul / Ur>`
576        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Div<$B<Ur>> for $A<Ul>
577        where
578            Ul: Cmp<Ur>,
579            $A<Ul>: PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>,
580        {
581            type Output = <$A<Ul> as PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>>::Output;
582            #[inline]
583            fn div(self, rhs: $B<Ur>) -> Self::Output {
584                let lhs_cmp_rhs = self.n.compare::<Internal>(&rhs.n);
585                self.private_div_int(lhs_cmp_rhs, rhs)
586            }
587        }
588        impl<Ul, Ur> PrivateDivInt<Less, $B<Ur>> for $A<Ul>
589        where
590            Ul: Unsigned + NonZero,
591            Ur: Unsigned + NonZero,
592        {
593            type Output = Z0;
594
595            #[inline]
596            fn private_div_int(self, _: Less, _: $B<Ur>) -> Self::Output {
597                Z0
598            }
599        }
600        impl<Ul, Ur> PrivateDivInt<Equal, $B<Ur>> for $A<Ul>
601        where
602            Ul: Unsigned + NonZero,
603            Ur: Unsigned + NonZero,
604        {
605            type Output = $R<U1>;
606
607            #[inline]
608            fn private_div_int(self, _: Equal, _: $B<Ur>) -> Self::Output {
609                $R { n: U1::new() }
610            }
611        }
612        impl<Ul, Ur> PrivateDivInt<Greater, $B<Ur>> for $A<Ul>
613        where
614            Ul: Unsigned + NonZero + Div<Ur>,
615            Ur: Unsigned + NonZero,
616            <Ul as Div<Ur>>::Output: Unsigned + NonZero,
617        {
618            type Output = $R<<Ul as Div<Ur>>::Output>;
619
620            #[inline]
621            fn private_div_int(self, _: Greater, d: $B<Ur>) -> Self::Output {
622                $R { n: self.n / d.n }
623            }
624        }
625    };
626}
627
628impl_int_div!(PInt, PInt, PInt);
629impl_int_div!(PInt, NInt, NInt);
630impl_int_div!(NInt, PInt, NInt);
631impl_int_div!(NInt, NInt, PInt);
632
633// ---------------------------------------------------------------------------------------
634// PartialDiv
635
636use crate::{PartialDiv, Quot};
637
638impl<M, N> PartialDiv<N> for M
639where
640    M: Integer + Div<N> + Rem<N, Output = Z0>,
641{
642    type Output = Quot<M, N>;
643    #[inline]
644    fn partial_div(self, rhs: N) -> Self::Output {
645        self / rhs
646    }
647}
648
649// ---------------------------------------------------------------------------------------
650// Cmp
651
652/// 0 == 0
653impl Cmp<Z0> for Z0 {
654    type Output = Equal;
655
656    #[inline]
657    fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
658        Equal
659    }
660}
661
662/// 0 > -X
663impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
664    type Output = Greater;
665
666    #[inline]
667    fn compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output {
668        Greater
669    }
670}
671
672/// 0 < X
673impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
674    type Output = Less;
675
676    #[inline]
677    fn compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output {
678        Less
679    }
680}
681
682/// X > 0
683impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
684    type Output = Greater;
685
686    #[inline]
687    fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
688        Greater
689    }
690}
691
692/// -X < 0
693impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
694    type Output = Less;
695
696    #[inline]
697    fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
698        Less
699    }
700}
701
702/// -X < Y
703impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
704    type Output = Less;
705
706    #[inline]
707    fn compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output {
708        Less
709    }
710}
711
712/// X > - Y
713impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
714    type Output = Greater;
715
716    #[inline]
717    fn compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output {
718        Greater
719    }
720}
721
722/// X <==> Y
723impl<Pl: Cmp<Pr> + Unsigned + NonZero, Pr: Unsigned + NonZero> Cmp<PInt<Pr>> for PInt<Pl> {
724    type Output = <Pl as Cmp<Pr>>::Output;
725
726    #[inline]
727    fn compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output {
728        self.n.compare::<Internal>(&rhs.n)
729    }
730}
731
732/// -X <==> -Y
733impl<Nl: Unsigned + NonZero, Nr: Cmp<Nl> + Unsigned + NonZero> Cmp<NInt<Nr>> for NInt<Nl> {
734    type Output = <Nr as Cmp<Nl>>::Output;
735
736    #[inline]
737    fn compare<IM: InternalMarker>(&self, rhs: &NInt<Nr>) -> Self::Output {
738        rhs.n.compare::<Internal>(&self.n)
739    }
740}
741
742// ---------------------------------------------------------------------------------------
743// Rem
744
745/// `Z0 % I = Z0` where `I != 0`
746impl<I: Integer + NonZero> Rem<I> for Z0 {
747    type Output = Z0;
748    #[inline]
749    fn rem(self, _: I) -> Self::Output {
750        Z0
751    }
752}
753
754macro_rules! impl_int_rem {
755    ($A:ident, $B:ident, $R:ident) => {
756        /// `$A<Ul> % $B<Ur> = $R<Ul % Ur>`
757        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Rem<$B<Ur>> for $A<Ul>
758        where
759            Ul: Rem<Ur>,
760            $A<Ul>: PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>,
761        {
762            type Output = <$A<Ul> as PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>>::Output;
763            #[inline]
764            fn rem(self, rhs: $B<Ur>) -> Self::Output {
765                self.private_rem(self.n % rhs.n, rhs)
766            }
767        }
768        impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> PrivateRem<U0, $B<Ur>> for $A<Ul> {
769            type Output = Z0;
770
771            #[inline]
772            fn private_rem(self, _: U0, _: $B<Ur>) -> Self::Output {
773                Z0
774            }
775        }
776        impl<Ul, Ur, U, B> PrivateRem<UInt<U, B>, $B<Ur>> for $A<Ul>
777        where
778            Ul: Unsigned + NonZero,
779            Ur: Unsigned + NonZero,
780            U: Unsigned,
781            B: Bit,
782        {
783            type Output = $R<UInt<U, B>>;
784
785            #[inline]
786            fn private_rem(self, urem: UInt<U, B>, _: $B<Ur>) -> Self::Output {
787                $R { n: urem }
788            }
789        }
790    };
791}
792
793impl_int_rem!(PInt, PInt, PInt);
794impl_int_rem!(PInt, NInt, PInt);
795impl_int_rem!(NInt, PInt, NInt);
796impl_int_rem!(NInt, NInt, NInt);
797
798// ---------------------------------------------------------------------------------------
799// Pow
800
801/// 0^0 = 1
802impl Pow<Z0> for Z0 {
803    type Output = P1;
804    #[inline]
805    fn powi(self, _: Z0) -> Self::Output {
806        P1::new()
807    }
808}
809
810/// 0^P = 0
811impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
812    type Output = Z0;
813    #[inline]
814    fn powi(self, _: PInt<U>) -> Self::Output {
815        Z0
816    }
817}
818
819/// 0^N = 0
820impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
821    type Output = Z0;
822    #[inline]
823    fn powi(self, _: NInt<U>) -> Self::Output {
824        Z0
825    }
826}
827
828/// 1^N = 1
829impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
830    type Output = P1;
831    #[inline]
832    fn powi(self, _: NInt<U>) -> Self::Output {
833        P1::new()
834    }
835}
836
837/// (-1)^N = 1 if N is even
838impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 {
839    type Output = P1;
840    #[inline]
841    fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output {
842        P1::new()
843    }
844}
845
846/// (-1)^N = -1 if N is odd
847impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 {
848    type Output = N1;
849    #[inline]
850    fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output {
851        N1::new()
852    }
853}
854
855/// P^0 = 1
856impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> {
857    type Output = P1;
858    #[inline]
859    fn powi(self, _: Z0) -> Self::Output {
860        P1::new()
861    }
862}
863
864/// N^0 = 1
865impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
866    type Output = P1;
867    #[inline]
868    fn powi(self, _: Z0) -> Self::Output {
869        P1::new()
870    }
871}
872
873/// P(Ul)^P(Ur) = P(Ul^Ur)
874impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul>
875where
876    Ul: Pow<Ur>,
877    <Ul as Pow<Ur>>::Output: Unsigned + NonZero,
878{
879    type Output = PInt<<Ul as Pow<Ur>>::Output>;
880    #[inline]
881    fn powi(self, _: PInt<Ur>) -> Self::Output {
882        PInt::new()
883    }
884}
885
886/// N(Ul)^P(Ur) = P(Ul^Ur) if Ur is even
887impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul>
888where
889    Ul: Pow<UInt<Ur, B0>>,
890    <Ul as Pow<UInt<Ur, B0>>>::Output: Unsigned + NonZero,
891{
892    type Output = PInt<<Ul as Pow<UInt<Ur, B0>>>::Output>;
893    #[inline]
894    fn powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output {
895        PInt::new()
896    }
897}
898
899/// N(Ul)^P(Ur) = N(Ul^Ur) if Ur is odd
900impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul>
901where
902    Ul: Pow<UInt<Ur, B1>>,
903    <Ul as Pow<UInt<Ur, B1>>>::Output: Unsigned + NonZero,
904{
905    type Output = NInt<<Ul as Pow<UInt<Ur, B1>>>::Output>;
906    #[inline]
907    fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
908        NInt::new()
909    }
910}
911
912// ---------------------------------------------------------------------------------------
913// Gcd
914use crate::{Gcd, Gcf};
915
916impl Gcd<Z0> for Z0 {
917    type Output = Z0;
918}
919
920impl<U> Gcd<PInt<U>> for Z0
921where
922    U: Unsigned + NonZero,
923{
924    type Output = PInt<U>;
925}
926
927impl<U> Gcd<Z0> for PInt<U>
928where
929    U: Unsigned + NonZero,
930{
931    type Output = PInt<U>;
932}
933
934impl<U> Gcd<NInt<U>> for Z0
935where
936    U: Unsigned + NonZero,
937{
938    type Output = PInt<U>;
939}
940
941impl<U> Gcd<Z0> for NInt<U>
942where
943    U: Unsigned + NonZero,
944{
945    type Output = PInt<U>;
946}
947
948impl<U1, U2> Gcd<PInt<U2>> for PInt<U1>
949where
950    U1: Unsigned + NonZero + Gcd<U2>,
951    U2: Unsigned + NonZero,
952    Gcf<U1, U2>: Unsigned + NonZero,
953{
954    type Output = PInt<Gcf<U1, U2>>;
955}
956
957impl<U1, U2> Gcd<PInt<U2>> for NInt<U1>
958where
959    U1: Unsigned + NonZero + Gcd<U2>,
960    U2: Unsigned + NonZero,
961    Gcf<U1, U2>: Unsigned + NonZero,
962{
963    type Output = PInt<Gcf<U1, U2>>;
964}
965
966impl<U1, U2> Gcd<NInt<U2>> for PInt<U1>
967where
968    U1: Unsigned + NonZero + Gcd<U2>,
969    U2: Unsigned + NonZero,
970    Gcf<U1, U2>: Unsigned + NonZero,
971{
972    type Output = PInt<Gcf<U1, U2>>;
973}
974
975impl<U1, U2> Gcd<NInt<U2>> for NInt<U1>
976where
977    U1: Unsigned + NonZero + Gcd<U2>,
978    U2: Unsigned + NonZero,
979    Gcf<U1, U2>: Unsigned + NonZero,
980{
981    type Output = PInt<Gcf<U1, U2>>;
982}
983
984// ---------------------------------------------------------------------------------------
985// Min
986use crate::{Max, Maximum, Min, Minimum};
987
988impl Min<Z0> for Z0 {
989    type Output = Z0;
990    #[inline]
991    fn min(self, _: Z0) -> Self::Output {
992        self
993    }
994}
995
996impl<U> Min<PInt<U>> for Z0
997where
998    U: Unsigned + NonZero,
999{
1000    type Output = Z0;
1001    #[inline]
1002    fn min(self, _: PInt<U>) -> Self::Output {
1003        self
1004    }
1005}
1006
1007impl<U> Min<NInt<U>> for Z0
1008where
1009    U: Unsigned + NonZero,
1010{
1011    type Output = NInt<U>;
1012    #[inline]
1013    fn min(self, rhs: NInt<U>) -> Self::Output {
1014        rhs
1015    }
1016}
1017
1018impl<U> Min<Z0> for PInt<U>
1019where
1020    U: Unsigned + NonZero,
1021{
1022    type Output = Z0;
1023    #[inline]
1024    fn min(self, rhs: Z0) -> Self::Output {
1025        rhs
1026    }
1027}
1028
1029impl<U> Min<Z0> for NInt<U>
1030where
1031    U: Unsigned + NonZero,
1032{
1033    type Output = NInt<U>;
1034    #[inline]
1035    fn min(self, _: Z0) -> Self::Output {
1036        self
1037    }
1038}
1039
1040impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul>
1041where
1042    Ul: Unsigned + NonZero + Min<Ur>,
1043    Ur: Unsigned + NonZero,
1044    Minimum<Ul, Ur>: Unsigned + NonZero,
1045{
1046    type Output = PInt<Minimum<Ul, Ur>>;
1047    #[inline]
1048    fn min(self, rhs: PInt<Ur>) -> Self::Output {
1049        PInt {
1050            n: self.n.min(rhs.n),
1051        }
1052    }
1053}
1054
1055impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
1056where
1057    Ul: Unsigned + NonZero,
1058    Ur: Unsigned + NonZero,
1059{
1060    type Output = NInt<Ul>;
1061    #[inline]
1062    fn min(self, _: PInt<Ur>) -> Self::Output {
1063        self
1064    }
1065}
1066
1067impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul>
1068where
1069    Ul: Unsigned + NonZero,
1070    Ur: Unsigned + NonZero,
1071{
1072    type Output = NInt<Ur>;
1073    #[inline]
1074    fn min(self, rhs: NInt<Ur>) -> Self::Output {
1075        rhs
1076    }
1077}
1078
1079impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul>
1080where
1081    Ul: Unsigned + NonZero + Max<Ur>,
1082    Ur: Unsigned + NonZero,
1083    Maximum<Ul, Ur>: Unsigned + NonZero,
1084{
1085    type Output = NInt<Maximum<Ul, Ur>>;
1086    #[inline]
1087    fn min(self, rhs: NInt<Ur>) -> Self::Output {
1088        NInt {
1089            n: self.n.max(rhs.n),
1090        }
1091    }
1092}
1093
1094// ---------------------------------------------------------------------------------------
1095// Max
1096
1097impl Max<Z0> for Z0 {
1098    type Output = Z0;
1099    #[inline]
1100    fn max(self, _: Z0) -> Self::Output {
1101        self
1102    }
1103}
1104
1105impl<U> Max<PInt<U>> for Z0
1106where
1107    U: Unsigned + NonZero,
1108{
1109    type Output = PInt<U>;
1110    #[inline]
1111    fn max(self, rhs: PInt<U>) -> Self::Output {
1112        rhs
1113    }
1114}
1115
1116impl<U> Max<NInt<U>> for Z0
1117where
1118    U: Unsigned + NonZero,
1119{
1120    type Output = Z0;
1121    #[inline]
1122    fn max(self, _: NInt<U>) -> Self::Output {
1123        self
1124    }
1125}
1126
1127impl<U> Max<Z0> for PInt<U>
1128where
1129    U: Unsigned + NonZero,
1130{
1131    type Output = PInt<U>;
1132    #[inline]
1133    fn max(self, _: Z0) -> Self::Output {
1134        self
1135    }
1136}
1137
1138impl<U> Max<Z0> for NInt<U>
1139where
1140    U: Unsigned + NonZero,
1141{
1142    type Output = Z0;
1143    #[inline]
1144    fn max(self, rhs: Z0) -> Self::Output {
1145        rhs
1146    }
1147}
1148
1149impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul>
1150where
1151    Ul: Unsigned + NonZero + Max<Ur>,
1152    Ur: Unsigned + NonZero,
1153    Maximum<Ul, Ur>: Unsigned + NonZero,
1154{
1155    type Output = PInt<Maximum<Ul, Ur>>;
1156    #[inline]
1157    fn max(self, rhs: PInt<Ur>) -> Self::Output {
1158        PInt {
1159            n: self.n.max(rhs.n),
1160        }
1161    }
1162}
1163
1164impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
1165where
1166    Ul: Unsigned + NonZero,
1167    Ur: Unsigned + NonZero,
1168{
1169    type Output = PInt<Ur>;
1170    #[inline]
1171    fn max(self, rhs: PInt<Ur>) -> Self::Output {
1172        rhs
1173    }
1174}
1175
1176impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul>
1177where
1178    Ul: Unsigned + NonZero,
1179    Ur: Unsigned + NonZero,
1180{
1181    type Output = PInt<Ul>;
1182    #[inline]
1183    fn max(self, _: NInt<Ur>) -> Self::Output {
1184        self
1185    }
1186}
1187
1188impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul>
1189where
1190    Ul: Unsigned + NonZero + Min<Ur>,
1191    Ur: Unsigned + NonZero,
1192    Minimum<Ul, Ur>: Unsigned + NonZero,
1193{
1194    type Output = NInt<Minimum<Ul, Ur>>;
1195    #[inline]
1196    fn max(self, rhs: NInt<Ur>) -> Self::Output {
1197        NInt {
1198            n: self.n.min(rhs.n),
1199        }
1200    }
1201}
1202
1203// -----------------------------------------
1204// ToInt
1205
1206impl ToInt<i8> for Z0 {
1207    #[inline]
1208    fn to_int() -> i8 {
1209        Self::I8
1210    }
1211    const INT: i8 = Self::I8;
1212}
1213
1214impl ToInt<i16> for Z0 {
1215    #[inline]
1216    fn to_int() -> i16 {
1217        Self::I16
1218    }
1219    const INT: i16 = Self::I16;
1220}
1221
1222impl ToInt<i32> for Z0 {
1223    #[inline]
1224    fn to_int() -> i32 {
1225        Self::I32
1226    }
1227    const INT: i32 = Self::I32;
1228}
1229
1230impl ToInt<i64> for Z0 {
1231    #[inline]
1232    fn to_int() -> i64 {
1233        Self::I64
1234    }
1235    const INT: i64 = Self::I64;
1236}
1237
1238impl ToInt<isize> for Z0 {
1239    #[inline]
1240    fn to_int() -> isize {
1241        Self::ISIZE
1242    }
1243    const INT: isize = Self::ISIZE;
1244}
1245
1246#[cfg(feature = "i128")]
1247impl ToInt<i128> for Z0 {
1248    #[inline]
1249    fn to_int() -> i128 {
1250        Self::I128
1251    }
1252    const INT: i128 = Self::I128;
1253}
1254
1255// negative numbers
1256
1257impl<U> ToInt<i8> for NInt<U>
1258where
1259    U: Unsigned + NonZero,
1260{
1261    #[inline]
1262    fn to_int() -> i8 {
1263        Self::I8
1264    }
1265    const INT: i8 = Self::I8;
1266}
1267
1268impl<U> ToInt<i16> for NInt<U>
1269where
1270    U: Unsigned + NonZero,
1271{
1272    #[inline]
1273    fn to_int() -> i16 {
1274        Self::I16
1275    }
1276    const INT: i16 = Self::I16;
1277}
1278
1279impl<U> ToInt<i32> for NInt<U>
1280where
1281    U: Unsigned + NonZero,
1282{
1283    #[inline]
1284    fn to_int() -> i32 {
1285        Self::I32
1286    }
1287    const INT: i32 = Self::I32;
1288}
1289
1290impl<U> ToInt<i64> for NInt<U>
1291where
1292    U: Unsigned + NonZero,
1293{
1294    #[inline]
1295    fn to_int() -> i64 {
1296        Self::I64
1297    }
1298    const INT: i64 = Self::I64;
1299}
1300
1301impl<U> ToInt<isize> for NInt<U>
1302where
1303    U: Unsigned + NonZero,
1304{
1305    #[inline]
1306    fn to_int() -> isize {
1307        Self::ISIZE
1308    }
1309    const INT: isize = Self::ISIZE;
1310}
1311
1312#[cfg(feature = "i128")]
1313impl<U> ToInt<i128> for NInt<U>
1314where
1315    U: Unsigned + NonZero,
1316{
1317    #[inline]
1318    fn to_int() -> i128 {
1319        Self::I128
1320    }
1321    const INT: i128 = Self::I128;
1322}
1323
1324// positive numbers
1325
1326impl<U> ToInt<i8> for PInt<U>
1327where
1328    U: Unsigned + NonZero,
1329{
1330    #[inline]
1331    fn to_int() -> i8 {
1332        Self::I8
1333    }
1334    const INT: i8 = Self::I8;
1335}
1336
1337impl<U> ToInt<i16> for PInt<U>
1338where
1339    U: Unsigned + NonZero,
1340{
1341    #[inline]
1342    fn to_int() -> i16 {
1343        Self::I16
1344    }
1345    const INT: i16 = Self::I16;
1346}
1347
1348impl<U> ToInt<i32> for PInt<U>
1349where
1350    U: Unsigned + NonZero,
1351{
1352    #[inline]
1353    fn to_int() -> i32 {
1354        Self::I32
1355    }
1356    const INT: i32 = Self::I32;
1357}
1358
1359impl<U> ToInt<i64> for PInt<U>
1360where
1361    U: Unsigned + NonZero,
1362{
1363    #[inline]
1364    fn to_int() -> i64 {
1365        Self::I64
1366    }
1367    const INT: i64 = Self::I64;
1368}
1369
1370impl<U> ToInt<isize> for PInt<U>
1371where
1372    U: Unsigned + NonZero,
1373{
1374    #[inline]
1375    fn to_int() -> isize {
1376        Self::ISIZE
1377    }
1378    const INT: isize = Self::ISIZE;
1379}
1380
1381#[cfg(feature = "i128")]
1382impl<U> ToInt<i128> for PInt<U>
1383where
1384    U: Unsigned + NonZero,
1385{
1386    #[inline]
1387    fn to_int() -> i128 {
1388        Self::I128
1389    }
1390    const INT: i128 = Self::I128;
1391}
1392
1393#[cfg(test)]
1394mod tests {
1395    use crate::{consts::*, Integer, ToInt};
1396
1397    #[test]
1398    fn to_ix_min() {
1399        assert_eq!(N128::to_i8(), ::core::i8::MIN);
1400        assert_eq!(N32768::to_i16(), ::core::i16::MIN);
1401    }
1402
1403    #[test]
1404    fn int_toint_test() {
1405        // i8
1406        assert_eq!(0_i8, Z0::to_int());
1407        assert_eq!(1_i8, P1::to_int());
1408        assert_eq!(2_i8, P2::to_int());
1409        assert_eq!(3_i8, P3::to_int());
1410        assert_eq!(4_i8, P4::to_int());
1411        assert_eq!(-1_i8, N1::to_int());
1412        assert_eq!(-2_i8, N2::to_int());
1413        assert_eq!(-3_i8, N3::to_int());
1414        assert_eq!(-4_i8, N4::to_int());
1415        assert_eq!(0_i8, Z0::INT);
1416        assert_eq!(1_i8, P1::INT);
1417        assert_eq!(2_i8, P2::INT);
1418        assert_eq!(3_i8, P3::INT);
1419        assert_eq!(4_i8, P4::INT);
1420        assert_eq!(-1_i8, N1::INT);
1421        assert_eq!(-2_i8, N2::INT);
1422        assert_eq!(-3_i8, N3::INT);
1423        assert_eq!(-4_i8, N4::INT);
1424
1425        // i16
1426        assert_eq!(0_i16, Z0::to_int());
1427        assert_eq!(1_i16, P1::to_int());
1428        assert_eq!(2_i16, P2::to_int());
1429        assert_eq!(3_i16, P3::to_int());
1430        assert_eq!(4_i16, P4::to_int());
1431        assert_eq!(-1_i16, N1::to_int());
1432        assert_eq!(-2_i16, N2::to_int());
1433        assert_eq!(-3_i16, N3::to_int());
1434        assert_eq!(-4_i16, N4::to_int());
1435        assert_eq!(0_i16, Z0::INT);
1436        assert_eq!(1_i16, P1::INT);
1437        assert_eq!(2_i16, P2::INT);
1438        assert_eq!(3_i16, P3::INT);
1439        assert_eq!(4_i16, P4::INT);
1440        assert_eq!(-1_i16, N1::INT);
1441        assert_eq!(-2_i16, N2::INT);
1442        assert_eq!(-3_i16, N3::INT);
1443        assert_eq!(-4_i16, N4::INT);
1444
1445        // i32
1446        assert_eq!(0_i32, Z0::to_int());
1447        assert_eq!(1_i32, P1::to_int());
1448        assert_eq!(2_i32, P2::to_int());
1449        assert_eq!(3_i32, P3::to_int());
1450        assert_eq!(4_i32, P4::to_int());
1451        assert_eq!(-1_i32, N1::to_int());
1452        assert_eq!(-2_i32, N2::to_int());
1453        assert_eq!(-3_i32, N3::to_int());
1454        assert_eq!(-4_i32, N4::to_int());
1455        assert_eq!(0_i32, Z0::INT);
1456        assert_eq!(1_i32, P1::INT);
1457        assert_eq!(2_i32, P2::INT);
1458        assert_eq!(3_i32, P3::INT);
1459        assert_eq!(4_i32, P4::INT);
1460        assert_eq!(-1_i32, N1::INT);
1461        assert_eq!(-2_i32, N2::INT);
1462        assert_eq!(-3_i32, N3::INT);
1463        assert_eq!(-4_i32, N4::INT);
1464
1465        // i64
1466        assert_eq!(0_i64, Z0::to_int());
1467        assert_eq!(1_i64, P1::to_int());
1468        assert_eq!(2_i64, P2::to_int());
1469        assert_eq!(3_i64, P3::to_int());
1470        assert_eq!(4_i64, P4::to_int());
1471        assert_eq!(-1_i64, N1::to_int());
1472        assert_eq!(-2_i64, N2::to_int());
1473        assert_eq!(-3_i64, N3::to_int());
1474        assert_eq!(-4_i64, N4::to_int());
1475        assert_eq!(0_i64, Z0::INT);
1476        assert_eq!(1_i64, P1::INT);
1477        assert_eq!(2_i64, P2::INT);
1478        assert_eq!(3_i64, P3::INT);
1479        assert_eq!(4_i64, P4::INT);
1480        assert_eq!(-1_i64, N1::INT);
1481        assert_eq!(-2_i64, N2::INT);
1482        assert_eq!(-3_i64, N3::INT);
1483        assert_eq!(-4_i64, N4::INT);
1484
1485        // isize
1486        assert_eq!(0_isize, Z0::to_int());
1487        assert_eq!(1_isize, P1::to_int());
1488        assert_eq!(2_isize, P2::to_int());
1489        assert_eq!(3_isize, P3::to_int());
1490        assert_eq!(4_isize, P4::to_int());
1491        assert_eq!(-1_isize, N1::to_int());
1492        assert_eq!(-2_isize, N2::to_int());
1493        assert_eq!(-3_isize, N3::to_int());
1494        assert_eq!(-4_isize, N4::to_int());
1495        assert_eq!(0_isize, Z0::INT);
1496        assert_eq!(1_isize, P1::INT);
1497        assert_eq!(2_isize, P2::INT);
1498        assert_eq!(3_isize, P3::INT);
1499        assert_eq!(4_isize, P4::INT);
1500        assert_eq!(-1_isize, N1::INT);
1501        assert_eq!(-2_isize, N2::INT);
1502        assert_eq!(-3_isize, N3::INT);
1503        assert_eq!(-4_isize, N4::INT);
1504
1505        // i128
1506        #[cfg(feature = "i128")]
1507        {
1508            assert_eq!(0_i128, Z0::to_int());
1509            assert_eq!(1_i128, P1::to_int());
1510            assert_eq!(2_i128, P2::to_int());
1511            assert_eq!(3_i128, P3::to_int());
1512            assert_eq!(4_i128, P4::to_int());
1513            assert_eq!(-1_i128, N1::to_int());
1514            assert_eq!(-2_i128, N2::to_int());
1515            assert_eq!(-3_i128, N3::to_int());
1516            assert_eq!(-4_i128, N4::to_int());
1517            assert_eq!(0_i128, Z0::INT);
1518            assert_eq!(1_i128, P1::INT);
1519            assert_eq!(2_i128, P2::INT);
1520            assert_eq!(3_i128, P3::INT);
1521            assert_eq!(4_i128, P4::INT);
1522            assert_eq!(-1_i128, N1::INT);
1523            assert_eq!(-2_i128, N2::INT);
1524            assert_eq!(-3_i128, N3::INT);
1525            assert_eq!(-4_i128, N4::INT);
1526        }
1527    }
1528}