1 //! Type-level signed integers. 2 //! 3 //! 4 //! Type **operators** implemented: 5 //! 6 //! From `core::ops`: `Add`, `Sub`, `Mul`, `Div`, and `Rem`. 7 //! From `typenum`: `Same`, `Cmp`, and `Pow`. 8 //! 9 //! Rather than directly using the structs defined in this module, it is recommended that 10 //! you import and use the relevant aliases from the [consts](../consts/index.html) module. 11 //! 12 //! Note that operators that work on the underlying structure of the number are 13 //! intentionally not implemented. This is because this implementation of signed integers 14 //! does *not* use twos-complement, and implementing them would require making arbitrary 15 //! choices, causing the results of such operators to be difficult to reason about. 16 //! 17 //! # Example 18 //! ```rust 19 //! use std::ops::{Add, Div, Mul, Rem, Sub}; 20 //! use typenum::{Integer, N3, P2}; 21 //! 22 //! assert_eq!(<N3 as Add<P2>>::Output::to_i32(), -1); 23 //! assert_eq!(<N3 as Sub<P2>>::Output::to_i32(), -5); 24 //! assert_eq!(<N3 as Mul<P2>>::Output::to_i32(), -6); 25 //! assert_eq!(<N3 as Div<P2>>::Output::to_i32(), -1); 26 //! assert_eq!(<N3 as Rem<P2>>::Output::to_i32(), -1); 27 //! ``` 28 29 pub use crate::marker_traits::Integer; 30 use crate::{ 31 bit::{Bit, B0, B1}, 32 consts::{N1, P1, U0, U1}, 33 private::{Internal, InternalMarker, PrivateDivInt, PrivateIntegerAdd, PrivateRem}, 34 uint::{UInt, Unsigned}, 35 Cmp, Equal, Greater, Less, NonZero, Pow, PowerOfTwo, ToInt, Zero, 36 }; 37 use core::ops::{Add, Div, Mul, Neg, Rem, Sub}; 38 39 /// Type-level signed integers with positive sign. 40 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] 41 #[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))] 42 pub struct PInt<U: Unsigned + NonZero> { 43 pub(crate) n: U, 44 } 45 46 /// Type-level signed integers with negative sign. 47 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] 48 #[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))] 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 #[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))] 72 pub struct Z0; 73 74 impl Z0 { 75 /// Instantiates a singleton representing the integer 0. 76 #[inline] new() -> Z077 pub fn new() -> Z0 { 78 Z0 79 } 80 } 81 82 impl<U: Unsigned + NonZero> NonZero for PInt<U> {} 83 impl<U: Unsigned + NonZero> NonZero for NInt<U> {} 84 impl Zero for Z0 {} 85 86 impl<U: Unsigned + NonZero + PowerOfTwo> PowerOfTwo for PInt<U> {} 87 88 impl Integer for Z0 { 89 const I8: i8 = 0; 90 const I16: i16 = 0; 91 const I32: i32 = 0; 92 const I64: i64 = 0; 93 #[cfg(feature = "i128")] 94 const I128: i128 = 0; 95 const ISIZE: isize = 0; 96 97 #[inline] to_i8() -> i898 fn to_i8() -> i8 { 99 0 100 } 101 #[inline] to_i16() -> i16102 fn to_i16() -> i16 { 103 0 104 } 105 #[inline] to_i32() -> i32106 fn to_i32() -> i32 { 107 0 108 } 109 #[inline] to_i64() -> i64110 fn to_i64() -> i64 { 111 0 112 } 113 #[cfg(feature = "i128")] 114 #[inline] to_i128() -> i128115 fn to_i128() -> i128 { 116 0 117 } 118 #[inline] to_isize() -> isize119 fn to_isize() -> isize { 120 0 121 } 122 } 123 124 impl<U: Unsigned + NonZero> Integer for PInt<U> { 125 const I8: i8 = U::I8; 126 const I16: i16 = U::I16; 127 const I32: i32 = U::I32; 128 const I64: i64 = U::I64; 129 #[cfg(feature = "i128")] 130 const I128: i128 = U::I128; 131 const ISIZE: isize = U::ISIZE; 132 133 #[inline] to_i8() -> i8134 fn to_i8() -> i8 { 135 <U as Unsigned>::to_i8() 136 } 137 #[inline] to_i16() -> i16138 fn to_i16() -> i16 { 139 <U as Unsigned>::to_i16() 140 } 141 #[inline] to_i32() -> i32142 fn to_i32() -> i32 { 143 <U as Unsigned>::to_i32() 144 } 145 #[inline] to_i64() -> i64146 fn to_i64() -> i64 { 147 <U as Unsigned>::to_i64() 148 } 149 #[cfg(feature = "i128")] 150 #[inline] to_i128() -> i128151 fn to_i128() -> i128 { 152 <U as Unsigned>::to_i128() 153 } 154 #[inline] to_isize() -> isize155 fn to_isize() -> isize { 156 <U as Unsigned>::to_isize() 157 } 158 } 159 160 // Simply negating the result of e.g. `U::I8` will result in overflow for `std::i8::MIN`. Instead, 161 // we use the fact that `U: NonZero` by subtracting one from the `U::U8` before negating. 162 impl<U: Unsigned + NonZero> Integer for NInt<U> { 163 const I8: i8 = -((U::U8 - 1) as i8) - 1; 164 const I16: i16 = -((U::U16 - 1) as i16) - 1; 165 const I32: i32 = -((U::U32 - 1) as i32) - 1; 166 const I64: i64 = -((U::U64 - 1) as i64) - 1; 167 #[cfg(feature = "i128")] 168 const I128: i128 = -((U::U128 - 1) as i128) - 1; 169 const ISIZE: isize = -((U::USIZE - 1) as isize) - 1; 170 171 #[inline] to_i8() -> i8172 fn to_i8() -> i8 { 173 Self::I8 174 } 175 #[inline] to_i16() -> i16176 fn to_i16() -> i16 { 177 Self::I16 178 } 179 #[inline] to_i32() -> i32180 fn to_i32() -> i32 { 181 Self::I32 182 } 183 #[inline] to_i64() -> i64184 fn to_i64() -> i64 { 185 Self::I64 186 } 187 #[cfg(feature = "i128")] 188 #[inline] to_i128() -> i128189 fn to_i128() -> i128 { 190 Self::I128 191 } 192 #[inline] to_isize() -> isize193 fn to_isize() -> isize { 194 Self::ISIZE 195 } 196 } 197 198 // --------------------------------------------------------------------------------------- 199 // Neg 200 201 /// `-Z0 = Z0` 202 impl Neg for Z0 { 203 type Output = Z0; 204 #[inline] neg(self) -> Self::Output205 fn neg(self) -> Self::Output { 206 Z0 207 } 208 } 209 210 /// `-PInt = NInt` 211 impl<U: Unsigned + NonZero> Neg for PInt<U> { 212 type Output = NInt<U>; 213 #[inline] 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>; 222 #[inline] neg(self) -> Self::Output223 fn neg(self) -> Self::Output { 224 PInt::new() 225 } 226 } 227 228 // --------------------------------------------------------------------------------------- 229 // Add 230 231 /// `Z0 + I = I` 232 impl<I: Integer> Add<I> for Z0 { 233 type Output = I; 234 #[inline] add(self, rhs: I) -> Self::Output235 fn add(self, rhs: I) -> Self::Output { 236 rhs 237 } 238 } 239 240 /// `PInt + Z0 = PInt` 241 impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> { 242 type Output = PInt<U>; 243 #[inline] add(self, _: Z0) -> Self::Output244 fn add(self, _: Z0) -> Self::Output { 245 PInt::new() 246 } 247 } 248 249 /// `NInt + Z0 = NInt` 250 impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> { 251 type Output = NInt<U>; 252 #[inline] add(self, _: Z0) -> Self::Output253 fn add(self, _: Z0) -> Self::Output { 254 NInt::new() 255 } 256 } 257 258 /// `P(Ul) + P(Ur) = P(Ul + Ur)` 259 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul> 260 where 261 Ul: Add<Ur>, 262 <Ul as Add<Ur>>::Output: Unsigned + NonZero, 263 { 264 type Output = PInt<<Ul as Add<Ur>>::Output>; 265 #[inline] add(self, _: PInt<Ur>) -> Self::Output266 fn add(self, _: PInt<Ur>) -> Self::Output { 267 PInt::new() 268 } 269 } 270 271 /// `N(Ul) + N(Ur) = N(Ul + Ur)` 272 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul> 273 where 274 Ul: Add<Ur>, 275 <Ul as Add<Ur>>::Output: Unsigned + NonZero, 276 { 277 type Output = NInt<<Ul as Add<Ur>>::Output>; 278 #[inline] add(self, _: NInt<Ur>) -> Self::Output279 fn add(self, _: NInt<Ur>) -> Self::Output { 280 NInt::new() 281 } 282 } 283 284 /// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd` 285 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul> 286 where 287 Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>, 288 { 289 type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output; 290 #[inline] add(self, rhs: NInt<Ur>) -> Self::Output291 fn add(self, rhs: NInt<Ur>) -> Self::Output { 292 let lhs = self.n; 293 let rhs = rhs.n; 294 let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs); 295 lhs.private_integer_add(lhs_cmp_rhs, rhs) 296 } 297 } 298 299 /// `N(Ul) + P(Ur)`: We resolve this with our `PrivateAdd` 300 // We just do the same thing as above, swapping Lhs and Rhs 301 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul> 302 where 303 Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>, 304 { 305 type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output; 306 #[inline] add(self, rhs: PInt<Ur>) -> Self::Output307 fn add(self, rhs: PInt<Ur>) -> Self::Output { 308 let lhs = self.n; 309 let rhs = rhs.n; 310 let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs); 311 rhs.private_integer_add(rhs_cmp_lhs, lhs) 312 } 313 } 314 315 /// `P + N = 0` where `P == N` 316 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P { 317 type Output = Z0; 318 319 #[inline] private_integer_add(self, _: Equal, _: N) -> Self::Output320 fn private_integer_add(self, _: Equal, _: N) -> Self::Output { 321 Z0 322 } 323 } 324 325 /// `P + N = Positive` where `P > N` 326 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P 327 where 328 P: Sub<N>, 329 <P as Sub<N>>::Output: Unsigned + NonZero, 330 { 331 type Output = PInt<<P as Sub<N>>::Output>; 332 333 #[inline] private_integer_add(self, _: Greater, n: N) -> Self::Output334 fn private_integer_add(self, _: Greater, n: N) -> Self::Output { 335 PInt { n: self - n } 336 } 337 } 338 339 /// `P + N = Negative` where `P < N` 340 impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P 341 where 342 N: Sub<P>, 343 <N as Sub<P>>::Output: Unsigned + NonZero, 344 { 345 type Output = NInt<<N as Sub<P>>::Output>; 346 347 #[inline] private_integer_add(self, _: Less, n: N) -> Self::Output348 fn private_integer_add(self, _: Less, n: N) -> Self::Output { 349 NInt { n: n - self } 350 } 351 } 352 353 // --------------------------------------------------------------------------------------- 354 // Sub 355 356 /// `Z0 - Z0 = Z0` 357 impl Sub<Z0> for Z0 { 358 type Output = Z0; 359 #[inline] sub(self, _: Z0) -> Self::Output360 fn sub(self, _: Z0) -> Self::Output { 361 Z0 362 } 363 } 364 365 /// `Z0 - P = N` 366 impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 { 367 type Output = NInt<U>; 368 #[inline] sub(self, _: PInt<U>) -> Self::Output369 fn sub(self, _: PInt<U>) -> Self::Output { 370 NInt::new() 371 } 372 } 373 374 /// `Z0 - N = P` 375 impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 { 376 type Output = PInt<U>; 377 #[inline] sub(self, _: NInt<U>) -> Self::Output378 fn sub(self, _: NInt<U>) -> Self::Output { 379 PInt::new() 380 } 381 } 382 383 /// `PInt - Z0 = PInt` 384 impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> { 385 type Output = PInt<U>; 386 #[inline] sub(self, _: Z0) -> Self::Output387 fn sub(self, _: Z0) -> Self::Output { 388 PInt::new() 389 } 390 } 391 392 /// `NInt - Z0 = NInt` 393 impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> { 394 type Output = NInt<U>; 395 #[inline] sub(self, _: Z0) -> Self::Output396 fn sub(self, _: Z0) -> Self::Output { 397 NInt::new() 398 } 399 } 400 401 /// `P(Ul) - N(Ur) = P(Ul + Ur)` 402 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul> 403 where 404 Ul: Add<Ur>, 405 <Ul as Add<Ur>>::Output: Unsigned + NonZero, 406 { 407 type Output = PInt<<Ul as Add<Ur>>::Output>; 408 #[inline] sub(self, _: NInt<Ur>) -> Self::Output409 fn sub(self, _: NInt<Ur>) -> Self::Output { 410 PInt::new() 411 } 412 } 413 414 /// `N(Ul) - P(Ur) = N(Ul + Ur)` 415 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul> 416 where 417 Ul: Add<Ur>, 418 <Ul as Add<Ur>>::Output: Unsigned + NonZero, 419 { 420 type Output = NInt<<Ul as Add<Ur>>::Output>; 421 #[inline] sub(self, _: PInt<Ur>) -> Self::Output422 fn sub(self, _: PInt<Ur>) -> Self::Output { 423 NInt::new() 424 } 425 } 426 427 /// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd` 428 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul> 429 where 430 Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>, 431 { 432 type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output; 433 #[inline] sub(self, rhs: PInt<Ur>) -> Self::Output434 fn sub(self, rhs: PInt<Ur>) -> Self::Output { 435 let lhs = self.n; 436 let rhs = rhs.n; 437 let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs); 438 lhs.private_integer_add(lhs_cmp_rhs, rhs) 439 } 440 } 441 442 /// `N(Ul) - N(Ur)`: We resolve this with our `PrivateAdd` 443 // We just do the same thing as above, swapping Lhs and Rhs 444 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul> 445 where 446 Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>, 447 { 448 type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output; 449 #[inline] sub(self, rhs: NInt<Ur>) -> Self::Output450 fn sub(self, rhs: NInt<Ur>) -> Self::Output { 451 let lhs = self.n; 452 let rhs = rhs.n; 453 let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs); 454 rhs.private_integer_add(rhs_cmp_lhs, lhs) 455 } 456 } 457 458 // --------------------------------------------------------------------------------------- 459 // Mul 460 461 /// `Z0 * I = Z0` 462 impl<I: Integer> Mul<I> for Z0 { 463 type Output = Z0; 464 #[inline] mul(self, _: I) -> Self::Output465 fn mul(self, _: I) -> Self::Output { 466 Z0 467 } 468 } 469 470 /// `P * Z0 = Z0` 471 impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> { 472 type Output = Z0; 473 #[inline] mul(self, _: Z0) -> Self::Output474 fn mul(self, _: Z0) -> Self::Output { 475 Z0 476 } 477 } 478 479 /// `N * Z0 = Z0` 480 impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> { 481 type Output = Z0; 482 #[inline] mul(self, _: Z0) -> Self::Output483 fn mul(self, _: Z0) -> Self::Output { 484 Z0 485 } 486 } 487 488 /// P(Ul) * P(Ur) = P(Ul * Ur) 489 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul> 490 where 491 Ul: Mul<Ur>, 492 <Ul as Mul<Ur>>::Output: Unsigned + NonZero, 493 { 494 type Output = PInt<<Ul as Mul<Ur>>::Output>; 495 #[inline] mul(self, _: PInt<Ur>) -> Self::Output496 fn mul(self, _: PInt<Ur>) -> Self::Output { 497 PInt::new() 498 } 499 } 500 501 /// N(Ul) * N(Ur) = P(Ul * Ur) 502 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul> 503 where 504 Ul: Mul<Ur>, 505 <Ul as Mul<Ur>>::Output: Unsigned + NonZero, 506 { 507 type Output = PInt<<Ul as Mul<Ur>>::Output>; 508 #[inline] mul(self, _: NInt<Ur>) -> Self::Output509 fn mul(self, _: NInt<Ur>) -> Self::Output { 510 PInt::new() 511 } 512 } 513 514 /// P(Ul) * N(Ur) = N(Ul * Ur) 515 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul> 516 where 517 Ul: Mul<Ur>, 518 <Ul as Mul<Ur>>::Output: Unsigned + NonZero, 519 { 520 type Output = NInt<<Ul as Mul<Ur>>::Output>; 521 #[inline] mul(self, _: NInt<Ur>) -> Self::Output522 fn mul(self, _: NInt<Ur>) -> Self::Output { 523 NInt::new() 524 } 525 } 526 527 /// N(Ul) * P(Ur) = N(Ul * Ur) 528 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul> 529 where 530 Ul: Mul<Ur>, 531 <Ul as Mul<Ur>>::Output: Unsigned + NonZero, 532 { 533 type Output = NInt<<Ul as Mul<Ur>>::Output>; 534 #[inline] mul(self, _: PInt<Ur>) -> Self::Output535 fn mul(self, _: PInt<Ur>) -> Self::Output { 536 NInt::new() 537 } 538 } 539 540 // --------------------------------------------------------------------------------------- 541 // Div 542 543 /// `Z0 / I = Z0` where `I != 0` 544 impl<I: Integer + NonZero> Div<I> for Z0 { 545 type Output = Z0; 546 #[inline] div(self, _: I) -> Self::Output547 fn div(self, _: I) -> Self::Output { 548 Z0 549 } 550 } 551 552 macro_rules! impl_int_div { 553 ($A:ident, $B:ident, $R:ident) => { 554 /// `$A<Ul> / $B<Ur> = $R<Ul / Ur>` 555 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Div<$B<Ur>> for $A<Ul> 556 where 557 Ul: Cmp<Ur>, 558 $A<Ul>: PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>, 559 { 560 type Output = <$A<Ul> as PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>>::Output; 561 #[inline] 562 fn div(self, rhs: $B<Ur>) -> Self::Output { 563 let lhs_cmp_rhs = self.n.compare::<Internal>(&rhs.n); 564 self.private_div_int(lhs_cmp_rhs, rhs) 565 } 566 } 567 impl<Ul, Ur> PrivateDivInt<Less, $B<Ur>> for $A<Ul> 568 where 569 Ul: Unsigned + NonZero, 570 Ur: Unsigned + NonZero, 571 { 572 type Output = Z0; 573 574 #[inline] 575 fn private_div_int(self, _: Less, _: $B<Ur>) -> Self::Output { 576 Z0 577 } 578 } 579 impl<Ul, Ur> PrivateDivInt<Equal, $B<Ur>> for $A<Ul> 580 where 581 Ul: Unsigned + NonZero, 582 Ur: Unsigned + NonZero, 583 { 584 type Output = $R<U1>; 585 586 #[inline] 587 fn private_div_int(self, _: Equal, _: $B<Ur>) -> Self::Output { 588 $R { n: U1::new() } 589 } 590 } 591 impl<Ul, Ur> PrivateDivInt<Greater, $B<Ur>> for $A<Ul> 592 where 593 Ul: Unsigned + NonZero + Div<Ur>, 594 Ur: Unsigned + NonZero, 595 <Ul as Div<Ur>>::Output: Unsigned + NonZero, 596 { 597 type Output = $R<<Ul as Div<Ur>>::Output>; 598 599 #[inline] 600 fn private_div_int(self, _: Greater, d: $B<Ur>) -> Self::Output { 601 $R { n: self.n / d.n } 602 } 603 } 604 }; 605 } 606 607 impl_int_div!(PInt, PInt, PInt); 608 impl_int_div!(PInt, NInt, NInt); 609 impl_int_div!(NInt, PInt, NInt); 610 impl_int_div!(NInt, NInt, PInt); 611 612 // --------------------------------------------------------------------------------------- 613 // PartialDiv 614 615 use crate::{PartialDiv, Quot}; 616 617 impl<M, N> PartialDiv<N> for M 618 where 619 M: Integer + Div<N> + Rem<N, Output = Z0>, 620 { 621 type Output = Quot<M, N>; 622 #[inline] partial_div(self, rhs: N) -> Self::Output623 fn partial_div(self, rhs: N) -> Self::Output { 624 self / rhs 625 } 626 } 627 628 // --------------------------------------------------------------------------------------- 629 // Cmp 630 631 /// 0 == 0 632 impl Cmp<Z0> for Z0 { 633 type Output = Equal; 634 635 #[inline] compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output636 fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output { 637 Equal 638 } 639 } 640 641 /// 0 > -X 642 impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 { 643 type Output = Greater; 644 645 #[inline] compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output646 fn compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output { 647 Greater 648 } 649 } 650 651 /// 0 < X 652 impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 { 653 type Output = Less; 654 655 #[inline] compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output656 fn compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output { 657 Less 658 } 659 } 660 661 /// X > 0 662 impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> { 663 type Output = Greater; 664 665 #[inline] compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output666 fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output { 667 Greater 668 } 669 } 670 671 /// -X < 0 672 impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> { 673 type Output = Less; 674 675 #[inline] compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output676 fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output { 677 Less 678 } 679 } 680 681 /// -X < Y 682 impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> { 683 type Output = Less; 684 685 #[inline] compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output686 fn compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output { 687 Less 688 } 689 } 690 691 /// X > - Y 692 impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> { 693 type Output = Greater; 694 695 #[inline] compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output696 fn compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output { 697 Greater 698 } 699 } 700 701 /// X <==> Y 702 impl<Pl: Cmp<Pr> + Unsigned + NonZero, Pr: Unsigned + NonZero> Cmp<PInt<Pr>> for PInt<Pl> { 703 type Output = <Pl as Cmp<Pr>>::Output; 704 705 #[inline] compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output706 fn compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output { 707 self.n.compare::<Internal>(&rhs.n) 708 } 709 } 710 711 /// -X <==> -Y 712 impl<Nl: Unsigned + NonZero, Nr: Cmp<Nl> + Unsigned + NonZero> Cmp<NInt<Nr>> for NInt<Nl> { 713 type Output = <Nr as Cmp<Nl>>::Output; 714 715 #[inline] compare<IM: InternalMarker>(&self, rhs: &NInt<Nr>) -> Self::Output716 fn compare<IM: InternalMarker>(&self, rhs: &NInt<Nr>) -> Self::Output { 717 rhs.n.compare::<Internal>(&self.n) 718 } 719 } 720 721 // --------------------------------------------------------------------------------------- 722 // Rem 723 724 /// `Z0 % I = Z0` where `I != 0` 725 impl<I: Integer + NonZero> Rem<I> for Z0 { 726 type Output = Z0; 727 #[inline] rem(self, _: I) -> Self::Output728 fn rem(self, _: I) -> Self::Output { 729 Z0 730 } 731 } 732 733 macro_rules! impl_int_rem { 734 ($A:ident, $B:ident, $R:ident) => { 735 /// `$A<Ul> % $B<Ur> = $R<Ul % Ur>` 736 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Rem<$B<Ur>> for $A<Ul> 737 where 738 Ul: Rem<Ur>, 739 $A<Ul>: PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>, 740 { 741 type Output = <$A<Ul> as PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>>::Output; 742 #[inline] 743 fn rem(self, rhs: $B<Ur>) -> Self::Output { 744 self.private_rem(self.n % rhs.n, rhs) 745 } 746 } 747 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> PrivateRem<U0, $B<Ur>> for $A<Ul> { 748 type Output = Z0; 749 750 #[inline] 751 fn private_rem(self, _: U0, _: $B<Ur>) -> Self::Output { 752 Z0 753 } 754 } 755 impl<Ul, Ur, U, B> PrivateRem<UInt<U, B>, $B<Ur>> for $A<Ul> 756 where 757 Ul: Unsigned + NonZero, 758 Ur: Unsigned + NonZero, 759 U: Unsigned, 760 B: Bit, 761 { 762 type Output = $R<UInt<U, B>>; 763 764 #[inline] 765 fn private_rem(self, urem: UInt<U, B>, _: $B<Ur>) -> Self::Output { 766 $R { n: urem } 767 } 768 } 769 }; 770 } 771 772 impl_int_rem!(PInt, PInt, PInt); 773 impl_int_rem!(PInt, NInt, PInt); 774 impl_int_rem!(NInt, PInt, NInt); 775 impl_int_rem!(NInt, NInt, NInt); 776 777 // --------------------------------------------------------------------------------------- 778 // Pow 779 780 /// 0^0 = 1 781 impl Pow<Z0> for Z0 { 782 type Output = P1; 783 #[inline] powi(self, _: Z0) -> Self::Output784 fn powi(self, _: Z0) -> Self::Output { 785 P1::new() 786 } 787 } 788 789 /// 0^P = 0 790 impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 { 791 type Output = Z0; 792 #[inline] powi(self, _: PInt<U>) -> Self::Output793 fn powi(self, _: PInt<U>) -> Self::Output { 794 Z0 795 } 796 } 797 798 /// 0^N = 0 799 impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 { 800 type Output = Z0; 801 #[inline] powi(self, _: NInt<U>) -> Self::Output802 fn powi(self, _: NInt<U>) -> Self::Output { 803 Z0 804 } 805 } 806 807 /// 1^N = 1 808 impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 { 809 type Output = P1; 810 #[inline] powi(self, _: NInt<U>) -> Self::Output811 fn powi(self, _: NInt<U>) -> Self::Output { 812 P1::new() 813 } 814 } 815 816 /// (-1)^N = 1 if N is even 817 impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 { 818 type Output = P1; 819 #[inline] powi(self, _: NInt<UInt<U, B0>>) -> Self::Output820 fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output { 821 P1::new() 822 } 823 } 824 825 /// (-1)^N = -1 if N is odd 826 impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 { 827 type Output = N1; 828 #[inline] powi(self, _: NInt<UInt<U, B1>>) -> Self::Output829 fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output { 830 N1::new() 831 } 832 } 833 834 /// P^0 = 1 835 impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> { 836 type Output = P1; 837 #[inline] powi(self, _: Z0) -> Self::Output838 fn powi(self, _: Z0) -> Self::Output { 839 P1::new() 840 } 841 } 842 843 /// N^0 = 1 844 impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> { 845 type Output = P1; 846 #[inline] powi(self, _: Z0) -> Self::Output847 fn powi(self, _: Z0) -> Self::Output { 848 P1::new() 849 } 850 } 851 852 /// P(Ul)^P(Ur) = P(Ul^Ur) 853 impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul> 854 where 855 Ul: Pow<Ur>, 856 <Ul as Pow<Ur>>::Output: Unsigned + NonZero, 857 { 858 type Output = PInt<<Ul as Pow<Ur>>::Output>; 859 #[inline] powi(self, _: PInt<Ur>) -> Self::Output860 fn powi(self, _: PInt<Ur>) -> Self::Output { 861 PInt::new() 862 } 863 } 864 865 /// N(Ul)^P(Ur) = P(Ul^Ur) if Ur is even 866 impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul> 867 where 868 Ul: Pow<UInt<Ur, B0>>, 869 <Ul as Pow<UInt<Ur, B0>>>::Output: Unsigned + NonZero, 870 { 871 type Output = PInt<<Ul as Pow<UInt<Ur, B0>>>::Output>; 872 #[inline] powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output873 fn powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output { 874 PInt::new() 875 } 876 } 877 878 /// N(Ul)^P(Ur) = N(Ul^Ur) if Ur is odd 879 impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul> 880 where 881 Ul: Pow<UInt<Ur, B1>>, 882 <Ul as Pow<UInt<Ur, B1>>>::Output: Unsigned + NonZero, 883 { 884 type Output = NInt<<Ul as Pow<UInt<Ur, B1>>>::Output>; 885 #[inline] powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output886 fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output { 887 NInt::new() 888 } 889 } 890 891 // --------------------------------------------------------------------------------------- 892 // Gcd 893 use crate::{Gcd, Gcf}; 894 895 impl Gcd<Z0> for Z0 { 896 type Output = Z0; 897 } 898 899 impl<U> Gcd<PInt<U>> for Z0 900 where 901 U: Unsigned + NonZero, 902 { 903 type Output = PInt<U>; 904 } 905 906 impl<U> Gcd<Z0> for PInt<U> 907 where 908 U: Unsigned + NonZero, 909 { 910 type Output = PInt<U>; 911 } 912 913 impl<U> Gcd<NInt<U>> for Z0 914 where 915 U: Unsigned + NonZero, 916 { 917 type Output = PInt<U>; 918 } 919 920 impl<U> Gcd<Z0> for NInt<U> 921 where 922 U: Unsigned + NonZero, 923 { 924 type Output = PInt<U>; 925 } 926 927 impl<U1, U2> Gcd<PInt<U2>> for PInt<U1> 928 where 929 U1: Unsigned + NonZero + Gcd<U2>, 930 U2: Unsigned + NonZero, 931 Gcf<U1, U2>: Unsigned + NonZero, 932 { 933 type Output = PInt<Gcf<U1, U2>>; 934 } 935 936 impl<U1, U2> Gcd<PInt<U2>> for NInt<U1> 937 where 938 U1: Unsigned + NonZero + Gcd<U2>, 939 U2: Unsigned + NonZero, 940 Gcf<U1, U2>: Unsigned + NonZero, 941 { 942 type Output = PInt<Gcf<U1, U2>>; 943 } 944 945 impl<U1, U2> Gcd<NInt<U2>> for PInt<U1> 946 where 947 U1: Unsigned + NonZero + Gcd<U2>, 948 U2: Unsigned + NonZero, 949 Gcf<U1, U2>: Unsigned + NonZero, 950 { 951 type Output = PInt<Gcf<U1, U2>>; 952 } 953 954 impl<U1, U2> Gcd<NInt<U2>> for NInt<U1> 955 where 956 U1: Unsigned + NonZero + Gcd<U2>, 957 U2: Unsigned + NonZero, 958 Gcf<U1, U2>: Unsigned + NonZero, 959 { 960 type Output = PInt<Gcf<U1, U2>>; 961 } 962 963 // --------------------------------------------------------------------------------------- 964 // Min 965 use crate::{Max, Maximum, Min, Minimum}; 966 967 impl Min<Z0> for Z0 { 968 type Output = Z0; 969 #[inline] min(self, _: Z0) -> Self::Output970 fn min(self, _: Z0) -> Self::Output { 971 self 972 } 973 } 974 975 impl<U> Min<PInt<U>> for Z0 976 where 977 U: Unsigned + NonZero, 978 { 979 type Output = Z0; 980 #[inline] min(self, _: PInt<U>) -> Self::Output981 fn min(self, _: PInt<U>) -> Self::Output { 982 self 983 } 984 } 985 986 impl<U> Min<NInt<U>> for Z0 987 where 988 U: Unsigned + NonZero, 989 { 990 type Output = NInt<U>; 991 #[inline] min(self, rhs: NInt<U>) -> Self::Output992 fn min(self, rhs: NInt<U>) -> Self::Output { 993 rhs 994 } 995 } 996 997 impl<U> Min<Z0> for PInt<U> 998 where 999 U: Unsigned + NonZero, 1000 { 1001 type Output = Z0; 1002 #[inline] min(self, rhs: Z0) -> Self::Output1003 fn min(self, rhs: Z0) -> Self::Output { 1004 rhs 1005 } 1006 } 1007 1008 impl<U> Min<Z0> for NInt<U> 1009 where 1010 U: Unsigned + NonZero, 1011 { 1012 type Output = NInt<U>; 1013 #[inline] min(self, _: Z0) -> Self::Output1014 fn min(self, _: Z0) -> Self::Output { 1015 self 1016 } 1017 } 1018 1019 impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul> 1020 where 1021 Ul: Unsigned + NonZero + Min<Ur>, 1022 Ur: Unsigned + NonZero, 1023 Minimum<Ul, Ur>: Unsigned + NonZero, 1024 { 1025 type Output = PInt<Minimum<Ul, Ur>>; 1026 #[inline] min(self, rhs: PInt<Ur>) -> Self::Output1027 fn min(self, rhs: PInt<Ur>) -> Self::Output { 1028 PInt { 1029 n: self.n.min(rhs.n), 1030 } 1031 } 1032 } 1033 1034 impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul> 1035 where 1036 Ul: Unsigned + NonZero, 1037 Ur: Unsigned + NonZero, 1038 { 1039 type Output = NInt<Ul>; 1040 #[inline] min(self, _: PInt<Ur>) -> Self::Output1041 fn min(self, _: PInt<Ur>) -> Self::Output { 1042 self 1043 } 1044 } 1045 1046 impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul> 1047 where 1048 Ul: Unsigned + NonZero, 1049 Ur: Unsigned + NonZero, 1050 { 1051 type Output = NInt<Ur>; 1052 #[inline] min(self, rhs: NInt<Ur>) -> Self::Output1053 fn min(self, rhs: NInt<Ur>) -> Self::Output { 1054 rhs 1055 } 1056 } 1057 1058 impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul> 1059 where 1060 Ul: Unsigned + NonZero + Max<Ur>, 1061 Ur: Unsigned + NonZero, 1062 Maximum<Ul, Ur>: Unsigned + NonZero, 1063 { 1064 type Output = NInt<Maximum<Ul, Ur>>; 1065 #[inline] min(self, rhs: NInt<Ur>) -> Self::Output1066 fn min(self, rhs: NInt<Ur>) -> Self::Output { 1067 NInt { 1068 n: self.n.max(rhs.n), 1069 } 1070 } 1071 } 1072 1073 // --------------------------------------------------------------------------------------- 1074 // Max 1075 1076 impl Max<Z0> for Z0 { 1077 type Output = Z0; 1078 #[inline] max(self, _: Z0) -> Self::Output1079 fn max(self, _: Z0) -> Self::Output { 1080 self 1081 } 1082 } 1083 1084 impl<U> Max<PInt<U>> for Z0 1085 where 1086 U: Unsigned + NonZero, 1087 { 1088 type Output = PInt<U>; 1089 #[inline] max(self, rhs: PInt<U>) -> Self::Output1090 fn max(self, rhs: PInt<U>) -> Self::Output { 1091 rhs 1092 } 1093 } 1094 1095 impl<U> Max<NInt<U>> for Z0 1096 where 1097 U: Unsigned + NonZero, 1098 { 1099 type Output = Z0; 1100 #[inline] max(self, _: NInt<U>) -> Self::Output1101 fn max(self, _: NInt<U>) -> Self::Output { 1102 self 1103 } 1104 } 1105 1106 impl<U> Max<Z0> for PInt<U> 1107 where 1108 U: Unsigned + NonZero, 1109 { 1110 type Output = PInt<U>; 1111 #[inline] max(self, _: Z0) -> Self::Output1112 fn max(self, _: Z0) -> Self::Output { 1113 self 1114 } 1115 } 1116 1117 impl<U> Max<Z0> for NInt<U> 1118 where 1119 U: Unsigned + NonZero, 1120 { 1121 type Output = Z0; 1122 #[inline] max(self, rhs: Z0) -> Self::Output1123 fn max(self, rhs: Z0) -> Self::Output { 1124 rhs 1125 } 1126 } 1127 1128 impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul> 1129 where 1130 Ul: Unsigned + NonZero + Max<Ur>, 1131 Ur: Unsigned + NonZero, 1132 Maximum<Ul, Ur>: Unsigned + NonZero, 1133 { 1134 type Output = PInt<Maximum<Ul, Ur>>; 1135 #[inline] max(self, rhs: PInt<Ur>) -> Self::Output1136 fn max(self, rhs: PInt<Ur>) -> Self::Output { 1137 PInt { 1138 n: self.n.max(rhs.n), 1139 } 1140 } 1141 } 1142 1143 impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul> 1144 where 1145 Ul: Unsigned + NonZero, 1146 Ur: Unsigned + NonZero, 1147 { 1148 type Output = PInt<Ur>; 1149 #[inline] max(self, rhs: PInt<Ur>) -> Self::Output1150 fn max(self, rhs: PInt<Ur>) -> Self::Output { 1151 rhs 1152 } 1153 } 1154 1155 impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul> 1156 where 1157 Ul: Unsigned + NonZero, 1158 Ur: Unsigned + NonZero, 1159 { 1160 type Output = PInt<Ul>; 1161 #[inline] max(self, _: NInt<Ur>) -> Self::Output1162 fn max(self, _: NInt<Ur>) -> Self::Output { 1163 self 1164 } 1165 } 1166 1167 impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul> 1168 where 1169 Ul: Unsigned + NonZero + Min<Ur>, 1170 Ur: Unsigned + NonZero, 1171 Minimum<Ul, Ur>: Unsigned + NonZero, 1172 { 1173 type Output = NInt<Minimum<Ul, Ur>>; 1174 #[inline] max(self, rhs: NInt<Ur>) -> Self::Output1175 fn max(self, rhs: NInt<Ur>) -> Self::Output { 1176 NInt { 1177 n: self.n.min(rhs.n), 1178 } 1179 } 1180 } 1181 1182 // ----------------------------------------- 1183 // ToInt 1184 1185 impl ToInt<i8> for Z0 { 1186 #[inline] to_int() -> i81187 fn to_int() -> i8 { 1188 Self::I8 1189 } 1190 } 1191 1192 impl ToInt<i16> for Z0 { 1193 #[inline] to_int() -> i161194 fn to_int() -> i16 { 1195 Self::I16 1196 } 1197 } 1198 1199 impl ToInt<i32> for Z0 { 1200 #[inline] to_int() -> i321201 fn to_int() -> i32 { 1202 Self::I32 1203 } 1204 } 1205 1206 impl ToInt<i64> for Z0 { 1207 #[inline] to_int() -> i641208 fn to_int() -> i64 { 1209 Self::I64 1210 } 1211 } 1212 1213 // negative numbers 1214 1215 impl<U> ToInt<i8> for NInt<U> 1216 where 1217 U: Unsigned + NonZero, 1218 { 1219 #[inline] to_int() -> i81220 fn to_int() -> i8 { 1221 Self::I8 1222 } 1223 } 1224 1225 impl<U> ToInt<i16> for NInt<U> 1226 where 1227 U: Unsigned + NonZero, 1228 { 1229 #[inline] to_int() -> i161230 fn to_int() -> i16 { 1231 Self::I16 1232 } 1233 } 1234 1235 impl<U> ToInt<i32> for NInt<U> 1236 where 1237 U: Unsigned + NonZero, 1238 { 1239 #[inline] to_int() -> i321240 fn to_int() -> i32 { 1241 Self::I32 1242 } 1243 } 1244 1245 impl<U> ToInt<i64> for NInt<U> 1246 where 1247 U: Unsigned + NonZero, 1248 { 1249 #[inline] to_int() -> i641250 fn to_int() -> i64 { 1251 Self::I64 1252 } 1253 } 1254 1255 // positive numbers 1256 1257 impl<U> ToInt<i8> for PInt<U> 1258 where 1259 U: Unsigned + NonZero, 1260 { 1261 #[inline] to_int() -> i81262 fn to_int() -> i8 { 1263 Self::I8 1264 } 1265 } 1266 1267 impl<U> ToInt<i16> for PInt<U> 1268 where 1269 U: Unsigned + NonZero, 1270 { 1271 #[inline] to_int() -> i161272 fn to_int() -> i16 { 1273 Self::I16 1274 } 1275 } 1276 1277 impl<U> ToInt<i32> for PInt<U> 1278 where 1279 U: Unsigned + NonZero, 1280 { 1281 #[inline] to_int() -> i321282 fn to_int() -> i32 { 1283 Self::I32 1284 } 1285 } 1286 1287 impl<U> ToInt<i64> for PInt<U> 1288 where 1289 U: Unsigned + NonZero, 1290 { 1291 #[inline] to_int() -> i641292 fn to_int() -> i64 { 1293 Self::I64 1294 } 1295 } 1296 1297 #[cfg(test)] 1298 mod tests { 1299 use crate::{consts::*, Integer, ToInt}; 1300 1301 #[test] to_ix_min()1302 fn to_ix_min() { 1303 assert_eq!(N128::to_i8(), ::core::i8::MIN); 1304 assert_eq!(N32768::to_i16(), ::core::i16::MIN); 1305 } 1306 1307 #[test] int_toint_test()1308 fn int_toint_test() { 1309 // i8 1310 assert_eq!(0_i8, Z0::to_int()); 1311 assert_eq!(1_i8, P1::to_int()); 1312 assert_eq!(2_i8, P2::to_int()); 1313 assert_eq!(3_i8, P3::to_int()); 1314 assert_eq!(4_i8, P4::to_int()); 1315 assert_eq!(-1_i8, N1::to_int()); 1316 assert_eq!(-2_i8, N2::to_int()); 1317 assert_eq!(-3_i8, N3::to_int()); 1318 assert_eq!(-4_i8, N4::to_int()); 1319 1320 // i16 1321 assert_eq!(0_i16, Z0::to_int()); 1322 assert_eq!(1_i16, P1::to_int()); 1323 assert_eq!(2_i16, P2::to_int()); 1324 assert_eq!(3_i16, P3::to_int()); 1325 assert_eq!(4_i16, P4::to_int()); 1326 assert_eq!(-1_i16, N1::to_int()); 1327 assert_eq!(-2_i16, N2::to_int()); 1328 assert_eq!(-3_i16, N3::to_int()); 1329 assert_eq!(-4_i16, N4::to_int()); 1330 1331 // i32 1332 assert_eq!(0_i32, Z0::to_int()); 1333 assert_eq!(1_i32, P1::to_int()); 1334 assert_eq!(2_i32, P2::to_int()); 1335 assert_eq!(3_i32, P3::to_int()); 1336 assert_eq!(4_i32, P4::to_int()); 1337 assert_eq!(-1_i32, N1::to_int()); 1338 assert_eq!(-2_i32, N2::to_int()); 1339 assert_eq!(-3_i32, N3::to_int()); 1340 assert_eq!(-4_i32, N4::to_int()); 1341 1342 // i64 1343 assert_eq!(0_i64, Z0::to_int()); 1344 assert_eq!(1_i64, P1::to_int()); 1345 assert_eq!(2_i64, P2::to_int()); 1346 assert_eq!(3_i64, P3::to_int()); 1347 assert_eq!(4_i64, P4::to_int()); 1348 assert_eq!(-1_i64, N1::to_int()); 1349 assert_eq!(-2_i64, N2::to_int()); 1350 assert_eq!(-3_i64, N3::to_int()); 1351 assert_eq!(-4_i64, N4::to_int()); 1352 } 1353 } 1354