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!(i64 { $($func),* }, -1);
342        signed_number_impl!(i32 { $($func),* }, -1);
343        signed_number_impl!(i16 { $($func),* }, -1);
344        signed_number_impl!(i8 { $($func),* }, -1);
345    }
346}
347
348macro_rules! signed_number_impl {
349    ($t:ident { $($func:ident),* }, $minus_one:literal) => {
350        impl SignedNumber for $t {
351            fn minus_one() -> Self {
352                $minus_one
353            }
354        }
355
356        impl SignedNumberOps<$t> for $t {
357            $(
358                fn $func(v: Self) -> Self {
359                    v.$func()
360                }
361            )*
362        }
363    }
364}
365
366macro_rules! float_trait_impl {
367    ($($func:ident),*) => {
368        pub trait Float: SignedNumber {
370            fn small_epsilon() -> Self;
371        }
372        float_impl!(f64 { $($func),* });
373        float_impl!(f32 { $($func),* });
374    }
375}
376
377macro_rules! float_impl {
378    ($t:ident { $($func:ident),* } ) => {
379        impl Float for $t {
380            fn small_epsilon() -> Self {
381                1e-30
382            }
383        }
384
385        impl Lerp<$t> for $t {
386            fn lerp(e0: Self, e1: Self, t: Self) -> Self {
387                e0 + t * (e1 - e0)
388            }
389        }
390
391        impl FloatOps<$t> for $t {
392            $(
393                fn $func(v: Self) -> Self {
394                    v.$func()
395                }
396            )*
397
398            fn point_five() -> Self {
399                0.5 as Self
400            }
401
402            #[allow(clippy::excessive_precision)]
403            fn pi() -> Self {
404                3.14159265358979323846264338327950288 as Self
405            }
406
407            fn two_pi() -> Self {
408                2.0 as Self * Self::pi() as Self
409            }
410
411            fn inv_pi() -> Self {
412                1.0 as Self / Self::pi() as Self
413            }
414
415            #[allow(clippy::excessive_precision)]
416            fn phi() -> Self {
417                1.618033988749894 as Self
418            }
419
420            fn inv_phi() -> Self {
421                1.0 as Self / Self::phi() as Self
422            }
423
424            #[allow(clippy::excessive_precision)]
425            fn tau() -> Self {
426                6.2831853071795864 as Self
427            }
428
429            fn rsqrt(a: Self) -> Self {
430                Self::one()/Self::sqrt(a)
431            }
432
433            fn approx(a: Self, b: Self, eps: Self) -> bool {
434                Self::abs(a - b) < eps
435            }
436
437            fn mad(m: Self, a: Self, b: Self) -> Self {
438                m.mul_add(a, b)
439            }
440
441            fn is_nan(v: Self) -> $t {
442                if v.is_nan() { $t::one() } else { $t::zero() }
443            }
444
445            fn is_infinite(v: Self) -> $t {
446                if v.is_infinite() { $t::one() } else { $t::zero() }
447            }
448
449            fn is_finite(v: Self) -> $t {
450                if v.is_finite() { $t::one() } else { $t::zero() }
451            }
452
453            fn copysign(a: Self, sign: $t) -> Self {
454                a.copysign(sign)
455            }
456
457            fn smoothstep(e0: Self, e1: Self, t: Self) -> Self {
458                if t < e0 { return Self::zero(); }
459                if (t >= e1) { return Self::one(); }
460                let x = (t - e0) / (e1 - e0);
461                x * x * (3 as Self - 2 as Self * x)
462            }
463
464            fn saturate(v: Self) -> Self {
465                Self::max(Self::min(v, 1.0), 0.0)
466            }
467
468            fn powi(v: Self, exp: i32) -> Self {
469                v.powi(exp)
470            }
471
472            fn powf(v: Self, exp: $t) -> Self {
473                v.powf(exp)
474            }
475
476            fn fmod(x: Self, y: Self) -> Self {
477                x % y
478            }
479
480            fn frac(v: Self) -> Self {
481                v.fract()
482            }
483
484            fn trunc(v: Self) -> Self {
485                v.trunc()
486            }
487
488            fn modf(v: Self) -> (Self, Self) {
489                (Self::frac(v), Self::trunc(v))
490            }
491
492            fn log(v: Self, base: Self) -> Self {
493                v.log(base)
494            }
495
496            fn sin_cos(v: Self) -> (Self, Self) {
497                (v.sin(), v.cos())
498            }
499
500            fn atan2(y: Self, x: Self) -> Self {
501                y.atan2(x)
502            }
503
504            fn deg_to_rad(theta: Self) -> Self {
505                theta.to_radians()
506            }
507
508            fn rad_to_deg(theta: Self) -> Self {
509                theta.to_degrees()
510            }
511        }
512    }
513}
514
515macro_rules! integer_trait_impl {
516    ($($func:ident),*) => {
517        pub trait Integer: Number +
519            Shl<Output=Self> + ShlAssign +
520            Shr<Output=Self> + ShrAssign +
521            BitOr<Output=Self> + BitOrAssign +
522            BitAnd<Output=Self> + BitAndAssign +
523            BitXor<Output=Self> + BitXorAssign {
524        }
525        integer_impl!(i8 { $($func),* });
526        integer_impl!(u8 { $($func),* });
527        integer_impl!(i16 { $($func),* });
528        integer_impl!(u16 { $($func),* });
529        integer_impl!(i32 { $($func),* });
530        integer_impl!(u32 { $($func),* });
531        integer_impl!(i64 { $($func),* });
532        integer_impl!(u64 { $($func),* });
533    }
534}
535
536macro_rules! integer_impl {
537    ($t:ident { $($func:ident),* } ) => {
538        impl Integer for $t {
539        }
540
541        impl IntegerOps<$t> for $t {
542            fn pow(v: Self, exp: u32) -> Self {
543                v.pow(exp)
544            }
545        }
546    }
547}
548
549number_trait_impl!();
550integer_trait_impl!();
551
552signed_number_trait_impl!(signum, abs);
553float_trait_impl!(
554    floor, ceil, round, sqrt, recip,
555    cos, sin, tan, acos, asin, atan, cosh, sinh, tanh,
556    exp, exp2, log2, log10
557);