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