Skip to main content

motion_core/
key.rs

1//! Bit-exact float keys for pure authoring caches.
2
3/// An f64 key distinguishing signed zero and all NaN payload bit patterns.
4#[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}