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