Add select for masks

This commit is contained in:
Caleb Zulawski 2021-05-08 00:07:07 +00:00
parent dfebaf901e
commit 0bf5eb5f72
3 changed files with 43 additions and 5 deletions

View file

@ -82,6 +82,7 @@ extern "platform-intrinsic" {
// select
pub(crate) fn simd_select<T, U>(m: T, a: U, b: U) -> U;
#[allow(unused)]
pub(crate) fn simd_select_bitmask<T, U>(m: T, a: U, b: U) -> U;
}

View file

@ -1,10 +1,13 @@
mod sealed {
pub trait Sealed {}
pub trait Sealed {}
}
use sealed::Sealed;
/// Supporting trait for vector `select` function
pub trait Select<Mask>: Sealed {}
pub trait Select<Mask>: Sealed {
#[doc(hidden)]
fn select(mask: Mask, true_values: Self, false_values: Self) -> Self;
}
macro_rules! impl_select {
{
@ -17,9 +20,32 @@ macro_rules! impl_select {
crate::$mask<LANES>: crate::Mask,
crate::$bits_ty<LANES>: crate::LanesAtMost32,
Self: crate::LanesAtMost32,
{}
{
#[doc(hidden)]
#[inline]
fn select(mask: crate::$mask<LANES>, true_values: Self, false_values: Self) -> Self {
unsafe { crate::intrinsics::simd_select(mask.to_int(), true_values, false_values) }
}
}
)*
impl<const LANES: usize> Sealed for crate::$mask<LANES>
where
Self: crate::Mask,
crate::$bits_ty<LANES>: crate::LanesAtMost32,
{}
impl<const LANES: usize> Select<Self> for crate::$mask<LANES>
where
Self: crate::Mask,
crate::$bits_ty<LANES>: crate::LanesAtMost32,
{
#[doc(hidden)]
#[inline]
fn select(mask: Self, true_values: Self, false_values: Self) -> Self {
mask & true_values | !mask & false_values
}
}
impl<const LANES: usize> crate::$mask<LANES>
where
Self: crate::Mask,
@ -38,8 +64,19 @@ macro_rules! impl_select {
/// 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<S: Select<Self>>(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)
}
}
}

View file

@ -1,8 +1,8 @@
#[macro_use]
mod mask_macros;
mod mask8;
mod mask16;
mod mask32;
mod mask64;
mod mask8;
mod masksize;