1use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
2
3pub 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
28macro_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
82macro_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);