43dabd1aea
* Add vector-vector arithmetic ops * Add operators and integer conversions for masks * Add unary traits * Implement Index and IndexMut * Implement by-ref ops for masks * Document intrinsics * Implement format traits for masks * Add floating point ops tests * Add integer tests * Add mask tests
128 lines
4.4 KiB
Rust
128 lines
4.4 KiB
Rust
pub(crate) trait BitEq {
|
|
fn biteq(&self, other: &Self) -> bool;
|
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result;
|
|
}
|
|
|
|
macro_rules! impl_biteq {
|
|
{ integer impl BitEq for $($type:ty,)* } => {
|
|
$(
|
|
impl BitEq for $type {
|
|
fn biteq(&self, other: &Self) -> bool {
|
|
self == other
|
|
}
|
|
|
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
|
write!(f, "{:?} ({:x})", self, self)
|
|
}
|
|
}
|
|
)*
|
|
};
|
|
{ float impl BitEq for $($type:ty,)* } => {
|
|
$(
|
|
impl BitEq for $type {
|
|
fn biteq(&self, other: &Self) -> bool {
|
|
self.to_bits() == other.to_bits()
|
|
}
|
|
|
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
|
write!(f, "{:?} ({:x})", self, self.to_bits())
|
|
}
|
|
}
|
|
)*
|
|
};
|
|
{ vector impl BitEq for $($type:ty,)* } => {
|
|
$(
|
|
impl BitEq for $type {
|
|
fn biteq(&self, other: &Self) -> bool {
|
|
let a: &[_] = self.as_ref();
|
|
let b: &[_] = other.as_ref();
|
|
if a.len() == b.len() {
|
|
a.iter().zip(b.iter()).fold(true, |value, (left, right)| {
|
|
value && left.biteq(right)
|
|
})
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
|
#[repr(transparent)]
|
|
struct Wrapper<'a, T: BitEq>(&'a T);
|
|
|
|
impl<T: BitEq> core::fmt::Debug for Wrapper<'_, T> {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
|
self.0.fmt(f)
|
|
}
|
|
}
|
|
|
|
let slice: &[_] = self.as_ref();
|
|
|
|
f.debug_list()
|
|
.entries(slice.iter().map(|x| Wrapper(x)))
|
|
.finish()
|
|
}
|
|
}
|
|
)*
|
|
};
|
|
}
|
|
|
|
impl_biteq! {
|
|
integer impl BitEq for
|
|
u8, u16, u32, u64, u128, usize,
|
|
i8, i16, i32, i64, i128, isize,
|
|
core_simd::mask8, core_simd::mask16, core_simd::mask32, core_simd::mask64, core_simd::mask128, core_simd::masksize,
|
|
}
|
|
|
|
impl_biteq! {
|
|
float impl BitEq for f32, f64,
|
|
}
|
|
|
|
impl_biteq! {
|
|
vector impl BitEq for
|
|
core_simd::u8x8, core_simd::u8x16, core_simd::u8x32, core_simd::u8x64,
|
|
core_simd::i8x8, core_simd::i8x16, core_simd::i8x32, core_simd::i8x64,
|
|
core_simd::u16x4, core_simd::u16x8, core_simd::u16x16, core_simd::u16x32,
|
|
core_simd::i16x4, core_simd::i16x8, core_simd::i16x16, core_simd::i16x32,
|
|
core_simd::u32x2, core_simd::u32x4, core_simd::u32x8, core_simd::u32x16,
|
|
core_simd::i32x2, core_simd::i32x4, core_simd::i32x8, core_simd::i32x16,
|
|
core_simd::u64x2, core_simd::u64x4, core_simd::u64x8,
|
|
core_simd::i64x2, core_simd::i64x4, core_simd::i64x8,
|
|
core_simd::u128x2, core_simd::u128x4,
|
|
core_simd::i128x2, core_simd::i128x4,
|
|
core_simd::usizex2, core_simd::usizex4, core_simd::usizex8,
|
|
core_simd::isizex2, core_simd::isizex4, core_simd::isizex8,
|
|
core_simd::f32x2, core_simd::f32x4, core_simd::f32x8, core_simd::f32x16,
|
|
core_simd::f64x2, core_simd::f64x4, core_simd::f64x8,
|
|
core_simd::mask8x8, core_simd::mask8x16, core_simd::mask8x32, core_simd::mask8x64,
|
|
core_simd::mask16x4, core_simd::mask16x8, core_simd::mask16x16, core_simd::mask16x32,
|
|
core_simd::mask32x2, core_simd::mask32x4, core_simd::mask32x8, core_simd::mask32x16,
|
|
core_simd::mask64x2, core_simd::mask64x4, core_simd::mask64x8,
|
|
core_simd::mask128x2, core_simd::mask128x4,
|
|
core_simd::masksizex2, core_simd::masksizex4, core_simd::masksizex8,
|
|
}
|
|
|
|
pub(crate) struct BitEqWrapper<'a, T>(pub(crate) &'a T);
|
|
|
|
impl<T: BitEq> PartialEq for BitEqWrapper<'_, T> {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.0.biteq(other.0)
|
|
}
|
|
}
|
|
|
|
impl<T: BitEq> core::fmt::Debug for BitEqWrapper<'_, T> {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
|
self.0.fmt(f)
|
|
}
|
|
}
|
|
|
|
macro_rules! assert_biteq {
|
|
{ $a:expr, $b:expr } => {
|
|
{
|
|
use helpers::biteq::BitEqWrapper;
|
|
let a = $a;
|
|
let b = $b;
|
|
assert_eq!(BitEqWrapper(&a), BitEqWrapper(&b));
|
|
}
|
|
}
|
|
}
|