1 //! Wrapped float that behaves like an integer. 2 //! 3 //! Comprehensive wrapper for the Float trait that acts like an Integer 4 //! trait, allowed floats to be mocked as integers. 5 //! Operations natively supported by floats are wrapped, while 6 //! those that can be mocked (like overflow-checked operations) 7 //! are implemented, and others (like bitshift assigns) are unimplemented. 8 9 use crate::lib::{cmp, fmt, iter, ops}; 10 use super::cast::*; 11 use super::config::*; 12 use super::num::*; 13 use super::primitive::*; 14 15 // WRAPPED FLOAT 16 17 /// Wrap a float to act like an integer. 18 /// 19 /// Required for the lossy atof algorithm. 20 #[derive(Clone, Copy, Debug, PartialOrd)] 21 pub(crate) struct WrappedFloat<T: Float> 22 { 23 /// Internal data. 24 data: T, 25 } 26 27 impl<T: Float> WrappedFloat<T> { 28 /// Wrap existing float. 29 #[inline] from_float(t: T) -> Self30 pub fn from_float(t: T) -> Self { 31 WrappedFloat { data: t } 32 } 33 34 /// Consume wrapper and return float. 35 #[inline] into_inner(self) -> T36 pub fn into_inner(self) -> T { 37 self.data 38 } 39 } 40 41 // IMPL AS PRIMITIVE 42 43 impl<T: Float> PartialEq for WrappedFloat<T> { eq(&self, other: &Self) -> bool44 fn eq(&self, other: &Self) -> bool { 45 // Need to return true when both are NaN, since the default 46 // PartialEq for floats returns false when both are NaN. 47 // We demand total ordering, do it the right way, 48 if self.data.is_nan() && other.data.is_nan() { 49 true 50 } else { 51 self.data == other.data 52 } 53 } 54 } 55 56 impl<T: Float> AsPrimitive for WrappedFloat<T> { 57 #[inline] as_u8(self) -> u858 fn as_u8(self) -> u8 { 59 as_cast(self.data) 60 } 61 62 #[inline] as_u16(self) -> u1663 fn as_u16(self) -> u16 { 64 as_cast(self.data) 65 } 66 67 #[inline] as_u32(self) -> u3268 fn as_u32(self) -> u32 { 69 as_cast(self.data) 70 } 71 72 #[inline] as_u64(self) -> u6473 fn as_u64(self) -> u64 { 74 as_cast(self.data) 75 } 76 77 #[inline] as_u128(self) -> u12878 fn as_u128(self) -> u128 { 79 as_cast(self.data) 80 } 81 82 #[inline] as_usize(self) -> usize83 fn as_usize(self) -> usize { 84 as_cast(self.data) 85 } 86 87 #[inline] as_i8(self) -> i888 fn as_i8(self) -> i8 { 89 as_cast(self.data) 90 } 91 92 #[inline] as_i16(self) -> i1693 fn as_i16(self) -> i16 { 94 as_cast(self.data) 95 } 96 97 #[inline] as_i32(self) -> i3298 fn as_i32(self) -> i32 { 99 as_cast(self.data) 100 } 101 102 #[inline] as_i64(self) -> i64103 fn as_i64(self) -> i64 { 104 as_cast(self.data) 105 } 106 107 #[inline] as_i128(self) -> i128108 fn as_i128(self) -> i128 { 109 as_cast(self.data) 110 } 111 112 #[inline] as_isize(self) -> isize113 fn as_isize(self) -> isize { 114 as_cast(self.data) 115 } 116 117 #[inline] as_f32(self) -> f32118 fn as_f32(self) -> f32 { 119 as_cast(self.data) 120 } 121 122 #[inline] as_f64(self) -> f64123 fn as_f64(self) -> f64 { 124 as_cast(self.data) 125 } 126 } 127 128 // IMPL TRY PRIMITIVE 129 130 impl<T: Float> TryPrimitive for WrappedFloat<T> { 131 #[inline] try_u8(self) -> Option<u8>132 fn try_u8(self) -> Option<u8> { 133 try_cast(self.data) 134 } 135 136 #[inline] try_u16(self) -> Option<u16>137 fn try_u16(self) -> Option<u16> { 138 try_cast(self.data) 139 } 140 141 #[inline] try_u32(self) -> Option<u32>142 fn try_u32(self) -> Option<u32> { 143 try_cast(self.data) 144 } 145 146 #[inline] try_u64(self) -> Option<u64>147 fn try_u64(self) -> Option<u64> { 148 try_cast(self.data) 149 } 150 151 #[inline] try_u128(self) -> Option<u128>152 fn try_u128(self) -> Option<u128> { 153 try_cast(self.data) 154 } 155 156 #[inline] try_usize(self) -> Option<usize>157 fn try_usize(self) -> Option<usize> { 158 try_cast(self.data) 159 } 160 161 #[inline] try_i8(self) -> Option<i8>162 fn try_i8(self) -> Option<i8> { 163 try_cast(self.data) 164 } 165 166 #[inline] try_i16(self) -> Option<i16>167 fn try_i16(self) -> Option<i16> { 168 try_cast(self.data) 169 } 170 171 #[inline] try_i32(self) -> Option<i32>172 fn try_i32(self) -> Option<i32> { 173 try_cast(self.data) 174 } 175 176 #[inline] try_i64(self) -> Option<i64>177 fn try_i64(self) -> Option<i64> { 178 try_cast(self.data) 179 } 180 181 #[inline] try_i128(self) -> Option<i128>182 fn try_i128(self) -> Option<i128> { 183 try_cast(self.data) 184 } 185 186 #[inline] try_isize(self) -> Option<isize>187 fn try_isize(self) -> Option<isize> { 188 try_cast(self.data) 189 } 190 191 #[inline] try_f32(self) -> Option<f32>192 fn try_f32(self) -> Option<f32> { 193 try_cast(self.data) 194 } 195 196 #[inline] try_f64(self) -> Option<f64>197 fn try_f64(self) -> Option<f64> { 198 try_cast(self.data) 199 } 200 } 201 202 // IMPL AS CAST 203 204 impl<T: Float> AsCast for WrappedFloat<T> { 205 #[inline] as_cast<N: AsPrimitive>(n: N) -> Self206 fn as_cast<N: AsPrimitive>(n: N) -> Self { 207 // Wrap to wide float and back down. Should be a no-op. Just indirection. 208 WrappedFloat { data: as_cast(n.as_f64()) } 209 } 210 } 211 212 // IMPL TRY CAST 213 214 impl<N: Primitive, T: Float + TryCast<N>> TryCast<N> for WrappedFloat<T> { 215 #[inline] try_cast(self) -> Option<N>216 fn try_cast(self) -> Option<N> { 217 try_cast(self.data) 218 } 219 } 220 221 // IMPL PRIMITIVE 222 223 impl<T: Float> fmt::Display for WrappedFloat<T> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result224 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 225 fmt::Display::fmt(&self.data, f) 226 } 227 } 228 229 impl<T: Float> Primitive for WrappedFloat<T> { 230 } 231 232 // IMPL NUMBER 233 234 impl<T: Float> iter::Product for WrappedFloat<T> { 235 #[inline] product<Iter: Iterator<Item=WrappedFloat<T>>>(iter: Iter) -> Self236 fn product<Iter: Iterator<Item=WrappedFloat<T>>>(iter: Iter) -> Self { 237 iter.fold(Self::from_float(T::ONE), ops::Mul::mul) 238 } 239 } 240 241 impl<T: Float> iter::Sum for WrappedFloat<T> { 242 #[inline] sum<Iter: Iterator<Item=WrappedFloat<T>>>(iter: Iter) -> Self243 fn sum<Iter: Iterator<Item=WrappedFloat<T>>>(iter: Iter) -> Self { 244 iter.fold(Self::from_float(T::ZERO), ops::Add::add) 245 } 246 } 247 248 /// Implement arithmetic operations. 249 macro_rules! ops_impl { 250 ($($t:ident, $meth:ident ;)*) => ($( 251 impl<T: Float> ops::$t for WrappedFloat<T> { 252 type Output = Self; 253 254 #[inline] 255 fn $meth(self, other: Self) -> Self::Output { 256 WrappedFloat { data: self.data.$meth(other.data) } 257 } 258 } 259 )*); 260 } 261 262 ops_impl! { 263 Add, add ; 264 Div, div ; 265 Mul, mul ; 266 Rem, rem ; 267 Sub, sub ; 268 } 269 270 /// Implement arithmetic assignment operations. 271 macro_rules! ops_assign_impl { 272 ($($t:ident, $meth:ident ;)*) => ($( 273 impl<T: Float> ops::$t for WrappedFloat<T> { 274 #[inline] 275 fn $meth(&mut self, other: Self) { 276 self.data.$meth(other.data) 277 } 278 } 279 )*); 280 } 281 282 ops_assign_impl! { 283 AddAssign, add_assign ; 284 DivAssign, div_assign ; 285 MulAssign, mul_assign ; 286 RemAssign, rem_assign ; 287 SubAssign, sub_assign ; 288 } 289 290 impl<T: Float> Number for WrappedFloat<T> { 291 const FORMATTED_SIZE: usize = T::FORMATTED_SIZE; 292 const FORMATTED_SIZE_DECIMAL: usize = T::FORMATTED_SIZE_DECIMAL; 293 const IS_SIGNED: bool = T::IS_SIGNED; 294 } 295 296 // IMPL INTEGER 297 298 impl<T: Float> Ord for WrappedFloat<T> { 299 #[inline] cmp(&self, other: &Self) -> cmp::Ordering300 fn cmp(&self, other: &Self) -> cmp::Ordering { 301 // Implements total ordering for a float, while keeping typical 302 // behavior. All ordering is preserved, except for NaN, 303 // such that if both are NaN, they compare equal. 304 // PartialOrd are fails to provide an Ordering if 305 // either are NaN, so we just need to provide consistent 306 // ordering if either is NaN. 307 if let Some(ordering) = self.partial_cmp(&other) { 308 ordering 309 } else if !self.data.is_nan() { 310 cmp::Ordering::Less 311 } else if other.data.is_nan() { 312 cmp::Ordering::Equal 313 } else { 314 cmp::Ordering::Greater 315 } 316 } 317 } 318 319 impl<T: Float> Eq for WrappedFloat<T> { 320 } 321 322 impl<T: Float> fmt::Octal for WrappedFloat<T> { 323 #[inline] fmt(&self, _: &mut fmt::Formatter) -> fmt::Result324 fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { 325 unimplemented!() 326 } 327 } 328 329 impl<T: Float> fmt::LowerHex for WrappedFloat<T> { 330 #[inline] fmt(&self, _: &mut fmt::Formatter) -> fmt::Result331 fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { 332 unimplemented!() 333 } 334 } 335 336 impl<T: Float> fmt::UpperHex for WrappedFloat<T> { 337 #[inline] fmt(&self, _: &mut fmt::Formatter) -> fmt::Result338 fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { 339 unimplemented!() 340 } 341 } 342 343 /// Unimplement bitwise operations. 344 macro_rules! bitwise_impl { 345 ($($t:ident, $meth:ident ;)*) => ($( 346 impl<T: Float> ops::$t for WrappedFloat<T> { 347 type Output = Self; 348 349 #[inline] 350 fn $meth(self, _: Self) -> Self::Output { 351 unimplemented!() 352 } 353 } 354 )*); 355 } 356 357 bitwise_impl! { 358 BitAnd, bitand ; 359 BitOr, bitor ; 360 BitXor, bitxor ; 361 } 362 363 /// Unimplement bitwise assignment operations. 364 macro_rules! bitwise_assign_impl { 365 ($($t:ident, $meth:ident ;)*) => ($( 366 impl<T: Float> ops::$t for WrappedFloat<T> { 367 #[inline] 368 fn $meth(&mut self, _: Self) { 369 unimplemented!() 370 } 371 } 372 )*); 373 } 374 375 bitwise_assign_impl! { 376 BitAndAssign, bitand_assign ; 377 BitOrAssign, bitor_assign ; 378 BitXorAssign, bitxor_assign ; 379 } 380 381 impl<T: Float> ops::Not for WrappedFloat<T> { 382 type Output = Self; 383 384 #[inline] not(self) -> Self::Output385 fn not(self) -> Self::Output { 386 unimplemented!() 387 } 388 } 389 390 /// Unimplement bitshift operations. 391 macro_rules! bitshift_impl { 392 ($t:tt, $meth:ident ; $($s:ty)*) => ($( 393 // Iterate over all primitives. 394 impl<T: Float> ops::$t<$s> for WrappedFloat<T> { 395 type Output = Self; 396 397 #[inline] 398 fn $meth(self, _: $s) -> Self::Output { 399 unimplemented!() 400 } 401 } 402 )*); 403 ($($t:ident, $meth:ident ;)*) => ($( 404 // Base case, same as self. 405 impl<T: Float> ops::$t<> for WrappedFloat<T> { 406 type Output = Self; 407 408 #[inline] 409 fn $meth(self, _: Self) -> Self::Output { 410 unimplemented!() 411 } 412 } 413 414 bitshift_impl!($t, $meth ; u8 u16 u32 u64 usize i8 i16 i32 i64 isize); 415 )*); 416 } 417 418 bitshift_impl! { 419 Shl, shl ; 420 Shr, shr ; 421 } 422 423 /// Unimplement bitshift assignment operations. 424 macro_rules! bitshift_assign_impl { 425 ($t:tt, $meth:ident ; $($s:ty)*) => ($( 426 // Iterate over all primitives. 427 impl<T: Float> ops::$t<$s> for WrappedFloat<T> { 428 #[inline] 429 fn $meth(&mut self, _: $s) { 430 unimplemented!() 431 } 432 } 433 )*); 434 ($($t:ident, $meth:ident ;)*) => ($( 435 // Base case, same as self. 436 impl<T: Float> ops::$t<> for WrappedFloat<T> { 437 #[inline] 438 fn $meth(&mut self, _: Self) { 439 unimplemented!() 440 } 441 } 442 443 bitshift_assign_impl!($t, $meth ; u8 u16 u32 u64 usize i8 i16 i32 i64 isize); 444 )*); 445 } 446 447 bitshift_assign_impl! { 448 ShlAssign, shl_assign ; 449 ShrAssign, shr_assign ; 450 } 451 452 impl<T: Float> Integer for WrappedFloat<T> { 453 const ZERO: Self = WrappedFloat { data: T::ZERO }; 454 const ONE: Self = WrappedFloat { data: T::ONE }; 455 const TWO: Self = WrappedFloat { data: T::TWO }; 456 const MAX: Self = WrappedFloat { data: T::MAX }; 457 const MIN: Self = WrappedFloat { data: T::MIN }; 458 const BITS: usize = T::BITS; 459 460 #[inline] max_value() -> Self461 fn max_value() -> Self { 462 Self::MAX 463 } 464 465 #[inline] min_value() -> Self466 fn min_value() -> Self { 467 Self::MIN 468 } 469 470 #[inline] count_ones(self) -> u32471 fn count_ones(self) -> u32 { 472 unreachable!() 473 } 474 475 #[inline] count_zeros(self) -> u32476 fn count_zeros(self) -> u32 { 477 unreachable!() 478 } 479 480 #[inline] leading_zeros(self) -> u32481 fn leading_zeros(self) -> u32 { 482 unreachable!() 483 } 484 485 #[inline] trailing_zeros(self) -> u32486 fn trailing_zeros(self) -> u32 { 487 unreachable!() 488 } 489 490 #[inline] pow(self, _: u32) -> Self491 fn pow(self, _: u32) -> Self { 492 unreachable!() 493 } 494 495 #[inline] checked_add(self, i: Self) -> Option<Self>496 fn checked_add(self, i: Self) -> Option<Self> { 497 Some(self + i) 498 } 499 500 #[inline] checked_sub(self, i: Self) -> Option<Self>501 fn checked_sub(self, i: Self) -> Option<Self> { 502 Some(self - i) 503 } 504 505 #[inline] checked_mul(self, i: Self) -> Option<Self>506 fn checked_mul(self, i: Self) -> Option<Self> { 507 Some(self * i) 508 } 509 510 #[inline] checked_div(self, i: Self) -> Option<Self>511 fn checked_div(self, i: Self) -> Option<Self> { 512 Some(self / i) 513 } 514 515 #[inline] checked_rem(self, i: Self) -> Option<Self>516 fn checked_rem(self, i: Self) -> Option<Self> { 517 Some(self % i) 518 } 519 520 #[inline] checked_neg(self) -> Option<Self>521 fn checked_neg(self) -> Option<Self> { 522 Some(-self) 523 } 524 525 #[inline] checked_shl(self, _: u32) -> Option<Self>526 fn checked_shl(self, _: u32) -> Option<Self> { 527 unimplemented!() 528 } 529 530 #[inline] checked_shr(self, _: u32) -> Option<Self>531 fn checked_shr(self, _: u32) -> Option<Self> { 532 unimplemented!() 533 } 534 535 #[inline] wrapping_add(self, i: Self) -> Self536 fn wrapping_add(self, i: Self) -> Self { 537 self + i 538 } 539 540 #[inline] wrapping_sub(self, i: Self) -> Self541 fn wrapping_sub(self, i: Self) -> Self { 542 self - i 543 } 544 545 #[inline] wrapping_mul(self, i: Self) -> Self546 fn wrapping_mul(self, i: Self) -> Self { 547 self * i 548 } 549 550 #[inline] wrapping_div(self, i: Self) -> Self551 fn wrapping_div(self, i: Self) -> Self { 552 self / i 553 } 554 555 #[inline] wrapping_rem(self, i: Self) -> Self556 fn wrapping_rem(self, i: Self) -> Self { 557 self % i 558 } 559 560 #[inline] wrapping_neg(self) -> Self561 fn wrapping_neg(self) -> Self { 562 -self 563 } 564 565 #[inline] wrapping_shl(self, _: u32) -> Self566 fn wrapping_shl(self, _: u32) -> Self { 567 unimplemented!() 568 } 569 570 #[inline] wrapping_shr(self, _: u32) -> Self571 fn wrapping_shr(self, _: u32) -> Self { 572 unimplemented!() 573 } 574 575 #[inline] overflowing_add(self, i: Self) -> (Self, bool)576 fn overflowing_add(self, i: Self) -> (Self, bool) { 577 (self + i, false) 578 } 579 580 #[inline] overflowing_sub(self, i: Self) -> (Self, bool)581 fn overflowing_sub(self, i: Self) -> (Self, bool) { 582 (self - i, false) 583 } 584 585 #[inline] overflowing_mul(self, i: Self) -> (Self, bool)586 fn overflowing_mul(self, i: Self) -> (Self, bool) { 587 (self * i, false) 588 } 589 590 #[inline] overflowing_div(self, i: Self) -> (Self, bool)591 fn overflowing_div(self, i: Self) -> (Self, bool) { 592 (self / i, false) 593 } 594 595 #[inline] overflowing_rem(self, i: Self) -> (Self, bool)596 fn overflowing_rem(self, i: Self) -> (Self, bool) { 597 (self % i, false) 598 } 599 600 #[inline] overflowing_neg(self) -> (Self, bool)601 fn overflowing_neg(self) -> (Self, bool) { 602 (-self, false) 603 } 604 605 #[inline] overflowing_shl(self, _: u32) -> (Self, bool)606 fn overflowing_shl(self, _: u32) -> (Self, bool) { 607 unimplemented!() 608 } 609 610 #[inline] overflowing_shr(self, _: u32) -> (Self, bool)611 fn overflowing_shr(self, _: u32) -> (Self, bool) { 612 unimplemented!() 613 } 614 615 #[inline] saturating_add(self, i: Self) -> Self616 fn saturating_add(self, i: Self) -> Self { 617 self + i 618 } 619 620 #[inline] saturating_sub(self, i: Self) -> Self621 fn saturating_sub(self, i: Self) -> Self { 622 self - i 623 } 624 625 #[inline] saturating_mul(self, i: Self) -> Self626 fn saturating_mul(self, i: Self) -> Self { 627 self * i 628 } 629 } 630 631 // SIGNED INTEGER 632 633 impl<T: Float> ops::Neg for WrappedFloat<T> { 634 type Output = Self; 635 636 #[inline] neg(self) -> Self637 fn neg(self) -> Self { 638 WrappedFloat { data: -self.data } 639 } 640 } 641 642 impl<T: Float> SignedInteger for WrappedFloat<T> { checked_abs(self) -> Option<Self>643 fn checked_abs(self) -> Option<Self> { 644 Some(self.wrapping_abs()) 645 } 646 wrapping_abs(self) -> Self647 fn wrapping_abs(self) -> Self { 648 WrappedFloat { data: self.data.abs() } 649 } 650 overflowing_abs(self) -> (Self, bool)651 fn overflowing_abs(self) -> (Self, bool) { 652 (self.wrapping_abs(), false) 653 } 654 } 655 656 // TEST 657 // ---- 658 659 #[cfg(test)] 660 mod tests { 661 use super::*; 662 check_integer<T: Integer>(mut x: T)663 fn check_integer<T: Integer>(mut x: T) { 664 // Copy, partialeq, partialord, ord, eq 665 let _ = x; 666 assert!(x > T::ONE); 667 assert!(x != T::ONE); 668 assert_eq!(x.min(T::ONE), T::ONE); 669 assert_eq!(x.max(T::ONE), x); 670 671 // Operations 672 let _ = x + T::ONE; 673 let _ = x - T::ONE; 674 let _ = x * T::ONE; 675 let _ = x / T::ONE; 676 let _ = x % T::ONE; 677 x += T::ONE; 678 x -= T::ONE; 679 x *= T::ONE; 680 x /= T::ONE; 681 x %= T::ONE; 682 683 // Functions 684 assert!(T::ZERO.is_zero()); 685 assert!(!T::ONE.is_zero()); 686 assert!(T::ONE.is_one()); 687 assert!(!T::ZERO.is_one()); 688 689 // As cast 690 let _: u8 = as_cast(x); 691 let _: u16 = as_cast(x); 692 let _: u32 = as_cast(x); 693 let _: u64 = as_cast(x); 694 let _: u128 = as_cast(x); 695 let _: usize = as_cast(x); 696 let _: i8 = as_cast(x); 697 let _: i16 = as_cast(x); 698 let _: i32 = as_cast(x); 699 let _: i64 = as_cast(x); 700 let _: i128 = as_cast(x); 701 let _: isize = as_cast(x); 702 let _: f32 = as_cast(x); 703 let _: f64 = as_cast(x); 704 } 705 check_try_cast_compile<T: Integer>(x: T)706 fn check_try_cast_compile<T: Integer>(x: T) { 707 // Try cast 708 let _: Option<u8> = try_cast(x); 709 let _: Option<u16> = try_cast(x); 710 let _: Option<u32> = try_cast(x); 711 let _: Option<u64> = try_cast(x); 712 let _: Option<u128> = try_cast(x); 713 let _: Option<usize> = try_cast(x); 714 let _: Option<i8> = try_cast(x); 715 let _: Option<i16> = try_cast(x); 716 let _: Option<i32> = try_cast(x); 717 let _: Option<i64> = try_cast(x); 718 let _: Option<i128> = try_cast(x); 719 let _: Option<isize> = try_cast(x); 720 let _: Option<f32> = try_cast(x); 721 let _: Option<f64> = try_cast(x); 722 } 723 724 #[allow(dead_code)] // Compile-only try_cast_test()725 fn try_cast_test() { 726 check_try_cast_compile(WrappedFloat::from_float(65f32)); 727 check_try_cast_compile(WrappedFloat::from_float(65f64)); 728 } 729 730 #[test] integer_test()731 fn integer_test() { 732 check_integer(WrappedFloat::from_float(65f32)); 733 check_integer(WrappedFloat::from_float(65f64)); 734 } 735 } 736