Add documentation
This commit is contained in:
parent
714ad639b3
commit
8c378d3027
8 changed files with 36 additions and 126 deletions
|
|
@ -1,120 +0,0 @@
|
|||
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,
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#[macro_use]
|
||||
pub mod biteq;
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
#[macro_use]
|
||||
#[path = "../helpers/mod.rs"]
|
||||
mod helpers;
|
||||
|
||||
#[macro_use]
|
||||
mod mask_macros;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/// Implements a test on a unary operation using proptest.
|
||||
///
|
||||
/// Compares the vector operation to the equivalent scalar operation.
|
||||
#[macro_export]
|
||||
macro_rules! impl_unary_op_test {
|
||||
{ $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $scalar_fn:expr } => {
|
||||
|
|
@ -16,6 +19,9 @@ macro_rules! impl_unary_op_test {
|
|||
};
|
||||
}
|
||||
|
||||
/// Implements a test on a binary operation using proptest.
|
||||
///
|
||||
/// Compares the vector operation to the equivalent scalar operation.
|
||||
#[macro_export]
|
||||
macro_rules! impl_binary_op_test {
|
||||
{ $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr } => {
|
||||
|
|
@ -70,6 +76,12 @@ macro_rules! impl_binary_op_test {
|
|||
};
|
||||
}
|
||||
|
||||
/// Implements a test on a binary operation using proptest.
|
||||
///
|
||||
/// Like `impl_binary_op_test`, but allows providing a function for rejecting particular inputs
|
||||
/// (like the `proptest_assume` macro).
|
||||
///
|
||||
/// Compares the vector operation to the equivalent scalar operation.
|
||||
#[macro_export]
|
||||
macro_rules! impl_binary_checked_op_test {
|
||||
{ $vector:ty, $scalar:ty, $trait:ident :: $fn:ident, $trait_assign:ident :: $fn_assign:ident, $scalar_fn:expr, $check_fn:expr } => {
|
||||
|
|
@ -124,6 +136,7 @@ macro_rules! impl_binary_checked_op_test {
|
|||
};
|
||||
}
|
||||
|
||||
/// Implement tests for signed integers.
|
||||
#[macro_export]
|
||||
macro_rules! impl_signed_tests {
|
||||
{ $vector:ident, $scalar:tt } => {
|
||||
|
|
@ -191,6 +204,8 @@ macro_rules! impl_signed_tests {
|
|||
impl_binary_op_test!(Vector<LANES>, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add);
|
||||
impl_binary_op_test!(Vector<LANES>, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub);
|
||||
impl_binary_op_test!(Vector<LANES>, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul);
|
||||
|
||||
// Exclude Div and Rem panicking cases
|
||||
impl_binary_checked_op_test!(Vector<LANES>, Scalar, Div::div, DivAssign::div_assign, Scalar::wrapping_div, |x, y| y != 0 && !(x == Scalar::MIN && y == -1));
|
||||
impl_binary_checked_op_test!(Vector<LANES>, Scalar, Rem::rem, RemAssign::rem_assign, Scalar::wrapping_rem, |x, y| y != 0 && !(x == Scalar::MIN && y == -1));
|
||||
|
||||
|
|
@ -202,6 +217,7 @@ macro_rules! impl_signed_tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// Implement tests for unsigned integers.
|
||||
#[macro_export]
|
||||
macro_rules! impl_unsigned_tests {
|
||||
{ $vector:ident, $scalar:tt } => {
|
||||
|
|
@ -220,6 +236,8 @@ macro_rules! impl_unsigned_tests {
|
|||
impl_binary_op_test!(Vector<LANES>, Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add);
|
||||
impl_binary_op_test!(Vector<LANES>, Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub);
|
||||
impl_binary_op_test!(Vector<LANES>, Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul);
|
||||
|
||||
// Exclude Div and Rem panicking cases
|
||||
impl_binary_checked_op_test!(Vector<LANES>, Scalar, Div::div, DivAssign::div_assign, Scalar::wrapping_div, |_, y| y != 0);
|
||||
impl_binary_checked_op_test!(Vector<LANES>, Scalar, Rem::rem, RemAssign::rem_assign, Scalar::wrapping_rem, |_, y| y != 0);
|
||||
|
||||
|
|
@ -231,6 +249,7 @@ macro_rules! impl_unsigned_tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// Implement tests for floating point numbers.
|
||||
#[macro_export]
|
||||
macro_rules! impl_float_tests {
|
||||
{ $vector:ident, $scalar:tt, $int_scalar:tt } => {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
//! Generic-length array strategy.
|
||||
|
||||
// Adapted from proptest's array code
|
||||
// Copyright 2017 Jason Lingle
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
//! Compare numeric types by exact bit value.
|
||||
|
||||
pub trait BitEq {
|
||||
fn biteq(&self, other: &Self) -> bool;
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ pub mod wasm;
|
|||
#[macro_use]
|
||||
pub mod biteq;
|
||||
|
||||
/// Specifies the default strategy for testing a type.
|
||||
///
|
||||
/// This strategy should be what "makes sense" to test.
|
||||
pub trait DefaultStrategy {
|
||||
type Strategy: proptest::strategy::Strategy<Value = Self>;
|
||||
fn default_strategy() -> Self::Strategy;
|
||||
|
|
@ -74,6 +77,7 @@ impl<T: core::fmt::Debug + DefaultStrategy, const LANES: usize> DefaultStrategy
|
|||
}
|
||||
}
|
||||
|
||||
/// Test a function that takes a single value.
|
||||
pub fn test_1<A: core::fmt::Debug + DefaultStrategy>(
|
||||
f: &dyn Fn(A) -> proptest::test_runner::TestCaseResult,
|
||||
) {
|
||||
|
|
@ -81,6 +85,7 @@ pub fn test_1<A: core::fmt::Debug + DefaultStrategy>(
|
|||
runner.run(&A::default_strategy(), f).unwrap();
|
||||
}
|
||||
|
||||
/// Test a function that takes two values.
|
||||
pub fn test_2<A: core::fmt::Debug + DefaultStrategy, B: core::fmt::Debug + DefaultStrategy>(
|
||||
f: &dyn Fn(A, B) -> proptest::test_runner::TestCaseResult,
|
||||
) {
|
||||
|
|
@ -92,6 +97,7 @@ pub fn test_2<A: core::fmt::Debug + DefaultStrategy, B: core::fmt::Debug + Defau
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
/// Test a unary vector function against a unary scalar function, applied elementwise.
|
||||
#[inline(never)]
|
||||
pub fn test_unary_elementwise<Scalar, ScalarResult, Vector, VectorResult, const LANES: usize>(
|
||||
fv: &dyn Fn(Vector) -> VectorResult,
|
||||
|
|
@ -118,6 +124,7 @@ pub fn test_unary_elementwise<Scalar, ScalarResult, Vector, VectorResult, const
|
|||
});
|
||||
}
|
||||
|
||||
/// Test a binary vector function against a binary scalar function, applied elementwise.
|
||||
#[inline(never)]
|
||||
pub fn test_binary_elementwise<
|
||||
Scalar1,
|
||||
|
|
@ -154,6 +161,7 @@ pub fn test_binary_elementwise<
|
|||
});
|
||||
}
|
||||
|
||||
/// Test a binary vector-scalar function against a binary scalar function, applied elementwise.
|
||||
#[inline(never)]
|
||||
pub fn test_binary_scalar_rhs_elementwise<
|
||||
Scalar1,
|
||||
|
|
@ -188,6 +196,7 @@ pub fn test_binary_scalar_rhs_elementwise<
|
|||
});
|
||||
}
|
||||
|
||||
/// Test a binary vector-scalar function against a binary scalar function, applied elementwise.
|
||||
#[inline(never)]
|
||||
pub fn test_binary_scalar_lhs_elementwise<
|
||||
Scalar1,
|
||||
|
|
@ -222,6 +231,7 @@ pub fn test_binary_scalar_lhs_elementwise<
|
|||
});
|
||||
}
|
||||
|
||||
/// Expand a const-generic test into separate tests for each possible lane count.
|
||||
#[macro_export]
|
||||
macro_rules! test_lanes {
|
||||
{
|
||||
|
|
@ -282,6 +292,7 @@ macro_rules! test_lanes {
|
|||
}
|
||||
}
|
||||
|
||||
/// Expand a const-generic `#[should_panic]` test into separate tests for each possible lane count.
|
||||
#[macro_export]
|
||||
macro_rules! test_lanes_panic {
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
//! Strategies for `u128` and `i128`, since proptest doesn't provide them for the wasm target.
|
||||
|
||||
macro_rules! impl_num {
|
||||
{ $name:ident } => {
|
||||
pub(crate) mod $name {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue