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, Sub, Mul, Div, Rem};
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 
30 use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
31 
32 use bit::{Bit, B0, B1};
33 use consts::{N1, P1, U0, U1};
34 use private::{Internal, InternalMarker};
35 use private::{PrivateDivInt, PrivateIntegerAdd, PrivateRem};
36 use uint::{UInt, Unsigned};
37 use {Cmp, Equal, Greater, Less, NonZero, Pow, PowerOfTwo};
38 
39 pub use marker_traits::Integer;
40 
41 /// Type-level signed integers with positive sign.
42 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
43 pub struct PInt<U: Unsigned + NonZero> {
44     pub(crate) n: U,
45 }
46 
47 /// Type-level signed integers with negative sign.
48 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
49 pub struct NInt<U: Unsigned + NonZero> {
50     pub(crate) n: U,
51 }
52 
53 impl<U: Unsigned + NonZero> PInt<U> {
54     /// Instantiates a singleton representing this strictly positive integer.
55     #[inline]
new() -> PInt<U>56     pub fn new() -> PInt<U> {
57         PInt::default()
58     }
59 }
60 
61 impl<U: Unsigned + NonZero> NInt<U> {
62     /// Instantiates a singleton representing this strictly negative integer.
63     #[inline]
new() -> NInt<U>64     pub fn new() -> NInt<U> {
65         NInt::default()
66     }
67 }
68 
69 /// The type-level signed integer 0.
70 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
71 pub struct Z0;
72 
73 impl Z0 {
74     /// Instantiates a singleton representing the integer 0.
75     #[inline]
new() -> Z076     pub fn new() -> Z0 {
77         Z0
78     }
79 }
80 
81 impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
82 impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
83 
84 impl<U: Unsigned + NonZero + PowerOfTwo> PowerOfTwo for PInt<U> {}
85 
86 impl Integer for Z0 {
87     const I8: i8 = 0;
88     const I16: i16 = 0;
89     const I32: i32 = 0;
90     const I64: i64 = 0;
91     #[cfg(feature = "i128")]
92     const I128: i128 = 0;
93     const ISIZE: isize = 0;
94 
95     #[inline]
to_i8() -> i896     fn to_i8() -> i8 {
97         0
98     }
99     #[inline]
to_i16() -> i16100     fn to_i16() -> i16 {
101         0
102     }
103     #[inline]
to_i32() -> i32104     fn to_i32() -> i32 {
105         0
106     }
107     #[inline]
to_i64() -> i64108     fn to_i64() -> i64 {
109         0
110     }
111     #[cfg(feature = "i128")]
112     #[inline]
to_i128() -> i128113     fn to_i128() -> i128 {
114         0
115     }
116     #[inline]
to_isize() -> isize117     fn to_isize() -> isize {
118         0
119     }
120 }
121 
122 impl<U: Unsigned + NonZero> Integer for PInt<U> {
123     const I8: i8 = U::I8;
124     const I16: i16 = U::I16;
125     const I32: i32 = U::I32;
126     const I64: i64 = U::I64;
127     #[cfg(feature = "i128")]
128     const I128: i128 = U::I128;
129     const ISIZE: isize = U::ISIZE;
130 
131     #[inline]
to_i8() -> i8132     fn to_i8() -> i8 {
133         <U as Unsigned>::to_i8()
134     }
135     #[inline]
to_i16() -> i16136     fn to_i16() -> i16 {
137         <U as Unsigned>::to_i16()
138     }
139     #[inline]
to_i32() -> i32140     fn to_i32() -> i32 {
141         <U as Unsigned>::to_i32()
142     }
143     #[inline]
to_i64() -> i64144     fn to_i64() -> i64 {
145         <U as Unsigned>::to_i64()
146     }
147     #[cfg(feature = "i128")]
148     #[inline]
to_i128() -> i128149     fn to_i128() -> i128 {
150         <U as Unsigned>::to_i128()
151     }
152     #[inline]
to_isize() -> isize153     fn to_isize() -> isize {
154         <U as Unsigned>::to_isize()
155     }
156 }
157 
158 // Simply negating the result of e.g. `U::I8` will result in overflow for `std::i8::MIN`. Instead,
159 // we use the fact that `U: NonZero` by subtracting one from the `U::U8` before negating.
160 impl<U: Unsigned + NonZero> Integer for NInt<U> {
161     const I8: i8 = -((U::U8 - 1) as i8) - 1;
162     const I16: i16 = -((U::U16 - 1) as i16) - 1;
163     const I32: i32 = -((U::U32 - 1) as i32) - 1;
164     const I64: i64 = -((U::U64 - 1) as i64) - 1;
165     #[cfg(feature = "i128")]
166     const I128: i128 = -((U::U128 - 1) as i128) - 1;
167     const ISIZE: isize = -((U::USIZE - 1) as isize) - 1;
168 
169     #[inline]
to_i8() -> i8170     fn to_i8() -> i8 {
171         Self::I8
172     }
173     #[inline]
to_i16() -> i16174     fn to_i16() -> i16 {
175         Self::I16
176     }
177     #[inline]
to_i32() -> i32178     fn to_i32() -> i32 {
179         Self::I32
180     }
181     #[inline]
to_i64() -> i64182     fn to_i64() -> i64 {
183         Self::I64
184     }
185     #[cfg(feature = "i128")]
186     #[inline]
to_i128() -> i128187     fn to_i128() -> i128 {
188         Self::I128
189     }
190     #[inline]
to_isize() -> isize191     fn to_isize() -> isize {
192         Self::ISIZE
193     }
194 }
195 
196 // ---------------------------------------------------------------------------------------
197 // Neg
198 
199 /// `-Z0 = Z0`
200 impl Neg for Z0 {
201     type Output = Z0;
202     #[inline]
neg(self) -> Self::Output203     fn neg(self) -> Self::Output {
204         Z0
205     }
206 }
207 
208 /// `-PInt = NInt`
209 impl<U: Unsigned + NonZero> Neg for PInt<U> {
210     type Output = NInt<U>;
211     #[inline]
neg(self) -> Self::Output212     fn neg(self) -> Self::Output {
213         NInt::new()
214     }
215 }
216 
217 /// `-NInt = PInt`
218 impl<U: Unsigned + NonZero> Neg for NInt<U> {
219     type Output = PInt<U>;
220     #[inline]
neg(self) -> Self::Output221     fn neg(self) -> Self::Output {
222         PInt::new()
223     }
224 }
225 
226 // ---------------------------------------------------------------------------------------
227 // Add
228 
229 /// `Z0 + I = I`
230 impl<I: Integer> Add<I> for Z0 {
231     type Output = I;
232     #[inline]
add(self, rhs: I) -> Self::Output233     fn add(self, rhs: I) -> Self::Output {
234         rhs
235     }
236 }
237 
238 /// `PInt + Z0 = PInt`
239 impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
240     type Output = PInt<U>;
241     #[inline]
add(self, _: Z0) -> Self::Output242     fn add(self, _: Z0) -> Self::Output {
243         PInt::new()
244     }
245 }
246 
247 /// `NInt + Z0 = NInt`
248 impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
249     type Output = NInt<U>;
250     #[inline]
add(self, _: Z0) -> Self::Output251     fn add(self, _: Z0) -> Self::Output {
252         NInt::new()
253     }
254 }
255 
256 /// `P(Ul) + P(Ur) = P(Ul + Ur)`
257 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul>
258 where
259     Ul: Add<Ur>,
260     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
261 {
262     type Output = PInt<<Ul as Add<Ur>>::Output>;
263     #[inline]
add(self, _: PInt<Ur>) -> Self::Output264     fn add(self, _: PInt<Ur>) -> Self::Output {
265         PInt::new()
266     }
267 }
268 
269 /// `N(Ul) + N(Ur) = N(Ul + Ur)`
270 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul>
271 where
272     Ul: Add<Ur>,
273     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
274 {
275     type Output = NInt<<Ul as Add<Ur>>::Output>;
276     #[inline]
add(self, _: NInt<Ur>) -> Self::Output277     fn add(self, _: NInt<Ur>) -> Self::Output {
278         NInt::new()
279     }
280 }
281 
282 /// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
283 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul>
284 where
285     Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
286 {
287     type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
288     #[inline]
add(self, rhs: NInt<Ur>) -> Self::Output289     fn add(self, rhs: NInt<Ur>) -> Self::Output {
290         let lhs = self.n;
291         let rhs = rhs.n;
292         let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
293         lhs.private_integer_add(lhs_cmp_rhs, rhs)
294     }
295 }
296 
297 /// `N(Ul) + P(Ur)`: We resolve this with our `PrivateAdd`
298 // We just do the same thing as above, swapping Lhs and Rhs
299 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul>
300 where
301     Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
302 {
303     type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
304     #[inline]
add(self, rhs: PInt<Ur>) -> Self::Output305     fn add(self, rhs: PInt<Ur>) -> Self::Output {
306         let lhs = self.n;
307         let rhs = rhs.n;
308         let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
309         rhs.private_integer_add(rhs_cmp_lhs, lhs)
310     }
311 }
312 
313 /// `P + N = 0` where `P == N`
314 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
315     type Output = Z0;
316 
317     #[inline]
private_integer_add(self, _: Equal, _: N) -> Self::Output318     fn private_integer_add(self, _: Equal, _: N) -> Self::Output {
319         Z0
320     }
321 }
322 
323 /// `P + N = Positive` where `P > N`
324 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P
325 where
326     P: Sub<N>,
327     <P as Sub<N>>::Output: Unsigned + NonZero,
328 {
329     type Output = PInt<<P as Sub<N>>::Output>;
330 
331     #[inline]
private_integer_add(self, _: Greater, n: N) -> Self::Output332     fn private_integer_add(self, _: Greater, n: N) -> Self::Output {
333         PInt { n: self - n }
334     }
335 }
336 
337 /// `P + N = Negative` where `P < N`
338 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P
339 where
340     N: Sub<P>,
341     <N as Sub<P>>::Output: Unsigned + NonZero,
342 {
343     type Output = NInt<<N as Sub<P>>::Output>;
344 
345     #[inline]
private_integer_add(self, _: Less, n: N) -> Self::Output346     fn private_integer_add(self, _: Less, n: N) -> Self::Output {
347         NInt { n: n - self }
348     }
349 }
350 
351 // ---------------------------------------------------------------------------------------
352 // Sub
353 
354 /// `Z0 - Z0 = Z0`
355 impl Sub<Z0> for Z0 {
356     type Output = Z0;
357     #[inline]
sub(self, _: Z0) -> Self::Output358     fn sub(self, _: Z0) -> Self::Output {
359         Z0
360     }
361 }
362 
363 /// `Z0 - P = N`
364 impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
365     type Output = NInt<U>;
366     #[inline]
sub(self, _: PInt<U>) -> Self::Output367     fn sub(self, _: PInt<U>) -> Self::Output {
368         NInt::new()
369     }
370 }
371 
372 /// `Z0 - N = P`
373 impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 {
374     type Output = PInt<U>;
375     #[inline]
sub(self, _: NInt<U>) -> Self::Output376     fn sub(self, _: NInt<U>) -> Self::Output {
377         PInt::new()
378     }
379 }
380 
381 /// `PInt - Z0 = PInt`
382 impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> {
383     type Output = PInt<U>;
384     #[inline]
sub(self, _: Z0) -> Self::Output385     fn sub(self, _: Z0) -> Self::Output {
386         PInt::new()
387     }
388 }
389 
390 /// `NInt - Z0 = NInt`
391 impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
392     type Output = NInt<U>;
393     #[inline]
sub(self, _: Z0) -> Self::Output394     fn sub(self, _: Z0) -> Self::Output {
395         NInt::new()
396     }
397 }
398 
399 /// `P(Ul) - N(Ur) = P(Ul + Ur)`
400 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul>
401 where
402     Ul: Add<Ur>,
403     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
404 {
405     type Output = PInt<<Ul as Add<Ur>>::Output>;
406     #[inline]
sub(self, _: NInt<Ur>) -> Self::Output407     fn sub(self, _: NInt<Ur>) -> Self::Output {
408         PInt::new()
409     }
410 }
411 
412 /// `N(Ul) - P(Ur) = N(Ul + Ur)`
413 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul>
414 where
415     Ul: Add<Ur>,
416     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
417 {
418     type Output = NInt<<Ul as Add<Ur>>::Output>;
419     #[inline]
sub(self, _: PInt<Ur>) -> Self::Output420     fn sub(self, _: PInt<Ur>) -> Self::Output {
421         NInt::new()
422     }
423 }
424 
425 /// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
426 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul>
427 where
428     Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
429 {
430     type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
431     #[inline]
sub(self, rhs: PInt<Ur>) -> Self::Output432     fn sub(self, rhs: PInt<Ur>) -> Self::Output {
433         let lhs = self.n;
434         let rhs = rhs.n;
435         let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
436         lhs.private_integer_add(lhs_cmp_rhs, rhs)
437     }
438 }
439 
440 /// `N(Ul) - N(Ur)`: We resolve this with our `PrivateAdd`
441 // We just do the same thing as above, swapping Lhs and Rhs
442 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul>
443 where
444     Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
445 {
446     type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
447     #[inline]
sub(self, rhs: NInt<Ur>) -> Self::Output448     fn sub(self, rhs: NInt<Ur>) -> Self::Output {
449         let lhs = self.n;
450         let rhs = rhs.n;
451         let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
452         rhs.private_integer_add(rhs_cmp_lhs, lhs)
453     }
454 }
455 
456 // ---------------------------------------------------------------------------------------
457 // Mul
458 
459 /// `Z0 * I = Z0`
460 impl<I: Integer> Mul<I> for Z0 {
461     type Output = Z0;
462     #[inline]
mul(self, _: I) -> Self::Output463     fn mul(self, _: I) -> Self::Output {
464         Z0
465     }
466 }
467 
468 /// `P * Z0 = Z0`
469 impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
470     type Output = Z0;
471     #[inline]
mul(self, _: Z0) -> Self::Output472     fn mul(self, _: Z0) -> Self::Output {
473         Z0
474     }
475 }
476 
477 /// `N * Z0 = Z0`
478 impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
479     type Output = Z0;
480     #[inline]
mul(self, _: Z0) -> Self::Output481     fn mul(self, _: Z0) -> Self::Output {
482         Z0
483     }
484 }
485 
486 /// P(Ul) * P(Ur) = P(Ul * Ur)
487 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul>
488 where
489     Ul: Mul<Ur>,
490     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
491 {
492     type Output = PInt<<Ul as Mul<Ur>>::Output>;
493     #[inline]
mul(self, _: PInt<Ur>) -> Self::Output494     fn mul(self, _: PInt<Ur>) -> Self::Output {
495         PInt::new()
496     }
497 }
498 
499 /// N(Ul) * N(Ur) = P(Ul * Ur)
500 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul>
501 where
502     Ul: Mul<Ur>,
503     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
504 {
505     type Output = PInt<<Ul as Mul<Ur>>::Output>;
506     #[inline]
mul(self, _: NInt<Ur>) -> Self::Output507     fn mul(self, _: NInt<Ur>) -> Self::Output {
508         PInt::new()
509     }
510 }
511 
512 /// P(Ul) * N(Ur) = N(Ul * Ur)
513 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul>
514 where
515     Ul: Mul<Ur>,
516     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
517 {
518     type Output = NInt<<Ul as Mul<Ur>>::Output>;
519     #[inline]
mul(self, _: NInt<Ur>) -> Self::Output520     fn mul(self, _: NInt<Ur>) -> Self::Output {
521         NInt::new()
522     }
523 }
524 
525 /// N(Ul) * P(Ur) = N(Ul * Ur)
526 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul>
527 where
528     Ul: Mul<Ur>,
529     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
530 {
531     type Output = NInt<<Ul as Mul<Ur>>::Output>;
532     #[inline]
mul(self, _: PInt<Ur>) -> Self::Output533     fn mul(self, _: PInt<Ur>) -> Self::Output {
534         NInt::new()
535     }
536 }
537 
538 // ---------------------------------------------------------------------------------------
539 // Div
540 
541 /// `Z0 / I = Z0` where `I != 0`
542 impl<I: Integer + NonZero> Div<I> for Z0 {
543     type Output = Z0;
544     #[inline]
div(self, _: I) -> Self::Output545     fn div(self, _: I) -> Self::Output {
546         Z0
547     }
548 }
549 
550 macro_rules! impl_int_div {
551     ($A:ident, $B:ident, $R:ident) => {
552         /// `$A<Ul> / $B<Ur> = $R<Ul / Ur>`
553         impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Div<$B<Ur>> for $A<Ul>
554         where
555             Ul: Cmp<Ur>,
556             $A<Ul>: PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>,
557         {
558             type Output = <$A<Ul> as PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>>::Output;
559             #[inline]
560             fn div(self, rhs: $B<Ur>) -> Self::Output {
561                 let lhs_cmp_rhs = self.n.compare::<Internal>(&rhs.n);
562                 self.private_div_int(lhs_cmp_rhs, rhs)
563             }
564         }
565         impl<Ul, Ur> PrivateDivInt<Less, $B<Ur>> for $A<Ul>
566         where
567             Ul: Unsigned + NonZero,
568             Ur: Unsigned + NonZero,
569         {
570             type Output = Z0;
571 
572             #[inline]
573             fn private_div_int(self, _: Less, _: $B<Ur>) -> Self::Output {
574                 Z0
575             }
576         }
577         impl<Ul, Ur> PrivateDivInt<Equal, $B<Ur>> for $A<Ul>
578         where
579             Ul: Unsigned + NonZero,
580             Ur: Unsigned + NonZero,
581         {
582             type Output = $R<U1>;
583 
584             #[inline]
585             fn private_div_int(self, _: Equal, _: $B<Ur>) -> Self::Output {
586                 $R { n: U1::new() }
587             }
588         }
589         impl<Ul, Ur> PrivateDivInt<Greater, $B<Ur>> for $A<Ul>
590         where
591             Ul: Unsigned + NonZero + Div<Ur>,
592             Ur: Unsigned + NonZero,
593             <Ul as Div<Ur>>::Output: Unsigned + NonZero,
594         {
595             type Output = $R<<Ul as Div<Ur>>::Output>;
596 
597             #[inline]
598             fn private_div_int(self, _: Greater, d: $B<Ur>) -> Self::Output {
599                 $R { n: self.n / d.n }
600             }
601         }
602     };
603 }
604 
605 impl_int_div!(PInt, PInt, PInt);
606 impl_int_div!(PInt, NInt, NInt);
607 impl_int_div!(NInt, PInt, NInt);
608 impl_int_div!(NInt, NInt, PInt);
609 
610 // ---------------------------------------------------------------------------------------
611 // PartialDiv
612 
613 use {PartialDiv, Quot};
614 
615 impl<M, N> PartialDiv<N> for M
616 where
617     M: Integer + Div<N> + Rem<N, Output = Z0>,
618 {
619     type Output = Quot<M, N>;
620     #[inline]
partial_div(self, rhs: N) -> Self::Output621     fn partial_div(self, rhs: N) -> Self::Output {
622         self / rhs
623     }
624 }
625 
626 // ---------------------------------------------------------------------------------------
627 // Cmp
628 
629 /// 0 == 0
630 impl Cmp<Z0> for Z0 {
631     type Output = Equal;
632 
633     #[inline]
compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output634     fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
635         Equal
636     }
637 }
638 
639 /// 0 > -X
640 impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
641     type Output = Greater;
642 
643     #[inline]
compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output644     fn compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output {
645         Greater
646     }
647 }
648 
649 /// 0 < X
650 impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
651     type Output = Less;
652 
653     #[inline]
compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output654     fn compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output {
655         Less
656     }
657 }
658 
659 /// X > 0
660 impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
661     type Output = Greater;
662 
663     #[inline]
compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output664     fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
665         Greater
666     }
667 }
668 
669 /// -X < 0
670 impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
671     type Output = Less;
672 
673     #[inline]
compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output674     fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
675         Less
676     }
677 }
678 
679 /// -X < Y
680 impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
681     type Output = Less;
682 
683     #[inline]
compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output684     fn compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output {
685         Less
686     }
687 }
688 
689 /// X > - Y
690 impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
691     type Output = Greater;
692 
693     #[inline]
compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output694     fn compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output {
695         Greater
696     }
697 }
698 
699 /// X <==> Y
700 impl<Pl: Cmp<Pr> + Unsigned + NonZero, Pr: Unsigned + NonZero> Cmp<PInt<Pr>> for PInt<Pl> {
701     type Output = <Pl as Cmp<Pr>>::Output;
702 
703     #[inline]
compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output704     fn compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output {
705         self.n.compare::<Internal>(&rhs.n)
706     }
707 }
708 
709 /// -X <==> -Y
710 impl<Nl: Unsigned + NonZero, Nr: Cmp<Nl> + Unsigned + NonZero> Cmp<NInt<Nr>> for NInt<Nl> {
711     type Output = <Nr as Cmp<Nl>>::Output;
712 
713     #[inline]
compare<IM: InternalMarker>(&self, rhs: &NInt<Nr>) -> Self::Output714     fn compare<IM: InternalMarker>(&self, rhs: &NInt<Nr>) -> Self::Output {
715         rhs.n.compare::<Internal>(&self.n)
716     }
717 }
718 
719 // ---------------------------------------------------------------------------------------
720 // Rem
721 
722 /// `Z0 % I = Z0` where `I != 0`
723 impl<I: Integer + NonZero> Rem<I> for Z0 {
724     type Output = Z0;
725     #[inline]
rem(self, _: I) -> Self::Output726     fn rem(self, _: I) -> Self::Output {
727         Z0
728     }
729 }
730 
731 macro_rules! impl_int_rem {
732     ($A:ident, $B:ident, $R:ident) => {
733         /// `$A<Ul> % $B<Ur> = $R<Ul % Ur>`
734         impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Rem<$B<Ur>> for $A<Ul>
735         where
736             Ul: Rem<Ur>,
737             $A<Ul>: PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>,
738         {
739             type Output = <$A<Ul> as PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>>::Output;
740             #[inline]
741             fn rem(self, rhs: $B<Ur>) -> Self::Output {
742                 self.private_rem(self.n % rhs.n, rhs)
743             }
744         }
745         impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> PrivateRem<U0, $B<Ur>> for $A<Ul> {
746             type Output = Z0;
747 
748             #[inline]
749             fn private_rem(self, _: U0, _: $B<Ur>) -> Self::Output {
750                 Z0
751             }
752         }
753         impl<Ul, Ur, U, B> PrivateRem<UInt<U, B>, $B<Ur>> for $A<Ul>
754         where
755             Ul: Unsigned + NonZero,
756             Ur: Unsigned + NonZero,
757             U: Unsigned,
758             B: Bit,
759         {
760             type Output = $R<UInt<U, B>>;
761 
762             #[inline]
763             fn private_rem(self, urem: UInt<U, B>, _: $B<Ur>) -> Self::Output {
764                 $R { n: urem }
765             }
766         }
767     };
768 }
769 
770 impl_int_rem!(PInt, PInt, PInt);
771 impl_int_rem!(PInt, NInt, PInt);
772 impl_int_rem!(NInt, PInt, NInt);
773 impl_int_rem!(NInt, NInt, NInt);
774 
775 // ---------------------------------------------------------------------------------------
776 // Pow
777 
778 /// 0^0 = 1
779 impl Pow<Z0> for Z0 {
780     type Output = P1;
781     #[inline]
powi(self, _: Z0) -> Self::Output782     fn powi(self, _: Z0) -> Self::Output {
783         P1::new()
784     }
785 }
786 
787 /// 0^P = 0
788 impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
789     type Output = Z0;
790     #[inline]
powi(self, _: PInt<U>) -> Self::Output791     fn powi(self, _: PInt<U>) -> Self::Output {
792         Z0
793     }
794 }
795 
796 /// 0^N = 0
797 impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
798     type Output = Z0;
799     #[inline]
powi(self, _: NInt<U>) -> Self::Output800     fn powi(self, _: NInt<U>) -> Self::Output {
801         Z0
802     }
803 }
804 
805 /// 1^N = 1
806 impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
807     type Output = P1;
808     #[inline]
powi(self, _: NInt<U>) -> Self::Output809     fn powi(self, _: NInt<U>) -> Self::Output {
810         P1::new()
811     }
812 }
813 
814 /// (-1)^N = 1 if N is even
815 impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 {
816     type Output = P1;
817     #[inline]
powi(self, _: NInt<UInt<U, B0>>) -> Self::Output818     fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output {
819         P1::new()
820     }
821 }
822 
823 /// (-1)^N = -1 if N is odd
824 impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 {
825     type Output = N1;
826     #[inline]
powi(self, _: NInt<UInt<U, B1>>) -> Self::Output827     fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output {
828         N1::new()
829     }
830 }
831 
832 /// P^0 = 1
833 impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> {
834     type Output = P1;
835     #[inline]
powi(self, _: Z0) -> Self::Output836     fn powi(self, _: Z0) -> Self::Output {
837         P1::new()
838     }
839 }
840 
841 /// N^0 = 1
842 impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
843     type Output = P1;
844     #[inline]
powi(self, _: Z0) -> Self::Output845     fn powi(self, _: Z0) -> Self::Output {
846         P1::new()
847     }
848 }
849 
850 /// P(Ul)^P(Ur) = P(Ul^Ur)
851 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul>
852 where
853     Ul: Pow<Ur>,
854     <Ul as Pow<Ur>>::Output: Unsigned + NonZero,
855 {
856     type Output = PInt<<Ul as Pow<Ur>>::Output>;
857     #[inline]
powi(self, _: PInt<Ur>) -> Self::Output858     fn powi(self, _: PInt<Ur>) -> Self::Output {
859         PInt::new()
860     }
861 }
862 
863 /// N(Ul)^P(Ur) = P(Ul^Ur) if Ur is even
864 impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul>
865 where
866     Ul: Pow<UInt<Ur, B0>>,
867     <Ul as Pow<UInt<Ur, B0>>>::Output: Unsigned + NonZero,
868 {
869     type Output = PInt<<Ul as Pow<UInt<Ur, B0>>>::Output>;
870     #[inline]
powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output871     fn powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output {
872         PInt::new()
873     }
874 }
875 
876 /// N(Ul)^P(Ur) = N(Ul^Ur) if Ur is odd
877 impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul>
878 where
879     Ul: Pow<UInt<Ur, B1>>,
880     <Ul as Pow<UInt<Ur, B1>>>::Output: Unsigned + NonZero,
881 {
882     type Output = NInt<<Ul as Pow<UInt<Ur, B1>>>::Output>;
883     #[inline]
powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output884     fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
885         NInt::new()
886     }
887 }
888 
889 // ---------------------------------------------------------------------------------------
890 // Gcd
891 use {Gcd, Gcf};
892 
893 impl Gcd<Z0> for Z0 {
894     type Output = Z0;
895 }
896 
897 impl<U> Gcd<PInt<U>> for Z0
898 where
899     U: Unsigned + NonZero,
900 {
901     type Output = PInt<U>;
902 }
903 
904 impl<U> Gcd<Z0> for PInt<U>
905 where
906     U: Unsigned + NonZero,
907 {
908     type Output = PInt<U>;
909 }
910 
911 impl<U> Gcd<NInt<U>> for Z0
912 where
913     U: Unsigned + NonZero,
914 {
915     type Output = PInt<U>;
916 }
917 
918 impl<U> Gcd<Z0> for NInt<U>
919 where
920     U: Unsigned + NonZero,
921 {
922     type Output = PInt<U>;
923 }
924 
925 impl<U1, U2> Gcd<PInt<U2>> for PInt<U1>
926 where
927     U1: Unsigned + NonZero + Gcd<U2>,
928     U2: Unsigned + NonZero,
929     Gcf<U1, U2>: Unsigned + NonZero,
930 {
931     type Output = PInt<Gcf<U1, U2>>;
932 }
933 
934 impl<U1, U2> Gcd<PInt<U2>> for NInt<U1>
935 where
936     U1: Unsigned + NonZero + Gcd<U2>,
937     U2: Unsigned + NonZero,
938     Gcf<U1, U2>: Unsigned + NonZero,
939 {
940     type Output = PInt<Gcf<U1, U2>>;
941 }
942 
943 impl<U1, U2> Gcd<NInt<U2>> for PInt<U1>
944 where
945     U1: Unsigned + NonZero + Gcd<U2>,
946     U2: Unsigned + NonZero,
947     Gcf<U1, U2>: Unsigned + NonZero,
948 {
949     type Output = PInt<Gcf<U1, U2>>;
950 }
951 
952 impl<U1, U2> Gcd<NInt<U2>> for NInt<U1>
953 where
954     U1: Unsigned + NonZero + Gcd<U2>,
955     U2: Unsigned + NonZero,
956     Gcf<U1, U2>: Unsigned + NonZero,
957 {
958     type Output = PInt<Gcf<U1, U2>>;
959 }
960 
961 // ---------------------------------------------------------------------------------------
962 // Min
963 use {Max, Maximum, Min, Minimum};
964 
965 impl Min<Z0> for Z0 {
966     type Output = Z0;
967     #[inline]
min(self, _: Z0) -> Self::Output968     fn min(self, _: Z0) -> Self::Output {
969         self
970     }
971 }
972 
973 impl<U> Min<PInt<U>> for Z0
974 where
975     U: Unsigned + NonZero,
976 {
977     type Output = Z0;
978     #[inline]
min(self, _: PInt<U>) -> Self::Output979     fn min(self, _: PInt<U>) -> Self::Output {
980         self
981     }
982 }
983 
984 impl<U> Min<NInt<U>> for Z0
985 where
986     U: Unsigned + NonZero,
987 {
988     type Output = NInt<U>;
989     #[inline]
min(self, rhs: NInt<U>) -> Self::Output990     fn min(self, rhs: NInt<U>) -> Self::Output {
991         rhs
992     }
993 }
994 
995 impl<U> Min<Z0> for PInt<U>
996 where
997     U: Unsigned + NonZero,
998 {
999     type Output = Z0;
1000     #[inline]
min(self, rhs: Z0) -> Self::Output1001     fn min(self, rhs: Z0) -> Self::Output {
1002         rhs
1003     }
1004 }
1005 
1006 impl<U> Min<Z0> for NInt<U>
1007 where
1008     U: Unsigned + NonZero,
1009 {
1010     type Output = NInt<U>;
1011     #[inline]
min(self, _: Z0) -> Self::Output1012     fn min(self, _: Z0) -> Self::Output {
1013         self
1014     }
1015 }
1016 
1017 impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul>
1018 where
1019     Ul: Unsigned + NonZero + Min<Ur>,
1020     Ur: Unsigned + NonZero,
1021     Minimum<Ul, Ur>: Unsigned + NonZero,
1022 {
1023     type Output = PInt<Minimum<Ul, Ur>>;
1024     #[inline]
min(self, rhs: PInt<Ur>) -> Self::Output1025     fn min(self, rhs: PInt<Ur>) -> Self::Output {
1026         PInt {
1027             n: self.n.min(rhs.n),
1028         }
1029     }
1030 }
1031 
1032 impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
1033 where
1034     Ul: Unsigned + NonZero,
1035     Ur: Unsigned + NonZero,
1036 {
1037     type Output = NInt<Ul>;
1038     #[inline]
min(self, _: PInt<Ur>) -> Self::Output1039     fn min(self, _: PInt<Ur>) -> Self::Output {
1040         self
1041     }
1042 }
1043 
1044 impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul>
1045 where
1046     Ul: Unsigned + NonZero,
1047     Ur: Unsigned + NonZero,
1048 {
1049     type Output = NInt<Ur>;
1050     #[inline]
min(self, rhs: NInt<Ur>) -> Self::Output1051     fn min(self, rhs: NInt<Ur>) -> Self::Output {
1052         rhs
1053     }
1054 }
1055 
1056 impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul>
1057 where
1058     Ul: Unsigned + NonZero + Max<Ur>,
1059     Ur: Unsigned + NonZero,
1060     Maximum<Ul, Ur>: Unsigned + NonZero,
1061 {
1062     type Output = NInt<Maximum<Ul, Ur>>;
1063     #[inline]
min(self, rhs: NInt<Ur>) -> Self::Output1064     fn min(self, rhs: NInt<Ur>) -> Self::Output {
1065         NInt {
1066             n: self.n.max(rhs.n),
1067         }
1068     }
1069 }
1070 
1071 // ---------------------------------------------------------------------------------------
1072 // Max
1073 
1074 impl Max<Z0> for Z0 {
1075     type Output = Z0;
1076     #[inline]
max(self, _: Z0) -> Self::Output1077     fn max(self, _: Z0) -> Self::Output {
1078         self
1079     }
1080 }
1081 
1082 impl<U> Max<PInt<U>> for Z0
1083 where
1084     U: Unsigned + NonZero,
1085 {
1086     type Output = PInt<U>;
1087     #[inline]
max(self, rhs: PInt<U>) -> Self::Output1088     fn max(self, rhs: PInt<U>) -> Self::Output {
1089         rhs
1090     }
1091 }
1092 
1093 impl<U> Max<NInt<U>> for Z0
1094 where
1095     U: Unsigned + NonZero,
1096 {
1097     type Output = Z0;
1098     #[inline]
max(self, _: NInt<U>) -> Self::Output1099     fn max(self, _: NInt<U>) -> Self::Output {
1100         self
1101     }
1102 }
1103 
1104 impl<U> Max<Z0> for PInt<U>
1105 where
1106     U: Unsigned + NonZero,
1107 {
1108     type Output = PInt<U>;
1109     #[inline]
max(self, _: Z0) -> Self::Output1110     fn max(self, _: Z0) -> Self::Output {
1111         self
1112     }
1113 }
1114 
1115 impl<U> Max<Z0> for NInt<U>
1116 where
1117     U: Unsigned + NonZero,
1118 {
1119     type Output = Z0;
1120     #[inline]
max(self, rhs: Z0) -> Self::Output1121     fn max(self, rhs: Z0) -> Self::Output {
1122         rhs
1123     }
1124 }
1125 
1126 impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul>
1127 where
1128     Ul: Unsigned + NonZero + Max<Ur>,
1129     Ur: Unsigned + NonZero,
1130     Maximum<Ul, Ur>: Unsigned + NonZero,
1131 {
1132     type Output = PInt<Maximum<Ul, Ur>>;
1133     #[inline]
max(self, rhs: PInt<Ur>) -> Self::Output1134     fn max(self, rhs: PInt<Ur>) -> Self::Output {
1135         PInt {
1136             n: self.n.max(rhs.n),
1137         }
1138     }
1139 }
1140 
1141 impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
1142 where
1143     Ul: Unsigned + NonZero,
1144     Ur: Unsigned + NonZero,
1145 {
1146     type Output = PInt<Ur>;
1147     #[inline]
max(self, rhs: PInt<Ur>) -> Self::Output1148     fn max(self, rhs: PInt<Ur>) -> Self::Output {
1149         rhs
1150     }
1151 }
1152 
1153 impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul>
1154 where
1155     Ul: Unsigned + NonZero,
1156     Ur: Unsigned + NonZero,
1157 {
1158     type Output = PInt<Ul>;
1159     #[inline]
max(self, _: NInt<Ur>) -> Self::Output1160     fn max(self, _: NInt<Ur>) -> Self::Output {
1161         self
1162     }
1163 }
1164 
1165 impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul>
1166 where
1167     Ul: Unsigned + NonZero + Min<Ur>,
1168     Ur: Unsigned + NonZero,
1169     Minimum<Ul, Ur>: Unsigned + NonZero,
1170 {
1171     type Output = NInt<Minimum<Ul, Ur>>;
1172     #[inline]
max(self, rhs: NInt<Ur>) -> Self::Output1173     fn max(self, rhs: NInt<Ur>) -> Self::Output {
1174         NInt {
1175             n: self.n.min(rhs.n),
1176         }
1177     }
1178 }
1179 
1180 #[cfg(test)]
1181 mod tests {
1182     use consts::*;
1183     use Integer;
1184 
1185     #[test]
to_ix_min()1186     fn to_ix_min() {
1187         assert_eq!(N128::to_i8(), ::core::i8::MIN);
1188         assert_eq!(N32768::to_i16(), ::core::i16::MIN);
1189     }
1190 }
1191