diff --git a/crates/core_simd/src/swizzle.rs b/crates/core_simd/src/swizzle.rs index 1b8cfdcba71..4d885e40f42 100644 --- a/crates/core_simd/src/swizzle.rs +++ b/crates/core_simd/src/swizzle.rs @@ -367,10 +367,38 @@ where /// Splits a vector into its two halves. /// + /// Vector length must be even, or a compile error will be raised. + /// + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let x = Simd::from_array([0, 1, 2, 3, 4, 5, 6, 7]); + /// let [y, z] = x.split(); + /// assert_eq!(y.to_array(), [0, 1, 2, 3]); + /// assert_eq!(z.to_array(), [4, 5, 6, 7]); + /// ``` + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + #[cfg(feature = "generic_const_exprs")] + pub fn split(self) -> [Simd; 2] + where + LaneCount<{ LANES / 2 }>: SupportedLaneCount, + { + self.split_to::<{ LANES / 2 }>() + } + + /// Splits a vector into its two halves. + /// + /// Vector length must be even, or a compile error will be raised. + /// /// Due to limitations in const generics, the length of the resulting vector cannot be inferred /// from the input vectors. You must specify it explicitly. A compile-time error will be raised /// if `HALF_LANES * 2 != LANES`. /// + /// When using the language feature and `std::simd` crate feature `generic_const_exprs`, prefer + /// to use `Simd::split` which can infer the output length. + /// /// ``` /// # #![feature(portable_simd)] /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; @@ -409,11 +437,35 @@ where [Split::::swizzle(self), Split::::swizzle(self)] } + /// Concatenates two vectors of equal length. + /// + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let x = Simd::from_array([0, 1, 2, 3]); + /// let y = Simd::from_array([4, 5, 6, 7]); + /// let z = x.concat_to::<8>(y); + /// assert_eq!(z.to_array(), [0, 1, 2, 3, 4, 5, 6, 7]); + /// ``` + #[inline] + #[must_use = "method returns a new vector and does not mutate the original inputs"] + #[cfg(feature = "generic_const_exprs")] + pub fn concat(self, other: Self) -> Simd + where + LaneCount<{ LANES * 2 }>: SupportedLaneCount, + { + self.concat_to::<{ LANES * 2 }>(other) + } + /// Concatenates two vectors of equal length. /// /// Due to limitations in const generics, the length of the resulting vector cannot be inferred /// from the input vectors. You must specify it explicitly. A compile time error will be raised - /// if `LANES * 2 != DOUBLE_LANES` + /// if `LANES * 2 != DOUBLE_LANES`. + /// + /// When using the language feature and `std::simd` crate feature `generic_const_exprs`, prefer + /// to use `Simd::split` which can infer the output length. /// /// ``` /// # #![feature(portable_simd)] diff --git a/crates/core_simd/tests/swizzle.rs b/crates/core_simd/tests/swizzle.rs index 0d4bd85a07d..2a810001787 100644 --- a/crates/core_simd/tests/swizzle.rs +++ b/crates/core_simd/tests/swizzle.rs @@ -1,5 +1,5 @@ #![feature(portable_simd)] -use core_simd::simd::{Simd, Swizzle}; +use core_simd::simd::{Simd, Swizzle, u32x4}; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -77,7 +77,7 @@ fn interleave_one() { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] -fn slice() { +fn split_to() { let a = Simd::from_array([0, 1, 2, 3, 4, 5, 6, 7]); let [lo, hi] = a.split_to::<4>(); assert_eq!(lo.to_array(), [0, 1, 2, 3]); @@ -86,13 +86,31 @@ fn slice() { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] -fn concat() { +fn split() { + let a = Simd::from_array([0, 1, 2, 3, 4, 5, 6, 7]); + let [lo, hi]: [u32x4] = a.split(); + assert_eq!(lo.to_array(), [0, 1, 2, 3]); + assert_eq!(hi.to_array(), [4, 5, 6, 7]); +} + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn concat_to() { let x = Simd::from_array([0, 1, 2, 3]); let y = Simd::from_array([4, 5, 6, 7]); let z = x.concat_to::<8>(y); assert_eq!(z.to_array(), [0, 1, 2, 3, 4, 5, 6, 7]); } +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn concat() { + let x = Simd::from_array([0, 1, 2, 3]); + let y = Simd::from_array([4, 5, 6, 7]); + let z = x.concat(y); + assert_eq!(z.to_array(), [0, 1, 2, 3, 4, 5, 6, 7]); +} + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn general_reverse() {