File catch_amalgamated.hpp
↰ Parent directory (include
)
Definition (include/catch_amalgamated.hpp
)
Detailed Description
This is a convenience header for Catch2. It includes all of Catch2 headers.
Generally the Catch2 users should use specific includes they need, but this header can be used instead for ease-of-experimentation, or just plain convenience, at the cost of (significantly) increased compilation times.
When a new header is added to either the top level folder, or to the corresponding internal subfolder, it should be added here. Headers added to the various subparts (e.g. matchers, generators, etc…), should go their respective catch-all headers.
This is a convenience header for Catch2’s benchmarking. It includes all of Catch2 headers related to benchmarking.
Generally the Catch2 users should use specific includes they need, but this header can be used instead for ease-of-experimentation, or just plain convenience, at the cost of (significantly) increased compilation times.
When a new header is added to either the benchmark
folder, or to the corresponding internal (detail) subfolder, it should be added here.
Wrapper for the CONFIG configuration option
When generating internal unique names, there are two options. Either we mix in the current line number, or mix in an incrementing number. We prefer the latter, using __COUNTER__
, but users might want to use the former.
Wrapper for the WCHAR configuration option
We want to support platforms that do not provide wchar_t
, so we sometimes have to disable providing wchar_t overloads through Catch2, e.g. the StringMaker specialization for std::wstring
.
Wrapper for the CATCH_CONFIG_PREFIX_MESSAGES configuration option
CATCH_CONFIG_PREFIX_ALL can be used to avoid clashes with other macros by prepending CATCH_. This may not be desirable if the only clashes are with logger macros such as INFO and WARN. In this cases CATCH_CONFIG_PREFIX_MESSAGES can be used to only prefix a small subset of relevant macros.
Why does decomposing look the way it does:
Conceptually, decomposing is simple. We change REQUIRE( a == b )
into Decomposer{} <= a == b
, so that Decomposer{} <= a
is evaluated first, and our custom operator is used for a == b
, because a
is transformed into ExprLhs<T&>
and then into BinaryExpr<T&, U&>
.
In practice, decomposing ends up a mess, because we have to support various fun things.
Types that are only comparable with literal 0, and they do this by comparing against a magic type with pointer constructor and deleted other constructors. Example:
REQUIRE((a <=> b) == 0)
in libstdc++Types that are only comparable with literal 0, and they do this by comparing against a magic type with consteval integer constructor. Example:
REQUIRE((a <=> b) == 0)
in current MSVC STL.Types that have no linkage, and so we cannot form a reference to them. Example: some implementations of traits.
Starting with C++20, when the compiler sees
a == b
, it also usesb == a
when constructing the overload set. For us this means that when the compiler handlesExprLhs<T> == b
, it also tries to resolve the overload set forb == ExprLhs<T>
.
To accomodate these use cases, decomposer ended up rather complex.
These types are handled by adding SFINAE overloads to our comparison operators, checking whether
T == U
are comparable with the given operator, and if not, whether T (or U) are comparable with literal 0. If yes, the overload compares T (or U) with 0 literal inline in the definition.
Note that for extra correctness, we check that the other type is either an int
(literal 0 is captured as int
by templates), or a long
(some platforms use 0L for NULL
and we want to support that for pointer comparisons).
For these types,
is_foo_comparable<T, int>
is true, but letting them fall into the overload that actually doesT == int
causes compilation error. Handling them requires that the decomposition isconstexpr
, so that P2564R3 applies and theconsteval
from their accompanying magic type is propagated through theconstexpr
call stack.
However this is not enough to handle these types automatically, because our default is to capture types by reference, to avoid runtime copies. While these references cannot become dangling, they outlive the constexpr context and thus the default capture path cannot be actually constexpr.
The solution is to capture these types by value, by explicitly specializing Catch::capture_by_value
for them. Catch2 provides specialization for ``std::foo_ordering``s, but users can specialize the trait for their own types as well.
If a type has no linkage, we also cannot capture it by reference. The solution is once again to capture them by value. We handle the common cases by using
std::is_arithmetic
as the default forCatch::capture_by_value
, but that is only a some-effort heuristic. But as with 2), users can specializecapture_by_value
for their own types as needed.To support C++20 and make the SFINAE on our decomposing operators work, the SFINAE has to happen in return type, rather than in a template type. This is due to our use of logical type traits (
conjunction
/disjunction
/negation
), that we use to workaround an issue in older (9-) versions of GCC. I still blame C++20 for this, because without the comparison order switching, the logical traits could still be used in template type.
There are also other side concerns, e.g. supporting both REQUIRE(a)
and REQUIRE(a == b)
, or making REQUIRE_THAT(a, IsEqual(b))
slot nicely into the same expression handling logic, but these are rather straightforward and add only a bit of complexity (e.g. common base class for decomposed expressions).
Wrapper for the STATIC_ANALYSIS_SUPPORT configuration option
Some of Catch2’s macros can be defined differently to work better with static analysis tools, like clang-tidy or coverity. Currently the main use case is to show that SECTION``s are executed exclusively, and not all in one run of a ``TEST_CASE
.
This is a convenience header for Catch2’s Generator support. It includes all of Catch2 headers related to generators.
Generally the Catch2 users should use specific includes they need, but this header can be used instead for ease-of-experimentation, or just plain convenience, at the cost of (significantly) increased compilation times.
When a new header is added to either the generators
folder, or to the corresponding internal subfolder, it should be added here.
Includes
algorithm
cassert
chrono
climits
cmath
cstddef
cstdint
cstring
ctime
exception
iosfwd
map
memory
ostream
ratio
sstream
string
tuple
type_traits
vector
Included By
Namespaces
Classes
Template Struct UnaryLambdaTraits< ReturnT(ClassT::*)(Args…) const >
Template Struct UnaryLambdaTraits< ReturnT(ClassT::*)(ArgT) const >
Template Struct is_range_impl< T, void_t< decltype(begin(std::declval< T >, ())) > >
Template Struct StringMaker< std::chrono::duration< Value, Ratio > >
Template Struct StringMaker< std::chrono::duration< Value, std::ratio< 1 > > >
Template Struct StringMaker< std::chrono::duration< Value, std::ratio< 3600 > > >
Template Struct StringMaker< std::chrono::duration< Value, std::ratio< 60 > > >
Template Struct StringMaker< std::chrono::time_point< Clock, Duration > >
Template Struct StringMaker< std::chrono::time_point< std::chrono::system_clock, Duration > >
Template Class ExceptionTranslatorRegistrar::ExceptionTranslator
Enums
Functions
Template Function Catch::Benchmark::Detail::estimate_clock_cost
Template Function Catch::Benchmark::Detail::estimate_clock_resolution
Template Function Catch::Benchmark::Detail::measure_environment
Template Function Catch::Benchmark::Detail::measure_one(Fun&&, int, std::false_type)
Template Function Catch::Benchmark::Detail::measure_one(Fun&&, int, std::true_type)
Template Function Catch::Benchmark::Detail::run_for_at_least
Function Catch::Benchmark::Detail::throw_optimized_away_error
Function Catch::Benchmark::Detail::weighted_average_quantile
Template Function Catch::Clara::Detail::convertInto(std::string const&, T&)
Function Catch::Clara::Detail::convertInto(std::string const&, std::string&)
Function Catch::Clara::Detail::convertInto(std::string const&, bool&)
Template Function Catch::Detail::convertUnstreamable(T const&)
Template Function Catch::Detail::convertUnstreamable(T const&)
Template Function Catch::Detail::convertUnstreamable(T const&)
Function Catch::Detail::rawMemoryToString(const void *, std::size_t)
Template Function Catch::Detail::rawMemoryToString(const T&)
Function Catch::Generators::Detail::throw_generator_exception
Template Function Catch::Generators::makeGenerators(GeneratorWrapper<T>&&, Gs&&…)
Template Function Catch::Generators::makeGenerators(GeneratorWrapper<T>&&)
Template Function Catch::Generators::makeGenerators(T&&, Gs&&…)
Template Function Catch::Generators::makeGenerators(as<T>, U&&, Gs&&…)
Template Function Catch::rangeToString(std::vector<bool, Allocator> const&)
Defines
Typedefs
Variables
Variable Catch::Benchmark::Detail::clock_cost_estimation_iterations
Variable Catch::Benchmark::Detail::clock_cost_estimation_tick_limit
Variable Catch::Benchmark::Detail::clock_cost_estimation_time
Variable Catch::Benchmark::Detail::clock_cost_estimation_time_limit
Variable Catch::Benchmark::Detail::clock_resolution_estimation_time