diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs index 61e1199095fb..e51052f53f2f 100644 --- a/crates/core_simd/src/masks/mod.rs +++ b/crates/core_simd/src/masks/mod.rs @@ -59,6 +59,24 @@ macro_rules! define_opaque_mask { } } + impl From<$inner_ty> for $name<$lanes> + where + BitMask<$lanes>: LanesAtMost64, + { + fn from(value: $inner_ty) -> Self { + Self(value) + } + } + + impl From<$name<$lanes>> for $inner_ty + where + BitMask<$lanes>: LanesAtMost64, + { + fn from(value: $name<$lanes>) -> Self { + value.0 + } + } + impl Copy for $name<$lanes> where BitMask<$lanes>: LanesAtMost64 {} impl Clone for $name<$lanes> where BitMask<$lanes>: LanesAtMost64 { diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs new file mode 100644 index 000000000000..1ae003fc27fc --- /dev/null +++ b/crates/core_simd/tests/masks.rs @@ -0,0 +1,67 @@ +use core_simd::{BitMask, Mask8, SimdMask8, SimdI8}; +use core::convert::TryFrom; + +#[cfg(target_arch = "wasm32")] +use wasm_bindgen_test::*; + +#[cfg(target_arch = "wasm32")] +wasm_bindgen_test_configure!(run_in_browser); + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn mask_format_round_trip() { + let ints = SimdI8::from_array([-1, 0, 0, -1]); + + let simd_mask = SimdMask8::try_from(ints).unwrap(); + + let bitmask = BitMask::from(simd_mask); + + let opaque_mask = Mask8::from(bitmask); + + let simd_mask_returned = SimdMask8::from(opaque_mask); + + let ints_returned = SimdI8::from(simd_mask_returned); + + assert_eq!(ints_returned, ints); +} + +macro_rules! test_mask_api { + { $name:ident } => { + #[allow(non_snake_case)] + mod $name { + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn set_and_test() { + let values = [true, false, false, true, false, false, true, false]; + let mut mask = core_simd::$name::<8>::splat(false); + for (lane, value) in values.iter().copied().enumerate() { + mask.set(lane, value); + } + for (lane, value) in values.iter().copied().enumerate() { + assert_eq!(mask.test(lane), value); + } + } + + #[test] + #[should_panic] + fn set_invalid_lane() { + let mut mask = core_simd::$name::<8>::splat(false); + mask.set(8, true); + let _ = mask; + } + + #[test] + #[should_panic] + fn test_invalid_lane() { + let mask = core_simd::$name::<8>::splat(false); + let _ = mask.test(8); + } + } + } +} + +mod mask_api { + test_mask_api!{ Mask8 } + test_mask_api!{ SimdMask8 } + test_mask_api!{ BitMask } +}