smooth_buffer/
num.rs

1use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
2
3/// A signed Number type. Currently implemented for f32, f64, i8, i16, i32 and i64.
4pub trait Num:
5    Default
6    + PartialEq
7    + PartialOrd
8    + Copy
9    + AddAssign
10    + MulAssign
11    + SubAssign
12    + DivAssign
13    + Add<Output = Self>
14    + Mul<Output = Self>
15    + Sub<Output = Self>
16    + Div<Output = Self>
17    + Neg<Output = Self>
18{
19    fn zero() -> Self;
20    fn two() -> Self;
21    fn four() -> Self;
22    fn max() -> Self;
23    fn from_usize(value: usize) -> Self;
24    fn get_max(a: Self, b: Self) -> Self;
25    fn get_min(a: Self, b: Self) -> Self;
26}
27
28/// Takes in the type and the necessary exponential function for that type.
29macro_rules! impl_num {
30    ($t:ty) => {
31        impl Num for $t {
32            #[inline(always)]
33            fn zero() -> Self {
34                0
35            }
36
37            #[inline(always)]
38            fn two() -> Self {
39                2
40            }
41
42            #[inline(always)]
43            fn four() -> Self {
44                4
45            }
46
47            #[inline(always)]
48            fn max() -> Self {
49                Self::MAX
50            }
51
52            #[inline(always)]
53            fn from_usize(value: usize) -> Self {
54                value as Self
55            }
56
57            #[inline(always)]
58            fn get_max(a: Self, b: Self) -> Self {
59                a.max(b)
60            }
61
62            #[inline(always)]
63            fn get_min(a: Self, b: Self) -> Self {
64                a.min(b)
65            }
66        }
67    };
68}
69
70impl_num!(i8);
71impl_num!(i16);
72impl_num!(i32);
73impl_num!(i64);
74
75pub trait Float: Num {
76    fn floor(a: Self) -> Self;
77    fn ceil(a: Self) -> Self;
78    fn round(a: Self) -> Self;
79    fn exp(a: Self) -> Self;
80}
81
82/// Takes in the type and the necessary exponential function for that type.
83macro_rules! impl_float {
84    ($t:ty, $exp_fn:ident, $floor_fn:ident, $ceil_fn:ident, $round_fn:ident) => {
85        impl Num for $t {
86            #[inline(always)]
87            fn zero() -> Self {
88                0.0
89            }
90
91            #[inline(always)]
92            fn two() -> Self {
93                2.0
94            }
95
96            #[inline(always)]
97            fn four() -> Self {
98                4.0
99            }
100
101            #[inline(always)]
102            fn max() -> Self {
103                Self::MAX
104            }
105
106            #[inline(always)]
107            fn from_usize(value: usize) -> Self {
108                value as Self
109            }
110
111            #[inline(always)]
112            fn get_max(a: Self, b: Self) -> Self {
113                a.max(b)
114            }
115
116            #[inline(always)]
117            fn get_min(a: Self, b: Self) -> Self {
118                a.min(b)
119            }
120        }
121
122        impl Float for $t {
123            #[inline(always)]
124            fn floor(a: Self) -> Self {
125                $floor_fn(a)
126            }
127
128            #[inline(always)]
129            fn ceil(a: Self) -> Self {
130                $ceil_fn(a)
131            }
132
133            #[inline(always)]
134            fn round(a: Self) -> Self {
135                $round_fn(a)
136            }
137
138
139            #[inline(always)]
140            fn exp(a: Self) -> Self {
141                $exp_fn(a)
142            }
143        }
144    };
145}
146
147use libm::{exp, expf, floor, floorf, ceil, ceilf, round, roundf};
148
149impl_float!(f32, expf, floorf, ceilf, roundf);
150impl_float!(f64, exp, floor, ceil, round);