typed_floats/types/impls/
eq.rs
1use crate::{
2 Negative, NegativeFinite, NonNaN, NonNaNFinite, NonZeroNonNaN, NonZeroNonNaNFinite, Positive,
3 PositiveFinite, StrictlyNegative, StrictlyNegativeFinite, StrictlyPositive,
4 StrictlyPositiveFinite,
5};
6
7macro_rules! impl_eq_self {
10 ($type:ident) => {
11 impl Eq for $type<f32> {}
12 impl Eq for $type<f64> {}
13
14 impl PartialEq for $type<f32> {
15 #[inline]
16 fn eq(&self, other: &Self) -> bool {
17 self.0 == other.0
18 }
19 }
20
21 impl PartialEq for $type<f64> {
22 #[inline]
23 fn eq(&self, other: &Self) -> bool {
24 self.0 == other.0
25 }
26 }
27 };
28}
29
30macro_rules! impl_eq_base {
31 ($type:ident) => {
32 impl PartialEq<$type<f32>> for f32 {
33 #[inline]
34 fn eq(&self, other: &$type<f32>) -> bool {
35 *self == other.0
36 }
37 }
38
39 impl PartialEq<$type<f64>> for f64 {
40 #[inline]
41 fn eq(&self, other: &$type<f64>) -> bool {
42 *self == other.0
43 }
44 }
45
46 impl PartialEq<f32> for $type<f32> {
47 #[inline]
48 fn eq(&self, other: &f32) -> bool {
49 self.0 == *other
50 }
51 }
52
53 impl PartialEq<f64> for $type<f64> {
54 #[inline]
55 fn eq(&self, other: &f64) -> bool {
56 self.0 == *other
57 }
58 }
59 };
60}
61
62macro_rules! impl_fast_eq_self {
64 ($type:ident) => {
65 impl Eq for $type<f32> {}
66 impl Eq for $type<f64> {}
67
68 impl PartialEq for $type<f32> {
69 #[inline]
70 fn eq(&self, other: &Self) -> bool {
71 self.0.to_bits() == other.0.to_bits()
72 }
73 }
74
75 impl PartialEq for $type<f64> {
76 #[inline]
77 fn eq(&self, other: &Self) -> bool {
78 self.0.to_bits() == other.0.to_bits()
79 }
80 }
81 };
82}
83
84macro_rules! impl_fast_eq_base {
86 ($type:ident) => {
87 impl PartialEq<$type<f32>> for f32 {
88 #[inline]
89 fn eq(&self, other: &$type<f32>) -> bool {
90 self.to_bits() == (&other.0).to_bits()
91 }
92 }
93
94 impl PartialEq<$type<f64>> for f64 {
95 #[inline]
96 fn eq(&self, other: &$type<f64>) -> bool {
97 self.to_bits() == (&other.0).to_bits()
98 }
99 }
100
101 impl PartialEq<f32> for $type<f32> {
102 #[inline]
103 fn eq(&self, other: &f32) -> bool {
104 (&self.0).to_bits() == other.to_bits()
105 }
106 }
107
108 impl PartialEq<f64> for $type<f64> {
109 #[inline]
110 fn eq(&self, other: &f64) -> bool {
111 (&self.0).to_bits() == other.to_bits()
112 }
113 }
114 };
115}
116
117impl_eq_base!(NonNaN);
118impl_eq_self!(NonNaN);
119
120impl_fast_eq_base!(NonZeroNonNaN);
121impl_fast_eq_self!(NonZeroNonNaN);
122
123impl_eq_base!(NonNaNFinite);
124impl_eq_self!(NonNaNFinite);
125
126impl_fast_eq_base!(NonZeroNonNaNFinite);
127impl_fast_eq_self!(NonZeroNonNaNFinite);
128
129impl_eq_base!(Positive);
130impl_fast_eq_self!(Positive);
131
132impl_eq_base!(Negative);
133impl_fast_eq_self!(Negative);
134
135impl_eq_base!(PositiveFinite);
136impl_fast_eq_self!(PositiveFinite);
137
138impl_eq_base!(NegativeFinite);
139impl_fast_eq_self!(NegativeFinite);
140
141impl_fast_eq_base!(StrictlyPositive);
142impl_fast_eq_self!(StrictlyPositive);
143
144impl_fast_eq_base!(StrictlyNegative);
145impl_fast_eq_self!(StrictlyNegative);
146
147impl_fast_eq_base!(StrictlyPositiveFinite);
148impl_fast_eq_self!(StrictlyPositiveFinite);
149
150impl_fast_eq_base!(StrictlyNegativeFinite);
151impl_fast_eq_self!(StrictlyNegativeFinite);
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156
157 macro_rules! impl_eq_test {
158 ($test:ident, $type:ident) => {
159 #[test]
160 fn $test() {
161 let values_f32 = crate::tf32::get_test_values();
162 let nan = f32::NAN;
163 for &value in &values_f32 {
164 if let Ok(t) = $type::<f32>::new(value) {
165 assert_eq!(t, t);
166 assert_eq!(t, value);
167 assert_eq!(value, t);
168
169 assert_ne!(t, nan);
170 assert_ne!(nan, t);
171
172 if value == 0.0 {
173 assert_eq!(t, -value);
174 assert_eq!(-value, t);
175 assert_eq!(t, 0.0);
176 assert_eq!(t, -0.0);
177 } else {
178 assert_ne!(t, -value);
179 assert_ne!(-value, t);
180 assert_ne!(t, 0.0);
181 assert_ne!(t, -0.0);
182 }
183
184 for &other in &values_f32 {
185 if let Ok(other_t) = $type::<f32>::new(other) {
186 if other == value {
187 assert_eq!(t, other_t);
188 assert_eq!(other_t, t);
189 assert_eq!(t, other);
190 assert_eq!(other, t);
191 assert_eq!(value, other);
192 assert_eq!(other, value);
193 } else {
194 assert_ne!(t, other_t);
195 assert_ne!(other_t, t);
196 assert_ne!(t, other);
197 assert_ne!(other, t);
198 assert_ne!(value, other);
199 assert_ne!(other, value);
200 }
201 }
202 }
203 }
204 }
205
206 let nan = f64::NAN;
207 let values_f64 = crate::tf64::get_test_values();
208 for &value in &values_f64 {
209 if let Ok(t) = $type::<f64>::new(value) {
210 assert_eq!(t, t);
211 assert_eq!(t, value);
212 assert_eq!(value, t);
213
214 assert_ne!(t, nan);
215 assert_ne!(nan, t);
216
217 if value == 0.0 {
218 assert_eq!(t, -value);
219 assert_eq!(-value, t);
220 assert_eq!(t, 0.0);
221 assert_eq!(t, -0.0);
222 } else {
223 assert_ne!(t, -value);
224 assert_ne!(-value, t);
225 assert_ne!(t, 0.0);
226 assert_ne!(t, -0.0);
227 }
228
229 for &other in &values_f64 {
230 if let Ok(other_t) = $type::<f64>::new(other) {
231 if other == value {
232 assert_eq!(t, other_t);
233 assert_eq!(other_t, t);
234 assert_eq!(t, other);
235 assert_eq!(other, t);
236 } else {
237 assert_ne!(t, other_t);
238 assert_ne!(other_t, t);
239 assert_ne!(t, other);
240 assert_ne!(other, t);
241 }
242 }
243 }
244 }
245 }
246 }
247 };
248 }
249
250 impl_eq_test!(non_nan, NonNaN);
251 impl_eq_test!(non_nan_finite, NonNaNFinite);
252 impl_eq_test!(non_zero_non_nan, NonZeroNonNaN);
253 impl_eq_test!(non_zero_non_nan_finite, NonZeroNonNaNFinite);
254 impl_eq_test!(positive, Positive);
255 impl_eq_test!(negative, Negative);
256 impl_eq_test!(positive_finite, PositiveFinite);
257 impl_eq_test!(negative_finite, NegativeFinite);
258 impl_eq_test!(strictly_positive, StrictlyPositive);
259 impl_eq_test!(strictly_negative, StrictlyNegative);
260 impl_eq_test!(strictly_positive_finite, StrictlyPositiveFinite);
261 impl_eq_test!(strictly_negative_finite, StrictlyNegativeFinite);
262}