diff --git a/Cargo.toml b/Cargo.toml index 60ca258..7a8234d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,9 +13,20 @@ keywords = ["finite", "float", "hash", "nan", "ord"] travis-ci = { repository = "olson-sean-k/decorum" } [features] -default = ["serialize-serde", "std"] +default = ["approx", "serialize-serde", "std"] serialize-serde = ["serde", "serde_derive"] -std = ["num-traits/std"] +std = ["approx/std", "num-traits/std"] + +[dependencies.approx] +version = "^0.3.0" +default-features = false +features = [] +optional = true + +[dependencies.num-traits] +version = "^0.2.4" +default-features = false +features = [] [dependencies.serde] version = "1.0" @@ -27,10 +38,5 @@ version = "1.0" default-features = false optional = true -[dependencies.num-traits] -version = "^0.2.4" -default-features = false -features = [] - [dev-dependencies] num = "^0.2.0" diff --git a/src/proxy.rs b/src/proxy.rs index a31ffc2..d9d0f6e 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -1,3 +1,4 @@ +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; use core::cmp::Ordering; use core::fmt::{self, Display, Formatter, LowerExp, UpperExp}; use core::hash::{Hash, Hasher}; @@ -212,7 +213,7 @@ where // It is not possible to implement `From` for proxies in a generic way, because // the `FloatConstraint` types `T` and `U` may be the same and conflict with -// the reflexive implementation in core. A similar problem prevents +// the reflexive implementation in `core`. A similar problem prevents // implementing `From` over a type `T: Float`. impl From> for Ordered @@ -270,6 +271,23 @@ where } } +impl AbsDiffEq for ConstrainedFloat +where + T: AbsDiffEq + Float + Primitive, + P: FloatConstraint + ConstraintEq, +{ + type Epsilon = Self; + + fn default_epsilon() -> Self::Epsilon { + Self::from_inner(T::default_epsilon()) + } + + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.into_inner() + .abs_diff_eq(&other.into_inner(), epsilon.into_inner()) + } +} + impl Add for ConstrainedFloat where T: Float + Primitive, @@ -1273,6 +1291,29 @@ where } } +impl RelativeEq for ConstrainedFloat +where + T: Float + Primitive + RelativeEq, + P: FloatConstraint + ConstraintEq, +{ + fn default_max_relative() -> Self::Epsilon { + Self::from_inner(T::default_max_relative()) + } + + fn relative_eq( + &self, + other: &Self, + epsilon: Self::Epsilon, + max_relative: Self::Epsilon, + ) -> bool { + self.into_inner().relative_eq( + &other.into_inner(), + epsilon.into_inner(), + max_relative.into_inner(), + ) + } +} + impl Rem for ConstrainedFloat where T: Float + Primitive, @@ -1468,6 +1509,21 @@ where } } +impl UlpsEq for ConstrainedFloat +where + T: Float + Primitive + UlpsEq, + P: FloatConstraint + ConstraintEq, +{ + fn default_max_ulps() -> u32 { + T::default_max_ulps() + } + + fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { + self.into_inner() + .ulps_eq(&other.into_inner(), epsilon.into_inner(), max_ulps) + } +} + impl UpperExp for ConstrainedFloat where T: Float + UpperExp + Primitive,