Because TokenStream is copied around a lot, moving it to use
`StringRef` removes _a lot_ of allocations per `Opt` in the parser.
Args are not copied around much, but changing them as well makes it
obvious that they do not participate in the ownership.
The changes add up to removing ~180 allocations for "empty"
invocation of the test binary.
(`./tests/ExtraTests/NoTests --allow-running-no-tests -o /dev/null`
is down to 317 allocs)
This prevents the full construction from being O(N^2) in number
of `Opt`s, and also reduces the number of allocations for running
no tests significantly:
`tests/SelfTest`: 7705 -> 6095
`tests/ExtraTests/NoTests` 2215 -> 605
* Clara::Opt::getHelpColumns returns single item
It could never return multiple items, but for some reason it
was wrapping that single item in a vector.
* Use ReusableStringStream in Clara
* Reserve HelpColumns ahead of time
* Use StringRef for descriptions in HelpColumn type
The combination of these changes ends up removing about 7% (~200)
of allocations when Catch2 has to prepare output for `-h`.
There is no good reason for these to be std::strings, as these
are just (optional) constants for nice user output. This ends up
reducing the allocations significantly.
When measuring allocations when running no tests, the changes are
`tests/SelfTest` 9213 -> 7705
`tests/ExtraTests/NoTests` 3723 -> 2215
By moving to use our `uniform_integer_distribution`, which is
reproducible across different platforms, instead of the stdlib
one which is not, we can provide reproducible results for `float`s
and `double`s. Still no reproducibility for `long double`s, because
those are too different across different platforms.
* Utility for extended mult n x n bits -> 2n bits
* Utility to adapt output from URBG to target (unsigned) integral
type
* Utility to reorder signed values into unsigned type while keeping
the order.
Specifically we add
* `gamma(a, b)`, which returns the magnitude of largest 1-ULP
step in range [a, b].
* `count_equidistant_float(a, b, distance)`, which returns the
number of equi-distant floats in range [a, b].
Together with liberal use of `_sr` UDL to compile-time convert
string literals into StringRefs, this will reduce the number of
allocation and remove most of the strcpy calls inherent in
converting string lits into `std::string`s.
Because the issue comes from the expansions of `UNSCOPED_INFO`,
surrogate TUs could not catch this bug, and in common usage, the
include transitively comes from `catch_test_macros.hpp`.
Fixes#2758
Technically, the declaration should not have a space between
the quotes and the underscore, because `_foo` is a reserved
identifier, but `""_foo` is not. In general it works, but newer
Clang versions warn about this, because WG21 wants to deprecate
and later remove this form completely.
The basic idea was to reduce the number of things dependent on the `Clock`
type. To that end, I replaced `Duration<Clock>` with `IDuration` typedef
for `std::nanoseconds`, and `FloatDuration<Clock>` with `FDuration`
typedef for `Duration<double, std::nano>`. We can generally assume that
any clock's duration can be expressed in nanoseconds, as long as we insert
`duration_cast`s into the right places.
Note that we cannot remove all dependence on `Clock` as a template
arguments, because functions that actually measure the elapsed time have
to use the Clock.
We also changed some template function arguments to pass plain function
pointers, so that the actual implementation can be placed into a cpp file.
This means that the user will see the estimation of full benchmark
running time when it is available, unlike now when it often only
ends up flushed after the benchmark is fully finished.
This means that the user will almost immediately see the start
of table like this
```
benchmark name samples iterations estimated
mean low mean high mean
std dev low std dev high std dev
-------------------------------------------------------------------------------
Fill vector generated 100 54 3.0834 ms
```
This presents significant improvement in user experience especially
for long running benchmarks.
* AssertionEnd does not reset the assertion info yet. That is done after populateReaction. And reset assertion info would also reset the result disposition to normal, so that any uncaught exception would be reported as failure
* Approving test output changes due to added unit tests
* Unit tests to throw std::runtime_error instead of std::exception
* Add a unit test to test incomplete assertion handler
---------
Co-authored-by: Ross <ross.tang@gfo-x.com>
* Add missing include for VxWorks build.
std::min is defined in algorithm provides std::min. It appears to be transitively included for most platforms. For VxWorks however this explicit include is required.
* Add option CATCH_CONFIG_PREFIX_MESSAGES to selectively prefix message macros only.
In contrast to CATCH_CONFIG_PREFIX_ALL, this will only prefix the following macros:
I.e. INFO, UNSCOPED_INFO, WARN and CATCH_CAPTURE
This is mainly useful for codebases that use INFO or WARN for their own logging macros.
Specifically we turned `mean`, `classify_outliers`, `jackknife`,
into concrete functions that take only `const_iterator` from vecs,
instead of generic iterators over anything.
I also changed `resample` to take `const_iterator` instead of
plain `iterator`, and similar for `standard_deviation`, and
`analyse_samples`.
* Split out BenchmarkInfo and BenchmarkStats to their own header
* Outline BenchmarkStats<> declaration to separate header
* Split out TestRunInfo into its own header
These changes let us remove the large `interfaces_reporter.hpp`
include from `benchmark.hpp`, and replace it with
`interfaces_capture.hpp` in `run_context.hpp`.
I also cleaned out `interfaces_repoter.hpp` from reporter headers
that depend on `reporter_common_base.hpp`. This will not change
anything in the actual inclusion set, but makes it logically
more consistent.
To keep the compilation firewall effect, the implementations
are hidden behind a PIMPL. In this case it is probably not
worth it, but we can inline it later if needed.
I do not know if checking the tracker name or the tracker's file
part of the location first would provide better results, but
in the common case, the line part of the location check should be
rather unique, because different `SECTION`s will have different
source lines where they are defined.
I also propagated this same check into `ITracker::findChild`,
because this significantly improves performance of section tracking
in Debug builds -> 10% in macro benchmark heavily focused on section
tracking. In Release build there is usually no difference, because
the inliner will inline `NameAndLoc::operator==` into `findChild`,
and then eliminate the redundant check. (If the inliner decides
against, then this still improves the performance on average).
`NameAndLocationRef` is pretty large type, so even in release build,
it is unlikely to be passed in registers. In addition to the fact
that some platforms currently do not allow passing even small types
in register (Windows ABI!!), it is better to pass it as a ref,
effectively passing around a pointer.