1pub 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#[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#[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 #[inline]
56 pub fn new() -> PInt<U> {
57 PInt::default()
58 }
59}
60
61impl<U: Unsigned + NonZero> NInt<U> {
62 #[inline]
64 pub fn new() -> NInt<U> {
65 NInt::default()
66 }
67}
68
69#[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 #[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
160impl<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
198impl 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
219impl Neg for Z0 {
224 type Output = Z0;
225 #[inline]
226 fn neg(self) -> Self::Output {
227 Z0
228 }
229}
230
231impl<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
240impl<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
249impl<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
261impl<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
270impl<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
279impl<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
292impl<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
305impl<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
320impl<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
336impl<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
346impl<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
360impl<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
374impl Sub<Z0> for Z0 {
379 type Output = Z0;
380 #[inline]
381 fn sub(self, _: Z0) -> Self::Output {
382 Z0
383 }
384}
385
386impl<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
395impl<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
404impl<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
413impl<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
422impl<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
435impl<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
448impl<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
463impl<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
479impl<I: Integer> Mul<I> for Z0 {
484 type Output = Z0;
485 #[inline]
486 fn mul(self, _: I) -> Self::Output {
487 Z0
488 }
489}
490
491impl<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
500impl<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
509impl<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
522impl<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
535impl<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
548impl<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
561impl<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 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
633use 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
649impl 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
662impl<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
672impl<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
682impl<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
692impl<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
702impl<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
712impl<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
722impl<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
732impl<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
742impl<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 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
798impl Pow<Z0> for Z0 {
803 type Output = P1;
804 #[inline]
805 fn powi(self, _: Z0) -> Self::Output {
806 P1::new()
807 }
808}
809
810impl<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
819impl<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
828impl<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
837impl<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
846impl<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
855impl<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
864impl<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
873impl<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
886impl<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
899impl<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
912use 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
984use 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
1094impl 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
1203impl 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
1255impl<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
1324impl<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 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 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 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 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 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 #[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}