ospf_rust_math/algebra/operator/algorithmic/
cross.rs

1use std::ops::Mul;
2
3pub trait Cross<Rhs = Self> {
4    type Output;
5
6    fn cross(self, rhs: Rhs) -> Self::Output;
7}
8
9pub fn cross<T: Cross<U>, U>(lhs: T, rhs: U) -> T::Output {
10    lhs.cross(rhs)
11}
12
13macro_rules! scalar_cross_template {
14    ($($type:ident)*) => ($(
15        impl <U> Cross<U> for $type where $type: Mul<U> {
16            type Output = <$type as Mul<U>>::Output;
17
18            fn cross(self, rhs: U) -> Self::Output {
19                self * rhs
20            }
21        }
22
23        impl <U> Cross<U> for &$type where for<'a> &'a $type: Mul<U> {
24            type Output = <Self as Mul<U>>::Output;
25
26            fn cross(self, rhs: U) -> Self::Output {
27                self * rhs
28            }
29        }
30    )*)
31}
32scalar_cross_template! { bool i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 }
33
34#[cfg(test)]
35mod tests {
36    use std::fmt::Debug;
37
38    use crate::algebra::concept::RealNumber;
39
40    use super::*;
41
42    fn test_real<T: RealNumber + Cross<T, Output = T> + Debug>()
43    where
44        for<'a> &'a T: Cross<&'a T, Output = T>,
45    {
46        assert_eq!(&(T::ZERO.clone().cross(T::ZERO.clone())), T::ZERO);
47        assert_eq!(&(T::ZERO.cross(T::ZERO)), T::ZERO);
48        assert_eq!(&cross(T::ZERO.clone(), T::ZERO.clone()), T::ZERO);
49        assert_eq!(&cross(T::ZERO, T::ZERO), T::ZERO);
50
51        assert_eq!(&(T::ONE.clone().cross(T::TWO.clone())), T::TWO);
52        assert_eq!(&(T::ONE.cross(T::TWO)), T::TWO);
53        assert_eq!(&cross(T::ONE.clone(), T::TWO.clone()), T::TWO);
54        assert_eq!(&cross(T::ONE, T::TWO), T::TWO);
55
56        assert_eq!(&(T::TWO.clone().cross(T::ONE.clone())), T::TWO);
57        assert_eq!(&(T::TWO.cross(T::ONE)), T::TWO);
58        assert_eq!(&cross(T::TWO.clone(), T::ONE.clone()), T::TWO);
59        assert_eq!(&cross(T::TWO, T::ONE), T::TWO);
60
61        assert_eq!(&(T::TWO.clone().cross(T::FIVE.clone())), T::TEN);
62        assert_eq!(&(T::TWO.cross(T::FIVE)), T::TEN);
63        assert_eq!(&cross(T::TWO.clone(), T::FIVE.clone()), T::TEN);
64        assert_eq!(&cross(T::TWO, T::FIVE), T::TEN);
65
66        assert_eq!(&(T::FIVE.clone().cross(T::TWO.clone())), T::TEN);
67        assert_eq!(&(T::FIVE.cross(T::TWO)), T::TEN);
68        assert_eq!(&cross(T::FIVE.clone(), T::TWO.clone()), T::TEN);
69        assert_eq!(&cross(T::FIVE, T::TWO), T::TEN);
70    }
71
72    #[test]
73    fn test() {
74        test_real::<i8>();
75        test_real::<i16>();
76        test_real::<i32>();
77        test_real::<i64>();
78        test_real::<i128>();
79        test_real::<u8>();
80        test_real::<u16>();
81        test_real::<u32>();
82        test_real::<u64>();
83        test_real::<u128>();
84        test_real::<f32>();
85        test_real::<f64>();
86    }
87}