use crate::simd::intrinsics;
use crate::simd::{LaneCount, Mask, MaskElement, Simd, SimdElement, SupportedLaneCount};
-mod sealed {
- pub trait Sealed<Mask> {
- fn select(mask: Mask, true_values: Self, false_values: Self) -> Self;
- }
-}
-use sealed::Sealed;
-
-/// Supporting trait for vector `select` function
-pub trait Select<Mask>: Sealed<Mask> {}
-
-impl<T, const LANES: usize> Sealed<Mask<T::Mask, LANES>> for Simd<T, LANES>
-where
- T: SimdElement,
- LaneCount<LANES>: SupportedLaneCount,
-{
- #[inline]
- #[must_use = "method returns a new vector and does not mutate the original inputs"]
- fn select(mask: Mask<T::Mask, LANES>, true_values: Self, false_values: Self) -> Self {
- unsafe { intrinsics::simd_select(mask.to_int(), true_values, false_values) }
- }
-}
-
-impl<T, const LANES: usize> Select<Mask<T::Mask, LANES>> for Simd<T, LANES>
-where
- T: SimdElement,
- LaneCount<LANES>: SupportedLaneCount,
-{
-}
-
-impl<T, const LANES: usize> Sealed<Self> for Mask<T, LANES>
-where
- T: MaskElement,
- LaneCount<LANES>: SupportedLaneCount,
-{
- #[inline]
- #[must_use = "method returns a new vector and does not mutate the original inputs"]
- fn select(mask: Self, true_values: Self, false_values: Self) -> Self {
- mask & true_values | !mask & false_values
- }
-}
-
-impl<T, const LANES: usize> Select<Self> for Mask<T, LANES>
-where
- T: MaskElement,
- LaneCount<LANES>: SupportedLaneCount,
-{
-}
-
impl<T, const LANES: usize> Mask<T, LANES>
where
T: MaskElement,
/// let c = mask.select(a, b);
/// assert_eq!(c.to_array(), [0, 5, 6, 3]);
/// ```
+ #[inline]
+ #[must_use = "method returns a new vector and does not mutate the original inputs"]
+ pub fn select<U>(
+ self,
+ true_values: Simd<U, LANES>,
+ false_values: Simd<U, LANES>,
+ ) -> Simd<U, LANES>
+ where
+ U: SimdElement<Mask = T>,
+ {
+ unsafe { intrinsics::simd_select(self.to_int(), true_values, false_values) }
+ }
+
+ /// Choose lanes from two masks.
+ ///
+ /// For each lane in the mask, choose the corresponding lane from `true_values` if
+ /// that lane mask is true, and `false_values` if that lane mask is false.
///
- /// `select` can also be used on masks:
/// ```
/// # #![feature(portable_simd)]
/// # #[cfg(feature = "std")] use core_simd::Mask;
/// let a = Mask::<i32, 4>::from_array([true, true, false, false]);
/// let b = Mask::<i32, 4>::from_array([false, false, true, true]);
/// let mask = Mask::<i32, 4>::from_array([true, false, false, true]);
- /// let c = mask.select(a, b);
+ /// let c = mask.select_mask(a, b);
/// assert_eq!(c.to_array(), [true, false, true, false]);
/// ```
#[inline]
- #[must_use = "method returns a new vector and does not mutate the original inputs"]
- pub fn select<S: Select<Self>>(self, true_values: S, false_values: S) -> S {
- S::select(self, true_values, false_values)
+ #[must_use = "method returns a new mask and does not mutate the original inputs"]
+ pub fn select_mask(self, true_values: Self, false_values: Self) -> Self {
+ self & true_values | !self & false_values
}
}