1use crate::cgmath64::*;
2use cgmath::AbsDiffEq;
3use std::fmt::Debug;
4
5pub const TOLERANCE: f64 = 1.0e-6;
7
8pub const TOLERANCE2: f64 = TOLERANCE * TOLERANCE;
10
11pub trait Tolerance: AbsDiffEq<Epsilon = f64> + Debug {
13 fn near(&self, other: &Self) -> bool { self.abs_diff_eq(other, TOLERANCE) }
15
16 fn near2(&self, other: &Self) -> bool { self.abs_diff_eq(other, TOLERANCE2) }
18}
19
20impl<T: AbsDiffEq<Epsilon = f64> + Debug> Tolerance for T {}
21
22#[macro_export]
24macro_rules! assert_near {
25 ($left: expr, $right: expr $(,)?) => {
26 assert!($left.near(&$right), "assertion failed: `left` is near `right`
27left: {:?},
28right: {:?}", $left, $right)
29 };
30 ($left: expr, $right: expr, $($arg: tt)+) => {
31 assert!($left.near(&$right), "assertion failed: `left` is near `right`
32left: {:?},
33right: {:?}: {}", $left, $right, format_args!($($arg)+))
34 };
35}
36
37#[test]
38#[should_panic]
39fn assert_near_without_msg() {
40 assert_near!(1.0, 2.0);
41}
42
43#[test]
44#[should_panic]
45fn assert_near_with_msg() {
46 assert_near!(1.0, 2.0, "{}", "test OK");
47}
48
49#[macro_export]
51macro_rules! assert_near2 {
52 ($left: expr, $right: expr $(,)?) => {
53 assert!($left.near2(&$right), "assertion failed: `left` is near `right`
54left: {:?},
55right: {:?}", $left, $right)
56 };
57 ($left: expr, $right: expr, $($arg: tt)+) => {
58 assert!($left.near2(&$right), "assertion failed: `left` is near `right`
59left: {:?},
60right: {:?}: {}", $left, $right, format_args!($($arg)+))
61 };
62}
63
64#[test]
65#[should_panic]
66fn assert_near2_without_msg() {
67 assert_near2!(1.0, 2.0);
68}
69
70#[test]
71#[should_panic]
72fn assert_near2_with_msg() {
73 assert_near2!(1.0, 2.0, "{}", "test OK");
74}
75
76pub trait Origin: Tolerance + Zero {
78 #[inline(always)]
80 fn so_small(&self) -> bool { self.near(&Self::zero()) }
81
82 #[inline(always)]
84 fn so_small2(&self) -> bool { self.near2(&Self::zero()) }
85}
86
87impl<T: Tolerance + Zero> Origin for T {}