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