From 18575c287cd5053875f7a86dd7c38d3b5ad64efd Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 29 Apr 2022 17:53:50 -0700 Subject: [PATCH] Forward euclid methods when possible --- build.rs | 1 + src/ops/euclid.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/build.rs b/build.rs index 83c8eee..887021d 100644 --- a/build.rs +++ b/build.rs @@ -19,6 +19,7 @@ fn main() { ac.emit_expression_cfg("1u32.reverse_bits()", "has_reverse_bits"); ac.emit_expression_cfg("1u32.trailing_ones()", "has_leading_trailing_ones"); ac.emit_expression_cfg("{ let mut x = 1; x += &2; }", "has_int_assignop_ref"); + ac.emit_expression_cfg("1u32.div_euclid(1u32)", "has_div_euclid"); autocfg::rerun_path("build.rs"); } diff --git a/src/ops/euclid.rs b/src/ops/euclid.rs index ef6546c..99b5127 100644 --- a/src/ops/euclid.rs +++ b/src/ops/euclid.rs @@ -48,8 +48,28 @@ pub trait Euclid: Sized + Div + Rem { fn rem_euclid(&self, v: &Self) -> Self; } +macro_rules! euclid_forward_impl { + ($($t:ty)*) => {$( + #[cfg(has_div_euclid)] + impl Euclid for $t { + #[inline] + fn div_euclid(&self, v: &$t) -> Self { + <$t>::div_euclid(*self, *v) + } + + #[inline] + fn rem_euclid(&self, v: &$t) -> Self { + <$t>::rem_euclid(*self, *v) + } + } + )*} +} + macro_rules! euclid_int_impl { ($($t:ty)*) => {$( + euclid_forward_impl!($t); + + #[cfg(not(has_div_euclid))] impl Euclid for $t { #[inline] fn div_euclid(&self, v: &$t) -> Self { @@ -79,6 +99,9 @@ macro_rules! euclid_int_impl { macro_rules! euclid_uint_impl { ($($t:ty)*) => {$( + euclid_forward_impl!($t); + + #[cfg(not(has_div_euclid))] impl Euclid for $t { #[inline] fn div_euclid(&self, v: &$t) -> Self { @@ -100,6 +123,10 @@ euclid_int_impl!(i128); #[cfg(has_i128)] euclid_uint_impl!(u128); +#[cfg(all(has_div_euclid, feature = "std"))] +euclid_forward_impl!(f32 f64); + +#[cfg(not(all(has_div_euclid, feature = "std")))] impl Euclid for f32 { #[inline] fn div_euclid(&self, v: &f32) -> f32 { @@ -121,6 +148,7 @@ impl Euclid for f32 { } } +#[cfg(not(all(has_div_euclid, feature = "std")))] impl Euclid for f64 { #[inline] fn div_euclid(&self, v: &f64) -> f64 { @@ -152,8 +180,28 @@ pub trait CheckedEuclid: Euclid { fn checked_rem_euclid(&self, v: &Self) -> Option; } +macro_rules! checked_euclid_forward_impl { + ($($t:ty)*) => {$( + #[cfg(has_div_euclid)] + impl CheckedEuclid for $t { + #[inline] + fn checked_div_euclid(&self, v: &$t) -> Option { + <$t>::checked_div_euclid(*self, *v) + } + + #[inline] + fn checked_rem_euclid(&self, v: &$t) -> Option { + <$t>::checked_rem_euclid(*self, *v) + } + } + )*} +} + macro_rules! checked_euclid_int_impl { ($($t:ty)*) => {$( + checked_euclid_forward_impl!($t); + + #[cfg(not(has_div_euclid))] impl CheckedEuclid for $t { #[inline] fn checked_div_euclid(&self, v: &$t) -> Option<$t> { @@ -178,6 +226,9 @@ macro_rules! checked_euclid_int_impl { macro_rules! checked_euclid_uint_impl { ($($t:ty)*) => {$( + checked_euclid_forward_impl!($t); + + #[cfg(not(has_div_euclid))] impl CheckedEuclid for $t { #[inline] fn checked_div_euclid(&self, v: &$t) -> Option<$t> {