Skip to content

Commit dfebaf9

Browse files
Merge pull request rust-lang#103 from rust-lang/feature/select
Implement trait Select<Mask> and fn select
2 parents 9a063bc + 563d2a2 commit dfebaf9

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

Diff for: crates/core_simd/src/intrinsics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ extern "platform-intrinsic" {
8181
pub(crate) fn simd_bitmask<T, U>(x: T) -> U;
8282

8383
// select
84+
pub(crate) fn simd_select<T, U>(m: T, a: U, b: U) -> U;
8485
pub(crate) fn simd_select_bitmask<T, U>(m: T, a: U, b: U) -> U;
8586
}
8687

Diff for: crates/core_simd/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ mod transmute;
1414
#[macro_use]
1515
mod reduction;
1616

17+
mod select;
18+
pub use select::Select;
19+
1720
mod comparisons;
1821
mod fmt;
1922
mod intrinsics;

Diff for: crates/core_simd/src/select.rs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
mod sealed {
2+
pub trait Sealed {}
3+
}
4+
use sealed::Sealed;
5+
6+
/// Supporting trait for vector `select` function
7+
pub trait Select<Mask>: Sealed {}
8+
9+
macro_rules! impl_select {
10+
{
11+
$mask:ident ($bits_ty:ident): $($type:ident),*
12+
} => {
13+
$(
14+
impl<const LANES: usize> Sealed for crate::$type<LANES> where Self: crate::LanesAtMost32 {}
15+
impl<const LANES: usize> Select<crate::$mask<LANES>> for crate::$type<LANES>
16+
where
17+
crate::$mask<LANES>: crate::Mask,
18+
crate::$bits_ty<LANES>: crate::LanesAtMost32,
19+
Self: crate::LanesAtMost32,
20+
{}
21+
)*
22+
23+
impl<const LANES: usize> crate::$mask<LANES>
24+
where
25+
Self: crate::Mask,
26+
crate::$bits_ty<LANES>: crate::LanesAtMost32,
27+
{
28+
/// Choose lanes from two vectors.
29+
///
30+
/// For each lane in the mask, choose the corresponding lane from `true_values` if
31+
/// that lane mask is true, and `false_values` if that lane mask is false.
32+
///
33+
/// ```
34+
/// # use core_simd::{Mask32, SimdI32};
35+
/// let a = SimdI32::from_array([0, 1, 2, 3]);
36+
/// let b = SimdI32::from_array([4, 5, 6, 7]);
37+
/// let mask = Mask32::from_array([true, false, false, true]);
38+
/// let c = mask.select(a, b);
39+
/// assert_eq!(c.to_array(), [0, 5, 6, 3]);
40+
/// ```
41+
pub fn select<S: Select<Self>>(self, true_values: S, false_values: S) -> S {
42+
unsafe { crate::intrinsics::simd_select(self.to_int(), true_values, false_values) }
43+
}
44+
}
45+
}
46+
}
47+
48+
impl_select! { Mask8 (SimdI8): SimdU8, SimdI8 }
49+
impl_select! { Mask16 (SimdI16): SimdU16, SimdI16 }
50+
impl_select! { Mask32 (SimdI32): SimdU32, SimdI32, SimdF32}
51+
impl_select! { Mask64 (SimdI64): SimdU64, SimdI64, SimdF64}
52+
impl_select! { MaskSize (SimdIsize): SimdUsize, SimdIsize }

0 commit comments

Comments
 (0)