Skip to main content

ear_algae/traits/
impls.rs

1
2use std::cmp::Ordering;
3
4use super::{Field, Ring};
5
6macro_rules! unsigned_impls {
7    ($($u:ty),*) => {
8        $(
9        impl Ring for $u {
10            const ZERO: Self = 0;
11            const ONE: Self = 1;
12            const TWO: Self = 2;
13            fn add(self, other: Self) -> Self {self + other}
14            fn add_assign(&mut self, other: Self) { *self += other }
15            fn mul(self, other: Self) -> Self {self * other}
16            fn mul_assign(&mut self, other: Self) { *self *= other }
17            fn sub(self, other: Self) -> Self {self-other}
18            fn sub_assign(&mut self, other: Self) { *self -= other }
19            fn div(self, other: Self) -> Self {self/other}
20            fn div_assign(&mut self, other: Self) { *self /= other }
21            fn pow(self, other: u32) -> Self {self.pow(other)}
22            fn abs(self) -> Self {self}
23            fn sign(self) -> Self {if self == 0 {0} else {1}}
24            fn neg(self) -> Self {0-self}
25            fn cmp(&self, other: &Self) -> Ordering {Ord::cmp(self, other)}
26            fn is_zero(self) -> bool {self == 0}
27            fn is_nan(self) -> bool {false}
28            fn is_finite(self) -> bool {true}
29            fn rem_euclid(self, other: Self) -> Self {self % other}
30        })*
31    }
32}
33
34macro_rules! signed_impls {
35    ($($i:ty),*) => {
36        $(
37        impl Ring for $i {
38            const ZERO: Self = 0;
39            const ONE: Self = 1;
40            const TWO: Self = 2;
41            fn add(self, other: Self) -> Self {self + other}
42            fn add_assign(&mut self, other: Self) { *self += other }
43            fn mul(self, other: Self) -> Self {self * other}
44            fn mul_assign(&mut self, other: Self) { *self *= other }
45            fn sub(self, other: Self) -> Self {self-other}
46            fn sub_assign(&mut self, other: Self) { *self -= other }
47            fn div(self, other: Self) -> Self {self/other}
48            fn div_assign(&mut self, other: Self) { *self /= other }
49            fn pow(self, other: u32) -> Self {self.pow(other)}
50            fn abs(self) -> Self {self.abs()}
51            fn sign(self) -> Self {match Ord::cmp(&self, &0) {Ordering::Less => {-1}, Ordering::Equal => {0}, Ordering::Greater => {1}}}
52            fn neg(self) -> Self {-self}
53            fn cmp(&self, other: &Self) -> Ordering {Ord::cmp(self, other)}
54            fn is_zero(self) -> bool {self == 0}
55            fn is_nan(self) -> bool {false}
56            fn is_finite(self) -> bool {true}
57            fn rem_euclid(self, other: Self) -> Self {self.rem_euclid(other)}
58        })*
59    }
60}
61
62macro_rules! float_impls {
63    ($($f:ty: $l:ident),*) => {
64        $(
65        impl Ring for $f {
66            const ZERO: Self = 0.;
67            const ONE: Self = 1.;
68            const TWO: Self = 2.;
69            fn add(self, other: Self) -> Self {self + other}
70            fn add_assign(&mut self, other: Self) { *self += other }
71            fn mul(self, other: Self) -> Self {self * other}
72            fn mul_assign(&mut self, other: Self) { *self *= other }
73            fn sub(self, other: Self) -> Self {self-other}
74            fn sub_assign(&mut self, other: Self) { *self -= other }
75            fn div(self, other: Self) -> Self {self/other}
76            fn div_assign(&mut self, other: Self) { *self /= other }
77            fn pow(self, other: u32) -> Self {self.powi(other as i32)}
78            fn abs(self) -> Self {self.abs()}
79            fn sign(self) -> Self {match self.float_cmp(&0.) {Ordering::Less => {-1.}, Ordering::Equal => {0.}, Ordering::Greater => {1.}}}
80            fn neg(self) -> Self {-self}
81            fn cmp(&self, other: &Self) -> Ordering {self.float_cmp(&other)}
82            fn is_zero(self) -> bool {self == 0.}
83            fn is_nan(self) -> bool {self.is_nan()}
84            fn is_finite(self) -> bool {self.is_finite()}
85            fn rem_euclid(self, other: Self) -> Self {self.rem_euclid(other)}
86        }
87    
88        impl Field for $f {
89            const HALF: Self = 0.5;
90        
91            const PI: Self = std::$l::consts::PI;
92            
93            const SQRT_2: Self = std::$l::consts::SQRT_2;
94
95            const INFINITY: Self = Self::INFINITY;
96
97            fn sqrt(self) -> Self {self.sqrt()}
98        
99            fn exp(self) -> Self {self.exp()}
100        
101            fn sin(self) -> Self {self.sin()}
102            fn cos(self) -> Self {self.cos()}
103            fn tan(self) -> Self {self.tan()}
104        
105            fn sin_cos(self) -> (Self, Self) {self.sin_cos()}
106        
107            fn ln(self) -> Self {self.ln()}
108        
109            fn asin(self) -> Self {self.asin()}
110            fn acos(self) -> Self {self.acos()}
111            fn atan(self) -> Self {self.atan()}
112        
113            fn atan2(y: Self, x: Self) -> Self {Self::atan2(y, x)}
114        })*
115    }
116}
117
118unsigned_impls!{u8, u16, u32, u64, u128, usize}
119signed_impls!{i8, i16, i32, i64, i128, isize}
120float_impls!{f32: f32, f64: f64}
121
122
123
124impl Ring for bool {
125    const ZERO: Self = false;
126    const ONE: Self = true;
127    const TWO: Self = true;
128    fn add(self, other: Self) -> Self {self || other}
129    fn add_assign(&mut self, other: Self) { *self |= other }
130    fn mul(self, other: Self) -> Self {self && other}
131    fn mul_assign(&mut self, other: Self) { *self &= other }
132    fn sub(self, other: Self) -> Self {self != other}
133    fn sub_assign(&mut self, other: Self) { *self ^= other }
134    fn div(self, other: Self) -> Self {self == other}
135    fn div_assign(&mut self, other: Self) { *self ^= !other }
136    fn pow(self, other: u32) -> Self {self || other==0}
137    fn abs(self) -> Self {self}
138    fn sign(self) -> Self {self}
139    fn neg(self) -> Self {self}
140    fn cmp(&self, other: &Self) -> Ordering {Ord::cmp(self, other)}
141    fn is_zero(self) -> bool {!self}
142    fn is_nan(self) -> bool {false}
143    fn is_finite(self) -> bool {true}
144    fn rem_euclid(self, _: Self) -> Self {false}
145}
146
147
148
149trait FloatCmp {
150    fn float_cmp(&self, other: &Self) -> Ordering;
151}
152
153impl FloatCmp for f32 {
154    fn float_cmp(&self, other: &Self) -> Ordering {
155        if let Some(cmp) = self.partial_cmp(other) {
156            return cmp;
157        }
158    
159        if self.is_nan() {
160            if other.is_nan() {
161                return Ordering::Equal;
162            }
163            return Ordering::Less;
164        }
165        Ordering::Greater
166    }
167}
168
169impl FloatCmp for f64 {
170    fn float_cmp(&self, other: &Self) -> Ordering {
171        if let Some(cmp) = self.partial_cmp(other) {
172            return cmp;
173        }
174    
175        if self.is_nan() {
176            if other.is_nan() {
177                return Ordering::Equal;
178            }
179            return Ordering::Less;
180        }
181        Ordering::Greater
182    }
183}