Diffstat (limited to 'src/algebraic.rs')
| -rw-r--r-- | src/algebraic.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/algebraic.rs b/src/algebraic.rs new file mode 100644 index 0000000..a7d6082 --- /dev/null +++ b/src/algebraic.rs @@ -0,0 +1,63 @@ +//! Provides the algebraic math trait and macro. +/// Trait for Algebraic-ly math'd floats. Try to use [`algebraic::math`](`math`). +pub trait Float: Copy { + fn add(self, other: Self) -> Self; + fn sub(self, other: Self) -> Self; + fn mul(self, other: Self) -> Self; + fn div(self, other: Self) -> Self; + fn rem(self, other: Self) -> Self; + + fn eq(self, other: Self) -> bool; + fn lt(self, other: Self) -> bool; + fn le(self, other: Self) -> bool; + fn ne(self, other: Self) -> bool; + fn ge(self, other: Self) -> bool; + fn gt(self, other: Self) -> bool; + + fn deref(&self) -> Self { + *self + } + fn neg(self) -> Self; +} +use std::intrinsics::*; +macro_rules! imp { + ($this:ty) => { +#[rustfmt::skip] +impl Float for $this { + fn add(self, other: Self) -> Self { fadd_algebraic(self, other) } + fn sub(self, other: Self) -> Self { fsub_algebraic(self, other) } + fn mul(self, other: Self) -> Self { fmul_algebraic(self, other) } + fn div(self, other: Self) -> Self { fdiv_algebraic(self, other) } + fn rem(self, other: Self) -> Self { frem_algebraic(self, other) } + + fn eq(self, other: Self) -> bool { self == other } + fn lt(self, other: Self) -> bool { self < other } + fn le(self, other: Self) -> bool { self <= other } + fn ne(self, other: Self) -> bool { self != other } + fn ge(self, other: Self) -> bool { self >= other } + fn gt(self, other: Self) -> bool { self > other } + + fn deref(&self) -> Self { *self } + fn neg(self) -> Self { -self } +} + }; +} +imp!(f32); +imp!(f64); + +/// Changes all the math to algebraic float math. See [`fadd_algebraic`]. +/// +/// This allows automatic vectorization of float math easier for the compiler, among other things. +/// If you intend to create a function in this, first import [`lower::algebraic::Float`](crate::algebraic::Float), use [`lower::math`](crate::math). +/// +/// This would lower `a + b + c + d` to `alge_add(alge_add(alge_add(a, b), c), d)` (which could be organized by the compiler into `(a + b) + (c + d)` if it chooses) +#[macro_export] +#[doc(hidden)] +macro_rules! algebraic { + ($($x:tt)+) => {{ + use $crate::algebraic::Float as _; + lower_macros::math! { $($x)+ } + }} +} +#[doc(inline)] +pub use algebraic as math; |