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.
This commit is contained in:
Martin Hořeňovský
2025-09-23 15:23:58 +02:00
parent a2e41916f2
commit 756ae05d30
4 changed files with 20 additions and 10 deletions

View File

@@ -7,7 +7,14 @@
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_capture.hpp> #include <catch2/interfaces/catch_interfaces_capture.hpp>
#include <catch2/internal/catch_enforce.hpp>
namespace Catch { namespace Catch {
IResultCapture::~IResultCapture() = default; namespace Detail {
void missingCaptureInstance() {
CATCH_INTERNAL_ERROR( "No result capture instance" );
} }
} // namespace Detail
IResultCapture::~IResultCapture() = default;
} // namespace Catch

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,17 @@ 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

@@ -32,7 +32,6 @@ namespace Catch {
m_resultCapture = resultCapture; m_resultCapture = resultCapture;
} }
constexpr void setConfig( IConfig const* config ) { m_config = config; } constexpr void setConfig( IConfig const* config ) { m_config = config; }
}; };
Context& getCurrentMutableContext(); Context& getCurrentMutableContext();

View File

@@ -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 ) { void IResultCapture::pushScopedMessage( MessageInfo&& message ) {
Detail::g_messages.push_back( CATCH_MOVE( message ) ); Detail::g_messages.push_back( CATCH_MOVE( message ) );
} }