blob: 64536be6cba13ff802d21767b2889dc5658bc6aa [file] [log] [blame]
//! Shuffle vector elements according to a dynamic vector of indices.
macro_rules! impl_shuffle1_dyn {
([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => {
impl $id {
/// Shuffle vector elements according to `indices`.
#[inline]
pub fn shuffle1_dyn<I>(self, indices: I) -> Self
where
Self: codegen::shuffle1_dyn::Shuffle1Dyn<Indices = I>,
{
codegen::shuffle1_dyn::Shuffle1Dyn::shuffle1_dyn(self, indices)
}
}
};
}
macro_rules! test_shuffle1_dyn {
([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => {
test_if! {
$test_tt:
paste::item! {
pub mod [<$id _shuffle1_dyn>] {
use super::*;
#[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn shuffle1_dyn() {
let increasing = {
let mut v = $id::splat(0 as $elem_ty);
for i in 0..$id::lanes() {
v = v.replace(i, i as $elem_ty);
}
v
};
let decreasing = {
let mut v = $id::splat(0 as $elem_ty);
for i in 0..$id::lanes() {
v = v.replace(
i,
($id::lanes() - 1 - i) as $elem_ty
);
}
v
};
type Indices = <
$id as codegen::shuffle1_dyn::Shuffle1Dyn
>::Indices;
let increasing_ids: Indices = increasing.cast();
let decreasing_ids: Indices = decreasing.cast();
assert_eq!(
increasing.shuffle1_dyn(increasing_ids),
increasing,
"(i,i)=>i"
);
assert_eq!(
decreasing.shuffle1_dyn(increasing_ids),
decreasing,
"(d,i)=>d"
);
assert_eq!(
increasing.shuffle1_dyn(decreasing_ids),
decreasing,
"(i,d)=>d"
);
assert_eq!(
decreasing.shuffle1_dyn(decreasing_ids),
increasing,
"(d,d)=>i"
);
for i in 0..$id::lanes() {
let v_ids: Indices
= $id::splat(i as $elem_ty).cast();
assert_eq!(increasing.shuffle1_dyn(v_ids),
$id::splat(increasing.extract(i))
);
assert_eq!(decreasing.shuffle1_dyn(v_ids),
$id::splat(decreasing.extract(i))
);
assert_eq!(
$id::splat(i as $elem_ty)
.shuffle1_dyn(increasing_ids),
$id::splat(i as $elem_ty)
);
assert_eq!(
$id::splat(i as $elem_ty)
.shuffle1_dyn(decreasing_ids),
$id::splat(i as $elem_ty)
);
}
}
}
}
}
};
}
macro_rules! test_shuffle1_dyn_mask {
([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => {
test_if! {
$test_tt:
paste::item! {
pub mod [<$id _shuffle1_dyn>] {
use super::*;
#[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn shuffle1_dyn() {
// alternating = [true, false, true, false, ...]
let mut alternating = $id::splat(false);
for i in 0..$id::lanes() {
if i % 2 == 0 {
alternating = alternating.replace(i, true);
}
}
type Indices = <
$id as codegen::shuffle1_dyn::Shuffle1Dyn
>::Indices;
// even = [0, 0, 2, 2, 4, 4, ..]
let even = {
let mut v = Indices::splat(0);
for i in 0..$id::lanes() {
if i % 2 == 0 {
v = v.replace(i, (i as u8).into());
} else {
v = v.replace(i, (i as u8 - 1).into());
}
}
v
};
// odd = [1, 1, 3, 3, 5, 5, ...]
let odd = {
let mut v = Indices::splat(0);
for i in 0..$id::lanes() {
if i % 2 != 0 {
v = v.replace(i, (i as u8).into());
} else {
v = v.replace(i, (i as u8 + 1).into());
}
}
v
};
assert_eq!(
alternating.shuffle1_dyn(even),
$id::splat(true)
);
if $id::lanes() > 1 {
assert_eq!(
alternating.shuffle1_dyn(odd),
$id::splat(false)
);
}
}
}
}
}
};
}