1use crate::simd::intrinsics;
2use crate::simd::{LaneCount, Mask, MaskElement, Simd, SimdElement, SupportedLaneCount};
3
4impl<T, const N: usize> Mask<T, N>
5where
6 T: MaskElement,
7 LaneCount<N>: SupportedLaneCount,
8{
9 /// Choose elements from two vectors.
10 ///
11 /// For each element in the mask, choose the corresponding element from `true_values` if
12 /// that element mask is true, and `false_values` if that element mask is false.
13 ///
14 /// # Examples
15 /// ```
16 /// # #![feature(portable_simd)]
17 /// # use core::simd::{Simd, Mask};
18 /// let a = Simd::from_array([0, 1, 2, 3]);
19 /// let b = Simd::from_array([4, 5, 6, 7]);
20 /// let mask = Mask::from_array([true, false, false, true]);
21 /// let c = mask.select(a, b);
22 /// assert_eq!(c.to_array(), [0, 5, 6, 3]);
23 /// ```
24 #[inline]
25 #[must_use = "method returns a new vector and does not mutate the original inputs"]
26 pub fn select<U>(self, true_values: Simd<U, N>, false_values: Simd<U, N>) -> Simd<U, N>
27 where
28 U: SimdElement<Mask = T>,
29 {
30 // Safety: The mask has been cast to a vector of integers,
31 // and the operands to select between are vectors of the same type and length.
32 unsafe { intrinsics::simd_select(self.to_int(), true_values, false_values) }
33 }
34
35 /// Choose elements from two masks.
36 ///
37 /// For each element in the mask, choose the corresponding element from `true_values` if
38 /// that element mask is true, and `false_values` if that element mask is false.
39 ///
40 /// # Examples
41 /// ```
42 /// # #![feature(portable_simd)]
43 /// # use core::simd::Mask;
44 /// let a = Mask::<i32, 4>::from_array([true, true, false, false]);
45 /// let b = Mask::<i32, 4>::from_array([false, false, true, true]);
46 /// let mask = Mask::<i32, 4>::from_array([true, false, false, true]);
47 /// let c = mask.select_mask(a, b);
48 /// assert_eq!(c.to_array(), [true, false, true, false]);
49 /// ```
50 #[inline]
51 #[must_use = "method returns a new mask and does not mutate the original inputs"]
52 pub fn select_mask(self, true_values: Self, false_values: Self) -> Self {
53 self & true_values | !self & false_values
54 }
55}
56