//! Implements mask's `select`. /// Implements mask select method macro_rules! impl_select { ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Selects elements of `a` and `b` using mask. /// /// The lanes of the result for which the mask is `true` contain /// the values of `a`. The remaining lanes contain the values of /// `b`. #[inline] pub fn select(self, a: Simd, b: Simd) -> Simd where T: sealed::SimdArray::NT>, { use crate::llvm::simd_select; Simd(unsafe { simd_select(self.0, a.0, b.0) }) } } test_select!(bool, $id, $id, (false, true) | $test_tt); }; } macro_rules! test_select { ( $elem_ty:ident, $mask_ty:ident, $vec_ty:ident,($small:expr, $large:expr) | $test_tt:tt ) => { test_if! { $test_tt: paste::item! { pub mod [<$vec_ty _select>] { use super::*; #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn select() { let o = $small as $elem_ty; let t = $large as $elem_ty; let a = $vec_ty::splat(o); let b = $vec_ty::splat(t); let m = a.lt(b); assert_eq!(m.select(a, b), a); let m = b.lt(a); assert_eq!(m.select(b, a), a); let mut c = a; let mut d = b; let mut m_e = $mask_ty::splat(false); for i in 0..$vec_ty::lanes() { if i % 2 == 0 { let c_tmp = c.extract(i); c = c.replace(i, d.extract(i)); d = d.replace(i, c_tmp); } else { m_e = m_e.replace(i, true); } } let m = c.lt(d); assert_eq!(m_e, m); assert_eq!(m.select(c, d), a); } } } } }; }