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::marker::PhantomData;
31 use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
32 
33 use bit::{Bit, B0, B1};
34 use consts::{N1, P1, U0, U1};
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     _marker: PhantomData<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     _marker: PhantomData<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 {
58             _marker: PhantomData,
59         }
60     }
61 }
62 
63 impl<U: Unsigned + NonZero> NInt<U> {
64     /// Instantiates a singleton representing this strictly negative integer.
65     #[inline]
new() -> NInt<U>66     pub fn new() -> NInt<U> {
67         NInt {
68             _marker: PhantomData,
69         }
70     }
71 }
72 
73 /// The type-level signed integer 0.
74 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
75 pub struct Z0;
76 
77 impl Z0 {
78     /// Instantiates a singleton representing the integer 0.
79     #[inline]
new() -> Z080     pub fn new() -> Z0 {
81         Z0
82     }
83 }
84 
85 impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
86 impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
87 
88 impl<U: Unsigned + NonZero + PowerOfTwo> PowerOfTwo for PInt<U> {}
89 
90 impl Integer for Z0 {
91     const I8: i8 = 0;
92     const I16: i16 = 0;
93     const I32: i32 = 0;
94     const I64: i64 = 0;
95     #[cfg(feature = "i128")]
96     const I128: i128 = 0;
97     const ISIZE: isize = 0;
98 
99     #[inline]
to_i8() -> i8100     fn to_i8() -> i8 {
101         0
102     }
103     #[inline]
to_i16() -> i16104     fn to_i16() -> i16 {
105         0
106     }
107     #[inline]
to_i32() -> i32108     fn to_i32() -> i32 {
109         0
110     }
111     #[inline]
to_i64() -> i64112     fn to_i64() -> i64 {
113         0
114     }
115     #[cfg(feature = "i128")]
116     #[inline]
to_i128() -> i128117     fn to_i128() -> i128 {
118         0
119     }
120     #[inline]
to_isize() -> isize121     fn to_isize() -> isize {
122         0
123     }
124 }
125 
126 impl<U: Unsigned + NonZero> Integer for PInt<U> {
127     const I8: i8 = U::I8;
128     const I16: i16 = U::I16;
129     const I32: i32 = U::I32;
130     const I64: i64 = U::I64;
131     #[cfg(feature = "i128")]
132     const I128: i128 = U::I128;
133     const ISIZE: isize = U::ISIZE;
134 
135     #[inline]
to_i8() -> i8136     fn to_i8() -> i8 {
137         <U as Unsigned>::to_i8()
138     }
139     #[inline]
to_i16() -> i16140     fn to_i16() -> i16 {
141         <U as Unsigned>::to_i16()
142     }
143     #[inline]
to_i32() -> i32144     fn to_i32() -> i32 {
145         <U as Unsigned>::to_i32()
146     }
147     #[inline]
to_i64() -> i64148     fn to_i64() -> i64 {
149         <U as Unsigned>::to_i64()
150     }
151     #[cfg(feature = "i128")]
152     #[inline]
to_i128() -> i128153     fn to_i128() -> i128 {
154         <U as Unsigned>::to_i128()
155     }
156     #[inline]
to_isize() -> isize157     fn to_isize() -> isize {
158         <U as Unsigned>::to_isize()
159     }
160 }
161 
162 // Simply negating the result of e.g. `U::I8` will result in overflow for `std::i8::MIN`. Instead,
163 // we use the fact that `U: NonZero` by subtracting one from the `U::U8` before negating.
164 impl<U: Unsigned + NonZero> Integer for NInt<U> {
165     const I8: i8 = -((U::U8 - 1) as i8) - 1;
166     const I16: i16 = -((U::U16 - 1) as i16) - 1;
167     const I32: i32 = -((U::U32 - 1) as i32) - 1;
168     const I64: i64 = -((U::U64 - 1) as i64) - 1;
169     #[cfg(feature = "i128")]
170     const I128: i128 = -((U::U128 - 1) as i128) - 1;
171     const ISIZE: isize = -((U::USIZE - 1) as isize) - 1;
172 
173     #[inline]
to_i8() -> i8174     fn to_i8() -> i8 {
175         Self::I8
176     }
177     #[inline]
to_i16() -> i16178     fn to_i16() -> i16 {
179         Self::I16
180     }
181     #[inline]
to_i32() -> i32182     fn to_i32() -> i32 {
183         Self::I32
184     }
185     #[inline]
to_i64() -> i64186     fn to_i64() -> i64 {
187         Self::I64
188     }
189     #[cfg(feature = "i128")]
190     #[inline]
to_i128() -> i128191     fn to_i128() -> i128 {
192         Self::I128
193     }
194     #[inline]
to_isize() -> isize195     fn to_isize() -> isize {
196         Self::ISIZE
197     }
198 }
199 
200 // ---------------------------------------------------------------------------------------
201 // Neg
202 
203 /// `-Z0 = Z0`
204 impl Neg for Z0 {
205     type Output = Z0;
neg(self) -> Self::Output206     fn neg(self) -> Self::Output {
207         Z0
208     }
209 }
210 
211 /// `-PInt = NInt`
212 impl<U: Unsigned + NonZero> Neg for PInt<U> {
213     type Output = NInt<U>;
neg(self) -> Self::Output214     fn neg(self) -> Self::Output {
215         NInt::new()
216     }
217 }
218 
219 /// `-NInt = PInt`
220 impl<U: Unsigned + NonZero> Neg for NInt<U> {
221     type Output = PInt<U>;
neg(self) -> Self::Output222     fn neg(self) -> Self::Output {
223         PInt::new()
224     }
225 }
226 
227 // ---------------------------------------------------------------------------------------
228 // Add
229 
230 /// `Z0 + I = I`
231 impl<I: Integer> Add<I> for Z0 {
232     type Output = I;
add(self, _: I) -> Self::Output233     fn add(self, _: I) -> Self::Output {
234         unsafe { ::core::mem::uninitialized() }
235     }
236 }
237 
238 /// `PInt + Z0 = PInt`
239 impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
240     type Output = PInt<U>;
add(self, _: Z0) -> Self::Output241     fn add(self, _: Z0) -> Self::Output {
242         PInt::new()
243     }
244 }
245 
246 /// `NInt + Z0 = NInt`
247 impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
248     type Output = NInt<U>;
add(self, _: Z0) -> Self::Output249     fn add(self, _: Z0) -> Self::Output {
250         NInt::new()
251     }
252 }
253 
254 /// `P(Ul) + P(Ur) = P(Ul + Ur)`
255 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul>
256 where
257     Ul: Add<Ur>,
258     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
259 {
260     type Output = PInt<<Ul as Add<Ur>>::Output>;
add(self, _: PInt<Ur>) -> Self::Output261     fn add(self, _: PInt<Ur>) -> Self::Output {
262         PInt::new()
263     }
264 }
265 
266 /// `N(Ul) + N(Ur) = N(Ul + Ur)`
267 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul>
268 where
269     Ul: Add<Ur>,
270     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
271 {
272     type Output = NInt<<Ul as Add<Ur>>::Output>;
add(self, _: NInt<Ur>) -> Self::Output273     fn add(self, _: NInt<Ur>) -> Self::Output {
274         NInt::new()
275     }
276 }
277 
278 /// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
279 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul>
280 where
281     Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
282 {
283     type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
add(self, _: NInt<Ur>) -> Self::Output284     fn add(self, _: NInt<Ur>) -> Self::Output {
285         unsafe { ::core::mem::uninitialized() }
286     }
287 }
288 
289 /// `N(Ul) + P(Ur)`: We resolve this with our `PrivateAdd`
290 // We just do the same thing as above, swapping Lhs and Rhs
291 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul>
292 where
293     Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
294 {
295     type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
add(self, _: PInt<Ur>) -> Self::Output296     fn add(self, _: PInt<Ur>) -> Self::Output {
297         unsafe { ::core::mem::uninitialized() }
298     }
299 }
300 
301 /// `P + N = 0` where `P == N`
302 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
303     type Output = Z0;
304 }
305 
306 /// `P + N = Positive` where `P > N`
307 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P
308 where
309     P: Sub<N>,
310     <P as Sub<N>>::Output: Unsigned + NonZero,
311 {
312     type Output = PInt<<P as Sub<N>>::Output>;
313 }
314 
315 /// `P + N = Negative` where `P < N`
316 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P
317 where
318     N: Sub<P>,
319     <N as Sub<P>>::Output: Unsigned + NonZero,
320 {
321     type Output = NInt<<N as Sub<P>>::Output>;
322 }
323 
324 // ---------------------------------------------------------------------------------------
325 // Sub
326 
327 /// `Z0 - Z0 = Z0`
328 impl Sub<Z0> for Z0 {
329     type Output = Z0;
sub(self, _: Z0) -> Self::Output330     fn sub(self, _: Z0) -> Self::Output {
331         Z0
332     }
333 }
334 
335 /// `Z0 - P = N`
336 impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
337     type Output = NInt<U>;
sub(self, _: PInt<U>) -> Self::Output338     fn sub(self, _: PInt<U>) -> Self::Output {
339         NInt::new()
340     }
341 }
342 
343 /// `Z0 - N = P`
344 impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 {
345     type Output = PInt<U>;
sub(self, _: NInt<U>) -> Self::Output346     fn sub(self, _: NInt<U>) -> Self::Output {
347         PInt::new()
348     }
349 }
350 
351 /// `PInt - Z0 = PInt`
352 impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> {
353     type Output = PInt<U>;
sub(self, _: Z0) -> Self::Output354     fn sub(self, _: Z0) -> Self::Output {
355         PInt::new()
356     }
357 }
358 
359 /// `NInt - Z0 = NInt`
360 impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
361     type Output = NInt<U>;
sub(self, _: Z0) -> Self::Output362     fn sub(self, _: Z0) -> Self::Output {
363         NInt::new()
364     }
365 }
366 
367 /// `P(Ul) - N(Ur) = P(Ul + Ur)`
368 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul>
369 where
370     Ul: Add<Ur>,
371     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
372 {
373     type Output = PInt<<Ul as Add<Ur>>::Output>;
sub(self, _: NInt<Ur>) -> Self::Output374     fn sub(self, _: NInt<Ur>) -> Self::Output {
375         PInt::new()
376     }
377 }
378 
379 /// `N(Ul) - P(Ur) = N(Ul + Ur)`
380 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul>
381 where
382     Ul: Add<Ur>,
383     <Ul as Add<Ur>>::Output: Unsigned + NonZero,
384 {
385     type Output = NInt<<Ul as Add<Ur>>::Output>;
sub(self, _: PInt<Ur>) -> Self::Output386     fn sub(self, _: PInt<Ur>) -> Self::Output {
387         NInt::new()
388     }
389 }
390 
391 /// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
392 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul>
393 where
394     Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
395 {
396     type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
sub(self, _: PInt<Ur>) -> Self::Output397     fn sub(self, _: PInt<Ur>) -> Self::Output {
398         unsafe { ::core::mem::uninitialized() }
399     }
400 }
401 
402 /// `N(Ul) - N(Ur)`: We resolve this with our `PrivateAdd`
403 // We just do the same thing as above, swapping Lhs and Rhs
404 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul>
405 where
406     Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
407 {
408     type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
sub(self, _: NInt<Ur>) -> Self::Output409     fn sub(self, _: NInt<Ur>) -> Self::Output {
410         unsafe { ::core::mem::uninitialized() }
411     }
412 }
413 
414 // ---------------------------------------------------------------------------------------
415 // Mul
416 
417 /// `Z0 * I = Z0`
418 impl<I: Integer> Mul<I> for Z0 {
419     type Output = Z0;
mul(self, _: I) -> Self::Output420     fn mul(self, _: I) -> Self::Output {
421         Z0
422     }
423 }
424 
425 /// `P * Z0 = Z0`
426 impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
427     type Output = Z0;
mul(self, _: Z0) -> Self::Output428     fn mul(self, _: Z0) -> Self::Output {
429         Z0
430     }
431 }
432 
433 /// `N * Z0 = Z0`
434 impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
435     type Output = Z0;
mul(self, _: Z0) -> Self::Output436     fn mul(self, _: Z0) -> Self::Output {
437         Z0
438     }
439 }
440 
441 /// P(Ul) * P(Ur) = P(Ul * Ur)
442 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul>
443 where
444     Ul: Mul<Ur>,
445     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
446 {
447     type Output = PInt<<Ul as Mul<Ur>>::Output>;
mul(self, _: PInt<Ur>) -> Self::Output448     fn mul(self, _: PInt<Ur>) -> Self::Output {
449         PInt::new()
450     }
451 }
452 
453 /// N(Ul) * N(Ur) = P(Ul * Ur)
454 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul>
455 where
456     Ul: Mul<Ur>,
457     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
458 {
459     type Output = PInt<<Ul as Mul<Ur>>::Output>;
mul(self, _: NInt<Ur>) -> Self::Output460     fn mul(self, _: NInt<Ur>) -> Self::Output {
461         PInt::new()
462     }
463 }
464 
465 /// P(Ul) * N(Ur) = N(Ul * Ur)
466 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul>
467 where
468     Ul: Mul<Ur>,
469     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
470 {
471     type Output = NInt<<Ul as Mul<Ur>>::Output>;
mul(self, _: NInt<Ur>) -> Self::Output472     fn mul(self, _: NInt<Ur>) -> Self::Output {
473         NInt::new()
474     }
475 }
476 
477 /// N(Ul) * P(Ur) = N(Ul * Ur)
478 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul>
479 where
480     Ul: Mul<Ur>,
481     <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
482 {
483     type Output = NInt<<Ul as Mul<Ur>>::Output>;
mul(self, _: PInt<Ur>) -> Self::Output484     fn mul(self, _: PInt<Ur>) -> Self::Output {
485         NInt::new()
486     }
487 }
488 
489 // ---------------------------------------------------------------------------------------
490 // Div
491 
492 /// `Z0 / I = Z0` where `I != 0`
493 impl<I: Integer + NonZero> Div<I> for Z0 {
494     type Output = Z0;
div(self, _: I) -> Self::Output495     fn div(self, _: I) -> Self::Output {
496         Z0
497     }
498 }
499 
500 macro_rules! impl_int_div {
501     ($A:ident, $B:ident, $R:ident) => {
502         /// `$A<Ul> / $B<Ur> = $R<Ul / Ur>`
503         impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Div<$B<Ur>> for $A<Ul>
504         where
505             Ul: Cmp<Ur>,
506             $A<Ul>: PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>,
507         {
508             type Output = <$A<Ul> as PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>>::Output;
509             fn div(self, _: $B<Ur>) -> Self::Output {
510                 unsafe { ::core::mem::uninitialized() }
511             }
512         }
513         impl<Ul, Ur> PrivateDivInt<Less, $B<Ur>> for $A<Ul>
514         where
515             Ul: Unsigned + NonZero,
516             Ur: Unsigned + NonZero,
517         {
518             type Output = Z0;
519         }
520         impl<Ul, Ur> PrivateDivInt<Equal, $B<Ur>> for $A<Ul>
521         where
522             Ul: Unsigned + NonZero,
523             Ur: Unsigned + NonZero,
524         {
525             type Output = $R<U1>;
526         }
527         impl<Ul, Ur> PrivateDivInt<Greater, $B<Ur>> for $A<Ul>
528         where
529             Ul: Unsigned + NonZero + Div<Ur>,
530             Ur: Unsigned + NonZero,
531             <Ul as Div<Ur>>::Output: Unsigned + NonZero,
532         {
533             type Output = $R<<Ul as Div<Ur>>::Output>;
534         }
535     };
536 }
537 
538 impl_int_div!(PInt, PInt, PInt);
539 impl_int_div!(PInt, NInt, NInt);
540 impl_int_div!(NInt, PInt, NInt);
541 impl_int_div!(NInt, NInt, PInt);
542 
543 // ---------------------------------------------------------------------------------------
544 // PartialDiv
545 
546 use {PartialDiv, Quot};
547 
548 impl<M, N> PartialDiv<N> for M
549 where
550     M: Integer + Div<N> + Rem<N, Output = Z0>,
551 {
552     type Output = Quot<M, N>;
partial_div(self, _: N) -> Self::Output553     fn partial_div(self, _: N) -> Self::Output {
554         unsafe { ::core::mem::uninitialized() }
555     }
556 }
557 
558 // ---------------------------------------------------------------------------------------
559 // Cmp
560 
561 /// 0 == 0
562 impl Cmp<Z0> for Z0 {
563     type Output = Equal;
564 }
565 
566 /// 0 > -X
567 impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
568     type Output = Greater;
569 }
570 
571 /// 0 < X
572 impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
573     type Output = Less;
574 }
575 
576 /// X > 0
577 impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
578     type Output = Greater;
579 }
580 
581 /// -X < 0
582 impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
583     type Output = Less;
584 }
585 
586 /// -X < Y
587 impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
588     type Output = Less;
589 }
590 
591 /// X > - Y
592 impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
593     type Output = Greater;
594 }
595 
596 /// X <==> Y
597 impl<Pl: Cmp<Pr> + Unsigned + NonZero, Pr: Unsigned + NonZero> Cmp<PInt<Pr>> for PInt<Pl> {
598     type Output = <Pl as Cmp<Pr>>::Output;
599 }
600 
601 /// -X <==> -Y
602 impl<Nl: Unsigned + NonZero, Nr: Cmp<Nl> + Unsigned + NonZero> Cmp<NInt<Nr>> for NInt<Nl> {
603     type Output = <Nr as Cmp<Nl>>::Output;
604 }
605 
606 // ---------------------------------------------------------------------------------------
607 // Rem
608 
609 /// `Z0 % I = Z0` where `I != 0`
610 impl<I: Integer + NonZero> Rem<I> for Z0 {
611     type Output = Z0;
rem(self, _: I) -> Self::Output612     fn rem(self, _: I) -> Self::Output {
613         Z0
614     }
615 }
616 
617 macro_rules! impl_int_rem {
618     ($A:ident, $B:ident, $R:ident) => {
619         /// `$A<Ul> % $B<Ur> = $R<Ul % Ur>`
620         impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Rem<$B<Ur>> for $A<Ul>
621         where
622             Ul: Rem<Ur>,
623             $A<Ul>: PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>,
624         {
625             type Output = <$A<Ul> as PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>>::Output;
626             fn rem(self, _: $B<Ur>) -> Self::Output {
627                 unsafe { ::core::mem::uninitialized() }
628             }
629         }
630         impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> PrivateRem<U0, $B<Ur>> for $A<Ul> {
631             type Output = Z0;
632         }
633         impl<Ul, Ur, U, B> PrivateRem<UInt<U, B>, $B<Ur>> for $A<Ul>
634         where
635             Ul: Unsigned + NonZero,
636             Ur: Unsigned + NonZero,
637             U: Unsigned,
638             B: Bit,
639         {
640             type Output = $R<UInt<U, B>>;
641         }
642     };
643 }
644 
645 impl_int_rem!(PInt, PInt, PInt);
646 impl_int_rem!(PInt, NInt, PInt);
647 impl_int_rem!(NInt, PInt, NInt);
648 impl_int_rem!(NInt, NInt, NInt);
649 
650 // ---------------------------------------------------------------------------------------
651 // Pow
652 
653 /// 0^0 = 1
654 impl Pow<Z0> for Z0 {
655     type Output = P1;
powi(self, _: Z0) -> Self::Output656     fn powi(self, _: Z0) -> Self::Output {
657         P1::new()
658     }
659 }
660 
661 /// 0^P = 0
662 impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
663     type Output = Z0;
powi(self, _: PInt<U>) -> Self::Output664     fn powi(self, _: PInt<U>) -> Self::Output {
665         Z0
666     }
667 }
668 
669 /// 0^N = 0
670 impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
671     type Output = Z0;
powi(self, _: NInt<U>) -> Self::Output672     fn powi(self, _: NInt<U>) -> Self::Output {
673         Z0
674     }
675 }
676 
677 /// 1^N = 1
678 impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
679     type Output = P1;
powi(self, _: NInt<U>) -> Self::Output680     fn powi(self, _: NInt<U>) -> Self::Output {
681         P1::new()
682     }
683 }
684 
685 /// (-1)^N = 1 if N is even
686 impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 {
687     type Output = P1;
powi(self, _: NInt<UInt<U, B0>>) -> Self::Output688     fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output {
689         P1::new()
690     }
691 }
692 
693 /// (-1)^N = -1 if N is odd
694 impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 {
695     type Output = N1;
powi(self, _: NInt<UInt<U, B1>>) -> Self::Output696     fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output {
697         N1::new()
698     }
699 }
700 
701 /// P^0 = 1
702 impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> {
703     type Output = P1;
powi(self, _: Z0) -> Self::Output704     fn powi(self, _: Z0) -> Self::Output {
705         P1::new()
706     }
707 }
708 
709 /// N^0 = 1
710 impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
711     type Output = P1;
powi(self, _: Z0) -> Self::Output712     fn powi(self, _: Z0) -> Self::Output {
713         P1::new()
714     }
715 }
716 
717 /// P(Ul)^P(Ur) = P(Ul^Ur)
718 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul>
719 where
720     Ul: Pow<Ur>,
721     <Ul as Pow<Ur>>::Output: Unsigned + NonZero,
722 {
723     type Output = PInt<<Ul as Pow<Ur>>::Output>;
powi(self, _: PInt<Ur>) -> Self::Output724     fn powi(self, _: PInt<Ur>) -> Self::Output {
725         PInt::new()
726     }
727 }
728 
729 /// N(Ul)^P(Ur) = P(Ul^Ur) if Ur is even
730 impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul>
731 where
732     Ul: Pow<UInt<Ur, B0>>,
733     <Ul as Pow<UInt<Ur, B0>>>::Output: Unsigned + NonZero,
734 {
735     type Output = PInt<<Ul as Pow<UInt<Ur, B0>>>::Output>;
powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output736     fn powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output {
737         PInt::new()
738     }
739 }
740 
741 /// N(Ul)^P(Ur) = N(Ul^Ur) if Ur is odd
742 impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul>
743 where
744     Ul: Pow<UInt<Ur, B1>>,
745     <Ul as Pow<UInt<Ur, B1>>>::Output: Unsigned + NonZero,
746 {
747     type Output = NInt<<Ul as Pow<UInt<Ur, B1>>>::Output>;
powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output748     fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
749         NInt::new()
750     }
751 }
752 
753 // ---------------------------------------------------------------------------------------
754 // Min
755 use {Max, Maximum, Min, Minimum};
756 
757 impl Min<Z0> for Z0 {
758     type Output = Z0;
min(self, _: Z0) -> Self::Output759     fn min(self, _: Z0) -> Self::Output {
760         self
761     }
762 }
763 
764 impl<U> Min<PInt<U>> for Z0
765 where
766     U: Unsigned + NonZero,
767 {
768     type Output = Z0;
min(self, _: PInt<U>) -> Self::Output769     fn min(self, _: PInt<U>) -> Self::Output {
770         self
771     }
772 }
773 
774 impl<U> Min<NInt<U>> for Z0
775 where
776     U: Unsigned + NonZero,
777 {
778     type Output = NInt<U>;
min(self, rhs: NInt<U>) -> Self::Output779     fn min(self, rhs: NInt<U>) -> Self::Output {
780         rhs
781     }
782 }
783 
784 impl<U> Min<Z0> for PInt<U>
785 where
786     U: Unsigned + NonZero,
787 {
788     type Output = Z0;
min(self, rhs: Z0) -> Self::Output789     fn min(self, rhs: Z0) -> Self::Output {
790         rhs
791     }
792 }
793 
794 impl<U> Min<Z0> for NInt<U>
795 where
796     U: Unsigned + NonZero,
797 {
798     type Output = NInt<U>;
min(self, _: Z0) -> Self::Output799     fn min(self, _: Z0) -> Self::Output {
800         self
801     }
802 }
803 
804 impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul>
805 where
806     Ul: Unsigned + NonZero + Min<Ur>,
807     Ur: Unsigned + NonZero,
808     Minimum<Ul, Ur>: Unsigned + NonZero,
809 {
810     type Output = PInt<Minimum<Ul, Ur>>;
min(self, _: PInt<Ur>) -> Self::Output811     fn min(self, _: PInt<Ur>) -> Self::Output {
812         unsafe { ::core::mem::uninitialized() }
813     }
814 }
815 
816 impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
817 where
818     Ul: Unsigned + NonZero,
819     Ur: Unsigned + NonZero,
820 {
821     type Output = NInt<Ul>;
min(self, _: PInt<Ur>) -> Self::Output822     fn min(self, _: PInt<Ur>) -> Self::Output {
823         self
824     }
825 }
826 
827 impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul>
828 where
829     Ul: Unsigned + NonZero,
830     Ur: Unsigned + NonZero,
831 {
832     type Output = NInt<Ur>;
min(self, rhs: NInt<Ur>) -> Self::Output833     fn min(self, rhs: NInt<Ur>) -> Self::Output {
834         rhs
835     }
836 }
837 
838 impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul>
839 where
840     Ul: Unsigned + NonZero + Max<Ur>,
841     Ur: Unsigned + NonZero,
842     Maximum<Ul, Ur>: Unsigned + NonZero,
843 {
844     type Output = NInt<Maximum<Ul, Ur>>;
min(self, _: NInt<Ur>) -> Self::Output845     fn min(self, _: NInt<Ur>) -> Self::Output {
846         unsafe { ::core::mem::uninitialized() }
847     }
848 }
849 
850 // ---------------------------------------------------------------------------------------
851 // Max
852 
853 impl Max<Z0> for Z0 {
854     type Output = Z0;
max(self, _: Z0) -> Self::Output855     fn max(self, _: Z0) -> Self::Output {
856         self
857     }
858 }
859 
860 impl<U> Max<PInt<U>> for Z0
861 where
862     U: Unsigned + NonZero,
863 {
864     type Output = PInt<U>;
max(self, rhs: PInt<U>) -> Self::Output865     fn max(self, rhs: PInt<U>) -> Self::Output {
866         rhs
867     }
868 }
869 
870 impl<U> Max<NInt<U>> for Z0
871 where
872     U: Unsigned + NonZero,
873 {
874     type Output = Z0;
max(self, _: NInt<U>) -> Self::Output875     fn max(self, _: NInt<U>) -> Self::Output {
876         self
877     }
878 }
879 
880 impl<U> Max<Z0> for PInt<U>
881 where
882     U: Unsigned + NonZero,
883 {
884     type Output = PInt<U>;
max(self, _: Z0) -> Self::Output885     fn max(self, _: Z0) -> Self::Output {
886         self
887     }
888 }
889 
890 impl<U> Max<Z0> for NInt<U>
891 where
892     U: Unsigned + NonZero,
893 {
894     type Output = Z0;
max(self, rhs: Z0) -> Self::Output895     fn max(self, rhs: Z0) -> Self::Output {
896         rhs
897     }
898 }
899 
900 impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul>
901 where
902     Ul: Unsigned + NonZero + Max<Ur>,
903     Ur: Unsigned + NonZero,
904     Maximum<Ul, Ur>: Unsigned + NonZero,
905 {
906     type Output = PInt<Maximum<Ul, Ur>>;
max(self, _: PInt<Ur>) -> Self::Output907     fn max(self, _: PInt<Ur>) -> Self::Output {
908         unsafe { ::core::mem::uninitialized() }
909     }
910 }
911 
912 impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
913 where
914     Ul: Unsigned + NonZero,
915     Ur: Unsigned + NonZero,
916 {
917     type Output = PInt<Ur>;
max(self, rhs: PInt<Ur>) -> Self::Output918     fn max(self, rhs: PInt<Ur>) -> Self::Output {
919         rhs
920     }
921 }
922 
923 impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul>
924 where
925     Ul: Unsigned + NonZero,
926     Ur: Unsigned + NonZero,
927 {
928     type Output = PInt<Ul>;
max(self, _: NInt<Ur>) -> Self::Output929     fn max(self, _: NInt<Ur>) -> Self::Output {
930         self
931     }
932 }
933 
934 impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul>
935 where
936     Ul: Unsigned + NonZero + Min<Ur>,
937     Ur: Unsigned + NonZero,
938     Minimum<Ul, Ur>: Unsigned + NonZero,
939 {
940     type Output = NInt<Minimum<Ul, Ur>>;
max(self, _: NInt<Ur>) -> Self::Output941     fn max(self, _: NInt<Ur>) -> Self::Output {
942         unsafe { ::core::mem::uninitialized() }
943     }
944 }
945 
946 #[cfg(test)]
947 mod tests {
948     use consts::*;
949     use Integer;
950 
951     #[test]
to_ix_min()952     fn to_ix_min() {
953         assert_eq!(N128::to_i8(), ::core::i8::MIN);
954         assert_eq!(N32768::to_i16(), ::core::i16::MIN);
955     }
956 }
957