| 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 | // verify-apilist-start |
| 48 | libm_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 | |
| 114 | libm_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)] |
| 189 | libm_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)] |
| 217 | libm_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 |
| 245 | |