From 0a6992f5bfb6a2e879d23ff015ae27e2534095aa Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 23 Nov 2021 16:15:19 -0800 Subject: [PATCH] impl deref.rs<&Self> for Simd Instead of implementing each "deref" pattern for every single scalar, we can use type parameters for Simd operating on &Self. We can use a macro, but keep it cleaner and more explicit. --- crates/core_simd/src/ops.rs | 62 +++------------------------ crates/core_simd/src/ops/deref.rs | 70 +++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 56 deletions(-) create mode 100644 crates/core_simd/src/ops/deref.rs diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index 5d7af474caf..f5683ebb2c0 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -1,5 +1,11 @@ use crate::simd::intrinsics; use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount}; +use core::ops::{Add, Mul}; +use core::ops::{BitAnd, BitOr, BitXor}; +use core::ops::{Div, Rem, Sub}; +use core::ops::{Shl, Shr}; + +mod deref; impl core::ops::Index for Simd where @@ -57,42 +63,6 @@ macro_rules! impl_ref_ops { $(#[$attrs])* fn $fn($self_tok, $rhs_arg: $rhs_arg_ty) -> Self::Output $body } - - impl core::ops::$trait<&'_ $rhs> for $type - where - LaneCount<$lanes2>: SupportedLaneCount, - { - type Output = <$type as core::ops::$trait<$rhs>>::Output; - - $(#[$attrs])* - fn $fn($self_tok, $rhs_arg: &$rhs) -> Self::Output { - core::ops::$trait::$fn($self_tok, *$rhs_arg) - } - } - - impl core::ops::$trait<$rhs> for &'_ $type - where - LaneCount<$lanes2>: SupportedLaneCount, - { - type Output = <$type as core::ops::$trait<$rhs>>::Output; - - $(#[$attrs])* - fn $fn($self_tok, $rhs_arg: $rhs) -> Self::Output { - core::ops::$trait::$fn(*$self_tok, $rhs_arg) - } - } - - impl core::ops::$trait<&'_ $rhs> for &'_ $type - where - LaneCount<$lanes2>: SupportedLaneCount, - { - type Output = <$type as core::ops::$trait<$rhs>>::Output; - - $(#[$attrs])* - fn $fn($self_tok, $rhs_arg: &$rhs) -> Self::Output { - core::ops::$trait::$fn(*$self_tok, *$rhs_arg) - } - } }; // binary assignment op @@ -112,16 +82,6 @@ macro_rules! impl_ref_ops { $(#[$attrs])* fn $fn(&mut $self_tok, $rhs_arg: $rhs_arg_ty) $body } - - impl core::ops::$trait<&'_ $rhs> for $type - where - LaneCount<$lanes2>: SupportedLaneCount, - { - $(#[$attrs])* - fn $fn(&mut $self_tok, $rhs_arg: &$rhs_arg_ty) { - core::ops::$trait::$fn($self_tok, *$rhs_arg) - } - } }; // unary op @@ -141,16 +101,6 @@ macro_rules! impl_ref_ops { type Output = $output; fn $fn($self_tok) -> Self::Output $body } - - impl core::ops::$trait for &'_ $type - where - LaneCount<$lanes2>: SupportedLaneCount, - { - type Output = <$type as core::ops::$trait>::Output; - fn $fn($self_tok) -> Self::Output { - core::ops::$trait::$fn(*$self_tok) - } - } } } diff --git a/crates/core_simd/src/ops/deref.rs b/crates/core_simd/src/ops/deref.rs new file mode 100644 index 00000000000..1138b9494f6 --- /dev/null +++ b/crates/core_simd/src/ops/deref.rs @@ -0,0 +1,70 @@ +//! This module hacks in "implicit deref" for Simd's operators. +//! Ideally, Rust would take care of this itself, +//! and method calls usually handle the LHS implicitly. +//! So, we'll manually deref the RHS. +use super::*; + +macro_rules! deref_ops { + ($(impl $trait:ident<&Self> for Simd { + fn $call:ident(rhs: &Self) + })*) => { + $(impl $trait<&Self> for Simd + where + Self: $trait, + T: SimdElement, + LaneCount: SupportedLaneCount, + { + type Output = Self; + + #[inline] + #[must_use = "operator returns a new vector without mutating the inputs"] + fn $call(self, rhs: &Self) -> Self::Output { + self.$call(*rhs) + } + })* + } +} + +deref_ops! { + // Arithmetic + impl Add<&Self> for Simd { + fn add(rhs: &Self) + } + + impl Mul<&Self> for Simd { + fn mul(rhs: &Self) + } + + impl Sub<&Self> for Simd { + fn sub(rhs: &Self) + } + + impl Div<&Self> for Simd { + fn div(rhs: &Self) + } + + impl Rem<&Self> for Simd { + fn rem(rhs: &Self) + } + + // Bitops + impl BitAnd<&Self> for Simd { + fn bitand(rhs: &Self) + } + + impl BitOr<&Self> for Simd { + fn bitor(rhs: &Self) + } + + impl BitXor<&Self> for Simd { + fn bitxor(rhs: &Self) + } + + impl Shl<&Self> for Simd { + fn shl(rhs: &Self) + } + + impl Shr<&Self> for Simd { + fn shr(rhs: &Self) + } +}