Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit 078a5b3

Browse files
committed
Introduce a func module
This contains: 1. Per-function and per-operation enums created by the proc macro 2. The `MathOp` trait which is implemented once per struct representing a function 3. Submodules for each function, each containing a type that implements `MathOp`
1 parent 9aef43a commit 078a5b3

File tree

3 files changed

+105
-2
lines changed

3 files changed

+105
-2
lines changed

crates/libm-test/src/func.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//! Types representing individual functions.
2+
//!
3+
//! Each function gets a module with its function name, e.g. `mod sinf { /* ... */ }`. The
4+
//! module contains a unit struct `Func` which implements `MathOp`.
5+
6+
use crate::{CheckOutput, Float, TupleCall};
7+
8+
/// An enum representing each possible function name.
9+
#[libm_macros::function_enum(BaseName)]
10+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
11+
pub enum Name {}
12+
13+
/// The name without any type specifier, e.g. `sin` and `sinf` both become `sin`.
14+
#[libm_macros::base_name_enum]
15+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
16+
pub enum BaseName {}
17+
18+
/// Attributes ascribed to a `libm` function including signature, type information,
19+
/// and naming.
20+
pub trait MathOp {
21+
/// The float type used for this operation.
22+
type FTy: Float;
23+
24+
/// The function type representing the signature in a C library.
25+
type CFn: Copy;
26+
27+
/// Arguments passed to the C library function as a tuple. These may include `&mut` return
28+
/// values.
29+
type CArgs<'a>
30+
where
31+
Self: 'a;
32+
33+
/// The type returned by C implementations.
34+
type CRet;
35+
36+
/// The signature of the Rust function as a `fn(...) -> ...` type.
37+
type RustFn: Copy;
38+
39+
/// Arguments passed to the Rust library function as a tuple.
40+
///
41+
/// The required `TupleCall` bounds ensure this type can be passed either to the C function or
42+
/// to the Rust function.
43+
type RustArgs: Copy
44+
+ TupleCall<Self::RustFn, Output = Self::RustRet>
45+
+ TupleCall<Self::CFn, Output = Self::RustRet>;
46+
47+
/// Type returned from the Rust function.
48+
type RustRet: CheckOutput<Self::RustArgs>;
49+
50+
/// The name of this function, including suffix (e.g. `sin`, `sinf`).
51+
const NAME: Name;
52+
53+
/// The name as a string.
54+
const NAME_STR: &'static str = Self::NAME.as_str();
55+
56+
/// The name of the function excluding the type suffix, e.g. `sin` and `sinf` are both `sin`.
57+
const BASE_NAME: BaseName = Self::NAME.base_name();
58+
59+
/// The function in `libm` which can be called.
60+
const LIBM_FN: Self::RustFn;
61+
}
62+
63+
macro_rules! do_thing {
64+
// Matcher for unary functions
65+
(
66+
fn_name: $fn_name:ident,
67+
FTy: $FTy:ty,
68+
CFn: $CFn:ty,
69+
CArgs: $CArgs:ty,
70+
CRet: $CRet:ty,
71+
RustFn: $RustFn:ty,
72+
RustArgs: $RustArgs:ty,
73+
RustRet: $RustRet:ty,
74+
) => {
75+
paste::paste! {
76+
pub mod $fn_name {
77+
use super::*;
78+
pub struct Func;
79+
80+
impl MathOp for Func {
81+
type FTy = $FTy;
82+
type CFn = for<'a> $CFn;
83+
type CArgs<'a> = $CArgs where Self: 'a;
84+
type CRet = $CRet;
85+
type RustFn = $RustFn;
86+
type RustArgs = $RustArgs;
87+
type RustRet = $RustRet;
88+
89+
const NAME: Name = Name::[< $fn_name:camel >];
90+
const LIBM_FN: Self::RustFn = libm::$fn_name;
91+
}
92+
}
93+
94+
}
95+
};
96+
}
97+
98+
libm_macros::for_each_function! {
99+
callback: do_thing,
100+
emit_types: all,
101+
}

crates/libm-test/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
pub mod func;
12
pub mod gen;
23
#[cfg(feature = "test-multiprecision")]
34
pub mod mpfloat;
45
mod precision;
56
mod test_traits;
67

8+
pub use func::{BaseName, MathOp, Name};
79
pub use libm::support::{Float, Int};
810
pub use precision::{MaybeOverride, SpecialCase, multiprec_allowed_ulp, musl_allowed_ulp};
911
pub use test_traits::{CheckBasis, CheckCtx, CheckOutput, GenerateInput, Hex, TupleCall};

crates/libm-test/src/test_traits.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ where
137137
}
138138
}
139139

140-
impl<T1, T2, T3> TupleCall<fn(T1, &mut T2, &mut T3)> for (T1,)
140+
impl<T1, T2, T3> TupleCall<for<'a> fn(T1, &'a mut T2, &'a mut T3)> for (T1,)
141141
where
142142
T1: fmt::Debug,
143143
T2: fmt::Debug + Default,
144144
T3: fmt::Debug + Default,
145145
{
146146
type Output = (T2, T3);
147147

148-
fn call(self, f: fn(T1, &mut T2, &mut T3)) -> Self::Output {
148+
fn call(self, f: for<'a> fn(T1, &'a mut T2, &'a mut T3)) -> Self::Output {
149149
let mut t2 = T2::default();
150150
let mut t3 = T3::default();
151151
f(self.0, &mut t2, &mut t3);

0 commit comments

Comments
 (0)