1use std::ops::Mul;
2use std::ops::MulAssign;
3use std::ops::Add;
4use std::ops::AddAssign;
5use std::ops::Sub;
6use std::ops::SubAssign;
7use std::ops::Div;
8use std::ops::DivAssign;
9use std::ops::Rem;
10use std::ops::RemAssign;
11use std::ops::Neg;
12use std::ops::Shl;
13use std::ops::ShlAssign;
14use std::ops::Shr;
15use std::ops::ShrAssign;
16use std::ops::BitOr;
17use std::ops::BitOrAssign;
18use std::ops::BitAnd;
19use std::ops::BitAndAssign;
20use std::ops::BitXor;
21use std::ops::BitXorAssign;
22
23use std::cmp::PartialEq;
24use std::cmp::PartialOrd;
25
26use std::fmt::Display;
27
28pub trait Base<T: Number>:
30 Copy + Display +
31 Add<Output=Self> + AddAssign +
32 Sub<Output=Self> + SubAssign +
33 Mul<Output=Self> + MulAssign +
34 Div<Output=Self> + DivAssign +
35 Rem<Output=Self> + RemAssign
36 where Self: Sized {
37 fn zero() -> Self;
39 fn one() -> Self;
41 fn two() -> Self;
43 fn three() -> Self;
45 fn four() -> Self;
47 fn min_value() -> Self;
49 fn max_value() -> Self;
51}
52
53pub trait NumberOps<T: Number> {
55 fn min(a: Self, b: Self) -> Self;
57 fn max(a: Self, b: Self) -> Self;
59 fn clamp(x: Self, min: Self, max: Self) -> Self;
61 fn step(a: Self, b: Self) -> Self;
63}
64
65pub trait SignedNumberOps<T: SignedNumber>: Neg<Output=Self> {
67 fn signum(a: Self) -> Self;
69 fn abs(a: Self) -> Self;
71}
72
73pub trait IntegerOps<T: Integer> {
75 fn pow(a: Self, exp: u32) -> Self;
77}
78
79pub trait Lerp<T: Float> {
81 fn lerp(e0: Self, e1: Self, t: T) -> Self;
83}
84
85pub trait Cast<T: Number> where Self: Sized {
86 fn from_f32(v: f32) -> Self;
87 fn from_f64(v: f64) -> Self;
88 fn from_u32(v: u32) -> Self;
89 fn from_i32(v: i32) -> Self;
90 fn from_u64(v: u64) -> Self;
91 fn from_i64(v: i64) -> Self;
92 fn from_usize(v: usize) -> Self;
93 fn as_f32(&self) -> f32;
94 fn as_f64(&self) -> f64;
95 fn as_u32(&self) -> u32;
96 fn as_i32(&self) -> i32;
97 fn as_u64(&self) -> u64;
98 fn as_i64(&self) -> i64;
99 fn as_usize(&self) -> usize;
100}
101
102pub trait FloatOps<T: Float>: Lerp<T> where Self: Sized {
104 fn point_five() -> Self;
106 fn pi() -> Self;
108 fn two_pi() -> Self;
110 fn inv_pi() -> Self;
112 fn phi() -> Self;
114 fn inv_phi() -> Self;
116 fn tau() -> Self;
118 fn sqrt(a: Self) -> Self;
120 fn rsqrt(a: Self) -> Self;
122 fn recip(a: Self) -> Self;
124 fn powi(a: Self, exp: i32) -> Self;
126 fn powf(a: Self, exp: T) -> Self;
128 fn mad(m: Self, a: Self, b: Self) -> Self;
130 fn approx(a: Self, b: Self, eps: T) -> bool;
132 fn floor(a: Self) -> Self;
134 fn ceil(a: Self) -> Self;
136 fn copysign(a: Self, sign: T) -> Self;
138 fn smoothstep(e0: Self, e1: Self, t: T) -> Self;
140 fn round(a: Self) -> Self;
142 fn is_nan(a: Self) -> Self;
144 fn is_infinite(a: Self) -> Self;
146 fn is_finite(a: Self) -> Self;
148 fn saturate(x: Self) -> Self;
150 fn deg_to_rad(theta: Self) -> Self;
152 fn rad_to_deg(theta: Self) -> Self;
154 fn fmod(x: Self, y: Self) -> Self;
156 fn frac(v: Self) -> Self;
158 fn trunc(v: Self) -> Self;
160 fn modf(v: Self) -> (Self, Self);
162 fn cos(v: Self) -> Self;
164 fn sin(v: Self) -> Self;
166 fn tan(v: Self) -> Self;
168 fn acos(v: Self) -> Self;
170 fn asin(v: Self) -> Self;
172 fn atan(v: Self) -> Self;
174 fn cosh(v: Self) -> Self;
176 fn sinh(v: Self) -> Self;
178 fn tanh(v: Self) -> Self;
180 fn sin_cos(v: Self) -> (Self, Self);
182 fn atan2(y: Self, x: Self) -> Self;
184 fn exp(v: Self) -> Self;
186 fn exp2(v: Self) -> Self;
188 fn log2(v: Self) -> Self;
190 fn log10(v: Self) -> Self;
192 fn log(v: Self, base: T) -> Self;
194}
195
196macro_rules! number_trait_impl {
197 ($($func:ident),*) => {
198 pub trait Number: Base<Self> + Default + PartialEq + PartialOrd {}
200 number_impl!(f64 { $($func),* }, 0.0, 1.0);
201 number_impl!(f32 { $($func),* }, 0.0, 1.0);
202 number_impl!(usize { $($func),* }, 0, 1);
203 number_impl!(isize { $($func),* }, 0, 1);
204 number_impl!(i64 { $($func),* }, 0, 1);
205 number_impl!(u64 { $($func),* }, 0, 1);
206 number_impl!(i32 { $($func),* }, 0, 1);
207 number_impl!(u32 { $($func),* }, 0, 1);
208 number_impl!(i16 { $($func),* }, 0, 1);
209 number_impl!(u16 { $($func),* }, 0, 1);
210 number_impl!(i8 { $($func),* }, 0, 1);
211 number_impl!(u8 { $($func),* }, 0, 1);
212 }
213}
214
215macro_rules! number_impl {
216 ($t:ident { $($func:ident),* }, $zero:literal, $one:literal) => {
217 impl Base<$t> for $t {
218 fn min_value() -> Self {
219 $t::MIN
220 }
221
222 fn max_value() -> Self {
223 $t::MAX
224 }
225
226 fn zero() -> Self {
227 $zero
228 }
229
230 fn one() -> Self {
231 $one
232 }
233
234 fn two() -> Self {
235 2 as Self
236 }
237
238 fn three() -> Self {
239 3 as Self
240 }
241
242 fn four() -> Self {
243 4 as Self
244 }
245
246 }
247
248 impl Number for $t {}
249
250 impl NumberOps<$t> for $t {
251 fn min(a: Self, b: Self) -> Self {
252 a.min(b)
253 }
254
255 fn max(a: Self, b: Self) -> Self {
256 a.max(b)
257 }
258
259 fn clamp(x: Self, min: Self, max: Self) -> Self {
260 NumberOps::max(NumberOps::min(x, max), min)
261 }
262
263 fn step(a: Self, b: Self) -> Self {
264 if a >= b {
265 Self::one()
266 }
267 else {
268 Self::zero()
269 }
270 }
271 }
272
273 impl Cast<$t> for $t {
274 fn from_f32(v: f32) -> Self {
275 v as Self
276 }
277
278 fn from_f64(v: f64) -> Self {
279 v as Self
280 }
281
282 fn from_u32(v: u32) -> Self {
283 v as Self
284 }
285
286 fn from_i32(v: i32) -> Self {
287 v as Self
288 }
289
290 fn from_u64(v: u64) -> Self {
291 v as Self
292 }
293
294 fn from_i64(v: i64) -> Self {
295 v as Self
296 }
297
298 fn from_usize(v: usize) -> Self {
299 v as Self
300 }
301
302 fn as_f32(&self) -> f32 {
303 *self as f32
304 }
305
306 fn as_f64(&self) -> f64 {
307 *self as f64
308 }
309
310 fn as_u32(&self) -> u32 {
311 *self as u32
312 }
313
314 fn as_i32(&self) -> i32 {
315 *self as i32
316 }
317
318 fn as_u64(&self) -> u64 {
319 *self as u64
320 }
321
322 fn as_i64(&self) -> i64 {
323 *self as i64
324 }
325
326 fn as_usize(&self) -> usize {
327 *self as usize
328 }
329 }
330 }
331}
332
333macro_rules! signed_number_trait_impl {
334 ($($func:ident),*) => {
335 pub trait SignedNumber: Number + Neg<Output=Self> {
337 fn minus_one() -> Self;
338 }
339 signed_number_impl!(f64 { $($func),* }, -1.0);
340 signed_number_impl!(f32 { $($func),* }, -1.0);
341 signed_number_impl!(isize { $($func),* }, -1);
342 signed_number_impl!(i64 { $($func),* }, -1);
343 signed_number_impl!(i32 { $($func),* }, -1);
344 signed_number_impl!(i16 { $($func),* }, -1);
345 signed_number_impl!(i8 { $($func),* }, -1);
346 }
347}
348
349macro_rules! signed_number_impl {
350 ($t:ident { $($func:ident),* }, $minus_one:literal) => {
351 impl SignedNumber for $t {
352 fn minus_one() -> Self {
353 $minus_one
354 }
355 }
356
357 impl SignedNumberOps<$t> for $t {
358 $(
359 fn $func(v: Self) -> Self {
360 v.$func()
361 }
362 )*
363 }
364 }
365}
366
367macro_rules! float_trait_impl {
368 ($($func:ident),*) => {
369 pub trait Float: SignedNumber {
371 fn small_epsilon() -> Self;
372 }
373 float_impl!(f64 { $($func),* });
374 float_impl!(f32 { $($func),* });
375 }
376}
377
378macro_rules! float_impl {
379 ($t:ident { $($func:ident),* } ) => {
380 impl Float for $t {
381 fn small_epsilon() -> Self {
382 1e-30
383 }
384 }
385
386 impl Lerp<$t> for $t {
387 fn lerp(e0: Self, e1: Self, t: Self) -> Self {
388 e0 + t * (e1 - e0)
389 }
390 }
391
392 impl FloatOps<$t> for $t {
393 $(
394 fn $func(v: Self) -> Self {
395 v.$func()
396 }
397 )*
398
399 fn point_five() -> Self {
400 0.5 as Self
401 }
402
403 #[allow(clippy::excessive_precision)]
404 fn pi() -> Self {
405 3.14159265358979323846264338327950288 as Self
406 }
407
408 fn two_pi() -> Self {
409 2.0 as Self * Self::pi() as Self
410 }
411
412 fn inv_pi() -> Self {
413 1.0 as Self / Self::pi() as Self
414 }
415
416 #[allow(clippy::excessive_precision)]
417 fn phi() -> Self {
418 1.618033988749894 as Self
419 }
420
421 fn inv_phi() -> Self {
422 1.0 as Self / Self::phi() as Self
423 }
424
425 #[allow(clippy::excessive_precision)]
426 fn tau() -> Self {
427 6.2831853071795864 as Self
428 }
429
430 fn rsqrt(a: Self) -> Self {
431 Self::one()/Self::sqrt(a)
432 }
433
434 fn approx(a: Self, b: Self, eps: Self) -> bool {
435 Self::abs(a - b) < eps
436 }
437
438 fn mad(m: Self, a: Self, b: Self) -> Self {
439 m.mul_add(a, b)
440 }
441
442 fn is_nan(v: Self) -> $t {
443 if v.is_nan() { $t::one() } else { $t::zero() }
444 }
445
446 fn is_infinite(v: Self) -> $t {
447 if v.is_infinite() { $t::one() } else { $t::zero() }
448 }
449
450 fn is_finite(v: Self) -> $t {
451 if v.is_finite() { $t::one() } else { $t::zero() }
452 }
453
454 fn copysign(a: Self, sign: $t) -> Self {
455 a.copysign(sign)
456 }
457
458 fn smoothstep(e0: Self, e1: Self, t: Self) -> Self {
459 if t < e0 { return Self::zero(); }
460 if (t >= e1) { return Self::one(); }
461 let x = (t - e0) / (e1 - e0);
462 x * x * (3 as Self - 2 as Self * x)
463 }
464
465 fn saturate(v: Self) -> Self {
466 Self::max(Self::min(v, 1.0), 0.0)
467 }
468
469 fn powi(v: Self, exp: i32) -> Self {
470 v.powi(exp)
471 }
472
473 fn powf(v: Self, exp: $t) -> Self {
474 v.powf(exp)
475 }
476
477 fn fmod(x: Self, y: Self) -> Self {
478 x % y
479 }
480
481 fn frac(v: Self) -> Self {
482 v.fract()
483 }
484
485 fn trunc(v: Self) -> Self {
486 v.trunc()
487 }
488
489 fn modf(v: Self) -> (Self, Self) {
490 (Self::frac(v), Self::trunc(v))
491 }
492
493 fn log(v: Self, base: Self) -> Self {
494 v.log(base)
495 }
496
497 fn sin_cos(v: Self) -> (Self, Self) {
498 (v.sin(), v.cos())
499 }
500
501 fn atan2(y: Self, x: Self) -> Self {
502 y.atan2(x)
503 }
504
505 fn deg_to_rad(theta: Self) -> Self {
506 theta.to_radians()
507 }
508
509 fn rad_to_deg(theta: Self) -> Self {
510 theta.to_degrees()
511 }
512 }
513 }
514}
515
516macro_rules! integer_trait_impl {
517 ($($func:ident),*) => {
518 pub trait Integer: Number +
520 Shl<Output=Self> + ShlAssign +
521 Shr<Output=Self> + ShrAssign +
522 BitOr<Output=Self> + BitOrAssign +
523 BitAnd<Output=Self> + BitAndAssign +
524 BitXor<Output=Self> + BitXorAssign {
525 }
526 integer_impl!(i8 { $($func),* });
527 integer_impl!(u8 { $($func),* });
528 integer_impl!(i16 { $($func),* });
529 integer_impl!(u16 { $($func),* });
530 integer_impl!(i32 { $($func),* });
531 integer_impl!(u32 { $($func),* });
532 integer_impl!(i64 { $($func),* });
533 integer_impl!(u64 { $($func),* });
534 }
535}
536
537macro_rules! integer_impl {
538 ($t:ident { $($func:ident),* } ) => {
539 impl Integer for $t {
540 }
541
542 impl IntegerOps<$t> for $t {
543 fn pow(v: Self, exp: u32) -> Self {
544 v.pow(exp)
545 }
546 }
547 }
548}
549
550number_trait_impl!();
551integer_trait_impl!();
552
553signed_number_trait_impl!(signum, abs);
554float_trait_impl!(
555 floor, ceil, round, sqrt, recip,
556 cos, sin, tan, acos, asin, atan, cosh, sinh, tanh,
557 exp, exp2, log2, log10
558);