1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#![cfg(not(feature = "no_float"))]
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
fmt,
hash::{Hash, Hasher},
ops::{Deref, DerefMut},
str::FromStr,
};
use num_traits::float::FloatCore as Float;
#[derive(Clone, Copy, PartialEq, PartialOrd)]
pub struct FloatWrapper<F>(F);
impl Hash for FloatWrapper<crate::FLOAT> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.to_ne_bytes().hash(state);
}
}
impl<F: Float> AsRef<F> for FloatWrapper<F> {
#[inline(always)]
#[must_use]
fn as_ref(&self) -> &F {
&self.0
}
}
impl<F: Float> AsMut<F> for FloatWrapper<F> {
#[inline(always)]
#[must_use]
fn as_mut(&mut self) -> &mut F {
&mut self.0
}
}
impl<F: Float> Deref for FloatWrapper<F> {
type Target = F;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<F: Float> DerefMut for FloatWrapper<F> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<F: Float + fmt::Debug> fmt::Debug for FloatWrapper<F> {
#[cold]
#[inline(never)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl<F: Float + fmt::Display + fmt::LowerExp + From<f32>> fmt::Display for FloatWrapper<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let abs = self.0.abs();
if abs.is_zero() {
f.write_str("0.0")
} else if abs > Self::MAX_NATURAL_FLOAT_FOR_DISPLAY.into()
|| abs < Self::MIN_NATURAL_FLOAT_FOR_DISPLAY.into()
{
write!(f, "{:e}", self.0)
} else {
fmt::Display::fmt(&self.0, f)?;
if abs.fract().is_zero() {
f.write_str(".0")?;
}
Ok(())
}
}
}
impl<F: Float> From<F> for FloatWrapper<F> {
#[inline(always)]
fn from(value: F) -> Self {
Self::new(value)
}
}
impl<F: Float + FromStr> FromStr for FloatWrapper<F> {
type Err = <F as FromStr>::Err;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
F::from_str(s).map(Into::into)
}
}
impl<F: Float> FloatWrapper<F> {
pub const MAX_NATURAL_FLOAT_FOR_DISPLAY: f32 = 10_000_000_000_000.0;
pub const MIN_NATURAL_FLOAT_FOR_DISPLAY: f32 = 0.000_000_000_000_1;
#[inline(always)]
#[must_use]
pub const fn new(value: F) -> Self {
Self(value)
}
}