From c848562fcff82e3a05c2066f9bc0406fdb97bc6c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 27 Feb 2018 14:31:09 -0800 Subject: [PATCH] Use forwarding macros to implement Float and Real --- src/float.rs | 289 +++++++++----------------------------------------- src/lib.rs | 3 + src/macros.rs | 25 +++++ src/real.rs | 188 +++++++++----------------------- 4 files changed, 127 insertions(+), 378 deletions(-) create mode 100644 src/macros.rs diff --git a/src/float.rs b/src/float.rs index 5ca80d2..d09bef7 100644 --- a/src/float.rs +++ b/src/float.rs @@ -1197,255 +1197,66 @@ macro_rules! float_impl { ::std::$T::MAX } - #[inline] - fn is_nan(self) -> bool { - <$T>::is_nan(self) - } - - #[inline] - fn is_infinite(self) -> bool { - <$T>::is_infinite(self) - } - - #[inline] - fn is_finite(self) -> bool { - <$T>::is_finite(self) - } - - #[inline] - fn is_normal(self) -> bool { - <$T>::is_normal(self) - } - - #[inline] - fn classify(self) -> FpCategory { - <$T>::classify(self) - } - - #[inline] - fn floor(self) -> Self { - <$T>::floor(self) - } - - #[inline] - fn ceil(self) -> Self { - <$T>::ceil(self) - } - - #[inline] - fn round(self) -> Self { - <$T>::round(self) - } - - #[inline] - fn trunc(self) -> Self { - <$T>::trunc(self) - } - - #[inline] - fn fract(self) -> Self { - <$T>::fract(self) - } - - #[inline] - fn abs(self) -> Self { - <$T>::abs(self) - } - - #[inline] - fn signum(self) -> Self { - <$T>::signum(self) - } - - #[inline] - fn is_sign_positive(self) -> bool { - <$T>::is_sign_positive(self) - } - - #[inline] - fn is_sign_negative(self) -> bool { - <$T>::is_sign_negative(self) - } - - #[inline] - fn mul_add(self, a: Self, b: Self) -> Self { - <$T>::mul_add(self, a, b) - } - - #[inline] - fn recip(self) -> Self { - <$T>::recip(self) - } - - #[inline] - fn powi(self, n: i32) -> Self { - <$T>::powi(self, n) - } - - #[inline] - fn powf(self, n: Self) -> Self { - <$T>::powf(self, n) - } - - #[inline] - fn sqrt(self) -> Self { - <$T>::sqrt(self) - } - - #[inline] - fn exp(self) -> Self { - <$T>::exp(self) - } - - #[inline] - fn exp2(self) -> Self { - <$T>::exp2(self) - } - - #[inline] - fn ln(self) -> Self { - <$T>::ln(self) - } - - #[inline] - fn log(self, base: Self) -> Self { - <$T>::log(self, base) - } - - #[inline] - fn log2(self) -> Self { - <$T>::log2(self) - } - - #[inline] - fn log10(self) -> Self { - <$T>::log10(self) - } - - #[inline] - fn to_degrees(self) -> Self { - // NB: `f32` didn't stabilize this until 1.7 - // <$T>::to_degrees(self) - self * (180. / ::std::$T::consts::PI) - } - - #[inline] - fn to_radians(self) -> Self { - // NB: `f32` didn't stabilize this until 1.7 - // <$T>::to_radians(self) - self * (::std::$T::consts::PI / 180.) - } - - #[inline] - fn max(self, other: Self) -> Self { - <$T>::max(self, other) - } - - #[inline] - fn min(self, other: Self) -> Self { - <$T>::min(self, other) - } - #[inline] #[allow(deprecated)] fn abs_sub(self, other: Self) -> Self { <$T>::abs_sub(self, other) } - #[inline] - fn cbrt(self) -> Self { - <$T>::cbrt(self) - } - - #[inline] - fn hypot(self, other: Self) -> Self { - <$T>::hypot(self, other) - } - - #[inline] - fn sin(self) -> Self { - <$T>::sin(self) - } - - #[inline] - fn cos(self) -> Self { - <$T>::cos(self) - } - - #[inline] - fn tan(self) -> Self { - <$T>::tan(self) - } - - #[inline] - fn asin(self) -> Self { - <$T>::asin(self) - } - - #[inline] - fn acos(self) -> Self { - <$T>::acos(self) - } - - #[inline] - fn atan(self) -> Self { - <$T>::atan(self) - } - - #[inline] - fn atan2(self, other: Self) -> Self { - <$T>::atan2(self, other) - } - - #[inline] - fn sin_cos(self) -> (Self, Self) { - <$T>::sin_cos(self) - } - - #[inline] - fn exp_m1(self) -> Self { - <$T>::exp_m1(self) - } - - #[inline] - fn ln_1p(self) -> Self { - <$T>::ln_1p(self) - } - - #[inline] - fn sinh(self) -> Self { - <$T>::sinh(self) - } - - #[inline] - fn cosh(self) -> Self { - <$T>::cosh(self) - } - - #[inline] - fn tanh(self) -> Self { - <$T>::tanh(self) - } - - #[inline] - fn asinh(self) -> Self { - <$T>::asinh(self) - } - - #[inline] - fn acosh(self) -> Self { - <$T>::acosh(self) - } - - #[inline] - fn atanh(self) -> Self { - <$T>::atanh(self) - } - #[inline] fn integer_decode(self) -> (u64, i16, i8) { $decode(self) } + + forward! { + Self::is_nan(self) -> bool; + Self::is_infinite(self) -> bool; + Self::is_finite(self) -> bool; + Self::is_normal(self) -> bool; + Self::classify(self) -> FpCategory; + Self::floor(self) -> Self; + Self::ceil(self) -> Self; + Self::round(self) -> Self; + Self::trunc(self) -> Self; + Self::fract(self) -> Self; + Self::abs(self) -> Self; + Self::signum(self) -> Self; + Self::is_sign_positive(self) -> bool; + Self::is_sign_negative(self) -> bool; + Self::mul_add(self, a: Self, b: Self) -> Self; + Self::recip(self) -> Self; + Self::powi(self, n: i32) -> Self; + Self::powf(self, n: Self) -> Self; + Self::sqrt(self) -> Self; + Self::exp(self) -> Self; + Self::exp2(self) -> Self; + Self::ln(self) -> Self; + Self::log(self, base: Self) -> Self; + Self::log2(self) -> Self; + Self::log10(self) -> Self; + Self::to_degrees(self) -> Self; + Self::to_radians(self) -> Self; + Self::max(self, other: Self) -> Self; + Self::min(self, other: Self) -> Self; + Self::cbrt(self) -> Self; + Self::hypot(self, other: Self) -> Self; + Self::sin(self) -> Self; + Self::cos(self) -> Self; + Self::tan(self) -> Self; + Self::asin(self) -> Self; + Self::acos(self) -> Self; + Self::atan(self) -> Self; + Self::atan2(self, other: Self) -> Self; + Self::sin_cos(self) -> (Self, Self); + Self::exp_m1(self) -> Self; + Self::ln_1p(self) -> Self; + Self::sinh(self) -> Self; + Self::cosh(self) -> Self; + Self::tanh(self) -> Self; + Self::asinh(self) -> Self; + Self::acosh(self) -> Self; + Self::atanh(self) -> Self; + } } ) } diff --git a/src/lib.rs b/src/lib.rs index 14bb3d3..3e1c80c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,9 @@ pub use cast::{AsPrimitive, FromPrimitive, ToPrimitive, NumCast, cast}; pub use int::PrimInt; pub use pow::{Pow, pow, checked_pow}; +#[macro_use] +mod macros; + pub mod identities; pub mod sign; pub mod ops; diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..8c7a6f8 --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,25 @@ + +/// Forward a method to an inherent method or a base trait method. +macro_rules! forward { + ($( Self :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*) + => {$( + #[inline] + fn $method(self $( , $arg : $ty )* ) -> $ret { + Self::$method(self $( , $arg )* ) + } + )*}; + ($( $base:ident :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*) + => {$( + #[inline] + fn $method(self $( , $arg : $ty )* ) -> $ret { + ::$method(self $( , $arg )* ) + } + )*}; + ($( $base:ident :: $method:ident ( $( $arg:ident : $ty:ty ),* ) -> $ret:ty ; )*) + => {$( + #[inline] + fn $method( $( $arg : $ty ),* ) -> $ret { + ::$method( $( $arg ),* ) + } + )*} +} diff --git a/src/real.rs b/src/real.rs index ab29d45..fb6714a 100644 --- a/src/real.rs +++ b/src/real.rs @@ -782,145 +782,55 @@ pub trait Real } impl Real for T { - fn min_value() -> Self { - Self::min_value() + forward! { + Float::min_value() -> Self; + Float::min_positive_value() -> Self; + Float::epsilon() -> Self; + Float::max_value() -> Self; } - fn min_positive_value() -> Self { - Self::min_positive_value() - } - fn epsilon() -> Self { - Self::epsilon() - } - fn max_value() -> Self { - Self::max_value() - } - fn floor(self) -> Self { - self.floor() - } - fn ceil(self) -> Self { - self.ceil() - } - fn round(self) -> Self { - self.round() - } - fn trunc(self) -> Self { - self.trunc() - } - fn fract(self) -> Self { - self.fract() - } - fn abs(self) -> Self { - self.abs() - } - fn signum(self) -> Self { - self.signum() - } - fn is_sign_positive(self) -> bool { - self.is_sign_positive() - } - fn is_sign_negative(self) -> bool { - self.is_sign_negative() - } - fn mul_add(self, a: Self, b: Self) -> Self { - self.mul_add(a, b) - } - fn recip(self) -> Self { - self.recip() - } - fn powi(self, n: i32) -> Self { - self.powi(n) - } - fn powf(self, n: Self) -> Self { - self.powf(n) - } - fn sqrt(self) -> Self { - self.sqrt() - } - fn exp(self) -> Self { - self.exp() - } - fn exp2(self) -> Self { - self.exp2() - } - fn ln(self) -> Self { - self.ln() - } - fn log(self, base: Self) -> Self { - self.log(base) - } - fn log2(self) -> Self { - self.log2() - } - fn log10(self) -> Self { - self.log10() - } - fn to_degrees(self) -> Self { - self.to_degrees() - } - fn to_radians(self) -> Self { - self.to_radians() - } - fn max(self, other: Self) -> Self { - self.max(other) - } - fn min(self, other: Self) -> Self { - self.min(other) - } - fn abs_sub(self, other: Self) -> Self { - self.abs_sub(other) - } - fn cbrt(self) -> Self { - self.cbrt() - } - fn hypot(self, other: Self) -> Self { - self.hypot(other) - } - fn sin(self) -> Self { - self.sin() - } - fn cos(self) -> Self { - self.cos() - } - fn tan(self) -> Self { - self.tan() - } - fn asin(self) -> Self { - self.asin() - } - fn acos(self) -> Self { - self.acos() - } - fn atan(self) -> Self { - self.atan() - } - fn atan2(self, other: Self) -> Self { - self.atan2(other) - } - fn sin_cos(self) -> (Self, Self) { - self.sin_cos() - } - fn exp_m1(self) -> Self { - self.exp_m1() - } - fn ln_1p(self) -> Self { - self.ln_1p() - } - fn sinh(self) -> Self { - self.sinh() - } - fn cosh(self) -> Self { - self.cosh() - } - fn tanh(self) -> Self { - self.tanh() - } - fn asinh(self) -> Self { - self.asinh() - } - fn acosh(self) -> Self { - self.acosh() - } - fn atanh(self) -> Self { - self.atanh() + forward! { + Float::floor(self) -> Self; + Float::ceil(self) -> Self; + Float::round(self) -> Self; + Float::trunc(self) -> Self; + Float::fract(self) -> Self; + Float::abs(self) -> Self; + Float::signum(self) -> Self; + Float::is_sign_positive(self) -> bool; + Float::is_sign_negative(self) -> bool; + Float::mul_add(self, a: Self, b: Self) -> Self; + Float::recip(self) -> Self; + Float::powi(self, n: i32) -> Self; + Float::powf(self, n: Self) -> Self; + Float::sqrt(self) -> Self; + Float::exp(self) -> Self; + Float::exp2(self) -> Self; + Float::ln(self) -> Self; + Float::log(self, base: Self) -> Self; + Float::log2(self) -> Self; + Float::log10(self) -> Self; + Float::to_degrees(self) -> Self; + Float::to_radians(self) -> Self; + Float::max(self, other: Self) -> Self; + Float::min(self, other: Self) -> Self; + Float::abs_sub(self, other: Self) -> Self; + Float::cbrt(self) -> Self; + Float::hypot(self, other: Self) -> Self; + Float::sin(self) -> Self; + Float::cos(self) -> Self; + Float::tan(self) -> Self; + Float::asin(self) -> Self; + Float::acos(self) -> Self; + Float::atan(self) -> Self; + Float::atan2(self, other: Self) -> Self; + Float::sin_cos(self) -> (Self, Self); + Float::exp_m1(self) -> Self; + Float::ln_1p(self) -> Self; + Float::sinh(self) -> Self; + Float::cosh(self) -> Self; + Float::tanh(self) -> Self; + Float::asinh(self) -> Self; + Float::acosh(self) -> Self; + Float::atanh(self) -> Self; } }