From bbc5134e3ad66b5fa57fc6ada58cebe54c072ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Tue, 23 Sep 2025 11:32:20 +0200 Subject: [PATCH] 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. --- src/catch2/catch_registry_hub.cpp | 1 - src/catch2/internal/catch_context.cpp | 15 ++------------- src/catch2/internal/catch_context.hpp | 12 ++---------- 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/catch2/catch_registry_hub.cpp b/src/catch2/catch_registry_hub.cpp index 3a594678..925468fa 100644 --- a/src/catch2/catch_registry_hub.cpp +++ b/src/catch2/catch_registry_hub.cpp @@ -96,7 +96,6 @@ namespace Catch { } void cleanUp() { cleanupSingletons(); - cleanUpContext(); } std::string translateActiveException() { return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); diff --git a/src/catch2/internal/catch_context.cpp b/src/catch2/internal/catch_context.cpp index 8acf1eda..5389de31 100644 --- a/src/catch2/internal/catch_context.cpp +++ b/src/catch2/internal/catch_context.cpp @@ -6,25 +6,14 @@ // SPDX-License-Identifier: BSL-1.0 #include -#include #include namespace Catch { - Context* Context::currentContext = nullptr; - - void cleanUpContext() { - delete Context::currentContext; - Context::currentContext = nullptr; - } - void Context::createContext() { - currentContext = new Context(); - } + Context Context::currentContext; Context& getCurrentMutableContext() { - if ( !Context::currentContext ) { Context::createContext(); } - // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn) - return *Context::currentContext; + return Context::currentContext; } SimplePcg32& sharedRng() { diff --git a/src/catch2/internal/catch_context.hpp b/src/catch2/internal/catch_context.hpp index 4d8a5da1..e35de4b4 100644 --- a/src/catch2/internal/catch_context.hpp +++ b/src/catch2/internal/catch_context.hpp @@ -19,11 +19,9 @@ namespace Catch { IConfig const* m_config = nullptr; IResultCapture* m_resultCapture = nullptr; - CATCH_EXPORT static Context* currentContext; + CATCH_EXPORT static Context currentContext; friend Context& getCurrentMutableContext(); friend Context const& getCurrentContext(); - static void createContext(); - friend void cleanUpContext(); public: constexpr IResultCapture* getResultCapture() const { @@ -40,15 +38,9 @@ namespace Catch { Context& getCurrentMutableContext(); inline Context const& getCurrentContext() { - // We duplicate the logic from `getCurrentMutableContext` here, - // to avoid paying the call overhead in debug mode. - if ( !Context::currentContext ) { Context::createContext(); } - // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn) - return *Context::currentContext; + return Context::currentContext; } - void cleanUpContext(); - class SimplePcg32; SimplePcg32& sharedRng(); }