Currently, all inputs are generated and then cached. This works
reasonably well but it isn't very configurable or extensible (adding
`f16` and `f128` is awkward).
Replace this with a trait for generating random sequences of tuples.
This also removes possible storage limitations of caching all inputs.
Introduce the `KnownSize` iterator wrapper, which allows providing the
size at construction time. This provides an `ExactSizeIterator`
implemenation so we can check a generator's value count during testing.
Currently, tests use a handful of constants to determine how many
iterations to perform: `NTESTS`, `AROUND`, and `MAX_CHECK_POINTS`. This
configuration is not very straightforward to adjust and needs to be
repeated everywhere it is used.
Replace this with new functions in the `run_cfg` module that determine
iteration counts in a more reusable and documented way.
This only updates `edge_cases` and `domain_logspace`, `random` is
refactored in a later commit.
Occasionally it is useful to see some information from running tests
without making everything noisy from `--nocapture`. Add a function to
log this kind of output to a file, and print the file as part of CI.
Currently our implementations for `abs` and `copysign` are defined on
the trait, and these are then called from `generic`. It would be better
to call core's `.abs()` / `.copysign(y)`, but we can't do this in the
generic because calling the standalone function could become recursive
(`fabsf` becomes `intrinsics::fabsf32`, that may lower to a call to
`fabsf`).
Change this so the traits uses the call to `core` if available, falling
back to a call to the standalone generic function.
In practice the recursion isn't likely to be a problem since LLVM
probably always lowers `abs`/`copysign` to assembly, but this pattern
should be more correct for functions that we will add in the future
(e.g. `fma`).
This should eventually be followed by a change to call the trait methods
rather than `fabs`/`copysign` directly.
Once we start addinf `f16` and `f128` routines, we will need to have
this cfg for almost all uses of `for_each_function`. Rather than needing
to specify this each time, always emit `#[cfg(f16_enabled)]` or
`#[cfg(f128_enabled)]` for each function that uses `f16` or `f128`,
respectively.
Now that we are using rustdoc output to locate public functions, the
test is indicating a few that were missed since they don't have their
own function. Update everything to now include the following routines:
* `erfc`
* `erfcf`
* `y0`
* `y0f`
* `y1`
* `y1f`
* `yn`
* `ynf`
Currently `logspace` does a lossy cast from `F::Int` to `usize`. This
could be problematic in the rare cases that this is called with a step
count exceeding what is representable in `usize`.
Resolve this by instead adding bounds so the float's integer type itself
can be iterated.
These types from `libm-macros` provide a way to get information about an
operation at runtime, rather than only being encoded in the type system.
Include the file and reexport relevant types.
This will enable us to `include!` the file to access these types in
`libm-test`, rather than somehow reproducing the types as part of the
macro. Ideally `libm-test` would just `use` the types from `libm-macros`
but proc macro crates cannot currently export anything else.
This also adjusts naming to closer match the scheme described in
`libm_test::op`.
The ambiguous associated types error sometimes fires in cases where it
shouldn't be ambiguous ([1]), which can make things clunky when working
with chained associated types (e.g. `Op::FTy::Int::*` does not work).
Add helper types that we can use instead of the full syntax.
There aren't too many cases in-crate now but this is relevant for some
open PRs.
[1]: https://github.com/rust-lang/rust/issues/38078
We now have tests against our custom-built musl as well as tests against
MPFR. The tests against system musl covers less than those against
custom-built musl, and are less portable; there isn't much benefit to
keeping them around so just remove them.
There are a handful of functions we can move out of the macro and to the
numeric traits as default implementations; do that here.
Additionally, add some bounds that make sense for completeness.
Currently there is a combination of names starting with
`multiprecision_`, `mp_` and `multiprec_`. Update so `multiprecision_`
is always used when a long form makes sense, `mp_` otherwise
(eliminating `multiprec_`).
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 `Routine` struct that
implements `MathOp`
Currently the macro always provides `CFn`, `RustFn`, `RustArgs`, etc.
Change this so that:
1. This information must be explicily requested in the invocation.
2. There is a new `FTy` field available that emits a single float type,
rather than a tuple or signature.
Additionally, add two new macros that create enums representing function
names.
This involves moving some things from full generic implementations (e.g.
`impl<F: Float> SomeTrait for F { /* ... */ }` to generic functions and
macros to implement traits that call them, due to orphan rule violations
after `Float` became a not-in-crate trait.
`Hex` was moved to `test_traits` so we can eliminate `num_traits`.