From 756ae05d307168eaa27bd904dbd8e591a6406889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Tue, 23 Sep 2025 15:23:58 +0200 Subject: [PATCH] Inline the `getResultCapture` helper into header. We still keep the error check in the function, but hide it in an outlined function inside a .cpp file, to promote inlining of the retrieval part. In the future, we should explore two things 1) Skipping over the context retrieval here, allowing direct access. I currently do not see a way to do this while keeping the "greppability" of mutable vs immutable accesses that is there now, but it would help a lot when inlining is not enabled. 2) Removing the error check, to make the function trivially inlinable, and without branches. **runtime difference** | --------- | Debug | Release | |:----------|------:|--------:| | Slow path | 0.98 | 1.07 | | Fast path | 1.04 | 1.08 | We lost bit of performance on the assertion slow path in debug mode, but together with the previous commit, it comes out at net zero. For other combinations, we see 5-10% perf improvement across the two commits. --- src/catch2/interfaces/catch_interfaces_capture.cpp | 9 ++++++++- src/catch2/interfaces/catch_interfaces_capture.hpp | 13 ++++++++++++- src/catch2/internal/catch_context.hpp | 1 - src/catch2/internal/catch_run_context.cpp | 7 ------- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/catch2/interfaces/catch_interfaces_capture.cpp b/src/catch2/interfaces/catch_interfaces_capture.cpp index 9b40ee5d..492c5bd9 100644 --- a/src/catch2/interfaces/catch_interfaces_capture.cpp +++ b/src/catch2/interfaces/catch_interfaces_capture.cpp @@ -7,7 +7,14 @@ // SPDX-License-Identifier: BSL-1.0 #include +#include namespace Catch { + namespace Detail { + void missingCaptureInstance() { + CATCH_INTERNAL_ERROR( "No result capture instance" ); + } + } // namespace Detail + IResultCapture::~IResultCapture() = default; -} +} // namespace Catch diff --git a/src/catch2/interfaces/catch_interfaces_capture.hpp b/src/catch2/interfaces/catch_interfaces_capture.hpp index 702ccb4d..4e27a985 100644 --- a/src/catch2/interfaces/catch_interfaces_capture.hpp +++ b/src/catch2/interfaces/catch_interfaces_capture.hpp @@ -10,6 +10,7 @@ #include +#include #include #include #include @@ -100,7 +101,17 @@ namespace Catch { virtual void exceptionEarlyReported() = 0; }; - IResultCapture& getResultCapture(); + namespace Detail { + [[noreturn]] + void missingCaptureInstance(); + } + inline IResultCapture& getResultCapture() { + if (auto* capture = getCurrentContext().getResultCapture()) { + return *capture; + } else { + Detail::missingCaptureInstance(); + } + } } diff --git a/src/catch2/internal/catch_context.hpp b/src/catch2/internal/catch_context.hpp index e35de4b4..0b89632c 100644 --- a/src/catch2/internal/catch_context.hpp +++ b/src/catch2/internal/catch_context.hpp @@ -32,7 +32,6 @@ namespace Catch { m_resultCapture = resultCapture; } constexpr void setConfig( IConfig const* config ) { m_config = config; } - }; Context& getCurrentMutableContext(); diff --git a/src/catch2/internal/catch_run_context.cpp b/src/catch2/internal/catch_run_context.cpp index fc521f8b..0029bf56 100644 --- a/src/catch2/internal/catch_run_context.cpp +++ b/src/catch2/internal/catch_run_context.cpp @@ -809,13 +809,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 ) { Detail::g_messages.push_back( CATCH_MOVE( message ) ); }