2
2
//! Types representing
3
3
#![ allow( non_camel_case_types) ]
4
4
5
- use crate :: simd:: { LaneCount , Select , Simd , SimdCast , SimdElement , SupportedLaneCount } ;
5
+ use crate :: core_simd:: vector:: sealed:: MaskElement ;
6
+ use crate :: simd:: { LaneCount , Select , Simd , SimdElement , SupportedLaneCount } ;
6
7
use core:: cmp:: Ordering ;
7
8
use core:: { fmt, mem} ;
8
9
@@ -29,91 +30,6 @@ macro_rules! impl_fix_endianness {
29
30
30
31
impl_fix_endianness ! { u8 , u16 , u32 , u64 }
31
32
32
- mod sealed {
33
- use super :: * ;
34
-
35
- /// Not only does this seal the `MaskElement` trait, but these functions prevent other traits
36
- /// from bleeding into the parent bounds.
37
- ///
38
- /// For example, `eq` could be provided by requiring `MaskElement: PartialEq`, but that would
39
- /// prevent us from ever removing that bound, or from implementing `MaskElement` on
40
- /// non-`PartialEq` types in the future.
41
- pub trait Sealed {
42
- fn valid < const N : usize > ( values : Simd < Self , N > ) -> bool
43
- where
44
- LaneCount < N > : SupportedLaneCount ,
45
- Self : SimdElement ;
46
-
47
- fn eq ( self , other : Self ) -> bool ;
48
-
49
- fn to_usize ( self ) -> usize ;
50
- fn max_unsigned ( ) -> u64 ;
51
-
52
- type Unsigned : SimdElement ;
53
-
54
- const TRUE : Self ;
55
-
56
- const FALSE : Self ;
57
- }
58
- }
59
- use sealed:: Sealed ;
60
-
61
- /// Marker trait for types that may be used as SIMD mask elements.
62
- ///
63
- /// # Safety
64
- /// Type must be a signed integer.
65
- pub unsafe trait MaskElement : SimdElement < Mask = Self > + SimdCast + Sealed { }
66
-
67
- macro_rules! impl_element {
68
- { $ty: ty, $unsigned: ty } => {
69
- impl Sealed for $ty {
70
- #[ inline]
71
- fn valid<const N : usize >( value: Simd <Self , N >) -> bool
72
- where
73
- LaneCount <N >: SupportedLaneCount ,
74
- {
75
- // We can't use `Simd` directly, because `Simd`'s functions call this function and
76
- // we will end up with an infinite loop.
77
- // Safety: `value` is an integer vector
78
- unsafe {
79
- use core:: intrinsics:: simd;
80
- let falses: Simd <Self , N > = simd:: simd_eq( value, Simd :: splat( 0 as _) ) ;
81
- let trues: Simd <Self , N > = simd:: simd_eq( value, Simd :: splat( -1 as _) ) ;
82
- let valid: Simd <Self , N > = simd:: simd_or( falses, trues) ;
83
- simd:: simd_reduce_all( valid)
84
- }
85
- }
86
-
87
- #[ inline]
88
- fn eq( self , other: Self ) -> bool { self == other }
89
-
90
- #[ inline]
91
- fn to_usize( self ) -> usize {
92
- self as usize
93
- }
94
-
95
- #[ inline]
96
- fn max_unsigned( ) -> u64 {
97
- <$unsigned>:: MAX as u64
98
- }
99
-
100
- type Unsigned = $unsigned;
101
-
102
- const TRUE : Self = -1 ;
103
- const FALSE : Self = 0 ;
104
- }
105
-
106
- // Safety: this is a valid mask element type
107
- unsafe impl MaskElement for $ty { }
108
- }
109
- }
110
-
111
- impl_element ! { i8 , u8 }
112
- impl_element ! { i16 , u16 }
113
- impl_element ! { i32 , u32 }
114
- impl_element ! { i64 , u64 }
115
- impl_element ! { isize , usize }
116
-
117
33
/// A SIMD vector mask for `N` elements matching the element type `T`.
118
34
///
119
35
/// Masks represent boolean inclusion/exclusion on a per-element basis.
155
71
#[ rustc_const_unstable( feature = "portable_simd" , issue = "86656" ) ]
156
72
pub const fn splat ( value : bool ) -> Self {
157
73
Self ( Simd :: splat ( if value {
158
- <T :: Mask as Sealed >:: TRUE
74
+ <T :: Mask as MaskElement >:: TRUE
159
75
} else {
160
- <T :: Mask as Sealed >:: FALSE
76
+ <T :: Mask as MaskElement >:: FALSE
161
77
} ) )
162
78
}
163
79
@@ -208,7 +124,7 @@ where
208
124
pub unsafe fn from_simd_unchecked ( value : Simd < T :: Mask , N > ) -> Self {
209
125
// Safety: the caller must confirm this invariant
210
126
unsafe {
211
- core:: intrinsics:: assume ( <T :: Mask as Sealed >:: valid ( value) ) ;
127
+ core:: intrinsics:: assume ( <T :: Mask as MaskElement >:: valid ( value) ) ;
212
128
}
213
129
Self ( value)
214
130
}
@@ -223,7 +139,7 @@ where
223
139
#[ track_caller]
224
140
pub fn from_simd ( value : Simd < T :: Mask , N > ) -> Self {
225
141
assert ! (
226
- <T :: Mask as Sealed >:: valid( value) ,
142
+ <T :: Mask as MaskElement >:: valid( value) ,
227
143
"all values must be either 0 or -1" ,
228
144
) ;
229
145
// Safety: the validity has been checked
@@ -256,9 +172,9 @@ where
256
172
pub unsafe fn test_unchecked ( & self , index : usize ) -> bool {
257
173
// Safety: the caller must confirm this invariant
258
174
unsafe {
259
- <T :: Mask as Sealed >:: eq (
175
+ <T :: Mask as MaskElement >:: eq (
260
176
* self . 0 . as_array ( ) . get_unchecked ( index) ,
261
- <T :: Mask as Sealed >:: TRUE ,
177
+ <T :: Mask as MaskElement >:: TRUE ,
262
178
)
263
179
}
264
180
}
@@ -271,7 +187,7 @@ where
271
187
#[ must_use = "method returns a new bool and does not mutate the original value" ]
272
188
#[ track_caller]
273
189
pub fn test ( & self , index : usize ) -> bool {
274
- <T :: Mask as Sealed >:: eq ( self . 0 [ index] , <T :: Mask as Sealed >:: TRUE )
190
+ <T :: Mask as MaskElement >:: eq ( self . 0 [ index] , <T :: Mask as MaskElement >:: TRUE )
275
191
}
276
192
277
193
/// Sets the value of the specified element.
@@ -283,9 +199,9 @@ where
283
199
// Safety: the caller must confirm this invariant
284
200
unsafe {
285
201
* self . 0 . as_mut_array ( ) . get_unchecked_mut ( index) = if value {
286
- <T :: Mask as Sealed >:: TRUE
202
+ <T :: Mask as MaskElement >:: TRUE
287
203
} else {
288
- <T :: Mask as Sealed >:: FALSE
204
+ <T :: Mask as MaskElement >:: FALSE
289
205
}
290
206
}
291
207
}
@@ -298,9 +214,9 @@ where
298
214
#[ track_caller]
299
215
pub fn set ( & mut self , index : usize , value : bool ) {
300
216
self . 0 [ index] = if value {
301
- <T :: Mask as Sealed >:: TRUE
217
+ <T :: Mask as MaskElement >:: TRUE
302
218
} else {
303
- <T :: Mask as Sealed >:: FALSE
219
+ <T :: Mask as MaskElement >:: FALSE
304
220
}
305
221
}
306
222
@@ -372,8 +288,8 @@ where
372
288
#[ must_use = "method returns a new mask and does not mutate the original value" ]
373
289
pub fn from_bitmask ( bitmask : u64 ) -> Self {
374
290
Self ( bitmask. select (
375
- Simd :: splat ( <T :: Mask as Sealed >:: TRUE ) ,
376
- Simd :: splat ( <T :: Mask as Sealed >:: FALSE ) ,
291
+ Simd :: splat ( <T :: Mask as MaskElement >:: TRUE ) ,
292
+ Simd :: splat ( <T :: Mask as MaskElement >:: FALSE ) ,
377
293
) )
378
294
}
379
295
@@ -426,20 +342,20 @@ where
426
342
} ;
427
343
428
344
// Safety: the input and output are integer vectors
429
- let masked_index: Simd < <T :: Mask as Sealed >:: Unsigned , N > =
345
+ let masked_index: Simd < <T :: Mask as MaskElement >:: Unsigned , N > =
430
346
unsafe { core:: intrinsics:: simd:: simd_cast ( masked_index) } ;
431
347
432
348
// Safety: the input is an integer vectors
433
- let min_index: <T :: Mask as Sealed >:: Unsigned =
349
+ let min_index: <T :: Mask as MaskElement >:: Unsigned =
434
350
unsafe { core:: intrinsics:: simd:: simd_reduce_min ( masked_index) } ;
435
351
436
352
// Safety: the return value is the unsigned version of T
437
353
let min_index: T :: Mask = unsafe { core:: mem:: transmute_copy ( & min_index) } ;
438
354
439
- if <T :: Mask as Sealed >:: eq ( min_index, <T :: Mask as Sealed >:: TRUE ) {
355
+ if <T :: Mask as MaskElement >:: eq ( min_index, <T :: Mask as MaskElement >:: TRUE ) {
440
356
None
441
357
} else {
442
- Some ( <T :: Mask as Sealed >:: to_usize ( min_index) )
358
+ Some ( <T :: Mask as MaskElement >:: to_usize ( min_index) )
443
359
}
444
360
}
445
361
}
0 commit comments