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);