1use core::marker::PhantomData;
2
3use crate::*;
4
5/// Generic helper for libm functions, abstracting over f32 and f64. <br/>
6/// # Type Parameter:
7/// - `T`: Either `f32` or `f64`
8///
9/// # Examples
10/// ```rust
11/// use libm::{self, Libm};
12///
13/// const PI_F32: f32 = 3.1415927410e+00;
14/// const PI_F64: f64 = 3.1415926535897931160e+00;
15///
16/// assert!(Libm::<f32>::cos(0.0f32) == libm::cosf(0.0));
17/// assert!(Libm::<f32>::sin(PI_F32) == libm::sinf(PI_F32));
18///
19/// assert!(Libm::<f64>::cos(0.0f64) == libm::cos(0.0));
20/// assert!(Libm::<f64>::sin(PI_F64) == libm::sin(PI_F64));
21/// ```
22pub struct Libm<T>(PhantomData<T>);
23
24macro_rules! libm_helper {
25 ($t:ident, funcs: $funcs:tt) => {
26 impl Libm<$t> {
27 #![allow(unused_parens)]
28
29 libm_helper! { $funcs }
30 }
31 };
32
33 ({$($func:tt);*}) => {
34 $(
35 libm_helper! { $func }
36 )*
37 };
38
39 ((fn $func:ident($($arg:ident: $arg_typ:ty),*) -> ($($ret_typ:ty),*); => $libm_fn:ident)) => {
40 #[inline(always)]
41 pub fn $func($($arg: $arg_typ),*) -> ($($ret_typ),*) {
42 $libm_fn($($arg),*)
43 }
44 };
45}
46
47libm_helper! {
48 f32,
49 funcs: {
50 (fn acos(x: f32) -> (f32); => acosf);
51 (fn acosh(x: f32) -> (f32); => acoshf);
52 (fn asin(x: f32) -> (f32); => asinf);
53 (fn asinh(x: f32) -> (f32); => asinhf);
54 (fn atan(x: f32) -> (f32); => atanf);
55 (fn atan2(y: f32, x: f32) -> (f32); => atan2f);
56 (fn atanh(x: f32) -> (f32); => atanhf);
57 (fn cbrt(x: f32) -> (f32); => cbrtf);
58 (fn ceil(x: f32) -> (f32); => ceilf);
59 (fn copysign(x: f32, y: f32) -> (f32); => copysignf);
60 (fn cos(x: f32) -> (f32); => cosf);
61 (fn cosh(x: f32) -> (f32); => coshf);
62 (fn erf(x: f32) -> (f32); => erff);
63 (fn erfc(x: f32) -> (f32); => erfcf);
64 (fn exp(x: f32) -> (f32); => expf);
65 (fn exp2(x: f32) -> (f32); => exp2f);
66 (fn exp10(x: f32) -> (f32); => exp10f);
67 (fn expm1(x: f32) -> (f32); => expm1f);
68 (fn fabs(x: f32) -> (f32); => fabsf);
69 (fn fdim(x: f32, y: f32) -> (f32); => fdimf);
70 (fn floor(x: f32) -> (f32); => floorf);
71 (fn fma(x: f32, y: f32, z: f32) -> (f32); => fmaf);
72 (fn fmax(x: f32, y: f32) -> (f32); => fmaxf);
73 (fn fmin(x: f32, y: f32) -> (f32); => fminf);
74 (fn fmod(x: f32, y: f32) -> (f32); => fmodf);
75 (fn frexp(x: f32) -> (f32, i32); => frexpf);
76 (fn hypot(x: f32, y: f32) -> (f32); => hypotf);
77 (fn ilogb(x: f32) -> (i32); => ilogbf);
78 (fn j0(x: f32) -> (f32); => j0f);
79 (fn j1(x: f32) -> (f32); => j1f);
80 (fn jn(n: i32, x: f32) -> (f32); => jnf);
81 (fn ldexp(x: f32, n: i32) -> (f32); => ldexpf);
82 (fn lgamma_r(x: f32) -> (f32, i32); => lgammaf_r);
83 (fn lgamma(x: f32) -> (f32); => lgammaf);
84 (fn log(x: f32) -> (f32); => logf);
85 (fn log1p(x: f32) -> (f32); => log1pf);
86 (fn log2(x: f32) -> (f32); => log2f);
87 (fn log10(x: f32) -> (f32); => log10f);
88 (fn modf(x: f32) -> (f32, f32); => modff);
89 (fn nextafter(x: f32, y: f32) -> (f32); => nextafterf);
90 (fn pow(x: f32, y: f32) -> (f32); => powf);
91 (fn remainder(x: f32, y: f32) -> (f32); => remainderf);
92 (fn remquo(x: f32, y: f32) -> (f32, i32); => remquof);
93 (fn rint(x: f32) -> (f32); => rintf);
94 (fn round(x: f32) -> (f32); => roundf);
95 (fn scalbn(x: f32, n: i32) -> (f32); => scalbnf);
96 (fn sin(x: f32) -> (f32); => sinf);
97 (fn sincos(x: f32) -> (f32, f32); => sincosf);
98 (fn sinh(x: f32) -> (f32); => sinhf);
99 (fn sqrt(x: f32) -> (f32); => sqrtf);
100 (fn tan(x: f32) -> (f32); => tanf);
101 (fn tanh(x: f32) -> (f32); => tanhf);
102 (fn tgamma(x: f32) -> (f32); => tgammaf);
103 (fn trunc(x: f32) -> (f32); => truncf);
104 (fn y0(x: f32) -> (f32); => y0f);
105 (fn y1(x: f32) -> (f32); => y1f);
106 (fn yn(n: i32, x: f32) -> (f32); => ynf)
107 }
108}
109
110libm_helper! {
111 f64,
112 funcs: {
113 (fn acos(x: f64) -> (f64); => acos);
114 (fn acosh(x: f64) -> (f64); => acosh);
115 (fn asin(x: f64) -> (f64); => asin);
116 (fn asinh(x: f64) -> (f64); => asinh);
117 (fn atan(x: f64) -> (f64); => atan);
118 (fn atan2(y: f64, x: f64) -> (f64); => atan2);
119 (fn atanh(x: f64) -> (f64); => atanh);
120 (fn cbrt(x: f64) -> (f64); => cbrt);
121 (fn ceil(x: f64) -> (f64); => ceil);
122 (fn copysign(x: f64, y: f64) -> (f64); => copysign);
123 (fn cos(x: f64) -> (f64); => cos);
124 (fn cosh(x: f64) -> (f64); => cosh);
125 (fn erf(x: f64) -> (f64); => erf);
126 (fn erfc(x: f64) -> (f64); => erfc);
127 (fn exp(x: f64) -> (f64); => exp);
128 (fn exp2(x: f64) -> (f64); => exp2);
129 (fn exp10(x: f64) -> (f64); => exp10);
130 (fn expm1(x: f64) -> (f64); => expm1);
131 (fn fabs(x: f64) -> (f64); => fabs);
132 (fn fdim(x: f64, y: f64) -> (f64); => fdim);
133 (fn floor(x: f64) -> (f64); => floor);
134 (fn fma(x: f64, y: f64, z: f64) -> (f64); => fma);
135 (fn fmax(x: f64, y: f64) -> (f64); => fmax);
136 (fn fmin(x: f64, y: f64) -> (f64); => fmin);
137 (fn fmod(x: f64, y: f64) -> (f64); => fmod);
138 (fn frexp(x: f64) -> (f64, i32); => frexp);
139 (fn hypot(x: f64, y: f64) -> (f64); => hypot);
140 (fn ilogb(x: f64) -> (i32); => ilogb);
141 (fn j0(x: f64) -> (f64); => j0);
142 (fn j1(x: f64) -> (f64); => j1);
143 (fn jn(n: i32, x: f64) -> (f64); => jn);
144 (fn ldexp(x: f64, n: i32) -> (f64); => ldexp);
145 (fn lgamma_r(x: f64) -> (f64, i32); => lgamma_r);
146 (fn lgamma(x: f64) -> (f64); => lgamma);
147 (fn log(x: f64) -> (f64); => log);
148 (fn log1p(x: f64) -> (f64); => log1p);
149 (fn log2(x: f64) -> (f64); => log2);
150 (fn log10(x: f64) -> (f64); => log10);
151 (fn modf(x: f64) -> (f64, f64); => modf);
152 (fn nextafter(x: f64, y: f64) -> (f64); => nextafter);
153 (fn pow(x: f64, y: f64) -> (f64); => pow);
154 (fn remainder(x: f64, y: f64) -> (f64); => remainder);
155 (fn remquo(x: f64, y: f64) -> (f64, i32); => remquo);
156 (fn rint(x: f64) -> (f64); => rint);
157 (fn round(x: f64) -> (f64); => round);
158 (fn scalbn(x: f64, n: i32) -> (f64); => scalbn);
159 (fn sin(x: f64) -> (f64); => sin);
160 (fn sincos(x: f64) -> (f64, f64); => sincos);
161 (fn sinh(x: f64) -> (f64); => sinh);
162 (fn sqrt(x: f64) -> (f64); => sqrt);
163 (fn tan(x: f64) -> (f64); => tan);
164 (fn tanh(x: f64) -> (f64); => tanh);
165 (fn tgamma(x: f64) -> (f64); => tgamma);
166 (fn trunc(x: f64) -> (f64); => trunc);
167 (fn y0(x: f64) -> (f64); => y0);
168 (fn y1(x: f64) -> (f64); => y1);
169 (fn yn(n: i32, x: f64) -> (f64); => yn)
170 }
171}
172