use core::cmp::Ordering;
use core::cmp::{Eq, Ord, PartialEq, PartialOrd};
use core::hash::{Hash, Hasher};
use core::option::{Option, Option::Some};
pub struct OrderedFloat(pub f64);
const CANONICAL_NAN_BITS: u64 = 0x7ff8000000000000u64;
#[inline(always)]
fn canonicalize_signed_zero(x: f64) -> f64 {
x + 0.0
}
impl Hash for OrderedFloat {
fn hash<H: Hasher>(&self, state: &mut H) {
let bits = if self.0.is_nan() {
CANONICAL_NAN_BITS
} else {
canonicalize_signed_zero(self.0).to_bits()
};
bits.hash(state)
}
}
impl Eq for OrderedFloat {}
impl PartialEq for OrderedFloat {
#[inline]
fn eq(&self, other: &OrderedFloat) -> bool {
if self.0.is_nan() {
other.0.is_nan()
} else {
self.0 == other.0
}
}
}
impl PartialOrd for OrderedFloat {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
#[inline]
fn lt(&self, other: &Self) -> bool {
!self.ge(other)
}
#[inline]
fn le(&self, other: &Self) -> bool {
other.ge(self)
}
#[inline]
fn gt(&self, other: &Self) -> bool {
!other.ge(self)
}
#[inline]
fn ge(&self, other: &Self) -> bool {
self.0.is_nan() | (self.0 >= other.0)
}
}
impl Ord for OrderedFloat {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
#[allow(clippy::comparison_chain)]
if self < other {
Ordering::Less
} else if self > other {
Ordering::Greater
} else {
Ordering::Equal
}
}
}