Skip to content

Commit 6094f22

Browse files
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.
1 parent 51ff925 commit 6094f22

File tree

2 files changed

+78
-52
lines changed

2 files changed

+78
-52
lines changed

crates/core_simd/src/ops.rs

+1-52
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use core::ops::{Shl, Shr};
77

88
mod assign;
99
mod deref;
10+
mod unary;
1011

1112
impl<I, T, const LANES: usize> core::ops::Index<I> for Simd<T, LANES>
1213
where
@@ -65,25 +66,6 @@ macro_rules! impl_ref_ops {
6566
fn $fn($self_tok, $rhs_arg: $rhs_arg_ty) -> Self::Output $body
6667
}
6768
};
68-
69-
// unary op
70-
{
71-
impl<const $lanes:ident: usize> core::ops::$trait:ident for $type:ty
72-
where
73-
LaneCount<$lanes2:ident>: SupportedLaneCount,
74-
{
75-
type Output = $output:ty;
76-
fn $fn:ident($self_tok:ident) -> Self::Output $body:tt
77-
}
78-
} => {
79-
impl<const $lanes: usize> core::ops::$trait for $type
80-
where
81-
LaneCount<$lanes2>: SupportedLaneCount,
82-
{
83-
type Output = $output;
84-
fn $fn($self_tok) -> Self::Output $body
85-
}
86-
}
8769
}
8870

8971
/// Automatically implements operators over vectors and scalars for a particular vector.
@@ -119,34 +101,6 @@ macro_rules! impl_op {
119101
impl_op! { @binary $scalar, BitXor::bitxor, simd_xor }
120102
};
121103

122-
{ impl Not for $scalar:ty } => {
123-
impl_ref_ops! {
124-
impl<const LANES: usize> core::ops::Not for Simd<$scalar, LANES>
125-
where
126-
LaneCount<LANES>: SupportedLaneCount,
127-
{
128-
type Output = Self;
129-
fn not(self) -> Self::Output {
130-
self ^ Self::splat(!<$scalar>::default())
131-
}
132-
}
133-
}
134-
};
135-
136-
{ impl Neg for $scalar:ty } => {
137-
impl_ref_ops! {
138-
impl<const LANES: usize> core::ops::Neg for Simd<$scalar, LANES>
139-
where
140-
LaneCount<LANES>: SupportedLaneCount,
141-
{
142-
type Output = Self;
143-
fn neg(self) -> Self::Output {
144-
unsafe { intrinsics::simd_neg(self) }
145-
}
146-
}
147-
}
148-
};
149-
150104
// generic binary op with assignment when output is `Self`
151105
{ @binary $scalar:ty, $trait:ident :: $trait_fn:ident, $intrinsic:ident } => {
152106
impl_ref_ops! {
@@ -204,7 +158,6 @@ macro_rules! impl_float_ops {
204158
impl_op! { impl Mul for $scalar }
205159
impl_op! { impl Div for $scalar }
206160
impl_op! { impl Rem for $scalar }
207-
impl_op! { impl Neg for $scalar }
208161
)*
209162
};
210163
}
@@ -219,7 +172,6 @@ macro_rules! impl_unsigned_int_ops {
219172
impl_op! { impl BitAnd for $scalar }
220173
impl_op! { impl BitOr for $scalar }
221174
impl_op! { impl BitXor for $scalar }
222-
impl_op! { impl Not for $scalar }
223175

224176
// Integers panic on divide by 0
225177
impl_ref_ops! {
@@ -441,9 +393,6 @@ macro_rules! impl_unsigned_int_ops {
441393
macro_rules! impl_signed_int_ops {
442394
{ $($scalar:ty),* } => {
443395
impl_unsigned_int_ops! { $($scalar),* }
444-
$( // scalar
445-
impl_op! { impl Neg for $scalar }
446-
)*
447396
};
448397
}
449398

crates/core_simd/src/ops/unary.rs

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use crate::simd::intrinsics;
2+
use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount};
3+
use core::ops::{Neg, Not}; // unary ops
4+
5+
macro_rules! neg {
6+
($(impl<const LANES: usize> Neg for Simd<$scalar:ty, LANES>)*) => {
7+
$(impl<const LANES: usize> Neg for Simd<$scalar, LANES>
8+
where
9+
$scalar: SimdElement,
10+
LaneCount<LANES>: SupportedLaneCount,
11+
{
12+
type Output = Self;
13+
14+
#[inline]
15+
#[must_use = "operator returns a new vector without mutating the input"]
16+
fn neg(self) -> Self::Output {
17+
unsafe { intrinsics::simd_neg(self) }
18+
}
19+
})*
20+
}
21+
}
22+
23+
neg! {
24+
impl<const LANES: usize> Neg for Simd<f32, LANES>
25+
26+
impl<const LANES: usize> Neg for Simd<f64, LANES>
27+
28+
impl<const LANES: usize> Neg for Simd<i8, LANES>
29+
30+
impl<const LANES: usize> Neg for Simd<i16, LANES>
31+
32+
impl<const LANES: usize> Neg for Simd<i32, LANES>
33+
34+
impl<const LANES: usize> Neg for Simd<i64, LANES>
35+
36+
impl<const LANES: usize> Neg for Simd<isize, LANES>
37+
}
38+
39+
macro_rules! not {
40+
($(impl<const LANES: usize> Not for Simd<$scalar:ty, LANES>)*) => {
41+
$(impl<const LANES: usize> Not for Simd<$scalar, LANES>
42+
where
43+
$scalar: SimdElement,
44+
LaneCount<LANES>: SupportedLaneCount,
45+
{
46+
type Output = Self;
47+
48+
#[inline]
49+
#[must_use = "operator returns a new vector without mutating the input"]
50+
fn not(self) -> Self::Output {
51+
self ^ (Simd::splat(!(0 as $scalar)))
52+
}
53+
})*
54+
}
55+
}
56+
57+
not! {
58+
impl<const LANES: usize> Not for Simd<i8, LANES>
59+
60+
impl<const LANES: usize> Not for Simd<i16, LANES>
61+
62+
impl<const LANES: usize> Not for Simd<i32, LANES>
63+
64+
impl<const LANES: usize> Not for Simd<i64, LANES>
65+
66+
impl<const LANES: usize> Not for Simd<isize, LANES>
67+
68+
impl<const LANES: usize> Not for Simd<u8, LANES>
69+
70+
impl<const LANES: usize> Not for Simd<u16, LANES>
71+
72+
impl<const LANES: usize> Not for Simd<u32, LANES>
73+
74+
impl<const LANES: usize> Not for Simd<u64, LANES>
75+
76+
impl<const LANES: usize> Not for Simd<usize, LANES>
77+
}

0 commit comments

Comments
 (0)