Trevor Gross 56deb13bd4 Add a procedural macro for expanding all function signatures
Introduce `libm_test::for_each_function`. which macro takes a callback
macro and invokes it once per function signature. This provides an
easier way of registering various tests and benchmarks without
duplicating the function names and signatures each time.
2024-10-28 12:59:38 -05:00

97 lines
2.5 KiB
Rust

// `STATUS_DLL_NOT_FOUND` on i686 MinGW, not worth looking into.
#![cfg(not(all(target_arch = "x86", target_os = "windows", target_env = "gnu")))]
macro_rules! basic {
(
fn_name: $fn_name:ident,
CFn: $CFn:ty,
CArgs: $CArgs:ty,
CRet: $CRet:ty,
RustFn: $RustFn:ty,
RustArgs: $RustArgs:ty,
RustRet: $RustRet:ty,
attrs: [$($meta:meta)*]
extra: [$($extra_tt:tt)*],
fn_extra: $fn_extra:expr,
) => {
$(#[$meta])*
mod $fn_name {
#[allow(unused)]
type CFnTy = $CFn;
// type CArgsTy<'_> = $CArgs;
// type CRetTy<'_> = $CRet;
#[allow(unused)]
type RustFnTy = $RustFn;
#[allow(unused)]
type RustArgsTy = $RustArgs;
#[allow(unused)]
type RustRetTy = $RustRet;
#[allow(unused)]
const A: &[&str] = &[$($extra_tt)*];
#[allow(unused)]
fn foo(a: f32) -> f32 {
$fn_extra(a)
}
}
};
}
mod test_basic {
libm_macros::for_each_function! {
callback: basic,
skip: [sin, cos],
attributes: [
// just some random attributes
#[allow(clippy::pedantic)]
#[allow(dead_code)]
[sinf, cosf]
],
extra: ["foo", "bar"],
fn_extra: match MACRO_FN_NAME {
sin => |x| x + 2.0,
cos | cosf => |x: f32| x.MACRO_FN_NAME_NORMALIZED(),
_ => |_x| 100.0
}
}
}
macro_rules! basic_no_extra {
(
fn_name: $fn_name:ident,
CFn: $CFn:ty,
CArgs: $CArgs:ty,
CRet: $CRet:ty,
RustFn: $RustFn:ty,
RustArgs: $RustArgs:ty,
RustRet: $RustRet:ty,
) => {
mod $fn_name {
#[allow(unused)]
type CFnTy = $CFn;
// type CArgsTy<'_> = $CArgs;
// type CRetTy<'_> = $CRet;
#[allow(unused)]
type RustFnTy = $RustFn;
#[allow(unused)]
type RustArgsTy = $RustArgs;
#[allow(unused)]
type RustRetTy = $RustRet;
}
};
}
mod test_basic_no_extra {
// Test with no extra, no skip, and no attributes
libm_macros::for_each_function! {
callback: basic_no_extra,
}
}
mod test_only {
// Test that only works
libm_macros::for_each_function! {
callback: basic_no_extra,
only: [sin, sinf],
}
}