ear_algae/traits/
impls.rs1
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}