diff --git a/Cargo.lock b/Cargo.lock index 13f27f1..7958e4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,15 +49,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "approx" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" -dependencies = [ - "num-traits", -] - [[package]] name = "approx" version = "0.5.1" @@ -371,7 +362,7 @@ dependencies = [ name = "coremem_types" version = "0.1.0" dependencies = [ - "decorum", + "serde", ] [[package]] @@ -556,18 +547,6 @@ dependencies = [ "parking_lot_core 0.9.3", ] -[[package]] -name = "decorum" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "281759d3c8a14f5c3f0c49363be56810fcd7f910422f97f2db850c2920fde5cf" -dependencies = [ - "approx 0.3.2", - "num-traits", - "serde", - "serde_derive", -] - [[package]] name = "deflate" version = "1.0.0" @@ -1005,7 +984,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aee993351d466301a29655d628bfc6f5a35a0d062b6160ca0808f425805fd7" dependencies = [ - "approx 0.5.1", + "approx", "conv", "image", "itertools", @@ -1289,7 +1268,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb2d0de08694bed883320212c18ee3008576bfe8c306f4c3c4a58b4876998be" dependencies = [ - "approx 0.5.1", + "approx", "matrixmultiply", "num-complex", "num-rational", @@ -2006,7 +1985,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13a2609e876d4f77f6ab7ff5254fc39b4f1927ba8e6db3d18be7c32534d3725e" dependencies = [ - "approx 0.5.1", + "approx", "num-complex", "num-traits", "paste", diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 1621dc2..f016f66 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -5,4 +5,4 @@ authors = ["Colin "] edition = "2021" [dependencies] -decorum = "0.3" # MIT +serde = "1.0" # MIT or Apache 2.0 diff --git a/crates/types/src/real.rs b/crates/types/src/real.rs index b6db969..859752f 100644 --- a/crates/types/src/real.rs +++ b/crates/types/src/real.rs @@ -1,14 +1,12 @@ -use std::fmt; +use core::fmt; use core::ops::{ Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign, }; use core::cmp::{Ordering, PartialOrd}; - -// finite. non-nan, non-inf -pub type R32 = decorum::R32; -pub type R64 = decorum::R64; +use serde::{Deserialize, Serialize}; pub trait ToFloat { + // TODO: make these by-value fn to_f32(&self) -> f32 { self.to_f64() as _ } @@ -58,10 +56,12 @@ pub trait Real: Self::from_primitive(u) } + // TODO: make this by-value fn cast(&self) -> R { R::from_primitive(*self) } + fn is_finite(self) -> bool; fn floor(self) -> Self; fn ceil(self) -> Self; fn round(self) -> Self; @@ -154,6 +154,9 @@ impl Real for f32 { fn from_f32(f: f32) -> Self { f } + fn is_finite(self) -> bool { + f32::is_finite(self) + } fn floor(self) -> Self { f32::floor(self) } @@ -190,6 +193,9 @@ impl Real for f64 { fn from_f64(f: f64) -> Self { f } + fn is_finite(self) -> bool { + f64::is_finite(self) + } fn floor(self) -> Self { f64::floor(self) } @@ -216,80 +222,125 @@ impl Real for f64 { } } -impl ToFloat for R32 { +#[derive(Default, Copy, Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)] +pub struct Finite(T); + +pub type R32 = Finite; +pub type R64 = Finite; + +impl Finite { + fn new(inner: T) -> Self { + assert!(inner.is_finite(), "{:} is not finite", inner); + Self(inner) + } +} + +impl fmt::Display for Finite { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::LowerExp for Finite { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Neg for Finite { + type Output = Self; + fn neg(self) -> Self { + Self::new(self.0.neg()) + } +} + +impl AddAssign for Finite { + fn add_assign(&mut self, other: Self) { + *self = Self::new(self.0.add(other.0)) + } +} +impl SubAssign for Finite { + fn sub_assign(&mut self, other: Self) { + *self = Self::new(self.0.sub(other.0)) + } +} +impl MulAssign for Finite { + fn mul_assign(&mut self, other: Self) { + *self = Self::new(self.0.mul(other.0)) + } +} +impl DivAssign for Finite { + fn div_assign(&mut self, other: Self) { + *self = Self::new(self.0.div(other.0)) + } +} + +impl Add for Finite { + type Output = Self; + fn add(self, other: Self) -> Self { + Self::new(self.0.add(other.0)) + } +} +impl Sub for Finite { + type Output = Self; + fn sub(self, other: Self) -> Self { + Self::new(self.0.sub(other.0)) + } +} +impl Mul for Finite { + type Output = Self; + fn mul(self, other: Self) -> Self { + Self::new(self.0.mul(other.0)) + } +} +impl Div for Finite { + type Output = Self; + fn div(self, other: Self) -> Self { + Self::new(self.0.div(other.0)) + } +} + + +impl ToFloat for Finite { fn to_f32(&self) -> f32 { - self.into_inner() + self.0.to_f32() } -} - -impl Real for R32 { - fn from_primitive(p: P) -> Self { - Self::from_f32(p.to_f32()) - } - fn from_f32(f: f32) -> Self { - Self::from_inner(f) - } - fn floor(self) -> Self { - Self::from_primitive(self.into_inner().floor()) - } - fn ceil(self) -> Self { - Self::from_primitive(self.into_inner().ceil()) - } - fn round(self) -> Self { - Self::from_primitive(self.into_inner().round()) - } - fn exp(self) -> Self { - Self::from_primitive(self.into_inner().exp()) - } - fn powf(self, p: Self) -> Self { - Self::from_primitive(self.into_inner().powf(p.into_inner())) - } - fn sqrt(self) -> Self { - Self::from_primitive(self.into_inner().sqrt()) - } - fn sin_cos(self) -> (Self, Self) { - let (s, c) = self.into_inner().sin_cos(); - (Self::from_primitive(s), Self::from_primitive(c)) - } - fn atan2(self, p: Self) -> Self { - Self::from_primitive(self.into_inner().atan2(p.into_inner())) - } -} - -impl ToFloat for R64 { fn to_f64(&self) -> f64 { - self.into_inner() + self.0.to_f64() } } -impl Real for R64 { - fn from_f64(f: f64) -> Self { - Self::from_inner(f) +impl Real for Finite { + fn from_primitive(p: P) -> Self { + Self::new(T::from_primitive(p)) + } + fn is_finite(self) -> bool { + true } fn floor(self) -> Self { - Self::from_primitive(self.into_inner().floor()) + Self::new(self.0.floor()) } fn ceil(self) -> Self { - Self::from_primitive(self.into_inner().ceil()) + Self::new(self.0.ceil()) } fn round(self) -> Self { - Self::from_primitive(self.into_inner().round()) + Self::new(self.0.round()) } fn exp(self) -> Self { - Self::from_primitive(self.into_inner().exp()) - } - fn powf(self, p: Self) -> Self { - Self::from_primitive(self.into_inner().powf(p.into_inner())) + Self::new(self.0.exp()) } fn sqrt(self) -> Self { - Self::from_primitive(self.into_inner().sqrt()) + Self::new(self.0.sqrt()) } - fn sin_cos(self) -> (Self, Self) { - let (s, c) = self.into_inner().sin_cos(); - (Self::from_primitive(s), Self::from_primitive(c)) + fn powf(self, p: Self) -> Self { + Self::new(self.0.powf(p.0)) } fn atan2(self, p: Self) -> Self { - Self::from_primitive(self.into_inner().atan2(p.into_inner())) + Self::new(self.0.atan2(p.0)) + } + fn sin_cos(self) -> (Self, Self) { + let (s, c) = self.0.sin_cos(); + (Self::new(s), Self::new(c)) } }