libm/
libm_helper.rs

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}