use std::cmp::Ordering;
use std::hash::Hash;
use std::hash::Hasher;
use std::mem;
#[derive(Debug, Copy, Clone)]
pub struct FiniteF64(pub f64);
impl Hash for FiniteF64 {
fn hash<H: Hasher>(&self, state: &mut H) {
let x = self.0;
if x.is_finite() {
let key: u64 = unsafe { mem::transmute(x) };
key.hash(state)
} else {
0.hash(state)
}
}
}
impl PartialEq for FiniteF64 {
fn eq(&self, other: &Self) -> bool {
let x = self.0;
let y = other.0;
if !x.is_nan() {
x.eq(&y)
} else {
y.is_nan()
}
}
}
impl Eq for FiniteF64 {}
impl PartialOrd for FiniteF64 {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let x = self.0;
let y = other.0;
x.partial_cmp(&y)
}
}
impl Ord for FiniteF64 {
fn cmp(&self, other: &Self) -> Ordering {
let x = self.0;
let y = other.0;
match x.partial_cmp(&y) {
Some(ordering) => ordering,
None if x.is_nan() => {
if y.is_nan() { Ordering::Equal } else { Ordering::Less }
},
None if y.is_nan() => {
if x.is_nan() { Ordering::Equal } else { Ordering::Greater }
},
None => {
panic!("Illegal comparison of {} and {}", x, y)
}
}
}
}