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