1use num_traits::Num;
2
3use crate::float16::pf16;
4
5pub trait AbsDiff {
6 type Abs: Num + PartialOrd + Copy + std::fmt::Debug + Send + Sync;
7
8 fn max_abs_diff() -> Self::Abs;
9 fn abs_diff(self, other: Self) -> Self::Abs;
10}
11
12macro_rules! impl_trivial_abs_diff {
13 ($T: ty, $max: expr) => {
14 impl AbsDiff for $T {
15 type Abs = $T;
16
17 fn max_abs_diff() -> Self::Abs {
18 $max
19 }
20
21 fn abs_diff(self, other: Self) -> Self::Abs {
22 if self > other {
23 self - other
24 } else {
25 other - self
26 }
27 }
28 }
29 };
30}
31
32macro_rules! impl_signed_abs_diff {
33 ($T: ty, $U: ty) => {
34 impl AbsDiff for $T {
35 type Abs = $U;
36
37 fn max_abs_diff() -> Self::Abs {
38 <$U>::MAX
39 }
40
41 fn abs_diff(self, other: Self) -> Self::Abs {
42 self.abs_diff(other)
43 }
44 }
45 };
46}
47
48impl_trivial_abs_diff!(u8, u8::MAX);
49impl_trivial_abs_diff!(u16, u16::MAX);
50impl_trivial_abs_diff!(u32, u32::MAX);
51impl_trivial_abs_diff!(u64, u64::MAX);
52impl_trivial_abs_diff!(u128, u128::MAX);
53impl_trivial_abs_diff!(usize, usize::MAX);
54impl_trivial_abs_diff!(pf16, pf16::INFINITY);
55impl_trivial_abs_diff!(f32, f32::INFINITY);
56impl_trivial_abs_diff!(f64, f64::INFINITY);
57impl_signed_abs_diff!(i8, u8);
58impl_signed_abs_diff!(i16, u16);
59impl_signed_abs_diff!(i32, u32);
60impl_signed_abs_diff!(i64, u64);
61impl_signed_abs_diff!(i128, u128);
62impl_signed_abs_diff!(isize, usize);