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