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 
29 pub use crate::marker_traits::Integer;
30 use 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 };
37 use 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))]
42 pub 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))]
49 pub struct NInt<U: Unsigned + NonZero> {
50     pub(crate) n: U,
51 }
52 
53 impl<U: Unsigned + NonZero> PInt<U> {
54     /// Instantiates a singleton representing this strictly positive integer.
55     #[inline]
new() -> PInt<U>56     pub fn new() -> PInt<U> {
57         PInt::default()
58     }
59 }
60 
61 impl<U: Unsigned + NonZero> NInt<U> {
62     /// Instantiates a singleton representing this strictly negative integer.
63     #[inline]
new() -> NInt<U>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))]
72 pub struct Z0;
73 
74 impl Z0 {
75     /// Instantiates a singleton representing the integer 0.
76     #[inline]
new() -> Z077     pub fn new() -> Z0 {
78         Z0
79     }
80 }
81 
82 impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
83 impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
84 impl Zero for Z0 {}
85 
86 impl<U: Unsigned + NonZero + PowerOfTwo> PowerOfTwo for PInt<U> {}
87 
88 impl 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]
to_i8() -> i898     fn to_i8() -> i8 {
99         0
100     }
101     #[inline]
to_i16() -> i16102     fn to_i16() -> i16 {
103         0
104     }
105     #[inline]
to_i32() -> i32106     fn to_i32() -> i32 {
107         0
108     }
109     #[inline]
to_i64() -> i64110     fn to_i64() -> i64 {
111         0
112     }
113     #[cfg(feature = "i128")]
114     #[inline]
to_i128() -> i128115     fn to_i128() -> i128 {
116         0
117     }
118     #[inline]
to_isize() -> isize119     fn to_isize() -> isize {
120         0
121     }
122 }
123 
124 impl<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]
to_i8() -> i8134     fn to_i8() -> i8 {
135         <U as Unsigned>::to_i8()
136     }
137     #[inline]
to_i16() -> i16138     fn to_i16() -> i16 {
139         <U as Unsigned>::to_i16()
140     }
141     #[inline]
to_i32() -> i32142     fn to_i32() -> i32 {
143         <U as Unsigned>::to_i32()
144     }
145     #[inline]
to_i64() -> i64146     fn to_i64() -> i64 {
147         <U as Unsigned>::to_i64()
148     }
149     #[cfg(feature = "i128")]
150     #[inline]
to_i128() -> i128151     fn to_i128() -> i128 {
152         <U as Unsigned>::to_i128()
153     }
154     #[inline]
to_isize() -> isize155     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.
162 impl<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]
to_i8() -> i8172     fn to_i8() -> i8 {
173         Self::I8
174     }
175     #[inline]
to_i16() -> i16176     fn to_i16() -> i16 {
177         Self::I16
178     }
179     #[inline]
to_i32() -> i32180     fn to_i32() -> i32 {
181         Self::I32
182     }
183     #[inline]
to_i64() -> i64184     fn to_i64() -> i64 {
185         Self::I64
186     }
187     #[cfg(feature = "i128")]
188     #[inline]
to_i128() -> i128189     fn to_i128() -> i128 {
190         Self::I128
191     }
192     #[inline]
to_isize() -> isize193     fn to_isize() -> isize {
194         Self::ISIZE
195     }
196 }
197 
198 // ---------------------------------------------------------------------------------------
199 // Neg
200 
201 /// `-Z0 = Z0`
202 impl Neg for Z0 {
203     type Output = Z0;
204     #[inline]
neg(self) -> Self::Output205     fn neg(self) -> Self::Output {
206         Z0
207     }
208 }
209 
210 /// `-PInt = NInt`
211 impl<U: Unsigned + NonZero> Neg for PInt<U> {
212     type Output = NInt<U>;
213     #[inline]
neg(self) -> Self::Output214     fn neg(self) -> Self::Output {
215         NInt::new()
216     }
217 }
218 
219 /// `-NInt = PInt`
220 impl<U: Unsigned + NonZero> Neg for NInt<U> {
221     type Output = PInt<U>;
222     #[inline]
neg(self) -> Self::Output223     fn neg(self) -> Self::Output {
224         PInt::new()
225     }
226 }
227 
228 // ---------------------------------------------------------------------------------------
229 // Add
230 
231 /// `Z0 + I = I`
232 impl<I: Integer> Add<I> for Z0 {
233     type Output = I;
234     #[inline]
add(self, rhs: I) -> Self::Output235     fn add(self, rhs: I) -> Self::Output {
236         rhs
237     }
238 }
239 
240 /// `PInt + Z0 = PInt`
241 impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
242     type Output = PInt<U>;
243     #[inline]
add(self, _: Z0) -> Self::Output244     fn add(self, _: Z0) -> Self::Output {
245         PInt::new()
246     }
247 }
248 
249 /// `NInt + Z0 = NInt`
250 impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
251     type Output = NInt<U>;
252     #[inline]
add(self, _: Z0) -> Self::Output253     fn add(self, _: Z0) -> Self::Output {
254         NInt::new()
255     }
256 }
257 
258 /// `P(Ul) + P(Ur) = P(Ul + Ur)`
259 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul>
260 where
261     Ul: Add<Ur>,
262     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
263 {
264     type Output = PInt<<Ul as Add<Ur>>::Output>;
265     #[inline]
add(self, _: PInt<Ur>) -> Self::Output266     fn add(self, _: PInt<Ur>) -> Self::Output {
267         PInt::new()
268     }
269 }
270 
271 /// `N(Ul) + N(Ur) = N(Ul + Ur)`
272 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul>
273 where
274     Ul: Add<Ur>,
275     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
276 {
277     type Output = NInt<<Ul as Add<Ur>>::Output>;
278     #[inline]
add(self, _: NInt<Ur>) -> Self::Output279     fn add(self, _: NInt<Ur>) -> Self::Output {
280         NInt::new()
281     }
282 }
283 
284 /// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
285 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul>
286 where
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]
add(self, rhs: NInt<Ur>) -> Self::Output291     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
301 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul>
302 where
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]
add(self, rhs: PInt<Ur>) -> Self::Output307     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`
316 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
317     type Output = Z0;
318 
319     #[inline]
private_integer_add(self, _: Equal, _: N) -> Self::Output320     fn private_integer_add(self, _: Equal, _: N) -> Self::Output {
321         Z0
322     }
323 }
324 
325 /// `P + N = Positive` where `P > N`
326 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P
327 where
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]
private_integer_add(self, _: Greater, n: N) -> Self::Output334     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`
340 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P
341 where
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]
private_integer_add(self, _: Less, n: N) -> Self::Output348     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`
357 impl Sub<Z0> for Z0 {
358     type Output = Z0;
359     #[inline]
sub(self, _: Z0) -> Self::Output360     fn sub(self, _: Z0) -> Self::Output {
361         Z0
362     }
363 }
364 
365 /// `Z0 - P = N`
366 impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
367     type Output = NInt<U>;
368     #[inline]
sub(self, _: PInt<U>) -> Self::Output369     fn sub(self, _: PInt<U>) -> Self::Output {
370         NInt::new()
371     }
372 }
373 
374 /// `Z0 - N = P`
375 impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 {
376     type Output = PInt<U>;
377     #[inline]
sub(self, _: NInt<U>) -> Self::Output378     fn sub(self, _: NInt<U>) -> Self::Output {
379         PInt::new()
380     }
381 }
382 
383 /// `PInt - Z0 = PInt`
384 impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> {
385     type Output = PInt<U>;
386     #[inline]
sub(self, _: Z0) -> Self::Output387     fn sub(self, _: Z0) -> Self::Output {
388         PInt::new()
389     }
390 }
391 
392 /// `NInt - Z0 = NInt`
393 impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
394     type Output = NInt<U>;
395     #[inline]
sub(self, _: Z0) -> Self::Output396     fn sub(self, _: Z0) -> Self::Output {
397         NInt::new()
398     }
399 }
400 
401 /// `P(Ul) - N(Ur) = P(Ul + Ur)`
402 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul>
403 where
404     Ul: Add<Ur>,
405     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
406 {
407     type Output = PInt<<Ul as Add<Ur>>::Output>;
408     #[inline]
sub(self, _: NInt<Ur>) -> Self::Output409     fn sub(self, _: NInt<Ur>) -> Self::Output {
410         PInt::new()
411     }
412 }
413 
414 /// `N(Ul) - P(Ur) = N(Ul + Ur)`
415 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul>
416 where
417     Ul: Add<Ur>,
418     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
419 {
420     type Output = NInt<<Ul as Add<Ur>>::Output>;
421     #[inline]
sub(self, _: PInt<Ur>) -> Self::Output422     fn sub(self, _: PInt<Ur>) -> Self::Output {
423         NInt::new()
424     }
425 }
426 
427 /// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
428 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul>
429 where
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]
sub(self, rhs: PInt<Ur>) -> Self::Output434     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
444 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul>
445 where
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]
sub(self, rhs: NInt<Ur>) -> Self::Output450     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`
462 impl<I: Integer> Mul<I> for Z0 {
463     type Output = Z0;
464     #[inline]
mul(self, _: I) -> Self::Output465     fn mul(self, _: I) -> Self::Output {
466         Z0
467     }
468 }
469 
470 /// `P * Z0 = Z0`
471 impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
472     type Output = Z0;
473     #[inline]
mul(self, _: Z0) -> Self::Output474     fn mul(self, _: Z0) -> Self::Output {
475         Z0
476     }
477 }
478 
479 /// `N * Z0 = Z0`
480 impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
481     type Output = Z0;
482     #[inline]
mul(self, _: Z0) -> Self::Output483     fn mul(self, _: Z0) -> Self::Output {
484         Z0
485     }
486 }
487 
488 /// P(Ul) * P(Ur) = P(Ul * Ur)
489 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul>
490 where
491     Ul: Mul<Ur>,
492     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
493 {
494     type Output = PInt<<Ul as Mul<Ur>>::Output>;
495     #[inline]
mul(self, _: PInt<Ur>) -> Self::Output496     fn mul(self, _: PInt<Ur>) -> Self::Output {
497         PInt::new()
498     }
499 }
500 
501 /// N(Ul) * N(Ur) = P(Ul * Ur)
502 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul>
503 where
504     Ul: Mul<Ur>,
505     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
506 {
507     type Output = PInt<<Ul as Mul<Ur>>::Output>;
508     #[inline]
mul(self, _: NInt<Ur>) -> Self::Output509     fn mul(self, _: NInt<Ur>) -> Self::Output {
510         PInt::new()
511     }
512 }
513 
514 /// P(Ul) * N(Ur) = N(Ul * Ur)
515 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul>
516 where
517     Ul: Mul<Ur>,
518     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
519 {
520     type Output = NInt<<Ul as Mul<Ur>>::Output>;
521     #[inline]
mul(self, _: NInt<Ur>) -> Self::Output522     fn mul(self, _: NInt<Ur>) -> Self::Output {
523         NInt::new()
524     }
525 }
526 
527 /// N(Ul) * P(Ur) = N(Ul * Ur)
528 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul>
529 where
530     Ul: Mul<Ur>,
531     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
532 {
533     type Output = NInt<<Ul as Mul<Ur>>::Output>;
534     #[inline]
mul(self, _: PInt<Ur>) -> Self::Output535     fn mul(self, _: PInt<Ur>) -> Self::Output {
536         NInt::new()
537     }
538 }
539 
540 // ---------------------------------------------------------------------------------------
541 // Div
542 
543 /// `Z0 / I = Z0` where `I != 0`
544 impl<I: Integer + NonZero> Div<I> for Z0 {
545     type Output = Z0;
546     #[inline]
div(self, _: I) -> Self::Output547     fn div(self, _: I) -> Self::Output {
548         Z0
549     }
550 }
551 
552 macro_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 
607 impl_int_div!(PInt, PInt, PInt);
608 impl_int_div!(PInt, NInt, NInt);
609 impl_int_div!(NInt, PInt, NInt);
610 impl_int_div!(NInt, NInt, PInt);
611 
612 // ---------------------------------------------------------------------------------------
613 // PartialDiv
614 
615 use crate::{PartialDiv, Quot};
616 
617 impl<M, N> PartialDiv<N> for M
618 where
619     M: Integer + Div<N> + Rem<N, Output = Z0>,
620 {
621     type Output = Quot<M, N>;
622     #[inline]
partial_div(self, rhs: N) -> Self::Output623     fn partial_div(self, rhs: N) -> Self::Output {
624         self / rhs
625     }
626 }
627 
628 // ---------------------------------------------------------------------------------------
629 // Cmp
630 
631 /// 0 == 0
632 impl Cmp<Z0> for Z0 {
633     type Output = Equal;
634 
635     #[inline]
compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output636     fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
637         Equal
638     }
639 }
640 
641 /// 0 > -X
642 impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
643     type Output = Greater;
644 
645     #[inline]
compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output646     fn compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output {
647         Greater
648     }
649 }
650 
651 /// 0 < X
652 impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
653     type Output = Less;
654 
655     #[inline]
compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output656     fn compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output {
657         Less
658     }
659 }
660 
661 /// X > 0
662 impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
663     type Output = Greater;
664 
665     #[inline]
compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output666     fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
667         Greater
668     }
669 }
670 
671 /// -X < 0
672 impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
673     type Output = Less;
674 
675     #[inline]
compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output676     fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
677         Less
678     }
679 }
680 
681 /// -X < Y
682 impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
683     type Output = Less;
684 
685     #[inline]
compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output686     fn compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output {
687         Less
688     }
689 }
690 
691 /// X > - Y
692 impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
693     type Output = Greater;
694 
695     #[inline]
compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output696     fn compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output {
697         Greater
698     }
699 }
700 
701 /// X <==> Y
702 impl<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]
compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output706     fn compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output {
707         self.n.compare::<Internal>(&rhs.n)
708     }
709 }
710 
711 /// -X <==> -Y
712 impl<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]
compare<IM: InternalMarker>(&self, rhs: &NInt<Nr>) -> Self::Output716     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`
725 impl<I: Integer + NonZero> Rem<I> for Z0 {
726     type Output = Z0;
727     #[inline]
rem(self, _: I) -> Self::Output728     fn rem(self, _: I) -> Self::Output {
729         Z0
730     }
731 }
732 
733 macro_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 
772 impl_int_rem!(PInt, PInt, PInt);
773 impl_int_rem!(PInt, NInt, PInt);
774 impl_int_rem!(NInt, PInt, NInt);
775 impl_int_rem!(NInt, NInt, NInt);
776 
777 // ---------------------------------------------------------------------------------------
778 // Pow
779 
780 /// 0^0 = 1
781 impl Pow<Z0> for Z0 {
782     type Output = P1;
783     #[inline]
powi(self, _: Z0) -> Self::Output784     fn powi(self, _: Z0) -> Self::Output {
785         P1::new()
786     }
787 }
788 
789 /// 0^P = 0
790 impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
791     type Output = Z0;
792     #[inline]
powi(self, _: PInt<U>) -> Self::Output793     fn powi(self, _: PInt<U>) -> Self::Output {
794         Z0
795     }
796 }
797 
798 /// 0^N = 0
799 impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
800     type Output = Z0;
801     #[inline]
powi(self, _: NInt<U>) -> Self::Output802     fn powi(self, _: NInt<U>) -> Self::Output {
803         Z0
804     }
805 }
806 
807 /// 1^N = 1
808 impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
809     type Output = P1;
810     #[inline]
powi(self, _: NInt<U>) -> Self::Output811     fn powi(self, _: NInt<U>) -> Self::Output {
812         P1::new()
813     }
814 }
815 
816 /// (-1)^N = 1 if N is even
817 impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 {
818     type Output = P1;
819     #[inline]
powi(self, _: NInt<UInt<U, B0>>) -> Self::Output820     fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output {
821         P1::new()
822     }
823 }
824 
825 /// (-1)^N = -1 if N is odd
826 impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 {
827     type Output = N1;
828     #[inline]
powi(self, _: NInt<UInt<U, B1>>) -> Self::Output829     fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output {
830         N1::new()
831     }
832 }
833 
834 /// P^0 = 1
835 impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> {
836     type Output = P1;
837     #[inline]
powi(self, _: Z0) -> Self::Output838     fn powi(self, _: Z0) -> Self::Output {
839         P1::new()
840     }
841 }
842 
843 /// N^0 = 1
844 impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
845     type Output = P1;
846     #[inline]
powi(self, _: Z0) -> Self::Output847     fn powi(self, _: Z0) -> Self::Output {
848         P1::new()
849     }
850 }
851 
852 /// P(Ul)^P(Ur) = P(Ul^Ur)
853 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul>
854 where
855     Ul: Pow<Ur>,
856     <Ul as Pow<Ur>>::Output: Unsigned + NonZero,
857 {
858     type Output = PInt<<Ul as Pow<Ur>>::Output>;
859     #[inline]
powi(self, _: PInt<Ur>) -> Self::Output860     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
866 impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul>
867 where
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]
powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output873     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
879 impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul>
880 where
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]
powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output886     fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
887         NInt::new()
888     }
889 }
890 
891 // ---------------------------------------------------------------------------------------
892 // Gcd
893 use crate::{Gcd, Gcf};
894 
895 impl Gcd<Z0> for Z0 {
896     type Output = Z0;
897 }
898 
899 impl<U> Gcd<PInt<U>> for Z0
900 where
901     U: Unsigned + NonZero,
902 {
903     type Output = PInt<U>;
904 }
905 
906 impl<U> Gcd<Z0> for PInt<U>
907 where
908     U: Unsigned + NonZero,
909 {
910     type Output = PInt<U>;
911 }
912 
913 impl<U> Gcd<NInt<U>> for Z0
914 where
915     U: Unsigned + NonZero,
916 {
917     type Output = PInt<U>;
918 }
919 
920 impl<U> Gcd<Z0> for NInt<U>
921 where
922     U: Unsigned + NonZero,
923 {
924     type Output = PInt<U>;
925 }
926 
927 impl<U1, U2> Gcd<PInt<U2>> for PInt<U1>
928 where
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 
936 impl<U1, U2> Gcd<PInt<U2>> for NInt<U1>
937 where
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 
945 impl<U1, U2> Gcd<NInt<U2>> for PInt<U1>
946 where
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 
954 impl<U1, U2> Gcd<NInt<U2>> for NInt<U1>
955 where
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
965 use crate::{Max, Maximum, Min, Minimum};
966 
967 impl Min<Z0> for Z0 {
968     type Output = Z0;
969     #[inline]
min(self, _: Z0) -> Self::Output970     fn min(self, _: Z0) -> Self::Output {
971         self
972     }
973 }
974 
975 impl<U> Min<PInt<U>> for Z0
976 where
977     U: Unsigned + NonZero,
978 {
979     type Output = Z0;
980     #[inline]
min(self, _: PInt<U>) -> Self::Output981     fn min(self, _: PInt<U>) -> Self::Output {
982         self
983     }
984 }
985 
986 impl<U> Min<NInt<U>> for Z0
987 where
988     U: Unsigned + NonZero,
989 {
990     type Output = NInt<U>;
991     #[inline]
min(self, rhs: NInt<U>) -> Self::Output992     fn min(self, rhs: NInt<U>) -> Self::Output {
993         rhs
994     }
995 }
996 
997 impl<U> Min<Z0> for PInt<U>
998 where
999     U: Unsigned + NonZero,
1000 {
1001     type Output = Z0;
1002     #[inline]
min(self, rhs: Z0) -> Self::Output1003     fn min(self, rhs: Z0) -> Self::Output {
1004         rhs
1005     }
1006 }
1007 
1008 impl<U> Min<Z0> for NInt<U>
1009 where
1010     U: Unsigned + NonZero,
1011 {
1012     type Output = NInt<U>;
1013     #[inline]
min(self, _: Z0) -> Self::Output1014     fn min(self, _: Z0) -> Self::Output {
1015         self
1016     }
1017 }
1018 
1019 impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul>
1020 where
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]
min(self, rhs: PInt<Ur>) -> Self::Output1027     fn min(self, rhs: PInt<Ur>) -> Self::Output {
1028         PInt {
1029             n: self.n.min(rhs.n),
1030         }
1031     }
1032 }
1033 
1034 impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
1035 where
1036     Ul: Unsigned + NonZero,
1037     Ur: Unsigned + NonZero,
1038 {
1039     type Output = NInt<Ul>;
1040     #[inline]
min(self, _: PInt<Ur>) -> Self::Output1041     fn min(self, _: PInt<Ur>) -> Self::Output {
1042         self
1043     }
1044 }
1045 
1046 impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul>
1047 where
1048     Ul: Unsigned + NonZero,
1049     Ur: Unsigned + NonZero,
1050 {
1051     type Output = NInt<Ur>;
1052     #[inline]
min(self, rhs: NInt<Ur>) -> Self::Output1053     fn min(self, rhs: NInt<Ur>) -> Self::Output {
1054         rhs
1055     }
1056 }
1057 
1058 impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul>
1059 where
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]
min(self, rhs: NInt<Ur>) -> Self::Output1066     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 
1076 impl Max<Z0> for Z0 {
1077     type Output = Z0;
1078     #[inline]
max(self, _: Z0) -> Self::Output1079     fn max(self, _: Z0) -> Self::Output {
1080         self
1081     }
1082 }
1083 
1084 impl<U> Max<PInt<U>> for Z0
1085 where
1086     U: Unsigned + NonZero,
1087 {
1088     type Output = PInt<U>;
1089     #[inline]
max(self, rhs: PInt<U>) -> Self::Output1090     fn max(self, rhs: PInt<U>) -> Self::Output {
1091         rhs
1092     }
1093 }
1094 
1095 impl<U> Max<NInt<U>> for Z0
1096 where
1097     U: Unsigned + NonZero,
1098 {
1099     type Output = Z0;
1100     #[inline]
max(self, _: NInt<U>) -> Self::Output1101     fn max(self, _: NInt<U>) -> Self::Output {
1102         self
1103     }
1104 }
1105 
1106 impl<U> Max<Z0> for PInt<U>
1107 where
1108     U: Unsigned + NonZero,
1109 {
1110     type Output = PInt<U>;
1111     #[inline]
max(self, _: Z0) -> Self::Output1112     fn max(self, _: Z0) -> Self::Output {
1113         self
1114     }
1115 }
1116 
1117 impl<U> Max<Z0> for NInt<U>
1118 where
1119     U: Unsigned + NonZero,
1120 {
1121     type Output = Z0;
1122     #[inline]
max(self, rhs: Z0) -> Self::Output1123     fn max(self, rhs: Z0) -> Self::Output {
1124         rhs
1125     }
1126 }
1127 
1128 impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul>
1129 where
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]
max(self, rhs: PInt<Ur>) -> Self::Output1136     fn max(self, rhs: PInt<Ur>) -> Self::Output {
1137         PInt {
1138             n: self.n.max(rhs.n),
1139         }
1140     }
1141 }
1142 
1143 impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
1144 where
1145     Ul: Unsigned + NonZero,
1146     Ur: Unsigned + NonZero,
1147 {
1148     type Output = PInt<Ur>;
1149     #[inline]
max(self, rhs: PInt<Ur>) -> Self::Output1150     fn max(self, rhs: PInt<Ur>) -> Self::Output {
1151         rhs
1152     }
1153 }
1154 
1155 impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul>
1156 where
1157     Ul: Unsigned + NonZero,
1158     Ur: Unsigned + NonZero,
1159 {
1160     type Output = PInt<Ul>;
1161     #[inline]
max(self, _: NInt<Ur>) -> Self::Output1162     fn max(self, _: NInt<Ur>) -> Self::Output {
1163         self
1164     }
1165 }
1166 
1167 impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul>
1168 where
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]
max(self, rhs: NInt<Ur>) -> Self::Output1175     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 
1185 impl ToInt<i8> for Z0 {
1186     #[inline]
to_int() -> i81187     fn to_int() -> i8 {
1188         Self::I8
1189     }
1190 }
1191 
1192 impl ToInt<i16> for Z0 {
1193     #[inline]
to_int() -> i161194     fn to_int() -> i16 {
1195         Self::I16
1196     }
1197 }
1198 
1199 impl ToInt<i32> for Z0 {
1200     #[inline]
to_int() -> i321201     fn to_int() -> i32 {
1202         Self::I32
1203     }
1204 }
1205 
1206 impl ToInt<i64> for Z0 {
1207     #[inline]
to_int() -> i641208     fn to_int() -> i64 {
1209         Self::I64
1210     }
1211 }
1212 
1213 // negative numbers
1214 
1215 impl<U> ToInt<i8> for NInt<U>
1216 where
1217     U: Unsigned + NonZero,
1218 {
1219     #[inline]
to_int() -> i81220     fn to_int() -> i8 {
1221         Self::I8
1222     }
1223 }
1224 
1225 impl<U> ToInt<i16> for NInt<U>
1226 where
1227     U: Unsigned + NonZero,
1228 {
1229     #[inline]
to_int() -> i161230     fn to_int() -> i16 {
1231         Self::I16
1232     }
1233 }
1234 
1235 impl<U> ToInt<i32> for NInt<U>
1236 where
1237     U: Unsigned + NonZero,
1238 {
1239     #[inline]
to_int() -> i321240     fn to_int() -> i32 {
1241         Self::I32
1242     }
1243 }
1244 
1245 impl<U> ToInt<i64> for NInt<U>
1246 where
1247     U: Unsigned + NonZero,
1248 {
1249     #[inline]
to_int() -> i641250     fn to_int() -> i64 {
1251         Self::I64
1252     }
1253 }
1254 
1255 // positive numbers
1256 
1257 impl<U> ToInt<i8> for PInt<U>
1258 where
1259     U: Unsigned + NonZero,
1260 {
1261     #[inline]
to_int() -> i81262     fn to_int() -> i8 {
1263         Self::I8
1264     }
1265 }
1266 
1267 impl<U> ToInt<i16> for PInt<U>
1268 where
1269     U: Unsigned + NonZero,
1270 {
1271     #[inline]
to_int() -> i161272     fn to_int() -> i16 {
1273         Self::I16
1274     }
1275 }
1276 
1277 impl<U> ToInt<i32> for PInt<U>
1278 where
1279     U: Unsigned + NonZero,
1280 {
1281     #[inline]
to_int() -> i321282     fn to_int() -> i32 {
1283         Self::I32
1284     }
1285 }
1286 
1287 impl<U> ToInt<i64> for PInt<U>
1288 where
1289     U: Unsigned + NonZero,
1290 {
1291     #[inline]
to_int() -> i641292     fn to_int() -> i64 {
1293         Self::I64
1294     }
1295 }
1296 
1297 #[cfg(test)]
1298 mod tests {
1299     use crate::{consts::*, Integer, ToInt};
1300 
1301     #[test]
to_ix_min()1302     fn to_ix_min() {
1303         assert_eq!(N128::to_i8(), ::core::i8::MIN);
1304         assert_eq!(N32768::to_i16(), ::core::i16::MIN);
1305     }
1306 
1307     #[test]
int_toint_test()1308     fn int_toint_test() {
1309         // i8
1310         assert_eq!(0_i8, Z0::to_int());
1311         assert_eq!(1_i8, P1::to_int());
1312         assert_eq!(2_i8, P2::to_int());
1313         assert_eq!(3_i8, P3::to_int());
1314         assert_eq!(4_i8, P4::to_int());
1315         assert_eq!(-1_i8, N1::to_int());
1316         assert_eq!(-2_i8, N2::to_int());
1317         assert_eq!(-3_i8, N3::to_int());
1318         assert_eq!(-4_i8, N4::to_int());
1319 
1320         // i16
1321         assert_eq!(0_i16, Z0::to_int());
1322         assert_eq!(1_i16, P1::to_int());
1323         assert_eq!(2_i16, P2::to_int());
1324         assert_eq!(3_i16, P3::to_int());
1325         assert_eq!(4_i16, P4::to_int());
1326         assert_eq!(-1_i16, N1::to_int());
1327         assert_eq!(-2_i16, N2::to_int());
1328         assert_eq!(-3_i16, N3::to_int());
1329         assert_eq!(-4_i16, N4::to_int());
1330 
1331         // i32
1332         assert_eq!(0_i32, Z0::to_int());
1333         assert_eq!(1_i32, P1::to_int());
1334         assert_eq!(2_i32, P2::to_int());
1335         assert_eq!(3_i32, P3::to_int());
1336         assert_eq!(4_i32, P4::to_int());
1337         assert_eq!(-1_i32, N1::to_int());
1338         assert_eq!(-2_i32, N2::to_int());
1339         assert_eq!(-3_i32, N3::to_int());
1340         assert_eq!(-4_i32, N4::to_int());
1341 
1342         // i64
1343         assert_eq!(0_i64, Z0::to_int());
1344         assert_eq!(1_i64, P1::to_int());
1345         assert_eq!(2_i64, P2::to_int());
1346         assert_eq!(3_i64, P3::to_int());
1347         assert_eq!(4_i64, P4::to_int());
1348         assert_eq!(-1_i64, N1::to_int());
1349         assert_eq!(-2_i64, N2::to_int());
1350         assert_eq!(-3_i64, N3::to_int());
1351         assert_eq!(-4_i64, N4::to_int());
1352     }
1353 }
1354