From: Caleb Zulawski Date: Sat, 8 May 2021 00:07:07 +0000 (+0000) Subject: Add select for masks X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;ds=sidebyside;h=0bf5eb5f72f354489ce897a2bd1f6c1e9102fdd2;p=rust.git Add select for masks --- diff --git a/crates/core_simd/src/intrinsics.rs b/crates/core_simd/src/intrinsics.rs index 798c4461f79..3779d96a40e 100644 --- a/crates/core_simd/src/intrinsics.rs +++ b/crates/core_simd/src/intrinsics.rs @@ -82,6 +82,7 @@ // select pub(crate) fn simd_select(m: T, a: U, b: U) -> U; + #[allow(unused)] pub(crate) fn simd_select_bitmask(m: T, a: U, b: U) -> U; } diff --git a/crates/core_simd/src/select.rs b/crates/core_simd/src/select.rs index 66b0839cf24..a00af73ef4d 100644 --- a/crates/core_simd/src/select.rs +++ b/crates/core_simd/src/select.rs @@ -1,10 +1,13 @@ mod sealed { -pub trait Sealed {} + pub trait Sealed {} } use sealed::Sealed; /// Supporting trait for vector `select` function -pub trait Select: Sealed {} +pub trait Select: Sealed { + #[doc(hidden)] + fn select(mask: Mask, true_values: Self, false_values: Self) -> Self; +} macro_rules! impl_select { { @@ -17,9 +20,32 @@ impl Select> for crate::$type crate::$mask: crate::Mask, crate::$bits_ty: crate::LanesAtMost32, Self: crate::LanesAtMost32, - {} + { + #[doc(hidden)] + #[inline] + fn select(mask: crate::$mask, true_values: Self, false_values: Self) -> Self { + unsafe { crate::intrinsics::simd_select(mask.to_int(), true_values, false_values) } + } + } )* + impl Sealed for crate::$mask + where + Self: crate::Mask, + crate::$bits_ty: crate::LanesAtMost32, + {} + impl Select for crate::$mask + where + Self: crate::Mask, + crate::$bits_ty: crate::LanesAtMost32, + { + #[doc(hidden)] + #[inline] + fn select(mask: Self, true_values: Self, false_values: Self) -> Self { + mask & true_values | !mask & false_values + } + } + impl crate::$mask where Self: crate::Mask, @@ -38,8 +64,19 @@ impl crate::$mask /// let c = mask.select(a, b); /// assert_eq!(c.to_array(), [0, 5, 6, 3]); /// ``` + /// + /// `select` can also be used with masks: + /// ``` + /// # use core_simd::{Mask32}; + /// let a = Mask32::from_array([true, true, false, false]); + /// let b = Mask32::from_array([false, false, true, true]); + /// let mask = Mask32::from_array([true, false, false, true]); + /// let c = mask.select(a, b); + /// assert_eq!(c.to_array(), [true, false, true, false]); + /// ``` + #[inline] pub fn select>(self, true_values: S, false_values: S) -> S { - unsafe { crate::intrinsics::simd_select(self.to_int(), true_values, false_values) } + S::select(self, true_values, false_values) } } } diff --git a/crates/core_simd/tests/mask_ops_impl/mod.rs b/crates/core_simd/tests/mask_ops_impl/mod.rs index ff36af95651..b414167866e 100644 --- a/crates/core_simd/tests/mask_ops_impl/mod.rs +++ b/crates/core_simd/tests/mask_ops_impl/mod.rs @@ -1,8 +1,8 @@ #[macro_use] mod mask_macros; -mod mask8; mod mask16; mod mask32; mod mask64; +mod mask8; mod masksize;