pub fn shuffle<const IDX: [u32; $n]>(self, second: Self) -> Self {
unsafe { crate::intrinsics::$fn(self, second, IDX) }
}
+
+ /// Reverse the order of the lanes in the vector.
+ #[inline]
+ pub fn reverse(self) -> Self {
+ const fn idx() -> [u32; $n] {
+ let mut idx = [0u32; $n];
+ let mut i = 0;
+ while i < $n {
+ idx[i] = ($n - i - 1) as u32;
+ i += 1;
+ }
+ idx
+ }
+ self.shuffle::<{ idx() }>(self)
+ }
+
+ /// Interleave two vectors.
+ ///
+ /// The even lanes of the first result contain the lower half of `self`, and the odd
+ /// lanes contain the lower half of `other`.
+ ///
+ /// The even lanes of the second result contain the upper half of `self`, and the odd
+ /// lanes contain the upper half of `other`.
+ #[inline]
+ pub fn interleave(self, other: Self) -> (Self, Self) {
+ const fn lo() -> [u32; $n] {
+ let mut idx = [0u32; $n];
+ let mut i = 0;
+ while i < $n {
+ let offset = i / 2;
+ idx[i] = if i % 2 == 0 {
+ offset
+ } else {
+ $n + offset
+ } as u32;
+ i += 1;
+ }
+ idx
+ }
+ const fn hi() -> [u32; $n] {
+ let mut idx = [0u32; $n];
+ let mut i = 0;
+ while i < $n {
+ let offset = ($n + i) / 2;
+ idx[i] = if i % 2 == 0 {
+ offset
+ } else {
+ $n + offset
+ } as u32;
+ i += 1;
+ }
+ idx
+ }
+ (self.shuffle::<{ lo() }>(other), self.shuffle::<{ hi() }>(other))
+ }
+
+ /// Deinterleave two vectors.
+ ///
+ /// The first result contains the even lanes of `self` and `other` concatenated.
+ ///
+ /// The second result contains the odd lanes of `self` and `other` concatenated.
+ #[inline]
+ pub fn deinterleave(self, other: Self) -> (Self, Self) {
+ const fn even() -> [u32; $n] {
+ let mut idx = [0u32; $n];
+ let mut i = 0;
+ while i < $n {
+ idx[i] = 2 * i as u32;
+ i += 1;
+ }
+ idx
+ }
+ const fn odd() -> [u32; $n] {
+ let mut idx = [0u32; $n];
+ let mut i = 0;
+ while i < $n {
+ idx[i] = 1 + 2 * i as u32;
+ i += 1;
+ }
+ idx
+ }
+ (self.shuffle::<{ even() }>(other), self.shuffle::<{ odd() }>(other))
+ }
}
}
}
let b = a;
assert_eq!(a.shuffle::<{ [3, 1, 4, 6] }>(b).to_array(), [9, 4, 2, 1]);
}
+
+#[test]
+#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+fn reverse() {
+ let a = SimdU32::from_array([0, 1, 2, 3, 4, 5, 6, 7]);
+ assert_eq!(a.reverse().to_array(), [7, 6, 5, 4, 3, 2, 1, 0]);
+}
+
+#[test]
+#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+fn interleave() {
+ let a = SimdU32::from_array([0, 1, 2, 3, 4, 5, 6, 7]);
+ let b = SimdU32::from_array([8, 9, 10, 11, 12, 13, 14, 15]);
+ let (lo, hi) = a.interleave(b);
+ assert_eq!(lo.to_array(), [0, 8, 1, 9, 2, 10, 3, 11]);
+ assert_eq!(hi.to_array(), [4, 12, 5, 13, 6, 14, 7, 15]);
+ let (even, odd) = lo.deinterleave(hi);
+ assert_eq!(even, a);
+ assert_eq!(odd, b);
+}