pub trait ApproxEqAbs<Rhs: ?Sized = Self> {
type Tolerance: Copy;
const DEFAULT_TOLERANCE_ABS: Self::Tolerance;
fn approx_eq_abs_tol(&self, other: &Rhs, tol: Self::Tolerance) -> bool;
fn approx_eq_abs(&self, other: &Rhs) -> bool {
self.approx_eq_abs_tol(other, Self::DEFAULT_TOLERANCE_ABS)
}
}
pub trait ApproxEqRel<Rhs: ?Sized = Self> {
type Tolerance: Copy;
const DEFAULT_TOLERANCE_REL: Self::Tolerance;
fn approx_eq_rel_tol(&self, other: &Rhs, tol: Self::Tolerance) -> bool;
fn approx_eq_rel(&self, other: &Rhs) -> bool {
self.approx_eq_rel_tol(other, Self::DEFAULT_TOLERANCE_REL)
}
}
#[macro_export]
macro_rules! approx_eq_abs {
($lhs:expr, $rhs:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
$crate::algebra::ApproxEqAbs::approx_eq_abs(&lhs, &rhs)
}};
($lhs:expr, $rhs:expr, $tol:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
$crate::algebra::ApproxEqAbs::approx_eq_abs_tol(&lhs, &rhs, tol)
}};
}
#[macro_export]
macro_rules! approx_ne_abs {
($lhs:expr, $rhs:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
!$crate::algebra::ApproxEqAbs::approx_eq_abs(&lhs, &rhs)
}};
($lhs:expr, $rhs:expr, $tol:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
!$crate::algebra::ApproxEqAbs::approx_eq_abs_tol(&lhs, &rhs, tol)
}};
}
#[macro_export]
macro_rules! assert_approx_eq_abs {
($lhs:expr, $rhs:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
assert!(
$crate::algebra::ApproxEqAbs::approx_eq_abs(&lhs, &rhs),
"assertion failed: approx_eq_abs!({}, {})",
stringify!($lhs),
stringify!($rhs)
);
}};
($lhs:expr, $rhs:expr, message = $($arg:tt)+) => {{
let lhs = $lhs;
let rhs = $rhs;
assert!($crate::algebra::ApproxEqAbs::approx_eq_abs(&lhs, &rhs), $($arg)+);
}};
($lhs:expr, $rhs:expr, $tol:expr, message = $($arg:tt)+) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
assert!($crate::algebra::ApproxEqAbs::approx_eq_abs_tol(&lhs, &rhs, tol), $($arg)+);
}};
($lhs:expr, $rhs:expr, $tol:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
assert!(
$crate::algebra::ApproxEqAbs::approx_eq_abs_tol(&lhs, &rhs, tol),
"assertion failed: approx_eq_abs!({}, {}, {})",
stringify!($lhs),
stringify!($rhs),
stringify!($tol)
);
}};
}
#[macro_export]
macro_rules! assert_approx_ne_abs {
($lhs:expr, $rhs:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
assert!(
!$crate::algebra::ApproxEqAbs::approx_eq_abs(&lhs, &rhs),
"assertion failed: approx_ne_abs!({}, {})",
stringify!($lhs),
stringify!($rhs)
);
}};
($lhs:expr, $rhs:expr, message = $($arg:tt)+) => {{
let lhs = $lhs;
let rhs = $rhs;
assert!(!$crate::algebra::ApproxEqAbs::approx_eq_abs(&lhs, &rhs), $($arg)+);
}};
($lhs:expr, $rhs:expr, $tol:expr, message = $($arg:tt)+) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
assert!(
!$crate::algebra::ApproxEqAbs::approx_eq_abs_tol(&lhs, &rhs, tol),
$($arg)+
);
}};
($lhs:expr, $rhs:expr, $tol:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
assert!(
!$crate::algebra::ApproxEqAbs::approx_eq_abs_tol(&lhs, &rhs, tol),
"assertion failed: approx_ne_abs!({}, {}, {})",
stringify!($lhs),
stringify!($rhs),
stringify!($tol)
);
}};
}
#[macro_export]
macro_rules! approx_eq_rel {
($lhs:expr, $rhs:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
$crate::algebra::ApproxEqRel::approx_eq_rel(&lhs, &rhs)
}};
($lhs:expr, $rhs:expr, $tol:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
$crate::algebra::ApproxEqRel::approx_eq_rel_tol(&lhs, &rhs, tol)
}};
}
#[macro_export]
macro_rules! approx_ne_rel {
($lhs:expr, $rhs:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
!$crate::algebra::ApproxEqRel::approx_eq_rel(&lhs, &rhs)
}};
($lhs:expr, $rhs:expr, $tol:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
!$crate::algebra::ApproxEqRel::approx_eq_rel_tol(&lhs, &rhs, tol)
}};
}
#[macro_export]
macro_rules! assert_approx_eq_rel {
($lhs:expr, $rhs:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
assert!(
$crate::algebra::ApproxEqRel::approx_eq_rel(&lhs, &rhs),
"assertion failed: approx_eq_rel!({}, {})",
stringify!($lhs),
stringify!($rhs)
);
}};
($lhs:expr, $rhs:expr, message = $($arg:tt)+) => {{
let lhs = $lhs;
let rhs = $rhs;
assert!($crate::algebra::ApproxEqRel::approx_eq_rel(&lhs, &rhs), $($arg)+);
}};
($lhs:expr, $rhs:expr, $tol:expr, message = $($arg:tt)+) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
assert!($crate::algebra::ApproxEqRel::approx_eq_rel_tol(&lhs, &rhs, tol), $($arg)+);
}};
($lhs:expr, $rhs:expr, $tol:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
assert!(
$crate::algebra::ApproxEqRel::approx_eq_rel_tol(&lhs, &rhs, tol),
"assertion failed: approx_eq_rel!({}, {}, {})",
stringify!($lhs),
stringify!($rhs),
stringify!($tol)
);
}};
}
#[macro_export]
macro_rules! assert_approx_ne_rel {
($lhs:expr, $rhs:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
assert!(
!$crate::algebra::ApproxEqRel::approx_eq_rel(&lhs, &rhs),
"assertion failed: approx_ne_rel!({}, {})",
stringify!($lhs),
stringify!($rhs)
);
}};
($lhs:expr, $rhs:expr, message = $($arg:tt)+) => {{
let lhs = $lhs;
let rhs = $rhs;
assert!(!$crate::algebra::ApproxEqRel::approx_eq_rel(&lhs, &rhs), $($arg)+);
}};
($lhs:expr, $rhs:expr, $tol:expr, message = $($arg:tt)+) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
assert!(
!$crate::algebra::ApproxEqRel::approx_eq_rel_tol(&lhs, &rhs, tol),
$($arg)+
);
}};
($lhs:expr, $rhs:expr, $tol:expr $(,)?) => {{
let lhs = $lhs;
let rhs = $rhs;
let tol = $tol;
assert!(
!$crate::algebra::ApproxEqRel::approx_eq_rel_tol(&lhs, &rhs, tol),
"assertion failed: approx_ne_rel!({}, {}, {})",
stringify!($lhs),
stringify!($rhs),
stringify!($tol)
);
}};
}