10
10
11
11
#![ allow( unused) ]
12
12
#![ allow( non_camel_case_types) ]
13
+ #![ allow( unexpected_cfgs) ]
13
14
14
15
// The field is currently left `pub` for convenience in porting tests, many of
15
16
// which attempt to just construct it directly. That still works; it's just the
@@ -24,39 +25,32 @@ impl<T: Copy, const N: usize> Clone for Simd<T, N> {
24
25
}
25
26
}
26
27
27
- impl < T : PartialEq , const N : usize > PartialEq for Simd < T , N > {
28
- fn eq ( & self , other : & Self ) -> bool {
29
- self . as_array ( ) == other. as_array ( )
30
- }
31
- }
32
-
33
28
impl < T : core:: fmt:: Debug , const N : usize > core:: fmt:: Debug for Simd < T , N > {
34
29
fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> Result < ( ) , core:: fmt:: Error > {
35
30
<[ T ; N ] as core:: fmt:: Debug >:: fmt ( self . as_array ( ) , f)
36
31
}
37
32
}
38
33
39
- impl < T , const N : usize > core:: ops:: Index < usize > for Simd < T , N > {
40
- type Output = T ;
41
- fn index ( & self , i : usize ) -> & T {
42
- & self . as_array ( ) [ i]
43
- }
44
- }
45
-
46
34
impl < T , const N : usize > Simd < T , N > {
47
35
pub const fn from_array ( a : [ T ; N ] ) -> Self {
48
36
Simd ( a)
49
37
}
50
- pub fn as_array ( & self ) -> & [ T ; N ] {
38
+ pub const fn as_array ( & self ) -> & [ T ; N ] {
51
39
let p: * const Self = self ;
52
40
unsafe { & * p. cast :: < [ T ; N ] > ( ) }
53
41
}
54
- pub fn into_array ( self ) -> [ T ; N ]
42
+ pub const fn into_array ( self ) -> [ T ; N ]
55
43
where
56
44
T : Copy ,
57
45
{
58
46
* self . as_array ( )
59
47
}
48
+ pub const fn splat ( a : T ) -> Self
49
+ where
50
+ T : Copy ,
51
+ {
52
+ Self ( [ a; N ] )
53
+ }
60
54
}
61
55
62
56
pub type u8x2 = Simd < u8 , 2 > ;
@@ -109,6 +103,14 @@ pub type i64x8 = Simd<i64, 8>;
109
103
pub type i128x2 = Simd < i128 , 2 > ;
110
104
pub type i128x4 = Simd < i128 , 4 > ;
111
105
106
+ pub type usizex2 = Simd < usize , 2 > ;
107
+ pub type usizex4 = Simd < usize , 4 > ;
108
+ pub type usizex8 = Simd < usize , 8 > ;
109
+
110
+ pub type isizex2 = Simd < isize , 2 > ;
111
+ pub type isizex4 = Simd < isize , 4 > ;
112
+ pub type isizex8 = Simd < isize , 8 > ;
113
+
112
114
pub type f32x2 = Simd < f32 , 2 > ;
113
115
pub type f32x4 = Simd < f32 , 4 > ;
114
116
pub type f32x8 = Simd < f32 , 8 > ;
@@ -122,7 +124,7 @@ pub type f64x8 = Simd<f64, 8>;
122
124
// which attempt to just construct it directly. That still works; it's just the
123
125
// `.0` projection that doesn't.
124
126
#[ repr( simd, packed) ]
125
- #[ derive( Copy ) ]
127
+ #[ derive( Copy , Eq ) ]
126
128
pub struct PackedSimd < T , const N : usize > ( pub [ T ; N ] ) ;
127
129
128
130
impl < T : Copy , const N : usize > Clone for PackedSimd < T , N > {
@@ -131,12 +133,6 @@ impl<T: Copy, const N: usize> Clone for PackedSimd<T, N> {
131
133
}
132
134
}
133
135
134
- impl < T : PartialEq , const N : usize > PartialEq for PackedSimd < T , N > {
135
- fn eq ( & self , other : & Self ) -> bool {
136
- self . as_array ( ) == other. as_array ( )
137
- }
138
- }
139
-
140
136
impl < T : core:: fmt:: Debug , const N : usize > core:: fmt:: Debug for PackedSimd < T , N > {
141
137
fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> Result < ( ) , core:: fmt:: Error > {
142
138
<[ T ; N ] as core:: fmt:: Debug >:: fmt ( self . as_array ( ) , f)
@@ -147,14 +143,100 @@ impl<T, const N: usize> PackedSimd<T, N> {
147
143
pub const fn from_array ( a : [ T ; N ] ) -> Self {
148
144
PackedSimd ( a)
149
145
}
150
- pub fn as_array ( & self ) -> & [ T ; N ] {
146
+ pub const fn as_array ( & self ) -> & [ T ; N ] {
151
147
let p: * const Self = self ;
152
148
unsafe { & * p. cast :: < [ T ; N ] > ( ) }
153
149
}
154
- pub fn into_array ( self ) -> [ T ; N ]
150
+ pub const fn into_array ( self ) -> [ T ; N ]
155
151
where
156
152
T : Copy ,
157
153
{
158
154
* self . as_array ( )
159
155
}
156
+ pub const fn splat ( a : T ) -> Self
157
+ where
158
+ T : Copy ,
159
+ {
160
+ Self ( [ a; N ] )
161
+ }
160
162
}
163
+
164
+ // As `const_trait_impl` is a language feature with specialized syntax, we have to use them in a way
165
+ // such that it doesn't get parsed as Rust code unless `cfg(minisimd_const)` is on. The easiest way
166
+ // for that is a macro
167
+
168
+ #[ cfg( minisimd_const) ]
169
+ macro_rules! impl_traits {
170
+ ( ) => {
171
+ impl <T : [ const ] PartialEq , const N : usize > const PartialEq for Simd <T , N > {
172
+ fn eq( & self , other: & Self ) -> bool {
173
+ self . as_array( ) == other. as_array( )
174
+ }
175
+ }
176
+
177
+ impl <T , const N : usize > const core:: ops:: Index <usize > for Simd <T , N > {
178
+ type Output = T ;
179
+ fn index( & self , i: usize ) -> & T {
180
+ & self . as_array( ) [ i]
181
+ }
182
+ }
183
+
184
+ impl <T : [ const ] PartialEq , const N : usize > const PartialEq for PackedSimd <T , N > {
185
+ fn eq( & self , other: & Self ) -> bool {
186
+ self . as_array( ) == other. as_array( )
187
+ }
188
+ }
189
+ } ;
190
+ }
191
+
192
+ #[ cfg( not( minisimd_const) ) ]
193
+ macro_rules! impl_traits {
194
+ ( ) => {
195
+ impl <T : PartialEq , const N : usize > PartialEq for Simd <T , N > {
196
+ fn eq( & self , other: & Self ) -> bool {
197
+ self . as_array( ) == other. as_array( )
198
+ }
199
+ }
200
+
201
+ impl <T , const N : usize > core:: ops:: Index <usize > for Simd <T , N > {
202
+ type Output = T ;
203
+ fn index( & self , i: usize ) -> & T {
204
+ & self . as_array( ) [ i]
205
+ }
206
+ }
207
+
208
+ impl <T : PartialEq , const N : usize > PartialEq for PackedSimd <T , N > {
209
+ fn eq( & self , other: & Self ) -> bool {
210
+ self . as_array( ) == other. as_array( )
211
+ }
212
+ }
213
+ } ;
214
+ }
215
+
216
+ impl_traits ! ( ) ;
217
+
218
+ /// Version of `assert_eq` that ignores fancy runtime printing in const context
219
+ #[ cfg( minisimd_const) ]
220
+ #[ macro_export]
221
+ macro_rules! assert_eq_const_safe {
222
+ ( $left: expr, $right: expr $( , ) ?) => {
223
+ assert_eq_const_safe!(
224
+ $left,
225
+ $right,
226
+ concat!( "`" , stringify!( $left) , "` == `" , stringify!( $right) , "`" )
227
+ ) ;
228
+ } ;
229
+ ( $left: expr, $right: expr$( , $( $arg: tt) +) ?) => {
230
+ {
231
+ let left = $left;
232
+ let right = $right;
233
+ // type inference works better with the concrete type on the
234
+ // left, but humans work better with the expected on the
235
+ // right
236
+ assert!( right == left, $( $( $arg) * ) ,* ) ;
237
+ }
238
+ } ;
239
+ }
240
+
241
+ #[ cfg( minisimd_const) ]
242
+ use assert_eq_const_safe;
0 commit comments