提交 6094f22c 编写于 作者: J Jubilee Young

impl unary.rs for Simd<{i,u}{8,16,32,64,size}, _>

In order to assure type soundness, these "base" impls
need to go directly on Simd<T, _> for every scalar type argument.
A bit of cleanup of ops.rs is still warranted.
上级 51ff9259
......@@ -7,6 +7,7 @@
mod assign;
mod deref;
mod unary;
impl<I, T, const LANES: usize> core::ops::Index<I> for Simd<T, LANES>
where
......@@ -65,25 +66,6 @@ impl<const $lanes: usize> core::ops::$trait<$rhs> for $type
fn $fn($self_tok, $rhs_arg: $rhs_arg_ty) -> Self::Output $body
}
};
// unary op
{
impl<const $lanes:ident: usize> core::ops::$trait:ident for $type:ty
where
LaneCount<$lanes2:ident>: SupportedLaneCount,
{
type Output = $output:ty;
fn $fn:ident($self_tok:ident) -> Self::Output $body:tt
}
} => {
impl<const $lanes: usize> core::ops::$trait for $type
where
LaneCount<$lanes2>: SupportedLaneCount,
{
type Output = $output;
fn $fn($self_tok) -> Self::Output $body
}
}
}
/// Automatically implements operators over vectors and scalars for a particular vector.
......@@ -119,34 +101,6 @@ fn $fn($self_tok) -> Self::Output $body
impl_op! { @binary $scalar, BitXor::bitxor, simd_xor }
};
{ impl Not for $scalar:ty } => {
impl_ref_ops! {
impl<const LANES: usize> core::ops::Not for Simd<$scalar, LANES>
where
LaneCount<LANES>: SupportedLaneCount,
{
type Output = Self;
fn not(self) -> Self::Output {
self ^ Self::splat(!<$scalar>::default())
}
}
}
};
{ impl Neg for $scalar:ty } => {
impl_ref_ops! {
impl<const LANES: usize> core::ops::Neg for Simd<$scalar, LANES>
where
LaneCount<LANES>: SupportedLaneCount,
{
type Output = Self;
fn neg(self) -> Self::Output {
unsafe { intrinsics::simd_neg(self) }
}
}
}
};
// generic binary op with assignment when output is `Self`
{ @binary $scalar:ty, $trait:ident :: $trait_fn:ident, $intrinsic:ident } => {
impl_ref_ops! {
......@@ -204,7 +158,6 @@ fn $trait_fn(self, rhs: Simd<$scalar, LANES>) -> Self::Output {
impl_op! { impl Mul for $scalar }
impl_op! { impl Div for $scalar }
impl_op! { impl Rem for $scalar }
impl_op! { impl Neg for $scalar }
)*
};
}
......@@ -219,7 +172,6 @@ fn $trait_fn(self, rhs: Simd<$scalar, LANES>) -> Self::Output {
impl_op! { impl BitAnd for $scalar }
impl_op! { impl BitOr for $scalar }
impl_op! { impl BitXor for $scalar }
impl_op! { impl Not for $scalar }
// Integers panic on divide by 0
impl_ref_ops! {
......@@ -441,9 +393,6 @@ fn shr(self, rhs: $scalar) -> Self::Output {
macro_rules! impl_signed_int_ops {
{ $($scalar:ty),* } => {
impl_unsigned_int_ops! { $($scalar),* }
$( // scalar
impl_op! { impl Neg for $scalar }
)*
};
}
......
use crate::simd::intrinsics;
use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount};
use core::ops::{Neg, Not}; // unary ops
macro_rules! neg {
($(impl<const LANES: usize> Neg for Simd<$scalar:ty, LANES>)*) => {
$(impl<const LANES: usize> Neg for Simd<$scalar, LANES>
where
$scalar: SimdElement,
LaneCount<LANES>: SupportedLaneCount,
{
type Output = Self;
#[inline]
#[must_use = "operator returns a new vector without mutating the input"]
fn neg(self) -> Self::Output {
unsafe { intrinsics::simd_neg(self) }
}
})*
}
}
neg! {
impl<const LANES: usize> Neg for Simd<f32, LANES>
impl<const LANES: usize> Neg for Simd<f64, LANES>
impl<const LANES: usize> Neg for Simd<i8, LANES>
impl<const LANES: usize> Neg for Simd<i16, LANES>
impl<const LANES: usize> Neg for Simd<i32, LANES>
impl<const LANES: usize> Neg for Simd<i64, LANES>
impl<const LANES: usize> Neg for Simd<isize, LANES>
}
macro_rules! not {
($(impl<const LANES: usize> Not for Simd<$scalar:ty, LANES>)*) => {
$(impl<const LANES: usize> Not for Simd<$scalar, LANES>
where
$scalar: SimdElement,
LaneCount<LANES>: SupportedLaneCount,
{
type Output = Self;
#[inline]
#[must_use = "operator returns a new vector without mutating the input"]
fn not(self) -> Self::Output {
self ^ (Simd::splat(!(0 as $scalar)))
}
})*
}
}
not! {
impl<const LANES: usize> Not for Simd<i8, LANES>
impl<const LANES: usize> Not for Simd<i16, LANES>
impl<const LANES: usize> Not for Simd<i32, LANES>
impl<const LANES: usize> Not for Simd<i64, LANES>
impl<const LANES: usize> Not for Simd<isize, LANES>
impl<const LANES: usize> Not for Simd<u8, LANES>
impl<const LANES: usize> Not for Simd<u16, LANES>
impl<const LANES: usize> Not for Simd<u32, LANES>
impl<const LANES: usize> Not for Simd<u64, LANES>
impl<const LANES: usize> Not for Simd<usize, LANES>
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册