Implement missing traits on opaque masks, fix tests

This commit is contained in:
Caleb Zulawski 2020-11-22 15:18:31 -05:00
parent 5bc5d7f0d1
commit 78a8d615b5
9 changed files with 233 additions and 86 deletions

View File

@ -158,6 +158,136 @@ macro_rules! define_opaque_mask {
self.0.partial_cmp(&other.0) self.0.partial_cmp(&other.0)
} }
} }
impl core::fmt::Debug for $name {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.debug_list()
.entries((0..$lanes).map(|i| self.test(i)))
.finish()
}
}
impl core::ops::BitAnd for $name {
type Output = Self;
#[inline]
fn bitand(self, rhs: Self) -> Self {
Self(self.0 & rhs.0)
}
}
impl core::ops::BitAnd<bool> for $name {
type Output = Self;
#[inline]
fn bitand(self, rhs: bool) -> Self {
self & Self::splat(rhs)
}
}
impl core::ops::BitAnd<$name> for bool {
type Output = $name;
#[inline]
fn bitand(self, rhs: $name) -> $name {
$name::splat(self) & rhs
}
}
impl core::ops::BitOr for $name {
type Output = Self;
#[inline]
fn bitor(self, rhs: Self) -> Self {
Self(self.0 | rhs.0)
}
}
impl core::ops::BitOr<bool> for $name {
type Output = Self;
#[inline]
fn bitor(self, rhs: bool) -> Self {
self | Self::splat(rhs)
}
}
impl core::ops::BitOr<$name> for bool {
type Output = $name;
#[inline]
fn bitor(self, rhs: $name) -> $name {
$name::splat(self) | rhs
}
}
impl core::ops::BitXor for $name {
type Output = Self;
#[inline]
fn bitxor(self, rhs: Self) -> Self::Output {
Self(self.0 ^ rhs.0)
}
}
impl core::ops::BitXor<bool> for $name {
type Output = Self;
#[inline]
fn bitxor(self, rhs: bool) -> Self::Output {
self ^ Self::splat(rhs)
}
}
impl core::ops::BitXor<$name> for bool {
type Output = $name;
#[inline]
fn bitxor(self, rhs: $name) -> Self::Output {
$name::splat(self) ^ rhs
}
}
impl core::ops::Not for $name {
type Output = $name;
#[inline]
fn not(self) -> Self::Output {
Self(!self.0)
}
}
impl core::ops::BitAndAssign for $name {
#[inline]
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0;
}
}
impl core::ops::BitAndAssign<bool> for $name {
#[inline]
fn bitand_assign(&mut self, rhs: bool) {
*self &= Self::splat(rhs);
}
}
impl core::ops::BitOrAssign for $name {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
impl core::ops::BitOrAssign<bool> for $name {
#[inline]
fn bitor_assign(&mut self, rhs: bool) {
*self |= Self::splat(rhs);
}
}
impl core::ops::BitXorAssign for $name {
#[inline]
fn bitxor_assign(&mut self, rhs: Self) {
self.0 ^= rhs.0;
}
}
impl core::ops::BitXorAssign<bool> for $name {
#[inline]
fn bitxor_assign(&mut self, rhs: bool) {
*self ^= Self::splat(rhs);
}
}
}; };
{ new [$width:ty; $lanes:tt] $($var:ident)* } => { { new [$width:ty; $lanes:tt] $($var:ident)* } => {
/// Construct a vector by setting each lane to the given values. /// Construct a vector by setting each lane to the given values.

View File

@ -70,7 +70,12 @@ impl_biteq! {
integer impl BitEq for integer impl BitEq for
u8, u16, u32, u64, u128, usize, u8, u16, u32, u64, u128, usize,
i8, i16, i32, i64, i128, isize, i8, i16, i32, i64, i128, isize,
core_simd::mask8, core_simd::mask16, core_simd::mask32, core_simd::mask64, core_simd::mask128, core_simd::masksize, core_simd::masks::wide::m8,
core_simd::masks::wide::m16,
core_simd::masks::wide::m32,
core_simd::masks::wide::m64,
core_simd::masks::wide::m128,
core_simd::masks::wide::msize,
} }
impl_biteq! { impl_biteq! {
@ -93,12 +98,12 @@ impl_biteq! {
core_simd::isizex2, core_simd::isizex4, core_simd::isizex8, core_simd::isizex2, core_simd::isizex4, core_simd::isizex8,
core_simd::f32x2, core_simd::f32x4, core_simd::f32x8, core_simd::f32x16, core_simd::f32x2, core_simd::f32x4, core_simd::f32x8, core_simd::f32x16,
core_simd::f64x2, core_simd::f64x4, core_simd::f64x8, core_simd::f64x2, core_simd::f64x4, core_simd::f64x8,
core_simd::mask8x8, core_simd::mask8x16, core_simd::mask8x32, core_simd::mask8x64, core_simd::masks::wide::m8x8, core_simd::masks::wide::m8x16, core_simd::masks::wide::m8x32, core_simd::masks::wide::m8x64,
core_simd::mask16x4, core_simd::mask16x8, core_simd::mask16x16, core_simd::mask16x32, core_simd::masks::wide::m16x4, core_simd::masks::wide::m16x8, core_simd::masks::wide::m16x16, core_simd::masks::wide::m16x32,
core_simd::mask32x2, core_simd::mask32x4, core_simd::mask32x8, core_simd::mask32x16, core_simd::masks::wide::m32x2, core_simd::masks::wide::m32x4, core_simd::masks::wide::m32x8, core_simd::masks::wide::m32x16,
core_simd::mask64x2, core_simd::mask64x4, core_simd::mask64x8, core_simd::masks::wide::m64x2, core_simd::masks::wide::m64x4, core_simd::masks::wide::m64x8,
core_simd::mask128x2, core_simd::mask128x4, core_simd::masks::wide::m128x2, core_simd::masks::wide::m128x4,
core_simd::masksizex2, core_simd::masksizex4, core_simd::masksizex8, core_simd::masks::wide::msizex2, core_simd::masks::wide::msizex4, core_simd::masks::wide::msizex8,
} }
pub(crate) struct BitEqWrapper<'a, T>(pub(crate) &'a T); pub(crate) struct BitEqWrapper<'a, T>(pub(crate) &'a T);

View File

@ -1,4 +1,2 @@
use super::helpers; mask_tests! { mask128x2, 2 }
mask_tests! { mask128x4, 4 }
mask_tests! { mask128x2, mask128 }
mask_tests! { mask128x4, mask128 }

View File

@ -1,6 +1,4 @@
use super::helpers; mask_tests! { mask16x4, 4 }
mask_tests! { mask16x8, 8 }
mask_tests! { mask16x4, mask16 } mask_tests! { mask16x16, 16 }
mask_tests! { mask16x8, mask16 } mask_tests! { mask16x32, 32 }
mask_tests! { mask16x16, mask16 }
mask_tests! { mask16x32, mask16 }

View File

@ -1,6 +1,4 @@
use super::helpers; mask_tests! { mask32x2, 2 }
mask_tests! { mask32x4, 4 }
mask_tests! { mask32x2, mask32 } mask_tests! { mask32x8, 8 }
mask_tests! { mask32x4, mask32 } mask_tests! { mask32x16, 16 }
mask_tests! { mask32x8, mask32 }
mask_tests! { mask32x16, mask32 }

View File

@ -1,5 +1,3 @@
use super::helpers; mask_tests! { mask64x2, 2 }
mask_tests! { mask64x4, 4 }
mask_tests! { mask64x2, mask64 } mask_tests! { mask64x8, 8 }
mask_tests! { mask64x4, mask64 }
mask_tests! { mask64x8, mask64 }

View File

@ -1,6 +1,4 @@
use super::helpers; mask_tests! { mask8x8, 8 }
mask_tests! { mask8x16, 16 }
mask_tests! { mask8x8, mask8 } mask_tests! { mask8x32, 32 }
mask_tests! { mask8x16, mask8 } mask_tests! { mask8x64, 64 }
mask_tests! { mask8x32, mask8 }
mask_tests! { mask8x64, mask8 }

View File

@ -1,9 +1,9 @@
macro_rules! mask_tests { macro_rules! mask_tests {
{ $vector:ident, $scalar:ident } => { { $vector:ident, $lanes:literal } => {
#[cfg(test)] #[cfg(test)]
mod $vector { mod $vector {
use super::*; use core_simd::$vector as Vector;
use helpers::lanewise::*; const LANES: usize = $lanes;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*; use wasm_bindgen_test::*;
@ -11,15 +11,44 @@ macro_rules! mask_tests {
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
wasm_bindgen_test_configure!(run_in_browser); wasm_bindgen_test_configure!(run_in_browser);
fn from_slice(slice: &[bool]) -> core_simd::$vector { fn from_slice(slice: &[bool]) -> Vector {
let mut value = core_simd::$vector::default(); let mut value = Vector::default();
let value_slice: &mut [_] = value.as_mut(); for (i, b) in slice.iter().take(LANES).enumerate() {
for (m, b) in value_slice.iter_mut().zip(slice.iter()) { value.set(i, *b);
*m = (*b).into();
} }
value value
} }
fn apply_unary_lanewise(x: Vector, f: impl Fn(bool) -> bool) -> Vector {
let mut value = Vector::default();
for i in 0..LANES {
value.set(i, f(x.test(i)));
}
value
}
fn apply_binary_lanewise(x: Vector, y: Vector, f: impl Fn(bool, bool) -> bool) -> Vector {
let mut value = Vector::default();
for i in 0..LANES {
value.set(i, f(x.test(i), y.test(i)));
}
value
}
fn apply_binary_scalar_lhs_lanewise(x: bool, mut y: Vector, f: impl Fn(bool, bool) -> bool) -> Vector {
for i in 0..LANES {
y.set(i, f(x, y.test(i)));
}
y
}
fn apply_binary_scalar_rhs_lanewise(mut x: Vector, y: bool, f: impl Fn(bool, bool) -> bool) -> Vector {
for i in 0..LANES {
x.set(i, f(x.test(i), y));
}
x
}
const A: [bool; 64] = [ const A: [bool; 64] = [
false, true, false, true, false, false, true, true, false, true, false, true, false, false, true, true,
false, true, false, true, false, false, true, true, false, true, false, true, false, false, true, true,
@ -41,18 +70,13 @@ macro_rules! mask_tests {
false, false, true, true, false, true, false, true, false, false, true, true, false, true, false, true,
]; ];
const SET_SCALAR: core_simd::$scalar = core_simd::$scalar::new(true);
const UNSET_SCALAR: core_simd::$scalar = core_simd::$scalar::new(false);
const SET_VECTOR: core_simd::$vector = core_simd::$vector::splat(SET_SCALAR);
const UNSET_VECTOR: core_simd::$vector = core_simd::$vector::splat(UNSET_SCALAR);
#[test] #[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn bitand() { fn bitand() {
let a = from_slice(&A); let a = from_slice(&A);
let b = from_slice(&B); let b = from_slice(&B);
let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand); let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand);
assert_biteq!(a & b, expected); assert_eq!(a & b, expected);
} }
#[test] #[test]
@ -62,7 +86,7 @@ macro_rules! mask_tests {
let b = from_slice(&B); let b = from_slice(&B);
let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand); let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand);
a &= b; a &= b;
assert_biteq!(a, expected); assert_eq!(a, expected);
} }
#[test] #[test]
@ -70,8 +94,8 @@ macro_rules! mask_tests {
fn bitand_scalar_rhs() { fn bitand_scalar_rhs() {
let a = from_slice(&A); let a = from_slice(&A);
let expected = a; let expected = a;
assert_biteq!(a & SET_SCALAR, expected); assert_eq!(a & true, expected);
assert_biteq!(a & UNSET_SCALAR, UNSET_VECTOR); assert_eq!(a & false, Vector::splat(false));
} }
#[test] #[test]
@ -79,8 +103,8 @@ macro_rules! mask_tests {
fn bitand_scalar_lhs() { fn bitand_scalar_lhs() {
let a = from_slice(&A); let a = from_slice(&A);
let expected = a; let expected = a;
assert_biteq!(SET_SCALAR & a, expected); assert_eq!(true & a, expected);
assert_biteq!(UNSET_SCALAR & a, UNSET_VECTOR); assert_eq!(false & a, Vector::splat(false));
} }
#[test] #[test]
@ -88,10 +112,10 @@ macro_rules! mask_tests {
fn bitand_assign_scalar() { fn bitand_assign_scalar() {
let mut a = from_slice(&A); let mut a = from_slice(&A);
let expected = a; let expected = a;
a &= SET_SCALAR; a &= true;
assert_biteq!(a, expected); assert_eq!(a, expected);
a &= UNSET_SCALAR; a &= false;
assert_biteq!(a, UNSET_VECTOR); assert_eq!(a, Vector::splat(false));
} }
#[test] #[test]
@ -100,7 +124,7 @@ macro_rules! mask_tests {
let a = from_slice(&A); let a = from_slice(&A);
let b = from_slice(&B); let b = from_slice(&B);
let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor); let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor);
assert_biteq!(a | b, expected); assert_eq!(a | b, expected);
} }
#[test] #[test]
@ -110,23 +134,23 @@ macro_rules! mask_tests {
let b = from_slice(&B); let b = from_slice(&B);
let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor); let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor);
a |= b; a |= b;
assert_biteq!(a, expected); assert_eq!(a, expected);
} }
#[test] #[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn bitor_scalar_rhs() { fn bitor_scalar_rhs() {
let a = from_slice(&A); let a = from_slice(&A);
assert_biteq!(a | UNSET_SCALAR, a); assert_eq!(a | false, a);
assert_biteq!(a | SET_SCALAR, SET_VECTOR); assert_eq!(a | true, Vector::splat(true));
} }
#[test] #[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn bitor_scalar_lhs() { fn bitor_scalar_lhs() {
let a = from_slice(&A); let a = from_slice(&A);
assert_biteq!(UNSET_SCALAR | a, a); assert_eq!(false | a, a);
assert_biteq!(SET_SCALAR | a, SET_VECTOR); assert_eq!(true | a, Vector::splat(true));
} }
#[test] #[test]
@ -134,10 +158,10 @@ macro_rules! mask_tests {
fn bitor_assign_scalar() { fn bitor_assign_scalar() {
let mut a = from_slice(&A); let mut a = from_slice(&A);
let expected = a; let expected = a;
a |= UNSET_SCALAR; a |= false;
assert_biteq!(a, expected); assert_eq!(a, expected);
a |= SET_SCALAR; a |= true;
assert_biteq!(a, SET_VECTOR); assert_eq!(a, Vector::splat(true));
} }
#[test] #[test]
@ -146,7 +170,7 @@ macro_rules! mask_tests {
let a = from_slice(&A); let a = from_slice(&A);
let b = from_slice(&B); let b = from_slice(&B);
let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor); let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor);
assert_biteq!(a ^ b, expected); assert_eq!(a ^ b, expected);
} }
#[test] #[test]
@ -156,25 +180,25 @@ macro_rules! mask_tests {
let b = from_slice(&B); let b = from_slice(&B);
let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor); let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor);
a ^= b; a ^= b;
assert_biteq!(a, expected); assert_eq!(a, expected);
} }
#[test] #[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn bitxor_scalar_rhs() { fn bitxor_scalar_rhs() {
let a = from_slice(&A); let a = from_slice(&A);
let expected = apply_binary_scalar_rhs_lanewise(a, SET_SCALAR, core::ops::BitXor::bitxor); let expected = apply_binary_scalar_rhs_lanewise(a, true, core::ops::BitXor::bitxor);
assert_biteq!(a ^ UNSET_SCALAR, a); assert_eq!(a ^ false, a);
assert_biteq!(a ^ SET_SCALAR, expected); assert_eq!(a ^ true, expected);
} }
#[test] #[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn bitxor_scalar_lhs() { fn bitxor_scalar_lhs() {
let a = from_slice(&A); let a = from_slice(&A);
let expected = apply_binary_scalar_lhs_lanewise(SET_SCALAR, a, core::ops::BitXor::bitxor); let expected = apply_binary_scalar_lhs_lanewise(true, a, core::ops::BitXor::bitxor);
assert_biteq!(UNSET_SCALAR ^ a, a); assert_eq!(false ^ a, a);
assert_biteq!(SET_SCALAR ^ a, expected); assert_eq!(true ^ a, expected);
} }
#[test] #[test]
@ -182,11 +206,11 @@ macro_rules! mask_tests {
fn bitxor_assign_scalar() { fn bitxor_assign_scalar() {
let mut a = from_slice(&A); let mut a = from_slice(&A);
let expected_unset = a; let expected_unset = a;
let expected_set = apply_binary_scalar_rhs_lanewise(a, SET_SCALAR, core::ops::BitXor::bitxor); let expected_set = apply_binary_scalar_rhs_lanewise(a, true, core::ops::BitXor::bitxor);
a ^= UNSET_SCALAR; a ^= false;
assert_biteq!(a, expected_unset); assert_eq!(a, expected_unset);
a ^= SET_SCALAR; a ^= true;
assert_biteq!(a, expected_set); assert_eq!(a, expected_set);
} }
#[test] #[test]
@ -194,7 +218,7 @@ macro_rules! mask_tests {
fn not() { fn not() {
let v = from_slice(&A); let v = from_slice(&A);
let expected = apply_unary_lanewise(v, core::ops::Not::not); let expected = apply_unary_lanewise(v, core::ops::Not::not);
assert_biteq!(!v, expected); assert_eq!(!v, expected);
} }
} }
} }

View File

@ -1,5 +1,3 @@
use super::helpers; mask_tests! { masksizex2, 2 }
mask_tests! { masksizex4, 4 }
mask_tests! { masksizex2, masksize } mask_tests! { masksizex8, 8 }
mask_tests! { masksizex4, masksize }
mask_tests! { masksizex8, masksize }