Turn IResultCapture::lastAssertionPassed into a free function

The thread-safety changes in assertions & messages turned whether
the last assertion passed or failed into thread-local state,
instead of being member of the `RunContext`. However, this change
was not reflected in the API `CHECKED_IF`/`CHECKED_ELSE` used,
which in turn required `catch_test_macro_impl.hpp` to include
`catch_interfaces_capture.hpp` for it.

Thanks to the combination of this commit and the previous similar
commit for the message stack handling, the main include path does
not need to include `catch_interfaces_capture.hpp` anymore.
This commit is contained in:
Martin Hořeňovský
2026-04-07 13:35:57 +02:00
parent 3ab0d7cef3
commit 77eae8bd2a
4 changed files with 12 additions and 14 deletions
@@ -61,7 +61,6 @@ namespace Catch {
virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
virtual void benchmarkFailed( StringRef error ) = 0;
virtual void handleFatalErrorCondition( StringRef message ) = 0;
virtual void handleExpr
@@ -87,9 +86,6 @@ namespace Catch {
ResultWas::OfType resultType,
AssertionReaction &reaction ) = 0;
virtual bool lastAssertionPassed() = 0;
// Deprecated, do not use:
virtual std::string getCurrentTestName() const = 0;
virtual const AssertionResult* getLastResult() const = 0;
+3 -5
View File
@@ -324,6 +324,9 @@ namespace Catch {
void addUnscopedMessage( MessageInfo&& message ) {
Detail::g_messageHolder().addUnscopedMessage( CATCH_MOVE( message ) );
}
bool lastAssertionPassed() { return Detail::g_lastAssertionPassed; }
} // namespace Detail
RunContext::RunContext(IConfig const* _config, IEventListenerPtr&& reporter)
@@ -720,10 +723,6 @@ namespace Catch {
m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
}
bool RunContext::lastAssertionPassed() {
return Detail::g_lastAssertionPassed;
}
void RunContext::assertionPassedFastPath(SourceLineInfo lineInfo) {
// We want to save the line info for better experience with unexpected assertions
Detail::g_lastKnownLineInfo = lineInfo;
@@ -953,7 +952,6 @@ namespace Catch {
}
}
void seedRng(IConfig const& config) {
sharedRng().seed(config.rngSeed());
}
@@ -102,8 +102,6 @@ namespace Catch {
void handleFatalErrorCondition( StringRef message ) override;
bool lastAssertionPassed() override;
public:
// !TBD We need to do this another way!
bool aborting() const;
@@ -11,10 +11,16 @@
#include <catch2/catch_user_config.hpp>
#include <catch2/internal/catch_assertion_handler.hpp>
#include <catch2/internal/catch_preprocessor_internal_stringify.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_source_line_info.hpp>
namespace Catch {
namespace Detail {
// Defined in catch_run_context.cpp, where the thread-local data lives.
bool lastAssertionPassed();
}
}
// We need this suppression to leak, because it took until GCC 10
// for the front end to handle local suppression via _Pragma properly
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ <= 9
@@ -57,12 +63,12 @@
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
if( Catch::getResultCapture().lastAssertionPassed() )
if( Catch::Detail::lastAssertionPassed() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
if( !Catch::getResultCapture().lastAssertionPassed() )
if( !Catch::Detail::lastAssertionPassed() )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \