1use core::fmt;
2use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
3
4pub trait Pow {
5 fn powf(self, exponent: Self) -> Self;
6}
7impl Pow for f32 {
8 fn powf(self, exponent: Self) -> Self {
9 self.powf(exponent)
10 }
11}
12impl Pow for f64 {
13 fn powf(self, exponent: Self) -> Self {
14 self.powf(exponent)
15 }
16}
17
18pub trait FromF64 {
19 fn from_f64(n: f64) -> Self;
20}
21impl FromF64 for f32 {
22 fn from_f64(n: f64) -> Self {
23 n as f32
24 }
25}
26impl FromF64 for f64 {
27 fn from_f64(n: f64) -> Self {
28 n
29 }
30}
31
32pub trait Sqrt {
33 type Output;
34 fn sqrt(self) -> Self::Output;
35}
36impl Sqrt for f32 {
37 type Output = f32;
38 fn sqrt(self) -> Self {
39 self.sqrt()
40 }
41}
42impl Sqrt for f64 {
43 type Output = f64;
44 fn sqrt(self) -> Self {
45 self.sqrt()
46 }
47}
48
49pub trait CubicRoot {
50 type Output;
51 fn cubic_root(self) -> Self::Output;
52}
53impl CubicRoot for f32 {
54 type Output = f32;
55 fn cubic_root(self) -> Self {
56 self.powf(1. / 3.)
57 }
58}
59impl CubicRoot for f64 {
60 type Output = f64;
61 fn cubic_root(self) -> Self {
62 self.powf(1. / 3.)
63 }
64}
65
66pub trait Trigonometry {
67 type Output;
68 fn cos(self) -> Self::Output;
69 fn sin(self) -> Self::Output;
70 fn tan(self) -> Self::Output;
71 fn sin_cos(self) -> (Self::Output, Self::Output);
72}
73impl Trigonometry for f32 {
74 type Output = f32;
75 fn cos(self) -> Self::Output {
76 self.cos()
77 }
78 fn sin(self) -> Self::Output {
79 self.sin()
80 }
81 fn tan(self) -> Self::Output {
82 self.tan()
83 }
84 fn sin_cos(self) -> (Self::Output, Self::Output) {
85 self.sin_cos()
86 }
87}
88impl Trigonometry for f64 {
89 type Output = f64;
90 fn cos(self) -> Self::Output {
91 self.cos()
92 }
93 fn sin(self) -> Self::Output {
94 self.sin()
95 }
96 fn tan(self) -> Self::Output {
97 self.tan()
98 }
99 fn sin_cos(self) -> (Self::Output, Self::Output) {
100 self.sin_cos()
101 }
102}
103
104pub trait InverseTrigonometry {
105 type Output;
106 fn acos(self) -> Self::Output;
107 fn asin(self) -> Self::Output;
108 fn atan2(self, other: Self) -> Self::Output;
109}
110impl InverseTrigonometry for f32 {
111 type Output = f32;
112 fn acos(self) -> Self::Output {
113 self.acos()
114 }
115 fn asin(self) -> Self::Output {
116 self.asin()
117 }
118 fn atan2(self, other: Self) -> Self::Output {
119 self.atan2(other)
120 }
121}
122impl InverseTrigonometry for f64 {
123 type Output = f64;
124 fn acos(self) -> Self::Output {
125 self.acos()
126 }
127 fn asin(self) -> Self::Output {
128 self.asin()
129 }
130 fn atan2(self, other: Self) -> Self::Output {
131 self.atan2(other)
132 }
133}
134
135pub trait Decibel {
136 fn to_decibels(self) -> Self;
137 fn decibels_to_value(self) -> Self;
138}
139impl Decibel for f32 {
140 fn to_decibels(self) -> Self {
141 self.log10() * 10.
142 }
143 fn decibels_to_value(self) -> Self {
144 10_f32.powf(self * 0.1)
145 }
146}
147impl Decibel for f64 {
148 fn to_decibels(self) -> Self {
149 self.log10() * 10.
150 }
151 fn decibels_to_value(self) -> Self {
152 10_f64.powf(self * 0.1)
153 }
154}
155
156pub trait HasZero {
157 const ZERO: Self;
158}
159impl HasZero for f32 {
160 const ZERO: Self = 0.;
161}
162impl HasZero for f64 {
163 const ZERO: Self = 0.;
164}
165
166pub trait HasOne {
167 const ONE: Self;
168}
169impl HasOne for f32 {
170 const ONE: Self = 1.;
171}
172impl HasOne for f64 {
173 const ONE: Self = 1.;
174}
175
176pub trait HasHalf {
177 const HALF: Self;
178}
179impl HasHalf for f32 {
180 const HALF: Self = 0.5;
181}
182impl HasHalf for f64 {
183 const HALF: Self = 0.5;
184}
185
186pub trait HasSign {
187 fn signum(self) -> Self;
188 fn abs(self) -> Self;
189}
190impl HasSign for f32 {
191 fn signum(self) -> Self {
192 self.signum()
193 }
194 fn abs(self) -> Self {
195 self.abs()
196 }
197}
198impl HasSign for f64 {
199 fn signum(self) -> Self {
200 self.signum()
201 }
202 fn abs(self) -> Self {
203 self.abs()
204 }
205}
206
207pub trait ArithmeticOps:
208 Neg<Output = Self>
209 + Add<Self, Output = Self>
210 + AddAssign<Self>
211 + Sub<Self, Output = Self>
212 + SubAssign<Self>
213 + Mul<Self, Output = Self>
214 + MulAssign<Self>
215 + Div<Self, Output = Self>
216 + DivAssign<Self>
217 + Rem<Self, Output = Self>
218 + Pow
219 + FromF64
220 + Sqrt<Output = Self>
221 + CubicRoot<Output = Self>
222 + Trigonometry<Output = Self>
223 + InverseTrigonometry<Output = Self>
224 + Decibel
225 + HasZero
226 + HasOne
227 + HasHalf
228 + HasSign
229 + std::iter::Sum
230 + fmt::Display
231 + fmt::Debug
232 + Clone
233 + Copy
234 + PartialOrd
235 + PartialEq
236where
237 Self: std::marker::Sized,
238{
239}
240
241impl<T> ArithmeticOps for T where
242 T: Neg<Output = Self>
243 + Add<T, Output = T>
244 + AddAssign<T>
245 + Sub<T, Output = Self>
246 + SubAssign<T>
247 + Mul<T, Output = Self>
248 + MulAssign<T>
249 + Div<T, Output = Self>
250 + DivAssign<T>
251 + Rem<T, Output = Self>
252 + Pow
253 + FromF64
254 + Sqrt<Output = Self>
255 + CubicRoot<Output = Self>
256 + Trigonometry<Output = Self>
257 + InverseTrigonometry<Output = Self>
258 + Decibel
259 + HasZero
260 + HasOne
261 + HasHalf
262 + HasSign
263 + std::iter::Sum
264 + fmt::Display
265 + fmt::Debug
266 + Clone
267 + Copy
268 + PartialOrd
269 + PartialEq
270{
271}
272
273pub trait LossyFrom<Source> {
294 fn lossy_from(n: Source) -> Self;
295}
296
297impl LossyFrom<f32> for f32 {
298 fn lossy_from(n: f32) -> Self {
299 n
300 }
301}
302impl LossyFrom<f32> for f64 {
303 fn lossy_from(n: f32) -> Self {
304 n as Self
305 }
306}
307impl LossyFrom<f64> for f32 {
308 fn lossy_from(n: f64) -> Self {
309 n as Self
310 }
311}
312impl LossyFrom<f64> for f64 {
313 fn lossy_from(n: f64) -> Self {
314 n
315 }
316}
317
318pub trait CrossProduct<Rhs = Self> {
319 type Output;
320 #[must_use]
321 fn cross_product(self, rhs: Rhs) -> Self::Output;
322}
323
324pub trait MeasurementUnit {
325 type Property: MeasurementProperty;
326 const RATIO: f64;
327 const OFFSET: f64;
328 const SUFFIX: &'static str;
329}
330
331pub trait AngleMeasurementUnit: MeasurementUnit<Property = crate::angle::Angle> {
332 const CYCLE_FRACTION: f64;
333}
334
335pub trait MeasurementProperty {}
336
337pub trait ScalarProperty: MeasurementProperty {}
338
339pub trait VectorProperty: MeasurementProperty {}