| 1 | use core::marker::PhantomData; | 
| 2 |  | 
|---|
| 3 | use 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 | /// ``` | 
|---|
| 22 | pub struct Libm<T>(PhantomData<T>); | 
|---|
| 23 |  | 
|---|
| 24 | macro_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 | libm_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 |  | 
|---|
| 110 | libm_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 |  | 
|---|