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