Compare commits

..

2 Commits

Author SHA1 Message Date
Martin Hořeňovský
b8a217fbcc WIP: allow inlining context retrieval 2025-09-23 20:59:26 +02:00
Martin Hořeňovský
bbc5134e3a Keep the main Context instance as static value, not pointer
This allows us to remove the lazy init checks, providing 3-8%
perf improvements when running tests.
2025-09-23 20:59:23 +02:00
5 changed files with 25 additions and 32 deletions

View File

@@ -96,7 +96,6 @@ namespace Catch {
} }
void cleanUp() { void cleanUp() {
cleanupSingletons(); cleanupSingletons();
cleanUpContext();
} }
std::string translateActiveException() { std::string translateActiveException() {
return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();

View File

@@ -10,6 +10,7 @@
#include <string> #include <string>
#include <catch2/internal/catch_context.hpp>
#include <catch2/internal/catch_stringref.hpp> #include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_result_type.hpp> #include <catch2/internal/catch_result_type.hpp>
#include <catch2/internal/catch_unique_ptr.hpp> #include <catch2/internal/catch_unique_ptr.hpp>
@@ -100,7 +101,19 @@ namespace Catch {
virtual void exceptionEarlyReported() = 0; virtual void exceptionEarlyReported() = 0;
}; };
IResultCapture& getResultCapture(); namespace Detail {
[[noreturn]]
void missingCaptureInstance();
}
inline IResultCapture& getResultCapture() {
if (auto* capture = getCurrentContext().getResultCapture()) {
return *capture;
} else {
Detail::missingCaptureInstance();
}
}
} }

View File

@@ -6,25 +6,14 @@
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
#include <catch2/internal/catch_context.hpp> #include <catch2/internal/catch_context.hpp>
#include <catch2/internal/catch_noncopyable.hpp>
#include <catch2/internal/catch_random_number_generator.hpp> #include <catch2/internal/catch_random_number_generator.hpp>
namespace Catch { namespace Catch {
Context* Context::currentContext = nullptr; Context Context::currentContext;
void cleanUpContext() {
delete Context::currentContext;
Context::currentContext = nullptr;
}
void Context::createContext() {
currentContext = new Context();
}
Context& getCurrentMutableContext() { Context& getCurrentMutableContext() {
if ( !Context::currentContext ) { Context::createContext(); } return Context::currentContext;
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
return *Context::currentContext;
} }
SimplePcg32& sharedRng() { SimplePcg32& sharedRng() {

View File

@@ -19,11 +19,9 @@ namespace Catch {
IConfig const* m_config = nullptr; IConfig const* m_config = nullptr;
IResultCapture* m_resultCapture = nullptr; IResultCapture* m_resultCapture = nullptr;
CATCH_EXPORT static Context* currentContext; CATCH_EXPORT static Context currentContext;
friend Context& getCurrentMutableContext(); friend Context& getCurrentMutableContext();
friend Context const& getCurrentContext(); friend Context const& getCurrentContext();
static void createContext();
friend void cleanUpContext();
public: public:
constexpr IResultCapture* getResultCapture() const { constexpr IResultCapture* getResultCapture() const {
@@ -40,15 +38,9 @@ namespace Catch {
Context& getCurrentMutableContext(); Context& getCurrentMutableContext();
inline Context const& getCurrentContext() { inline Context const& getCurrentContext() {
// We duplicate the logic from `getCurrentMutableContext` here, return Context::currentContext;
// to avoid paying the call overhead in debug mode.
if ( !Context::currentContext ) { Context::createContext(); }
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
return *Context::currentContext;
} }
void cleanUpContext();
class SimplePcg32; class SimplePcg32;
SimplePcg32& sharedRng(); SimplePcg32& sharedRng();
} }

View File

@@ -21,6 +21,7 @@
#include <catch2/internal/catch_assertion_handler.hpp> #include <catch2/internal/catch_assertion_handler.hpp>
#include <catch2/internal/catch_test_failure_exception.hpp> #include <catch2/internal/catch_test_failure_exception.hpp>
#include <catch2/internal/catch_result_type.hpp> #include <catch2/internal/catch_result_type.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <cassert> #include <cassert>
#include <algorithm> #include <algorithm>
@@ -809,13 +810,6 @@ namespace Catch {
} }
} }
IResultCapture& getResultCapture() {
if (auto* capture = getCurrentContext().getResultCapture())
return *capture;
else
CATCH_INTERNAL_ERROR("No result capture instance");
}
void IResultCapture::pushScopedMessage( MessageInfo&& message ) { void IResultCapture::pushScopedMessage( MessageInfo&& message ) {
Detail::g_messages.push_back( CATCH_MOVE( message ) ); Detail::g_messages.push_back( CATCH_MOVE( message ) );
} }
@@ -846,4 +840,10 @@ namespace Catch {
return getCurrentContext().getConfig()->rngSeed(); return getCurrentContext().getConfig()->rngSeed();
} }
namespace Detail {
void missingCaptureInstance() {
CATCH_INTERNAL_ERROR( "No result capture instance" );
}
} // namespace Detail
} }