1//! Type-level signed integers.
2//!
3//!
4//! Type **operators** implemented:
5//!
6//! From `core::ops`: `Add`, `Sub`, `Mul`, `Div`, and `Rem`.
7//! From `typenum`: `Same`, `Cmp`, and `Pow`.
8//!
9//! Rather than directly using the structs defined in this module, it is recommended that
10//! you import and use the relevant aliases from the [consts](../consts/index.html) module.
11//!
12//! Note that operators that work on the underlying structure of the number are
13//! intentionally not implemented. This is because this implementation of signed integers
14//! does *not* use twos-complement, and implementing them would require making arbitrary
15//! choices, causing the results of such operators to be difficult to reason about.
16//!
17//! # Example
18//! ```rust
19//! use std::ops::{Add, Div, Mul, Rem, Sub};
20//! use typenum::{Integer, N3, P2};
21//!
22//! assert_eq!(<N3 as Add<P2>>::Output::to_i32(), -1);
23//! assert_eq!(<N3 as Sub<P2>>::Output::to_i32(), -5);
24//! assert_eq!(<N3 as Mul<P2>>::Output::to_i32(), -6);
25//! assert_eq!(<N3 as Div<P2>>::Output::to_i32(), -1);
26//! assert_eq!(<N3 as Rem<P2>>::Output::to_i32(), -1);
27//! ```
28
29pub use crate::marker_traits::Integer;
30use crate::{
31 bit::{Bit, B0, B1},
32 consts::{N1, P1, U0, U1},
33 private::{Internal, InternalMarker, PrivateDivInt, PrivateIntegerAdd, PrivateRem},
34 uint::{UInt, Unsigned},
35 Cmp, Equal, Greater, Less, NonZero, Pow, PowerOfTwo, ToInt, Zero,
36};
37use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
38
39/// Type-level signed integers with positive sign.
40#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
41#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
42pub struct PInt<U: Unsigned + NonZero> {
43 pub(crate) n: U,
44}
45
46/// Type-level signed integers with negative sign.
47#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
48#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
49pub struct NInt<U: Unsigned + NonZero> {
50 pub(crate) n: U,
51}
52
53impl<U: Unsigned + NonZero> PInt<U> {
54 /// Instantiates a singleton representing this strictly positive integer.
55 #[inline]
56 pub fn new() -> PInt<U> {
57 PInt::default()
58 }
59}
60
61impl<U: Unsigned + NonZero> NInt<U> {
62 /// Instantiates a singleton representing this strictly negative integer.
63 #[inline]
64 pub fn new() -> NInt<U> {
65 NInt::default()
66 }
67}
68
69/// The type-level signed integer 0.
70#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
71#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
72pub struct Z0;
73
74impl Z0 {
75 /// Instantiates a singleton representing the integer 0.
76 #[inline]
77 pub fn new() -> Z0 {
78 Z0
79 }
80}
81
82impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
83impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
84impl Zero for Z0 {}
85
86impl<U: Unsigned + NonZero + PowerOfTwo> PowerOfTwo for PInt<U> {}
87
88impl Integer for Z0 {
89 const I8: i8 = 0;
90 const I16: i16 = 0;
91 const I32: i32 = 0;
92 const I64: i64 = 0;
93 #[cfg(feature = "i128")]
94 const I128: i128 = 0;
95 const ISIZE: isize = 0;
96
97 #[inline]
98 fn to_i8() -> i8 {
99 0
100 }
101 #[inline]
102 fn to_i16() -> i16 {
103 0
104 }
105 #[inline]
106 fn to_i32() -> i32 {
107 0
108 }
109 #[inline]
110 fn to_i64() -> i64 {
111 0
112 }
113 #[cfg(feature = "i128")]
114 #[inline]
115 fn to_i128() -> i128 {
116 0
117 }
118 #[inline]
119 fn to_isize() -> isize {
120 0
121 }
122}
123
124impl<U: Unsigned + NonZero> Integer for PInt<U> {
125 const I8: i8 = U::I8;
126 const I16: i16 = U::I16;
127 const I32: i32 = U::I32;
128 const I64: i64 = U::I64;
129 #[cfg(feature = "i128")]
130 const I128: i128 = U::I128;
131 const ISIZE: isize = U::ISIZE;
132
133 #[inline]
134 fn to_i8() -> i8 {
135 <U as Unsigned>::to_i8()
136 }
137 #[inline]
138 fn to_i16() -> i16 {
139 <U as Unsigned>::to_i16()
140 }
141 #[inline]
142 fn to_i32() -> i32 {
143 <U as Unsigned>::to_i32()
144 }
145 #[inline]
146 fn to_i64() -> i64 {
147 <U as Unsigned>::to_i64()
148 }
149 #[cfg(feature = "i128")]
150 #[inline]
151 fn to_i128() -> i128 {
152 <U as Unsigned>::to_i128()
153 }
154 #[inline]
155 fn to_isize() -> isize {
156 <U as Unsigned>::to_isize()
157 }
158}
159
160// Simply negating the result of e.g. `U::I8` will result in overflow for `std::i8::MIN`. Instead,
161// we use the fact that `U: NonZero` by subtracting one from the `U::U8` before negating.
162impl<U: Unsigned + NonZero> Integer for NInt<U> {
163 const I8: i8 = -((U::U8 - 1) as i8) - 1;
164 const I16: i16 = -((U::U16 - 1) as i16) - 1;
165 const I32: i32 = -((U::U32 - 1) as i32) - 1;
166 const I64: i64 = -((U::U64 - 1) as i64) - 1;
167 #[cfg(feature = "i128")]
168 const I128: i128 = -((U::U128 - 1) as i128) - 1;
169 const ISIZE: isize = -((U::USIZE - 1) as isize) - 1;
170
171 #[inline]
172 fn to_i8() -> i8 {
173 Self::I8
174 }
175 #[inline]
176 fn to_i16() -> i16 {
177 Self::I16
178 }
179 #[inline]
180 fn to_i32() -> i32 {
181 Self::I32
182 }
183 #[inline]
184 fn to_i64() -> i64 {
185 Self::I64
186 }
187 #[cfg(feature = "i128")]
188 #[inline]
189 fn to_i128() -> i128 {
190 Self::I128
191 }
192 #[inline]
193 fn to_isize() -> isize {
194 Self::ISIZE
195 }
196}
197
198// ---------------------------------------------------------------------------------------
199// Neg
200
201/// `-Z0 = Z0`
202impl Neg for Z0 {
203 type Output = Z0;
204 #[inline]
205 fn neg(self) -> Self::Output {
206 Z0
207 }
208}
209
210/// `-PInt = NInt`
211impl<U: Unsigned + NonZero> Neg for PInt<U> {
212 type Output = NInt<U>;
213 #[inline]
214 fn neg(self) -> Self::Output {
215 NInt::new()
216 }
217}
218
219/// `-NInt = PInt`
220impl<U: Unsigned + NonZero> Neg for NInt<U> {
221 type Output = PInt<U>;
222 #[inline]
223 fn neg(self) -> Self::Output {
224 PInt::new()
225 }
226}
227
228// ---------------------------------------------------------------------------------------
229// Add
230
231/// `Z0 + I = I`
232impl<I: Integer> Add<I> for Z0 {
233 type Output = I;
234 #[inline]
235 fn add(self, rhs: I) -> Self::Output {
236 rhs
237 }
238}
239
240/// `PInt + Z0 = PInt`
241impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
242 type Output = PInt<U>;
243 #[inline]
244 fn add(self, _: Z0) -> Self::Output {
245 PInt::new()
246 }
247}
248
249/// `NInt + Z0 = NInt`
250impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
251 type Output = NInt<U>;
252 #[inline]
253 fn add(self, _: Z0) -> Self::Output {
254 NInt::new()
255 }
256}
257
258/// `P(Ul) + P(Ur) = P(Ul + Ur)`
259impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul>
260where
261 Ul: Add<Ur>,
262 <Ul as Add<Ur>>::Output: Unsigned + NonZero,
263{
264 type Output = PInt<<Ul as Add<Ur>>::Output>;
265 #[inline]
266 fn add(self, _: PInt<Ur>) -> Self::Output {
267 PInt::new()
268 }
269}
270
271/// `N(Ul) + N(Ur) = N(Ul + Ur)`
272impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul>
273where
274 Ul: Add<Ur>,
275 <Ul as Add<Ur>>::Output: Unsigned + NonZero,
276{
277 type Output = NInt<<Ul as Add<Ur>>::Output>;
278 #[inline]
279 fn add(self, _: NInt<Ur>) -> Self::Output {
280 NInt::new()
281 }
282}
283
284/// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
285impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul>
286where
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]
291 fn add(self, rhs: NInt<Ur>) -> Self::Output {
292 let lhs: Ul = self.n;
293 let rhs: Ur = rhs.n;
294 let lhs_cmp_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
301impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul>
302where
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]
307 fn add(self, rhs: PInt<Ur>) -> Self::Output {
308 let lhs: Ul = self.n;
309 let rhs: Ur = rhs.n;
310 let rhs_cmp_lhs: >::Output = rhs.compare::<Internal>(&lhs);
311 rhs.private_integer_add(rhs_cmp_lhs, lhs)
312 }
313}
314
315/// `P + N = 0` where `P == N`
316impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
317 type Output = Z0;
318
319 #[inline]
320 fn private_integer_add(self, _: Equal, _: N) -> Self::Output {
321 Z0
322 }
323}
324
325/// `P + N = Positive` where `P > N`
326impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P
327where
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]
334 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`
340impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P
341where
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]
348 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`
357impl Sub<Z0> for Z0 {
358 type Output = Z0;
359 #[inline]
360 fn sub(self, _: Z0) -> Self::Output {
361 Z0
362 }
363}
364
365/// `Z0 - P = N`
366impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
367 type Output = NInt<U>;
368 #[inline]
369 fn sub(self, _: PInt<U>) -> Self::Output {
370 NInt::new()
371 }
372}
373
374/// `Z0 - N = P`
375impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 {
376 type Output = PInt<U>;
377 #[inline]
378 fn sub(self, _: NInt<U>) -> Self::Output {
379 PInt::new()
380 }
381}
382
383/// `PInt - Z0 = PInt`
384impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> {
385 type Output = PInt<U>;
386 #[inline]
387 fn sub(self, _: Z0) -> Self::Output {
388 PInt::new()
389 }
390}
391
392/// `NInt - Z0 = NInt`
393impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
394 type Output = NInt<U>;
395 #[inline]
396 fn sub(self, _: Z0) -> Self::Output {
397 NInt::new()
398 }
399}
400
401/// `P(Ul) - N(Ur) = P(Ul + Ur)`
402impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul>
403where
404 Ul: Add<Ur>,
405 <Ul as Add<Ur>>::Output: Unsigned + NonZero,
406{
407 type Output = PInt<<Ul as Add<Ur>>::Output>;
408 #[inline]
409 fn sub(self, _: NInt<Ur>) -> Self::Output {
410 PInt::new()
411 }
412}
413
414/// `N(Ul) - P(Ur) = N(Ul + Ur)`
415impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul>
416where
417 Ul: Add<Ur>,
418 <Ul as Add<Ur>>::Output: Unsigned + NonZero,
419{
420 type Output = NInt<<Ul as Add<Ur>>::Output>;
421 #[inline]
422 fn sub(self, _: PInt<Ur>) -> Self::Output {
423 NInt::new()
424 }
425}
426
427/// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
428impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul>
429where
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]
434 fn sub(self, rhs: PInt<Ur>) -> Self::Output {
435 let lhs: Ul = self.n;
436 let rhs: Ur = rhs.n;
437 let lhs_cmp_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
444impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul>
445where
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]
450 fn sub(self, rhs: NInt<Ur>) -> Self::Output {
451 let lhs: Ul = self.n;
452 let rhs: Ur = rhs.n;
453 let rhs_cmp_lhs: >::Output = rhs.compare::<Internal>(&lhs);
454 rhs.private_integer_add(rhs_cmp_lhs, lhs)
455 }
456}
457
458// ---------------------------------------------------------------------------------------
459// Mul
460
461/// `Z0 * I = Z0`
462impl<I: Integer> Mul<I> for Z0 {
463 type Output = Z0;
464 #[inline]
465 fn mul(self, _: I) -> Self::Output {
466 Z0
467 }
468}
469
470/// `P * Z0 = Z0`
471impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
472 type Output = Z0;
473 #[inline]
474 fn mul(self, _: Z0) -> Self::Output {
475 Z0
476 }
477}
478
479/// `N * Z0 = Z0`
480impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
481 type Output = Z0;
482 #[inline]
483 fn mul(self, _: Z0) -> Self::Output {
484 Z0
485 }
486}
487
488/// P(Ul) * P(Ur) = P(Ul * Ur)
489impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul>
490where
491 Ul: Mul<Ur>,
492 <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
493{
494 type Output = PInt<<Ul as Mul<Ur>>::Output>;
495 #[inline]
496 fn mul(self, _: PInt<Ur>) -> Self::Output {
497 PInt::new()
498 }
499}
500
501/// N(Ul) * N(Ur) = P(Ul * Ur)
502impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul>
503where
504 Ul: Mul<Ur>,
505 <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
506{
507 type Output = PInt<<Ul as Mul<Ur>>::Output>;
508 #[inline]
509 fn mul(self, _: NInt<Ur>) -> Self::Output {
510 PInt::new()
511 }
512}
513
514/// P(Ul) * N(Ur) = N(Ul * Ur)
515impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul>
516where
517 Ul: Mul<Ur>,
518 <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
519{
520 type Output = NInt<<Ul as Mul<Ur>>::Output>;
521 #[inline]
522 fn mul(self, _: NInt<Ur>) -> Self::Output {
523 NInt::new()
524 }
525}
526
527/// N(Ul) * P(Ur) = N(Ul * Ur)
528impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul>
529where
530 Ul: Mul<Ur>,
531 <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
532{
533 type Output = NInt<<Ul as Mul<Ur>>::Output>;
534 #[inline]
535 fn mul(self, _: PInt<Ur>) -> Self::Output {
536 NInt::new()
537 }
538}
539
540// ---------------------------------------------------------------------------------------
541// Div
542
543/// `Z0 / I = Z0` where `I != 0`
544impl<I: Integer + NonZero> Div<I> for Z0 {
545 type Output = Z0;
546 #[inline]
547 fn div(self, _: I) -> Self::Output {
548 Z0
549 }
550}
551
552macro_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
607impl_int_div!(PInt, PInt, PInt);
608impl_int_div!(PInt, NInt, NInt);
609impl_int_div!(NInt, PInt, NInt);
610impl_int_div!(NInt, NInt, PInt);
611
612// ---------------------------------------------------------------------------------------
613// PartialDiv
614
615use crate::{PartialDiv, Quot};
616
617impl<M, N> PartialDiv<N> for M
618where
619 M: Integer + Div<N> + Rem<N, Output = Z0>,
620{
621 type Output = Quot<M, N>;
622 #[inline]
623 fn partial_div(self, rhs: N) -> Self::Output {
624 self / rhs
625 }
626}
627
628// ---------------------------------------------------------------------------------------
629// Cmp
630
631/// 0 == 0
632impl Cmp<Z0> for Z0 {
633 type Output = Equal;
634
635 #[inline]
636 fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
637 Equal
638 }
639}
640
641/// 0 > -X
642impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
643 type Output = Greater;
644
645 #[inline]
646 fn compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output {
647 Greater
648 }
649}
650
651/// 0 < X
652impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
653 type Output = Less;
654
655 #[inline]
656 fn compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output {
657 Less
658 }
659}
660
661/// X > 0
662impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
663 type Output = Greater;
664
665 #[inline]
666 fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
667 Greater
668 }
669}
670
671/// -X < 0
672impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
673 type Output = Less;
674
675 #[inline]
676 fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
677 Less
678 }
679}
680
681/// -X < Y
682impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
683 type Output = Less;
684
685 #[inline]
686 fn compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output {
687 Less
688 }
689}
690
691/// X > - Y
692impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
693 type Output = Greater;
694
695 #[inline]
696 fn compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output {
697 Greater
698 }
699}
700
701/// X <==> Y
702impl<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]
706 fn compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output {
707 self.n.compare::<Internal>(&rhs.n)
708 }
709}
710
711/// -X <==> -Y
712impl<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]
716 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`
725impl<I: Integer + NonZero> Rem<I> for Z0 {
726 type Output = Z0;
727 #[inline]
728 fn rem(self, _: I) -> Self::Output {
729 Z0
730 }
731}
732
733macro_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
772impl_int_rem!(PInt, PInt, PInt);
773impl_int_rem!(PInt, NInt, PInt);
774impl_int_rem!(NInt, PInt, NInt);
775impl_int_rem!(NInt, NInt, NInt);
776
777// ---------------------------------------------------------------------------------------
778// Pow
779
780/// 0^0 = 1
781impl Pow<Z0> for Z0 {
782 type Output = P1;
783 #[inline]
784 fn powi(self, _: Z0) -> Self::Output {
785 P1::new()
786 }
787}
788
789/// 0^P = 0
790impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
791 type Output = Z0;
792 #[inline]
793 fn powi(self, _: PInt<U>) -> Self::Output {
794 Z0
795 }
796}
797
798/// 0^N = 0
799impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
800 type Output = Z0;
801 #[inline]
802 fn powi(self, _: NInt<U>) -> Self::Output {
803 Z0
804 }
805}
806
807/// 1^N = 1
808impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
809 type Output = P1;
810 #[inline]
811 fn powi(self, _: NInt<U>) -> Self::Output {
812 P1::new()
813 }
814}
815
816/// (-1)^N = 1 if N is even
817impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 {
818 type Output = P1;
819 #[inline]
820 fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output {
821 P1::new()
822 }
823}
824
825/// (-1)^N = -1 if N is odd
826impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 {
827 type Output = N1;
828 #[inline]
829 fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output {
830 N1::new()
831 }
832}
833
834/// P^0 = 1
835impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> {
836 type Output = P1;
837 #[inline]
838 fn powi(self, _: Z0) -> Self::Output {
839 P1::new()
840 }
841}
842
843/// N^0 = 1
844impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
845 type Output = P1;
846 #[inline]
847 fn powi(self, _: Z0) -> Self::Output {
848 P1::new()
849 }
850}
851
852/// P(Ul)^P(Ur) = P(Ul^Ur)
853impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul>
854where
855 Ul: Pow<Ur>,
856 <Ul as Pow<Ur>>::Output: Unsigned + NonZero,
857{
858 type Output = PInt<<Ul as Pow<Ur>>::Output>;
859 #[inline]
860 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
866impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul>
867where
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]
873 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
879impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul>
880where
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]
886 fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
887 NInt::new()
888 }
889}
890
891// ---------------------------------------------------------------------------------------
892// Gcd
893use crate::{Gcd, Gcf};
894
895impl Gcd<Z0> for Z0 {
896 type Output = Z0;
897}
898
899impl<U> Gcd<PInt<U>> for Z0
900where
901 U: Unsigned + NonZero,
902{
903 type Output = PInt<U>;
904}
905
906impl<U> Gcd<Z0> for PInt<U>
907where
908 U: Unsigned + NonZero,
909{
910 type Output = PInt<U>;
911}
912
913impl<U> Gcd<NInt<U>> for Z0
914where
915 U: Unsigned + NonZero,
916{
917 type Output = PInt<U>;
918}
919
920impl<U> Gcd<Z0> for NInt<U>
921where
922 U: Unsigned + NonZero,
923{
924 type Output = PInt<U>;
925}
926
927impl<U1, U2> Gcd<PInt<U2>> for PInt<U1>
928where
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
936impl<U1, U2> Gcd<PInt<U2>> for NInt<U1>
937where
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
945impl<U1, U2> Gcd<NInt<U2>> for PInt<U1>
946where
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
954impl<U1, U2> Gcd<NInt<U2>> for NInt<U1>
955where
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
965use crate::{Max, Maximum, Min, Minimum};
966
967impl Min<Z0> for Z0 {
968 type Output = Z0;
969 #[inline]
970 fn min(self, _: Z0) -> Self::Output {
971 self
972 }
973}
974
975impl<U> Min<PInt<U>> for Z0
976where
977 U: Unsigned + NonZero,
978{
979 type Output = Z0;
980 #[inline]
981 fn min(self, _: PInt<U>) -> Self::Output {
982 self
983 }
984}
985
986impl<U> Min<NInt<U>> for Z0
987where
988 U: Unsigned + NonZero,
989{
990 type Output = NInt<U>;
991 #[inline]
992 fn min(self, rhs: NInt<U>) -> Self::Output {
993 rhs
994 }
995}
996
997impl<U> Min<Z0> for PInt<U>
998where
999 U: Unsigned + NonZero,
1000{
1001 type Output = Z0;
1002 #[inline]
1003 fn min(self, rhs: Z0) -> Self::Output {
1004 rhs
1005 }
1006}
1007
1008impl<U> Min<Z0> for NInt<U>
1009where
1010 U: Unsigned + NonZero,
1011{
1012 type Output = NInt<U>;
1013 #[inline]
1014 fn min(self, _: Z0) -> Self::Output {
1015 self
1016 }
1017}
1018
1019impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul>
1020where
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]
1027 fn min(self, rhs: PInt<Ur>) -> Self::Output {
1028 PInt {
1029 n: self.n.min(rhs.n),
1030 }
1031 }
1032}
1033
1034impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
1035where
1036 Ul: Unsigned + NonZero,
1037 Ur: Unsigned + NonZero,
1038{
1039 type Output = NInt<Ul>;
1040 #[inline]
1041 fn min(self, _: PInt<Ur>) -> Self::Output {
1042 self
1043 }
1044}
1045
1046impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul>
1047where
1048 Ul: Unsigned + NonZero,
1049 Ur: Unsigned + NonZero,
1050{
1051 type Output = NInt<Ur>;
1052 #[inline]
1053 fn min(self, rhs: NInt<Ur>) -> Self::Output {
1054 rhs
1055 }
1056}
1057
1058impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul>
1059where
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]
1066 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
1076impl Max<Z0> for Z0 {
1077 type Output = Z0;
1078 #[inline]
1079 fn max(self, _: Z0) -> Self::Output {
1080 self
1081 }
1082}
1083
1084impl<U> Max<PInt<U>> for Z0
1085where
1086 U: Unsigned + NonZero,
1087{
1088 type Output = PInt<U>;
1089 #[inline]
1090 fn max(self, rhs: PInt<U>) -> Self::Output {
1091 rhs
1092 }
1093}
1094
1095impl<U> Max<NInt<U>> for Z0
1096where
1097 U: Unsigned + NonZero,
1098{
1099 type Output = Z0;
1100 #[inline]
1101 fn max(self, _: NInt<U>) -> Self::Output {
1102 self
1103 }
1104}
1105
1106impl<U> Max<Z0> for PInt<U>
1107where
1108 U: Unsigned + NonZero,
1109{
1110 type Output = PInt<U>;
1111 #[inline]
1112 fn max(self, _: Z0) -> Self::Output {
1113 self
1114 }
1115}
1116
1117impl<U> Max<Z0> for NInt<U>
1118where
1119 U: Unsigned + NonZero,
1120{
1121 type Output = Z0;
1122 #[inline]
1123 fn max(self, rhs: Z0) -> Self::Output {
1124 rhs
1125 }
1126}
1127
1128impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul>
1129where
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]
1136 fn max(self, rhs: PInt<Ur>) -> Self::Output {
1137 PInt {
1138 n: self.n.max(rhs.n),
1139 }
1140 }
1141}
1142
1143impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
1144where
1145 Ul: Unsigned + NonZero,
1146 Ur: Unsigned + NonZero,
1147{
1148 type Output = PInt<Ur>;
1149 #[inline]
1150 fn max(self, rhs: PInt<Ur>) -> Self::Output {
1151 rhs
1152 }
1153}
1154
1155impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul>
1156where
1157 Ul: Unsigned + NonZero,
1158 Ur: Unsigned + NonZero,
1159{
1160 type Output = PInt<Ul>;
1161 #[inline]
1162 fn max(self, _: NInt<Ur>) -> Self::Output {
1163 self
1164 }
1165}
1166
1167impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul>
1168where
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]
1175 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
1185impl ToInt<i8> for Z0 {
1186 #[inline]
1187 fn to_int() -> i8 {
1188 Self::I8
1189 }
1190 const INT: i8 = Self::I8;
1191}
1192
1193impl ToInt<i16> for Z0 {
1194 #[inline]
1195 fn to_int() -> i16 {
1196 Self::I16
1197 }
1198 const INT: i16 = Self::I16;
1199}
1200
1201impl ToInt<i32> for Z0 {
1202 #[inline]
1203 fn to_int() -> i32 {
1204 Self::I32
1205 }
1206 const INT: i32 = Self::I32;
1207}
1208
1209impl ToInt<i64> for Z0 {
1210 #[inline]
1211 fn to_int() -> i64 {
1212 Self::I64
1213 }
1214 const INT: i64 = Self::I64;
1215}
1216
1217// negative numbers
1218
1219impl<U> ToInt<i8> for NInt<U>
1220where
1221 U: Unsigned + NonZero,
1222{
1223 #[inline]
1224 fn to_int() -> i8 {
1225 Self::I8
1226 }
1227 const INT: i8 = Self::I8;
1228}
1229
1230impl<U> ToInt<i16> for NInt<U>
1231where
1232 U: Unsigned + NonZero,
1233{
1234 #[inline]
1235 fn to_int() -> i16 {
1236 Self::I16
1237 }
1238 const INT: i16 = Self::I16;
1239}
1240
1241impl<U> ToInt<i32> for NInt<U>
1242where
1243 U: Unsigned + NonZero,
1244{
1245 #[inline]
1246 fn to_int() -> i32 {
1247 Self::I32
1248 }
1249 const INT: i32 = Self::I32;
1250}
1251
1252impl<U> ToInt<i64> for NInt<U>
1253where
1254 U: Unsigned + NonZero,
1255{
1256 #[inline]
1257 fn to_int() -> i64 {
1258 Self::I64
1259 }
1260 const INT: i64 = Self::I64;
1261}
1262
1263// positive numbers
1264
1265impl<U> ToInt<i8> for PInt<U>
1266where
1267 U: Unsigned + NonZero,
1268{
1269 #[inline]
1270 fn to_int() -> i8 {
1271 Self::I8
1272 }
1273 const INT: i8 = Self::I8;
1274}
1275
1276impl<U> ToInt<i16> for PInt<U>
1277where
1278 U: Unsigned + NonZero,
1279{
1280 #[inline]
1281 fn to_int() -> i16 {
1282 Self::I16
1283 }
1284 const INT: i16 = Self::I16;
1285}
1286
1287impl<U> ToInt<i32> for PInt<U>
1288where
1289 U: Unsigned + NonZero,
1290{
1291 #[inline]
1292 fn to_int() -> i32 {
1293 Self::I32
1294 }
1295 const INT: i32 = Self::I32;
1296}
1297
1298impl<U> ToInt<i64> for PInt<U>
1299where
1300 U: Unsigned + NonZero,
1301{
1302 #[inline]
1303 fn to_int() -> i64 {
1304 Self::I64
1305 }
1306 const INT: i64 = Self::I64;
1307}
1308
1309#[cfg(test)]
1310mod tests {
1311 use crate::{consts::*, Integer, ToInt};
1312
1313 #[test]
1314 fn to_ix_min() {
1315 assert_eq!(N128::to_i8(), ::core::i8::MIN);
1316 assert_eq!(N32768::to_i16(), ::core::i16::MIN);
1317 }
1318
1319 #[test]
1320 fn int_toint_test() {
1321 // i8
1322 assert_eq!(0_i8, Z0::to_int());
1323 assert_eq!(1_i8, P1::to_int());
1324 assert_eq!(2_i8, P2::to_int());
1325 assert_eq!(3_i8, P3::to_int());
1326 assert_eq!(4_i8, P4::to_int());
1327 assert_eq!(-1_i8, N1::to_int());
1328 assert_eq!(-2_i8, N2::to_int());
1329 assert_eq!(-3_i8, N3::to_int());
1330 assert_eq!(-4_i8, N4::to_int());
1331 assert_eq!(0_i8, Z0::INT);
1332 assert_eq!(1_i8, P1::INT);
1333 assert_eq!(2_i8, P2::INT);
1334 assert_eq!(3_i8, P3::INT);
1335 assert_eq!(4_i8, P4::INT);
1336 assert_eq!(-1_i8, N1::INT);
1337 assert_eq!(-2_i8, N2::INT);
1338 assert_eq!(-3_i8, N3::INT);
1339 assert_eq!(-4_i8, N4::INT);
1340
1341 // i16
1342 assert_eq!(0_i16, Z0::to_int());
1343 assert_eq!(1_i16, P1::to_int());
1344 assert_eq!(2_i16, P2::to_int());
1345 assert_eq!(3_i16, P3::to_int());
1346 assert_eq!(4_i16, P4::to_int());
1347 assert_eq!(-1_i16, N1::to_int());
1348 assert_eq!(-2_i16, N2::to_int());
1349 assert_eq!(-3_i16, N3::to_int());
1350 assert_eq!(-4_i16, N4::to_int());
1351 assert_eq!(0_i16, Z0::INT);
1352 assert_eq!(1_i16, P1::INT);
1353 assert_eq!(2_i16, P2::INT);
1354 assert_eq!(3_i16, P3::INT);
1355 assert_eq!(4_i16, P4::INT);
1356 assert_eq!(-1_i16, N1::INT);
1357 assert_eq!(-2_i16, N2::INT);
1358 assert_eq!(-3_i16, N3::INT);
1359 assert_eq!(-4_i16, N4::INT);
1360
1361 // i32
1362 assert_eq!(0_i32, Z0::to_int());
1363 assert_eq!(1_i32, P1::to_int());
1364 assert_eq!(2_i32, P2::to_int());
1365 assert_eq!(3_i32, P3::to_int());
1366 assert_eq!(4_i32, P4::to_int());
1367 assert_eq!(-1_i32, N1::to_int());
1368 assert_eq!(-2_i32, N2::to_int());
1369 assert_eq!(-3_i32, N3::to_int());
1370 assert_eq!(-4_i32, N4::to_int());
1371 assert_eq!(0_i32, Z0::INT);
1372 assert_eq!(1_i32, P1::INT);
1373 assert_eq!(2_i32, P2::INT);
1374 assert_eq!(3_i32, P3::INT);
1375 assert_eq!(4_i32, P4::INT);
1376 assert_eq!(-1_i32, N1::INT);
1377 assert_eq!(-2_i32, N2::INT);
1378 assert_eq!(-3_i32, N3::INT);
1379 assert_eq!(-4_i32, N4::INT);
1380
1381 // i64
1382 assert_eq!(0_i64, Z0::to_int());
1383 assert_eq!(1_i64, P1::to_int());
1384 assert_eq!(2_i64, P2::to_int());
1385 assert_eq!(3_i64, P3::to_int());
1386 assert_eq!(4_i64, P4::to_int());
1387 assert_eq!(-1_i64, N1::to_int());
1388 assert_eq!(-2_i64, N2::to_int());
1389 assert_eq!(-3_i64, N3::to_int());
1390 assert_eq!(-4_i64, N4::to_int());
1391 assert_eq!(0_i64, Z0::INT);
1392 assert_eq!(1_i64, P1::INT);
1393 assert_eq!(2_i64, P2::INT);
1394 assert_eq!(3_i64, P3::INT);
1395 assert_eq!(4_i64, P4::INT);
1396 assert_eq!(-1_i64, N1::INT);
1397 assert_eq!(-2_i64, N2::INT);
1398 assert_eq!(-3_i64, N3::INT);
1399 assert_eq!(-4_i64, N4::INT);
1400 }
1401}
1402