1
0
Fork 0
mirror of https://github.com/sile/hls_m3u8.git synced 2024-05-25 03:38:21 +00:00

impl Ord, Eq and Hash for (U)Float

This commit is contained in:
Luro02 2020-02-16 17:09:40 +01:00
parent b54b17df73
commit d3c238df92
No known key found for this signature in database
GPG key ID: B66FD4F74501A9CF
2 changed files with 98 additions and 0 deletions

View file

@ -1,3 +1,4 @@
use core::cmp::Ordering;
use core::convert::TryFrom;
use core::str::FromStr;
@ -99,6 +100,47 @@ impl PartialEq<f32> for Float {
fn eq(&self, other: &f32) -> bool { &self.0 == other }
}
// In order to implement `Eq` a struct has to satisfy
// the following requirements:
// - reflexive: a == a;
// - symmetric: a == b implies b == a; and
// - transitive: a == b and b == c implies a == c.
//
// The symmetric and transitive parts are already satisfied
// through `PartialEq`. The reflexive part is not satisfied for f32,
// because `f32::NAN` never equals `f32::NAN`. (`assert!(f32::NAN, f32::NAN)`)
//
// It is ensured, that this struct can not be constructed
// with NaN so all of the above requirements are satisfied and therefore Eq can
// be soundly implemented.
impl Eq for Float {}
impl Ord for Float {
#[inline]
#[must_use]
fn cmp(&self, other: &Self) -> Ordering {
if *self < *other {
Ordering::Less
} else if *self == *other {
Ordering::Equal
} else {
Ordering::Greater
}
}
}
#[doc(hidden)]
impl ::core::hash::Hash for Float {
fn hash<H>(&self, state: &mut H)
where
H: ::core::hash::Hasher,
{
// this should be totally fine (definitely not the most
// efficient implementation as this requires an allocation)
state.write(self.to_string().as_bytes())
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -170,4 +212,11 @@ mod tests {
assert!(Float::try_from(::core::f32::NAN).is_err());
assert!(Float::try_from(::core::f32::NEG_INFINITY).is_err());
}
#[test]
fn test_eq() {
struct _AssertEq
where
Float: Eq;
}
}

View file

@ -1,3 +1,4 @@
use core::cmp::Ordering;
use core::convert::TryFrom;
use core::str::FromStr;
@ -110,6 +111,47 @@ impl PartialEq<f32> for UFloat {
fn eq(&self, other: &f32) -> bool { &self.0 == other }
}
// In order to implement `Eq` a struct has to satisfy
// the following requirements:
// - reflexive: a == a;
// - symmetric: a == b implies b == a; and
// - transitive: a == b and b == c implies a == c.
//
// The symmetric and transitive parts are already satisfied
// through `PartialEq`. The reflexive part is not satisfied for f32,
// because `f32::NAN` never equals `f32::NAN`. (`assert!(f32::NAN, f32::NAN)`)
//
// It is ensured, that this struct can not be constructed
// with NaN so all of the above requirements are satisfied and therefore Eq can
// be soundly implemented.
impl Eq for UFloat {}
impl Ord for UFloat {
#[inline]
#[must_use]
fn cmp(&self, other: &Self) -> Ordering {
if *self < *other {
Ordering::Less
} else if *self == *other {
Ordering::Equal
} else {
Ordering::Greater
}
}
}
#[doc(hidden)]
impl ::core::hash::Hash for UFloat {
fn hash<H>(&self, state: &mut H)
where
H: ::core::hash::Hasher,
{
// this should be totally fine (definitely not the most
// efficient implementation as this requires an allocation)
state.write(self.to_string().as_bytes())
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -179,4 +221,11 @@ mod tests {
assert!(UFloat::try_from(::core::f32::NAN).is_err());
assert!(UFloat::try_from(::core::f32::NEG_INFINITY).is_err());
}
#[test]
fn test_eq() {
struct _AssertEq
where
UFloat: Eq;
}
}