dvcompute_dist/simulation/utils/
finite_f64.rs1use std::cmp::Ordering;
8use std::hash::Hash;
9use std::hash::Hasher;
10use std::mem;
11
12#[derive(Debug, Copy, Clone)]
14pub struct FiniteF64(pub f64);
15
16impl Hash for FiniteF64 {
17
18 fn hash<H: Hasher>(&self, state: &mut H) {
19
20 let x = self.0;
21
22 if x.is_finite() {
23 let key: u64 = unsafe { mem::transmute(x) };
24 key.hash(state)
25 } else {
26 0.hash(state)
27 }
28 }
29}
30
31impl PartialEq for FiniteF64 {
32
33 fn eq(&self, other: &Self) -> bool {
34
35 let x = self.0;
36 let y = other.0;
37
38 if !x.is_nan() {
39 x.eq(&y)
40 } else {
41 y.is_nan()
43 }
44 }
45}
46
47impl Eq for FiniteF64 {}
48
49impl PartialOrd for FiniteF64 {
50
51 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
52
53 let x = self.0;
54 let y = other.0;
55
56 x.partial_cmp(&y)
57 }
58}
59
60impl Ord for FiniteF64 {
61
62 fn cmp(&self, other: &Self) -> Ordering {
63
64 let x = self.0;
65 let y = other.0;
66
67 match x.partial_cmp(&y) {
68 Some(ordering) => ordering,
69 None if x.is_nan() => {
70 if y.is_nan() { Ordering::Equal } else { Ordering::Less }
71 },
72 None if y.is_nan() => {
73 if x.is_nan() { Ordering::Equal } else { Ordering::Greater }
74 },
75 None => {
76 panic!("Illegal comparison of {} and {}", x, y)
78 }
79 }
80 }
81}