]> git.proxmox.com Git - cargo.git/blob - vendor/typenum/src/int.rs
New upstream version 0.52.0
[cargo.git] / vendor / typenum / src / int.rs
1 //! Type-level signed integers.
2 //!
3 //!
4 //! Type **operators** implemented:
5 //!
6 //! From `core::ops`: `Add`, `Sub`, `Mul`, `Div`, and `Rem`.
7 //! From `typenum`: `Same`, `Cmp`, and `Pow`.
8 //!
9 //! Rather than directly using the structs defined in this module, it is recommended that
10 //! you import and use the relevant aliases from the [consts](../consts/index.html) module.
11 //!
12 //! Note that operators that work on the underlying structure of the number are
13 //! intentionally not implemented. This is because this implementation of signed integers
14 //! does *not* use twos-complement, and implementing them would require making arbitrary
15 //! choices, causing the results of such operators to be difficult to reason about.
16 //!
17 //! # Example
18 //! ```rust
19 //! use std::ops::{Add, Div, Mul, Rem, Sub};
20 //! use typenum::{Integer, N3, P2};
21 //!
22 //! assert_eq!(<N3 as Add<P2>>::Output::to_i32(), -1);
23 //! assert_eq!(<N3 as Sub<P2>>::Output::to_i32(), -5);
24 //! assert_eq!(<N3 as Mul<P2>>::Output::to_i32(), -6);
25 //! assert_eq!(<N3 as Div<P2>>::Output::to_i32(), -1);
26 //! assert_eq!(<N3 as Rem<P2>>::Output::to_i32(), -1);
27 //! ```
28
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]
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]
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]
74 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]
95 fn to_i8() -> i8 {
96 0
97 }
98 #[inline]
99 fn to_i16() -> i16 {
100 0
101 }
102 #[inline]
103 fn to_i32() -> i32 {
104 0
105 }
106 #[inline]
107 fn to_i64() -> i64 {
108 0
109 }
110 #[cfg(feature = "i128")]
111 #[inline]
112 fn to_i128() -> i128 {
113 0
114 }
115 #[inline]
116 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]
131 fn to_i8() -> i8 {
132 <U as Unsigned>::to_i8()
133 }
134 #[inline]
135 fn to_i16() -> i16 {
136 <U as Unsigned>::to_i16()
137 }
138 #[inline]
139 fn to_i32() -> i32 {
140 <U as Unsigned>::to_i32()
141 }
142 #[inline]
143 fn to_i64() -> i64 {
144 <U as Unsigned>::to_i64()
145 }
146 #[cfg(feature = "i128")]
147 #[inline]
148 fn to_i128() -> i128 {
149 <U as Unsigned>::to_i128()
150 }
151 #[inline]
152 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]
169 fn to_i8() -> i8 {
170 Self::I8
171 }
172 #[inline]
173 fn to_i16() -> i16 {
174 Self::I16
175 }
176 #[inline]
177 fn to_i32() -> i32 {
178 Self::I32
179 }
180 #[inline]
181 fn to_i64() -> i64 {
182 Self::I64
183 }
184 #[cfg(feature = "i128")]
185 #[inline]
186 fn to_i128() -> i128 {
187 Self::I128
188 }
189 #[inline]
190 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]
202 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]
211 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]
220 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]
232 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]
241 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]
250 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]
263 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]
276 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]
288 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]
304 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]
317 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]
331 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]
345 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]
357 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]
366 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]
375 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]
384 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]
393 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]
406 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]
419 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]
431 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]
447 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]
462 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]
471 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]
480 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]
493 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]
506 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]
519 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]
532 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]
544 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]
620 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]
633 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]
643 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]
653 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]
663 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]
673 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]
683 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]
693 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]
703 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]
713 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]
725 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]
781 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]
790 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]
799 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]
808 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]
817 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]
826 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]
835 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]
844 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]
857 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]
870 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]
883 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]
967 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]
978 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]
989 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]
1000 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]
1011 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]
1024 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]
1038 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]
1050 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]
1063 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]
1076 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]
1087 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]
1098 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]
1109 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]
1120 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]
1133 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]
1147 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]
1159 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]
1172 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]
1184 fn to_int() -> i8 {
1185 Self::I8
1186 }
1187 }
1188
1189 impl ToInt<i16> for Z0 {
1190 #[inline]
1191 fn to_int() -> i16 {
1192 Self::I16
1193 }
1194 }
1195
1196 impl ToInt<i32> for Z0 {
1197 #[inline]
1198 fn to_int() -> i32 {
1199 Self::I32
1200 }
1201 }
1202
1203 impl ToInt<i64> for Z0 {
1204 #[inline]
1205 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]
1217 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]
1227 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]
1237 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]
1247 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]
1259 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]
1269 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]
1279 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]
1289 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]
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]
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 }