Skip to content

Commit bce8032

Browse files
committed
Use generic trait parameters to minimize associated types
1 parent cc032ad commit bce8032

8 files changed

Lines changed: 232 additions & 310 deletions

File tree

crates/core_simd/src/simd/cmp/eq.rs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,32 @@ use crate::simd::{
44
};
55

66
/// Parallel `PartialEq`.
7-
pub trait SimdPartialEq {
8-
/// The mask type returned by each comparison.
9-
type Mask;
10-
7+
pub trait SimdPartialEq<T, const N: usize>
8+
where
9+
T: SimdElement,
10+
{
1111
/// Test if each element is equal to the corresponding element in `other`.
1212
#[must_use = "method returns a new mask and does not mutate the original value"]
13-
fn simd_eq(self, other: Self) -> Self::Mask;
13+
fn simd_eq(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;
1414

1515
/// Test if each element is not equal to the corresponding element in `other`.
1616
#[must_use = "method returns a new mask and does not mutate the original value"]
17-
fn simd_ne(self, other: Self) -> Self::Mask;
17+
fn simd_ne(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;
1818
}
1919

2020
macro_rules! impl_number {
2121
{ $($number:ty),* } => {
2222
$(
23-
impl<const N: usize> SimdPartialEq for Simd<$number, N>
24-
{
25-
type Mask = Mask<<$number as SimdElement>::Mask, N>;
26-
23+
impl<const N: usize> SimdPartialEq<$number, N> for Simd<$number, N> {
2724
#[inline]
28-
fn simd_eq(self, other: Self) -> Self::Mask {
25+
fn simd_eq(self, other: Self) -> Mask<<$number as SimdElement>::Mask, N> {
2926
// Safety: `self` is a vector, and the result of the comparison
3027
// is always a valid mask.
3128
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_eq(self, other)) }
3229
}
3330

3431
#[inline]
35-
fn simd_ne(self, other: Self) -> Self::Mask {
32+
fn simd_ne(self, other: Self) -> Mask<<$number as SimdElement>::Mask, N> {
3633
// Safety: `self` is a vector, and the result of the comparison
3734
// is always a valid mask.
3835
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ne(self, other)) }
@@ -47,19 +44,16 @@ impl_number! { f16, f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize
4744
macro_rules! impl_mask {
4845
{ $($integer:ty),* } => {
4946
$(
50-
impl<const N: usize> SimdPartialEq for Mask<$integer, N>
51-
{
52-
type Mask = Self;
53-
47+
impl<const N: usize> SimdPartialEq<$integer, N> for Mask<$integer, N> {
5448
#[inline]
55-
fn simd_eq(self, other: Self) -> Self::Mask {
49+
fn simd_eq(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
5650
// Safety: `self` is a vector, and the result of the comparison
5751
// is always a valid mask.
5852
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_eq(self.to_simd(), other.to_simd())) }
5953
}
6054

6155
#[inline]
62-
fn simd_ne(self, other: Self) -> Self::Mask {
56+
fn simd_ne(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
6357
// Safety: `self` is a vector, and the result of the comparison
6458
// is always a valid mask.
6559
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ne(self.to_simd(), other.to_simd())) }
@@ -71,30 +65,26 @@ macro_rules! impl_mask {
7165

7266
impl_mask! { i8, i16, i32, i64, isize }
7367

74-
impl<T, const N: usize> SimdPartialEq for Simd<*const T, N> {
75-
type Mask = Mask<isize, N>;
76-
68+
impl<T, const N: usize> SimdPartialEq<*const T, N> for Simd<*const T, N> {
7769
#[inline]
78-
fn simd_eq(self, other: Self) -> Self::Mask {
70+
fn simd_eq(self, other: Self) -> Mask<isize, N> {
7971
self.addr().simd_eq(other.addr())
8072
}
8173

8274
#[inline]
83-
fn simd_ne(self, other: Self) -> Self::Mask {
75+
fn simd_ne(self, other: Self) -> Mask<isize, N> {
8476
self.addr().simd_ne(other.addr())
8577
}
8678
}
8779

88-
impl<T, const N: usize> SimdPartialEq for Simd<*mut T, N> {
89-
type Mask = Mask<isize, N>;
90-
80+
impl<T, const N: usize> SimdPartialEq<*mut T, N> for Simd<*mut T, N> {
9181
#[inline]
92-
fn simd_eq(self, other: Self) -> Self::Mask {
82+
fn simd_eq(self, other: Self) -> Mask<isize, N> {
9383
self.addr().simd_eq(other.addr())
9484
}
9585

9686
#[inline]
97-
fn simd_ne(self, other: Self) -> Self::Mask {
87+
fn simd_ne(self, other: Self) -> Mask<isize, N> {
9888
self.addr().simd_ne(other.addr())
9989
}
10090
}

crates/core_simd/src/simd/cmp/ord.rs

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,36 @@
11
use crate::simd::{
2-
Mask, Select, Simd,
2+
Mask, Select, Simd, SimdElement,
33
cmp::SimdPartialEq,
44
ptr::{SimdConstPtr, SimdMutPtr},
55
};
66

77
/// Parallel `PartialOrd`.
8-
pub trait SimdPartialOrd: SimdPartialEq {
8+
pub trait SimdPartialOrd<T, const N: usize>: SimdPartialEq<T, N>
9+
where
10+
T: SimdElement,
11+
{
912
/// Test if each element is less than the corresponding element in `other`.
1013
#[must_use = "method returns a new mask and does not mutate the original value"]
11-
fn simd_lt(self, other: Self) -> Self::Mask;
14+
fn simd_lt(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;
1215

1316
/// Test if each element is less than or equal to the corresponding element in `other`.
1417
#[must_use = "method returns a new mask and does not mutate the original value"]
15-
fn simd_le(self, other: Self) -> Self::Mask;
18+
fn simd_le(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;
1619

1720
/// Test if each element is greater than the corresponding element in `other`.
1821
#[must_use = "method returns a new mask and does not mutate the original value"]
19-
fn simd_gt(self, other: Self) -> Self::Mask;
22+
fn simd_gt(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;
2023

2124
/// Test if each element is greater than or equal to the corresponding element in `other`.
2225
#[must_use = "method returns a new mask and does not mutate the original value"]
23-
fn simd_ge(self, other: Self) -> Self::Mask;
26+
fn simd_ge(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;
2427
}
2528

2629
/// Parallel `Ord`.
27-
pub trait SimdOrd: SimdPartialOrd {
30+
pub trait SimdOrd<T, const N: usize>: SimdPartialOrd<T, N>
31+
where
32+
T: SimdElement,
33+
{
2834
/// Returns the element-wise maximum with `other`.
2935
#[must_use = "method returns a new vector and does not mutate the original value"]
3036
fn simd_max(self, other: Self) -> Self;
@@ -48,38 +54,38 @@ pub trait SimdOrd: SimdPartialOrd {
4854
macro_rules! impl_integer {
4955
{ $($integer:ty),* } => {
5056
$(
51-
impl<const N: usize> SimdPartialOrd for Simd<$integer, N>
57+
impl<const N: usize> SimdPartialOrd<$integer, N> for Simd<$integer, N>
5258
{
5359
#[inline]
54-
fn simd_lt(self, other: Self) -> Self::Mask {
60+
fn simd_lt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
5561
// Safety: `self` is a vector, and the result of the comparison
5662
// is always a valid mask.
5763
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_lt(self, other)) }
5864
}
5965

6066
#[inline]
61-
fn simd_le(self, other: Self) -> Self::Mask {
67+
fn simd_le(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
6268
// Safety: `self` is a vector, and the result of the comparison
6369
// is always a valid mask.
6470
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_le(self, other)) }
6571
}
6672

6773
#[inline]
68-
fn simd_gt(self, other: Self) -> Self::Mask {
74+
fn simd_gt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
6975
// Safety: `self` is a vector, and the result of the comparison
7076
// is always a valid mask.
7177
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_gt(self, other)) }
7278
}
7379

7480
#[inline]
75-
fn simd_ge(self, other: Self) -> Self::Mask {
81+
fn simd_ge(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
7682
// Safety: `self` is a vector, and the result of the comparison
7783
// is always a valid mask.
7884
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ge(self, other)) }
7985
}
8086
}
8187

82-
impl<const N: usize> SimdOrd for Simd<$integer, N>
88+
impl<const N: usize> SimdOrd<$integer, N> for Simd<$integer, N>
8389
{
8490
#[inline]
8591
fn simd_max(self, other: Self) -> Self {
@@ -110,31 +116,31 @@ impl_integer! { u8, u16, u32, u64, usize, i8, i16, i32, i64, isize }
110116
macro_rules! impl_float {
111117
{ $($float:ty),* } => {
112118
$(
113-
impl<const N: usize> SimdPartialOrd for Simd<$float, N>
119+
impl<const N: usize> SimdPartialOrd<$float, N> for Simd<$float, N>
114120
{
115121
#[inline]
116-
fn simd_lt(self, other: Self) -> Self::Mask {
122+
fn simd_lt(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> {
117123
// Safety: `self` is a vector, and the result of the comparison
118124
// is always a valid mask.
119125
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_lt(self, other)) }
120126
}
121127

122128
#[inline]
123-
fn simd_le(self, other: Self) -> Self::Mask {
129+
fn simd_le(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> {
124130
// Safety: `self` is a vector, and the result of the comparison
125131
// is always a valid mask.
126132
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_le(self, other)) }
127133
}
128134

129135
#[inline]
130-
fn simd_gt(self, other: Self) -> Self::Mask {
136+
fn simd_gt(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> {
131137
// Safety: `self` is a vector, and the result of the comparison
132138
// is always a valid mask.
133139
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_gt(self, other)) }
134140
}
135141

136142
#[inline]
137-
fn simd_ge(self, other: Self) -> Self::Mask {
143+
fn simd_ge(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> {
138144
// Safety: `self` is a vector, and the result of the comparison
139145
// is always a valid mask.
140146
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ge(self, other)) }
@@ -149,38 +155,38 @@ impl_float! { f16, f32, f64 }
149155
macro_rules! impl_mask {
150156
{ $($integer:ty),* } => {
151157
$(
152-
impl<const N: usize> SimdPartialOrd for Mask<$integer, N>
158+
impl<const N: usize> SimdPartialOrd<$integer, N> for Mask<$integer, N>
153159
{
154160
#[inline]
155-
fn simd_lt(self, other: Self) -> Self::Mask {
161+
fn simd_lt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
156162
// Safety: `self` is a vector, and the result of the comparison
157163
// is always a valid mask.
158164
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_lt(self.to_simd(), other.to_simd())) }
159165
}
160166

161167
#[inline]
162-
fn simd_le(self, other: Self) -> Self::Mask {
168+
fn simd_le(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
163169
// Safety: `self` is a vector, and the result of the comparison
164170
// is always a valid mask.
165171
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_le(self.to_simd(), other.to_simd())) }
166172
}
167173

168174
#[inline]
169-
fn simd_gt(self, other: Self) -> Self::Mask {
175+
fn simd_gt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
170176
// Safety: `self` is a vector, and the result of the comparison
171177
// is always a valid mask.
172178
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_gt(self.to_simd(), other.to_simd())) }
173179
}
174180

175181
#[inline]
176-
fn simd_ge(self, other: Self) -> Self::Mask {
182+
fn simd_ge(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
177183
// Safety: `self` is a vector, and the result of the comparison
178184
// is always a valid mask.
179185
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ge(self.to_simd(), other.to_simd())) }
180186
}
181187
}
182188

183-
impl<const N: usize> SimdOrd for Mask<$integer, N>
189+
impl<const N: usize> SimdOrd<$integer, N> for Mask<$integer, N>
184190
{
185191
#[inline]
186192
fn simd_max(self, other: Self) -> Self {
@@ -208,29 +214,29 @@ macro_rules! impl_mask {
208214

209215
impl_mask! { i8, i16, i32, i64, isize }
210216

211-
impl<T, const N: usize> SimdPartialOrd for Simd<*const T, N> {
217+
impl<T, const N: usize> SimdPartialOrd<*const T, N> for Simd<*const T, N> {
212218
#[inline]
213-
fn simd_lt(self, other: Self) -> Self::Mask {
219+
fn simd_lt(self, other: Self) -> Mask<isize, N> {
214220
self.addr().simd_lt(other.addr())
215221
}
216222

217223
#[inline]
218-
fn simd_le(self, other: Self) -> Self::Mask {
224+
fn simd_le(self, other: Self) -> Mask<isize, N> {
219225
self.addr().simd_le(other.addr())
220226
}
221227

222228
#[inline]
223-
fn simd_gt(self, other: Self) -> Self::Mask {
229+
fn simd_gt(self, other: Self) -> Mask<isize, N> {
224230
self.addr().simd_gt(other.addr())
225231
}
226232

227233
#[inline]
228-
fn simd_ge(self, other: Self) -> Self::Mask {
234+
fn simd_ge(self, other: Self) -> Mask<isize, N> {
229235
self.addr().simd_ge(other.addr())
230236
}
231237
}
232238

233-
impl<T, const N: usize> SimdOrd for Simd<*const T, N> {
239+
impl<T, const N: usize> SimdOrd<*const T, N> for Simd<*const T, N> {
234240
#[inline]
235241
fn simd_max(self, other: Self) -> Self {
236242
self.simd_lt(other).select(other, self)
@@ -252,29 +258,29 @@ impl<T, const N: usize> SimdOrd for Simd<*const T, N> {
252258
}
253259
}
254260

255-
impl<T, const N: usize> SimdPartialOrd for Simd<*mut T, N> {
261+
impl<T, const N: usize> SimdPartialOrd<*mut T, N> for Simd<*mut T, N> {
256262
#[inline]
257-
fn simd_lt(self, other: Self) -> Self::Mask {
263+
fn simd_lt(self, other: Self) -> Mask<isize, N> {
258264
self.addr().simd_lt(other.addr())
259265
}
260266

261267
#[inline]
262-
fn simd_le(self, other: Self) -> Self::Mask {
268+
fn simd_le(self, other: Self) -> Mask<isize, N> {
263269
self.addr().simd_le(other.addr())
264270
}
265271

266272
#[inline]
267-
fn simd_gt(self, other: Self) -> Self::Mask {
273+
fn simd_gt(self, other: Self) -> Mask<isize, N> {
268274
self.addr().simd_gt(other.addr())
269275
}
270276

271277
#[inline]
272-
fn simd_ge(self, other: Self) -> Self::Mask {
278+
fn simd_ge(self, other: Self) -> Mask<isize, N> {
273279
self.addr().simd_ge(other.addr())
274280
}
275281
}
276282

277-
impl<T, const N: usize> SimdOrd for Simd<*mut T, N> {
283+
impl<T, const N: usize> SimdOrd<*mut T, N> for Simd<*mut T, N> {
278284
#[inline]
279285
fn simd_max(self, other: Self) -> Self {
280286
self.simd_lt(other).select(other, self)

0 commit comments

Comments
 (0)