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
47// verify-apilist-start
48libm_helper! {
49    f32,
50    funcs: {
51        // verify-sorted-start
52        (fn acos(x: f32) -> (f32);                  => acosf);
53        (fn acosh(x: f32) -> (f32);                 => acoshf);
54        (fn asin(x: f32) -> (f32);                  => asinf);
55        (fn asinh(x: f32) -> (f32);                 => asinhf);
56        (fn atan(x: f32) -> (f32);                  => atanf);
57        (fn atan2(y: f32, x: f32) -> (f32);         => atan2f);
58        (fn atanh(x: f32) -> (f32);                 => atanhf);
59        (fn cbrt(x: f32) -> (f32);                  => cbrtf);
60        (fn ceil(x: f32) -> (f32);                  => ceilf);
61        (fn copysign(x: f32, y: f32) -> (f32);      => copysignf);
62        (fn cos(x: f32) -> (f32);                   => cosf);
63        (fn cosh(x: f32) -> (f32);                  => coshf);
64        (fn erf(x: f32) -> (f32);                   => erff);
65        (fn erfc(x: f32) -> (f32);                  => erfcf);
66        (fn exp(x: f32) -> (f32);                   => expf);
67        (fn exp10(x: f32) -> (f32);                 => exp10f);
68        (fn exp2(x: f32) -> (f32);                  => exp2f);
69        (fn expm1(x: f32) -> (f32);                 => expm1f);
70        (fn fabs(x: f32) -> (f32);                  => fabsf);
71        (fn fdim(x: f32, y: f32) -> (f32);          => fdimf);
72        (fn floor(x: f32) -> (f32);                 => floorf);
73        (fn fma(x: f32, y: f32, z: f32) -> (f32);   => fmaf);
74        (fn fmax(x: f32, y: f32) -> (f32);          => fmaxf);
75        (fn fmin(x: f32, y: f32) -> (f32);          => fminf);
76        (fn fmod(x: f32, y: f32) -> (f32);          => fmodf);
77        (fn frexp(x: f32) -> (f32, i32);            => frexpf);
78        (fn hypot(x: f32, y: f32) -> (f32);         => hypotf);
79        (fn ilogb(x: f32) -> (i32);                 => ilogbf);
80        (fn j0(x: f32) -> (f32);                    => j0f);
81        (fn j1(x: f32) -> (f32);                    => j1f);
82        (fn jn(n: i32, x: f32) -> (f32);            => jnf);
83        (fn ldexp(x: f32, n: i32) -> (f32);         => ldexpf);
84        (fn lgamma(x: f32) -> (f32);                => lgammaf);
85        (fn lgamma_r(x: f32) -> (f32, i32);         => lgammaf_r);
86        (fn log(x: f32) -> (f32);                   => logf);
87        (fn log10(x: f32) -> (f32);                 => log10f);
88        (fn log1p(x: f32) -> (f32);                 => log1pf);
89        (fn log2(x: f32) -> (f32);                  => log2f);
90        (fn modf(x: f32) -> (f32, f32);             => modff);
91        (fn nextafter(x: f32, y: f32) -> (f32);     => nextafterf);
92        (fn pow(x: f32, y: f32) -> (f32);           => powf);
93        (fn remainder(x: f32, y: f32) -> (f32);     => remainderf);
94        (fn remquo(x: f32, y: f32) -> (f32, i32);   => remquof);
95        (fn rint(x: f32) -> (f32);                  => rintf);
96        (fn round(x: f32) -> (f32);                 => roundf);
97        (fn roundeven(x: f32) -> (f32);             => roundevenf);
98        (fn scalbn(x: f32, n: i32) -> (f32);        => scalbnf);
99        (fn sin(x: f32) -> (f32);                   => sinf);
100        (fn sincos(x: f32) -> (f32, f32);           => sincosf);
101        (fn sinh(x: f32) -> (f32);                  => sinhf);
102        (fn sqrt(x: f32) -> (f32);                  => sqrtf);
103        (fn tan(x: f32) -> (f32);                   => tanf);
104        (fn tanh(x: f32) -> (f32);                  => tanhf);
105        (fn tgamma(x: f32) -> (f32);                => tgammaf);
106        (fn trunc(x: f32) -> (f32);                 => truncf);
107        (fn y0(x: f32) -> (f32);                    => y0f);
108        (fn y1(x: f32) -> (f32);                    => y1f);
109        (fn yn(n: i32, x: f32) -> (f32);            => ynf);
110        // verify-sorted-end
111    }
112}
113
114libm_helper! {
115    f64,
116    funcs: {
117        // verify-sorted-start
118        (fn acos(x: f64) -> (f64);                  => acos);
119        (fn acosh(x: f64) -> (f64);                 => acosh);
120        (fn asin(x: f64) -> (f64);                  => asin);
121        (fn asinh(x: f64) -> (f64);                 => asinh);
122        (fn atan(x: f64) -> (f64);                  => atan);
123        (fn atan2(y: f64, x: f64) -> (f64);         => atan2);
124        (fn atanh(x: f64) -> (f64);                 => atanh);
125        (fn cbrt(x: f64) -> (f64);                  => cbrt);
126        (fn ceil(x: f64) -> (f64);                  => ceil);
127        (fn copysign(x: f64, y: f64) -> (f64);      => copysign);
128        (fn cos(x: f64) -> (f64);                   => cos);
129        (fn cosh(x: f64) -> (f64);                  => cosh);
130        (fn erf(x: f64) -> (f64);                   => erf);
131        (fn erfc(x: f64) -> (f64);                  => erfc);
132        (fn exp(x: f64) -> (f64);                   => exp);
133        (fn exp10(x: f64) -> (f64);                 => exp10);
134        (fn exp2(x: f64) -> (f64);                  => exp2);
135        (fn expm1(x: f64) -> (f64);                 => expm1);
136        (fn fabs(x: f64) -> (f64);                  => fabs);
137        (fn fdim(x: f64, y: f64) -> (f64);          => fdim);
138        (fn floor(x: f64) -> (f64);                 => floor);
139        (fn fma(x: f64, y: f64, z: f64) -> (f64);   => fma);
140        (fn fmax(x: f64, y: f64) -> (f64);          => fmax);
141        (fn fmaximum(x: f64, y: f64) -> (f64);      => fmaximum);
142        (fn fmaximum_num(x: f64, y: f64) -> (f64);  => fmaximum_num);
143        (fn fmaximum_numf(x: f32, y: f32) -> (f32); => fmaximum_numf);
144        (fn fmaximumf(x: f32, y: f32) -> (f32);     => fmaximumf);
145        (fn fmin(x: f64, y: f64) -> (f64);          => fmin);
146        (fn fminimum(x: f64, y: f64) -> (f64);      => fminimum);
147        (fn fminimum_num(x: f64, y: f64) -> (f64);  => fminimum_num);
148        (fn fminimum_numf(x: f32, y: f32) -> (f32); => fminimum_numf);
149        (fn fminimumf(x: f32, y: f32) -> (f32);     => fminimumf);
150        (fn fmod(x: f64, y: f64) -> (f64);          => fmod);
151        (fn frexp(x: f64) -> (f64, i32);            => frexp);
152        (fn hypot(x: f64, y: f64) -> (f64);         => hypot);
153        (fn ilogb(x: f64) -> (i32);                 => ilogb);
154        (fn j0(x: f64) -> (f64);                    => j0);
155        (fn j1(x: f64) -> (f64);                    => j1);
156        (fn jn(n: i32, x: f64) -> (f64);            => jn);
157        (fn ldexp(x: f64, n: i32) -> (f64);         => ldexp);
158        (fn lgamma(x: f64) -> (f64);                => lgamma);
159        (fn lgamma_r(x: f64) -> (f64, i32);         => lgamma_r);
160        (fn log(x: f64) -> (f64);                   => log);
161        (fn log10(x: f64) -> (f64);                 => log10);
162        (fn log1p(x: f64) -> (f64);                 => log1p);
163        (fn log2(x: f64) -> (f64);                  => log2);
164        (fn modf(x: f64) -> (f64, f64);             => modf);
165        (fn nextafter(x: f64, y: f64) -> (f64);     => nextafter);
166        (fn pow(x: f64, y: f64) -> (f64);           => pow);
167        (fn remainder(x: f64, y: f64) -> (f64);     => remainder);
168        (fn remquo(x: f64, y: f64) -> (f64, i32);   => remquo);
169        (fn rint(x: f64) -> (f64);                  => rint);
170        (fn round(x: f64) -> (f64);                 => round);
171        (fn roundevem(x: f64) -> (f64);             => roundeven);
172        (fn scalbn(x: f64, n: i32) -> (f64);        => scalbn);
173        (fn sin(x: f64) -> (f64);                   => sin);
174        (fn sincos(x: f64) -> (f64, f64);           => sincos);
175        (fn sinh(x: f64) -> (f64);                  => sinh);
176        (fn sqrt(x: f64) -> (f64);                  => sqrt);
177        (fn tan(x: f64) -> (f64);                   => tan);
178        (fn tanh(x: f64) -> (f64);                  => tanh);
179        (fn tgamma(x: f64) -> (f64);                => tgamma);
180        (fn trunc(x: f64) -> (f64);                 => trunc);
181        (fn y0(x: f64) -> (f64);                    => y0);
182        (fn y1(x: f64) -> (f64);                    => y1);
183        (fn yn(n: i32, x: f64) -> (f64);            => yn);
184        // verify-sorted-end
185    }
186}
187
188#[cfg(f16_enabled)]
189libm_helper! {
190    f16,
191    funcs: {
192        // verify-sorted-start
193        (fn ceil(x: f16) -> (f16);                  => ceilf16);
194        (fn copysign(x: f16, y: f16) -> (f16);      => copysignf16);
195        (fn fabs(x: f16) -> (f16);                  => fabsf16);
196        (fn fdim(x: f16, y: f16) -> (f16);          => fdimf16);
197        (fn floor(x: f16) -> (f16);                 => floorf16);
198        (fn fmax(x: f16, y: f16) -> (f16);          => fmaxf16);
199        (fn fmaximum_num(x: f16, y: f16) -> (f16);  => fmaximum_numf16);
200        (fn fmaximumf16(x: f16, y: f16) -> (f16);   => fmaximumf16);
201        (fn fmin(x: f16, y: f16) -> (f16);          => fminf16);
202        (fn fminimum(x: f16, y: f16) -> (f16);      => fminimumf16);
203        (fn fminimum_num(x: f16, y: f16) -> (f16);  => fminimum_numf16);
204        (fn fmod(x: f16, y: f16) -> (f16);          => fmodf16);
205        (fn ldexp(x: f16, n: i32) -> (f16);         => ldexpf16);
206        (fn rint(x: f16) -> (f16);                  => rintf16);
207        (fn round(x: f16) -> (f16);                 => roundf16);
208        (fn roundeven(x: f16) -> (f16);             => roundevenf16);
209        (fn scalbn(x: f16, n: i32) -> (f16);        => scalbnf16);
210        (fn sqrtf(x: f16) -> (f16);                 => sqrtf16);
211        (fn truncf(x: f16) -> (f16);                => truncf16);
212        // verify-sorted-end
213    }
214}
215
216#[cfg(f128_enabled)]
217libm_helper! {
218    f128,
219    funcs: {
220        // verify-sorted-start
221        (fn ceil(x: f128) -> (f128);                => ceilf128);
222        (fn copysign(x: f128, y: f128) -> (f128);   => copysignf128);
223        (fn fabs(x: f128) -> (f128);                => fabsf128);
224        (fn fdim(x: f128, y: f128) -> (f128);       => fdimf128);
225        (fn floor(x: f128) -> (f128);               => floorf128);
226        (fn fma(x: f128, y: f128, z: f128) -> (f128); => fmaf128);
227        (fn fmax(x: f128, y: f128) -> (f128);       => fmaxf128);
228        (fn fmaximum(x: f128, y: f128) -> (f128);      => fmaximumf128);
229        (fn fmaximum_num(x: f128, y: f128) -> (f128);  => fmaximum_numf128);
230        (fn fmin(x: f128, y: f128) -> (f128);       => fminf128);
231        (fn fminimum(x: f128, y: f128) -> (f128);      => fminimumf128);
232        (fn fminimum_num(x: f128, y: f128) -> (f128);  => fminimum_numf128);
233        (fn fmod(x: f128, y: f128) -> (f128);       => fmodf128);
234        (fn ldexp(x: f128, n: i32) -> (f128);       => ldexpf128);
235        (fn rint(x: f128) -> (f128);                => rintf128);
236        (fn round(x: f128) -> (f128);               => roundf128);
237        (fn roundeven(x: f128) -> (f128);           => roundevenf128);
238        (fn scalbn(x: f128, n: i32) -> (f128);      => scalbnf128);
239        (fn sqrt(x: f128) -> (f128);                => sqrtf128);
240        (fn trunc(x: f128) -> (f128);               => truncf128);
241        // verify-sorted-end
242    }
243}
244// verify-apilist-end