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