1
1
use super :: sealed:: Sealed ;
2
2
use crate :: simd:: {
3
- intrinsics, LaneCount , Mask , Simd , SimdCast , SimdElement , SimdPartialOrd , SupportedLaneCount ,
3
+ intrinsics, LaneCount , Mask , Simd , SimdCast , SimdElement , SimdPartialOrd , SimdUint ,
4
+ SupportedLaneCount ,
4
5
} ;
5
6
6
7
/// Operations on SIMD vectors of signed integers.
@@ -11,6 +12,9 @@ pub trait SimdInt: Copy + Sealed {
11
12
/// Scalar type contained by this SIMD vector type.
12
13
type Scalar ;
13
14
15
+ /// A SIMD vector of unsigned integers with the same element size.
16
+ type Unsigned ;
17
+
14
18
/// A SIMD vector with a different element type.
15
19
type Cast < T : SimdElement > ;
16
20
@@ -200,20 +204,20 @@ pub trait SimdInt: Copy + Sealed {
200
204
fn reverse_bits ( self ) -> Self ;
201
205
202
206
/// Returns the number of leading zeros in the binary representation of each element.
203
- fn leading_zeros ( self ) -> Self ;
207
+ fn leading_zeros ( self ) -> Self :: Unsigned ;
204
208
205
209
/// Returns the number of trailing zeros in the binary representation of each element.
206
- fn trailing_zeros ( self ) -> Self ;
210
+ fn trailing_zeros ( self ) -> Self :: Unsigned ;
207
211
208
212
/// Returns the number of leading ones in the binary representation of each element.
209
- fn leading_ones ( self ) -> Self ;
213
+ fn leading_ones ( self ) -> Self :: Unsigned ;
210
214
211
215
/// Returns the number of trailing ones in the binary representation of each element.
212
- fn trailing_ones ( self ) -> Self ;
216
+ fn trailing_ones ( self ) -> Self :: Unsigned ;
213
217
}
214
218
215
219
macro_rules! impl_trait {
216
- { $( $ty: ty ) ,* } => {
220
+ { $( $ty: ident ( $unsigned : ident ) ) ,* } => {
217
221
$(
218
222
impl <const LANES : usize > Sealed for Simd <$ty, LANES >
219
223
where
@@ -227,6 +231,7 @@ macro_rules! impl_trait {
227
231
{
228
232
type Mask = Mask <<$ty as SimdElement >:: Mask , LANES >;
229
233
type Scalar = $ty;
234
+ type Unsigned = Simd <$unsigned, LANES >;
230
235
type Cast <T : SimdElement > = Simd <T , LANES >;
231
236
232
237
#[ inline]
@@ -340,29 +345,27 @@ macro_rules! impl_trait {
340
345
}
341
346
342
347
#[ inline]
343
- fn leading_zeros( self ) -> Self {
344
- // Safety: `self` is an integer vector
345
- unsafe { intrinsics:: simd_ctlz( self ) }
348
+ fn leading_zeros( self ) -> Self :: Unsigned {
349
+ self . cast:: <$unsigned>( ) . leading_zeros( )
346
350
}
347
351
348
352
#[ inline]
349
- fn trailing_zeros( self ) -> Self {
350
- // Safety: `self` is an integer vector
351
- unsafe { intrinsics:: simd_cttz( self ) }
353
+ fn trailing_zeros( self ) -> Self :: Unsigned {
354
+ self . cast:: <$unsigned>( ) . trailing_zeros( )
352
355
}
353
356
354
357
#[ inline]
355
- fn leading_ones( self ) -> Self {
356
- ( ! self ) . leading_zeros ( )
358
+ fn leading_ones( self ) -> Self :: Unsigned {
359
+ self . cast :: <$unsigned> ( ) . leading_ones ( )
357
360
}
358
361
359
362
#[ inline]
360
- fn trailing_ones( self ) -> Self {
361
- ( ! self ) . trailing_zeros ( )
363
+ fn trailing_ones( self ) -> Self :: Unsigned {
364
+ self . cast :: <$unsigned> ( ) . trailing_ones ( )
362
365
}
363
366
}
364
367
) *
365
368
}
366
369
}
367
370
368
- impl_trait ! { i8 , i16 , i32 , i64 , isize }
371
+ impl_trait ! { i8 ( u8 ) , i16 ( u16 ) , i32 ( u32 ) , i64 ( u64 ) , isize ( usize ) }
0 commit comments