1#[derive(Clone, Copy, Debug)]
5pub struct F64(pub f64);
6
7impl PartialEq for F64 {
8 fn eq(&self, other: &Self) -> bool {
9 self.0.to_bits() == other.0.to_bits()
10 }
11}
12
13impl Eq for F64 {}
14
15impl std::hash::Hash for F64 {
16 fn hash<Hasher: std::hash::Hasher>(&self, state: &mut Hasher) {
17 state.write_u64(self.0.to_bits());
18 }
19}
20
21impl PartialOrd for F64 {
22 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
23 Some(self.cmp(other))
24 }
25}
26
27impl Ord for F64 {
28 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
29 self.0.total_cmp(&other.0)
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 #[test]
38 fn keys_distinguish_signed_zero_and_nan_payloads() {
39 let values = [
40 F64(0.0),
41 F64(-0.0),
42 F64(f64::NAN),
43 F64(f64::from_bits(f64::NAN.to_bits() + 1)),
44 ];
45 assert_eq!(
46 values
47 .into_iter()
48 .collect::<std::collections::HashSet<_>>()
49 .len(),
50 4
51 );
52 assert_eq!(
53 values
54 .into_iter()
55 .collect::<std::collections::BTreeSet<_>>()
56 .len(),
57 4
58 );
59 }
60}