From 2ab20a0e008845e02bd06248e61ca6e5ad1aba33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 29 Jan 2023 23:18:57 +0100 Subject: [PATCH] v3.3.1 --- CMakeLists.txt | 2 +- docs/release-notes.md | 11 ++ extras/catch_amalgamated.cpp | 168 ++++++++++++++++------------ extras/catch_amalgamated.hpp | 89 ++++++++++----- meson.build | 2 +- src/catch2/catch_version.cpp | 2 +- src/catch2/catch_version_macros.hpp | 2 +- 7 files changed, 174 insertions(+), 102 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cf35c0e451..38d2b47e61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() project(Catch2 - VERSION 3.3.0 # CML version placeholder, don't delete + VERSION 3.3.1 # CML version placeholder, don't delete LANGUAGES CXX # HOMEPAGE_URL is not supported until CMake version 3.12, which # we do not target yet. diff --git a/docs/release-notes.md b/docs/release-notes.md index 449ca7f982..3c46cb5732 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[3.3.1](#331)
[3.3.0](#330)
[3.2.1](#321)
[3.2.0](#320)
@@ -55,6 +56,16 @@ +## 3.3.1 + +### Improvements +* Reduced allocations and improved performance + * The exact improvements are dependent on your usage of Catch2. + * For example running Catch2's SelfTest binary performs 8k less allocations. + * The main improvement comes from smarter handling of `SECTION`s, especially sibling `SECTION`s + + + ## 3.3.0 ### Improvements diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp index 0722b49163..0e12bd1438 100644 --- a/extras/catch_amalgamated.cpp +++ b/extras/catch_amalgamated.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.3.0 -// Generated: 2023-01-22 19:46:24.251531 +// Catch v3.3.1 +// Generated: 2023-01-29 22:55:05.183536 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -428,9 +428,9 @@ namespace Catch { return reconstructedExpression; } - AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) + AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData&& data ) : m_info( info ), - m_resultData( data ) + m_resultData( CATCH_MOVE(data) ) {} // Result was a success @@ -758,8 +758,8 @@ namespace Catch { //////////////////////////////////////////////////////////////////////////// - ScopedMessage::ScopedMessage( MessageBuilder const& builder ): - m_info( builder.m_info ) { + ScopedMessage::ScopedMessage( MessageBuilder&& builder ): + m_info( CATCH_MOVE(builder.m_info) ) { m_info.message = builder.m_stream.str(); getResultCapture().pushScopedMessage( m_info ); } @@ -2022,7 +2022,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 3, 0, "", 0 ); + static Version version( 3, 3, 1, "", 0 ); return version; } @@ -2179,18 +2179,17 @@ namespace Catch { // Copy message into messages list. // !TBD This should have been done earlier, somewhere MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); - builder << assertionResult.getMessage(); - builder.m_info.message = builder.m_stream.str(); + builder.m_info.message = static_cast(assertionResult.getMessage()); - infoMessages.push_back( builder.m_info ); + infoMessages.push_back( CATCH_MOVE(builder.m_info) ); } } - SectionStats::SectionStats( SectionInfo const& _sectionInfo, + SectionStats::SectionStats( SectionInfo&& _sectionInfo, Counts const& _assertions, double _durationInSeconds, bool _missingAssertions ) - : sectionInfo( _sectionInfo ), + : sectionInfo( CATCH_MOVE(_sectionInfo) ), assertions( _assertions ), durationInSeconds( _durationInSeconds ), missingAssertions( _missingAssertions ) @@ -4993,12 +4992,12 @@ namespace Catch { struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker { GeneratorBasePtr m_generator; - GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) - : TrackerBase( nameAndLocation, ctx, parent ) + GeneratorTracker( TestCaseTracking::NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( CATCH_MOVE(nameAndLocation), ctx, parent ) {} ~GeneratorTracker() override; - static GeneratorTracker* acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) { + static GeneratorTracker* acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocationRef nameAndLocation ) { GeneratorTracker* tracker; ITracker& currentTracker = ctx.currentTracker(); @@ -5190,7 +5189,7 @@ namespace Catch { uint64_t testRuns = 0; do { m_trackerContext.startCycle(); - m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo)); + m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocationRef(testInfo.name, testInfo.lineInfo)); m_reporter->testCasePartialStarting(testInfo, testRuns); @@ -5261,12 +5260,17 @@ namespace Catch { m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr; } - bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) { - ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo)); + bool RunContext::sectionStarted(StringRef sectionName, SourceLineInfo const& sectionLineInfo, Counts & assertions) { + ITracker& sectionTracker = + SectionTracker::acquire( m_trackerContext, + TestCaseTracking::NameAndLocationRef( + sectionName, sectionLineInfo ) ); + if (!sectionTracker.isOpen()) return false; m_activeSections.push_back(§ionTracker); + SectionInfo sectionInfo( sectionLineInfo, static_cast(sectionName) ); m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; m_reporter->sectionStarting(sectionInfo); @@ -5281,8 +5285,8 @@ namespace Catch { using namespace Generators; GeneratorTracker* tracker = GeneratorTracker::acquire( m_trackerContext, - TestCaseTracking::NameAndLocation( - static_cast( generatorName ), lineInfo ) ); + TestCaseTracking::NameAndLocationRef( + generatorName, lineInfo ) ); m_lastAssertionInfo.lineInfo = lineInfo; return tracker; } @@ -5299,7 +5303,7 @@ namespace Catch { "Trying to create tracker for a genreator that already has one" ); auto newTracker = Catch::Detail::make_unique( - nameAndLoc, m_trackerContext, ¤tTracker ); + CATCH_MOVE(nameAndLoc), m_trackerContext, ¤tTracker ); auto ret = newTracker.get(); currentTracker.addChild( CATCH_MOVE( newTracker ) ); @@ -5320,7 +5324,7 @@ namespace Catch { return true; } - void RunContext::sectionEnded(SectionEndInfo const & endInfo) { + void RunContext::sectionEnded(SectionEndInfo&& endInfo) { Counts assertions = m_totals.assertions - endInfo.prevAssertions; bool missingAssertions = testForMissingAssertions(assertions); @@ -5329,19 +5333,20 @@ namespace Catch { m_activeSections.pop_back(); } - m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); + m_reporter->sectionEnded(SectionStats(CATCH_MOVE(endInfo.sectionInfo), assertions, endInfo.durationInSeconds, missingAssertions)); m_messages.clear(); m_messageScopes.clear(); } - void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { - if (m_unfinishedSections.empty()) + void RunContext::sectionEndedEarly(SectionEndInfo&& endInfo) { + if ( m_unfinishedSections.empty() ) { m_activeSections.back()->fail(); - else + } else { m_activeSections.back()->close(); + } m_activeSections.pop_back(); - m_unfinishedSections.push_back(endInfo); + m_unfinishedSections.push_back(CATCH_MOVE(endInfo)); } void RunContext::benchmarkPreparing( StringRef name ) { @@ -5365,8 +5370,8 @@ namespace Catch { m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); } - void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) { - m_messageScopes.emplace_back( builder ); + void RunContext::emplaceUnscopedMessage( MessageBuilder&& builder ) { + m_messageScopes.emplace_back( CATCH_MOVE(builder) ); } std::string RunContext::getCurrentTestName() const { @@ -5391,7 +5396,7 @@ namespace Catch { // Instead, fake a result data. AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } ); tempResult.message = static_cast(message); - AssertionResult result(m_lastAssertionInfo, tempResult); + AssertionResult result(m_lastAssertionInfo, CATCH_MOVE(tempResult)); assertionEnded(result); @@ -5403,7 +5408,7 @@ namespace Catch { Counts assertions; assertions.failed = 1; - SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false); + SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, 0, false); m_reporter->sectionEnded(testCaseSectionStats); auto const& testInfo = m_activeTestCase->getTestCaseInfo(); @@ -5482,7 +5487,7 @@ namespace Catch { m_messages.clear(); m_messageScopes.clear(); - SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); + SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, duration, missingAssertions); m_reporter->sectionEnded(testCaseSectionStats); } @@ -5506,7 +5511,7 @@ namespace Catch { itEnd = m_unfinishedSections.rend(); it != itEnd; ++it) - sectionEnded(*it); + sectionEnded(CATCH_MOVE(*it)); m_unfinishedSections.clear(); } @@ -5542,7 +5547,7 @@ namespace Catch { m_lastAssertionInfo = info; AssertionResultData data( resultType, LazyExpression( negated ) ); - AssertionResult assertionResult{ info, data }; + AssertionResult assertionResult{ info, CATCH_MOVE( data ) }; assertionResult.m_resultData.lazyExpression.m_transientExpression = expr; assertionEnded( assertionResult ); @@ -5560,7 +5565,8 @@ namespace Catch { AssertionResultData data( resultType, LazyExpression( false ) ); data.message = static_cast(message); - AssertionResult assertionResult{ m_lastAssertionInfo, data }; + AssertionResult assertionResult{ m_lastAssertionInfo, + CATCH_MOVE( data ) }; assertionEnded( assertionResult ); if ( !assertionResult.isOk() ) { populateReaction( reaction ); @@ -5586,7 +5592,7 @@ namespace Catch { AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); data.message = message; - AssertionResult assertionResult{ info, data }; + AssertionResult assertionResult{ info, CATCH_MOVE(data) }; assertionEnded( assertionResult ); populateReaction( reaction ); } @@ -5603,7 +5609,7 @@ namespace Catch { AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; - AssertionResult assertionResult{ info, data }; + AssertionResult assertionResult{ info, CATCH_MOVE( data ) }; assertionEnded( assertionResult ); } void RunContext::handleNonExpr( @@ -5614,7 +5620,7 @@ namespace Catch { m_lastAssertionInfo = info; AssertionResultData data( resultType, LazyExpression( false ) ); - AssertionResult assertionResult{ info, data }; + AssertionResult assertionResult{ info, CATCH_MOVE( data ) }; assertionEnded( assertionResult ); if( !assertionResult.isOk() ) @@ -5646,7 +5652,7 @@ namespace Catch { Section::Section( SectionInfo&& info ): m_info( CATCH_MOVE( info ) ), m_sectionIncluded( - getResultCapture().sectionStarted( m_info, m_assertions ) ) { + getResultCapture().sectionStarted( m_info.name, m_info.lineInfo, m_assertions ) ) { // Non-"included" sections will not use the timing information // anyway, so don't bother with the potential syscall. if (m_sectionIncluded) { @@ -5654,13 +5660,31 @@ namespace Catch { } } + Section::Section( SourceLineInfo const& _lineInfo, + StringRef _name, + const char* const ): + m_info( { "invalid", static_cast(-1) }, "" ), + m_sectionIncluded( + getResultCapture().sectionStarted( _name, _lineInfo, m_assertions ) ) { + // We delay initialization the SectionInfo member until we know + // this section needs it, so we avoid allocating std::string for name. + // We also delay timer start to avoid the potential syscall unless we + // will actually use the result. + if ( m_sectionIncluded ) { + m_info.name = static_cast( _name ); + m_info.lineInfo = _lineInfo; + m_timer.start(); + } + } + Section::~Section() { if( m_sectionIncluded ) { - SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() }; - if( uncaught_exceptions() ) - getResultCapture().sectionEndedEarly( endInfo ); - else - getResultCapture().sectionEnded( endInfo ); + SectionEndInfo endInfo{ CATCH_MOVE(m_info), m_assertions, m_timer.getElapsedSeconds() }; + if ( uncaught_exceptions() ) { + getResultCapture().sectionEndedEarly( CATCH_MOVE(endInfo) ); + } else { + getResultCapture().sectionEnded( CATCH_MOVE( endInfo ) ); + } } } @@ -6155,8 +6179,8 @@ namespace Catch { namespace Catch { namespace TestCaseTracking { - NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) - : name( _name ), + NameAndLocation::NameAndLocation( std::string&& _name, SourceLineInfo const& _location ) + : name( CATCH_MOVE(_name) ), location( _location ) {} @@ -6171,14 +6195,12 @@ namespace TestCaseTracking { m_children.push_back( CATCH_MOVE(child) ); } - ITracker* ITracker::findChild( NameAndLocation const& nameAndLocation ) { + ITracker* ITracker::findChild( NameAndLocationRef nameAndLocation ) { auto it = std::find_if( m_children.begin(), m_children.end(), [&nameAndLocation]( ITrackerPtr const& tracker ) { - return tracker->nameAndLocation().location == - nameAndLocation.location && - tracker->nameAndLocation().name == nameAndLocation.name; + return tracker->nameAndLocation() == nameAndLocation; } ); return ( it != m_children.end() ) ? it->get() : nullptr; } @@ -6241,8 +6263,8 @@ namespace TestCaseTracking { } - TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ): - ITracker(nameAndLocation, parent), + TrackerBase::TrackerBase( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent ): + ITracker(CATCH_MOVE(nameAndLocation), parent), m_ctx( ctx ) {} @@ -6302,13 +6324,14 @@ namespace TestCaseTracking { m_ctx.setCurrentTracker( this ); } - SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) - : TrackerBase( nameAndLocation, ctx, parent ), - m_trimmed_name(trim(nameAndLocation.name)) + SectionTracker::SectionTracker( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( CATCH_MOVE(nameAndLocation), ctx, parent ), + m_trimmed_name(trim(ITracker::nameAndLocation().name)) { if( parent ) { - while( !parent->isSectionTracker() ) + while ( !parent->isSectionTracker() ) { parent = parent->parent(); + } SectionTracker& parentSection = static_cast( *parent ); addNextFilters( parentSection.m_filters ); @@ -6328,24 +6351,30 @@ namespace TestCaseTracking { bool SectionTracker::isSectionTracker() const { return true; } - SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { - SectionTracker* section; + SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocationRef nameAndLocation ) { + SectionTracker* tracker; ITracker& currentTracker = ctx.currentTracker(); if ( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { assert( childTracker ); assert( childTracker->isSectionTracker() ); - section = static_cast( childTracker ); + tracker = static_cast( childTracker ); } else { - auto newSection = Catch::Detail::make_unique( - nameAndLocation, ctx, ¤tTracker ); - section = newSection.get(); - currentTracker.addChild( CATCH_MOVE( newSection ) ); + auto newTracker = Catch::Detail::make_unique( + NameAndLocation{ static_cast(nameAndLocation.name), + nameAndLocation.location }, + ctx, + ¤tTracker ); + tracker = newTracker.get(); + currentTracker.addChild( CATCH_MOVE( newTracker ) ); + } + + if ( !ctx.completedCycle() ) { + tracker->tryOpen(); } - if( !ctx.completedCycle() ) - section->tryOpen(); - return *section; + + return *tracker; } void SectionTracker::tryOpen() { @@ -8809,7 +8838,8 @@ namespace Catch { void CumulativeReporterBase::sectionStarting( SectionInfo const& sectionInfo ) { - SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); + // We need a copy, because SectionStats expect to take ownership + SectionStats incompleteStats( SectionInfo(sectionInfo), Counts(), 0, false ); SectionNode* node; if ( m_sectionStack.empty() ) { if ( !m_rootSection ) { @@ -9792,7 +9822,7 @@ namespace Catch { } void SonarQubeReporter::writeRun( TestRunNode const& runNode ) { - std::map> testsPerFile; + std::map> testsPerFile; for ( auto const& child : runNode.children ) { testsPerFile[child->value.testInfo->lineInfo.file].push_back( @@ -9804,7 +9834,7 @@ namespace Catch { } } - void SonarQubeReporter::writeTestFile(std::string const& filename, std::vector const& testCaseNodes) { + void SonarQubeReporter::writeTestFile(StringRef filename, std::vector const& testCaseNodes) { XmlWriter::ScopedElement e = xml.scopedElement("file"); xml.writeAttribute("path"_sr, filename); diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp index 25928e4e57..88f2dd912c 100644 --- a/extras/catch_amalgamated.hpp +++ b/extras/catch_amalgamated.hpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.3.0 -// Generated: 2023-01-22 19:46:23.163056 +// Catch v3.3.1 +// Generated: 2023-01-29 22:55:03.856079 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -1039,7 +1039,7 @@ namespace Catch { class AssertionResult { public: AssertionResult() = delete; - AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); + AssertionResult( AssertionInfo const& info, AssertionResultData&& data ); bool isOk() const; bool succeeded() const; @@ -1217,10 +1217,11 @@ namespace Catch { public: virtual ~IResultCapture(); - virtual bool sectionStarted( SectionInfo const& sectionInfo, - Counts& assertions ) = 0; - virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; - virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; + virtual bool sectionStarted( StringRef sectionName, + SourceLineInfo const& sectionLineInfo, + Counts& assertions ) = 0; + virtual void sectionEnded( SectionEndInfo&& endInfo ) = 0; + virtual void sectionEndedEarly( SectionEndInfo&& endInfo ) = 0; virtual IGeneratorTracker* acquireGeneratorTracker( StringRef generatorName, @@ -1238,7 +1239,7 @@ namespace Catch { virtual void pushScopedMessage( MessageInfo const& message ) = 0; virtual void popScopedMessage( MessageInfo const& message ) = 0; - virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0; + virtual void emplaceUnscopedMessage( MessageBuilder&& builder ) = 0; virtual void handleFatalErrorCondition( StringRef message ) = 0; @@ -1419,7 +1420,7 @@ namespace Catch { }; struct SectionStats { - SectionStats( SectionInfo const& _sectionInfo, + SectionStats( SectionInfo&& _sectionInfo, Counts const& _assertions, double _durationInSeconds, bool _missingAssertions ); @@ -2691,7 +2692,7 @@ namespace Catch { }); BenchmarkInfo info { - name, + CATCH_MOVE(name), plan.estimated_duration.count(), plan.iterations_per_sample, cfg->benchmarkSamples(), @@ -2707,7 +2708,7 @@ namespace Catch { }); auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end()); - BenchmarkStats> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; + BenchmarkStats> stats{ CATCH_MOVE(info), CATCH_MOVE(analysis.samples), analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; getResultCapture().benchmarkEnded(stats); } CATCH_CATCH_ANON (TestFailureException) { getResultCapture().benchmarkFailed("Benchmark failed due to failed assertion"_sr); @@ -4459,11 +4460,10 @@ namespace Catch { ResultWas::OfType type ): m_info(macroName, lineInfo, type) {} - template - MessageBuilder& operator << ( T const& value ) { + MessageBuilder&& operator << ( T const& value ) && { m_stream << value; - return *this; + return CATCH_MOVE(*this); } MessageInfo m_info; @@ -4471,7 +4471,7 @@ namespace Catch { class ScopedMessage { public: - explicit ScopedMessage( MessageBuilder const& builder ); + explicit ScopedMessage( MessageBuilder&& builder ); ScopedMessage( ScopedMessage& duplicate ) = delete; ScopedMessage( ScopedMessage&& old ) noexcept; ~ScopedMessage(); @@ -6071,6 +6071,9 @@ namespace Catch { class Section : Detail::NonCopyable { public: Section( SectionInfo&& info ); + Section( SourceLineInfo const& _lineInfo, + StringRef _name, + const char* const = nullptr ); ~Section(); // This indicates whether the section should be executed or not @@ -6089,7 +6092,7 @@ namespace Catch { #define INTERNAL_CATCH_SECTION( ... ) \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ - if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \ @@ -7399,7 +7402,7 @@ namespace Catch { #define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MINOR 3 -#define CATCH_VERSION_PATCH 0 +#define CATCH_VERSION_PATCH 1 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED @@ -9194,7 +9197,7 @@ namespace TestCaseTracking { std::string name; SourceLineInfo location; - NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); + NameAndLocation( std::string&& _name, SourceLineInfo const& _location ); friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) { return lhs.name == rhs.name && lhs.location == rhs.location; @@ -9205,6 +9208,32 @@ namespace TestCaseTracking { } }; + /** + * This is a variant of `NameAndLocation` that does not own the name string + * + * This avoids extra allocations when trying to locate a tracker by its + * name and location, as long as we make sure that trackers only keep + * around the owning variant. + */ + struct NameAndLocationRef { + StringRef name; + SourceLineInfo location; + + constexpr NameAndLocationRef( StringRef name_, + SourceLineInfo location_ ): + name( name_ ), location( location_ ) {} + + friend bool operator==( NameAndLocation const& lhs, + NameAndLocationRef rhs ) { + return StringRef( lhs.name ) == rhs.name && + lhs.location == rhs.location; + } + friend bool operator==( NameAndLocationRef lhs, + NameAndLocation const& rhs ) { + return rhs == lhs; + } + }; + class ITracker; using ITrackerPtr = Catch::Detail::unique_ptr; @@ -9229,8 +9258,8 @@ namespace TestCaseTracking { CycleState m_runState = NotStarted; public: - ITracker( NameAndLocation const& nameAndLoc, ITracker* parent ): - m_nameAndLocation( nameAndLoc ), + ITracker( NameAndLocation&& nameAndLoc, ITracker* parent ): + m_nameAndLocation( CATCH_MOVE(nameAndLoc) ), m_parent( parent ) {} @@ -9269,7 +9298,7 @@ namespace TestCaseTracking { * * Returns nullptr if not found. */ - ITracker* findChild( NameAndLocation const& nameAndLocation ); + ITracker* findChild( NameAndLocationRef nameAndLocation ); //! Have any children been added? bool hasChildren() const { return !m_children.empty(); @@ -9326,7 +9355,7 @@ namespace TestCaseTracking { TrackerContext& m_ctx; public: - TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); + TrackerBase( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent ); bool isComplete() const override; @@ -9344,13 +9373,13 @@ namespace TestCaseTracking { std::vector m_filters; std::string m_trimmed_name; public: - SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); + SectionTracker( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent ); bool isSectionTracker() const override; bool isComplete() const override; - static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); + static SectionTracker& acquire( TrackerContext& ctx, NameAndLocationRef nameAndLocation ); void tryOpen(); @@ -9420,10 +9449,12 @@ namespace Catch { ResultWas::OfType resultType, AssertionReaction &reaction ) override; - bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override; + bool sectionStarted( StringRef sectionName, + SourceLineInfo const& sectionLineInfo, + Counts& assertions ) override; - void sectionEnded( SectionEndInfo const& endInfo ) override; - void sectionEndedEarly( SectionEndInfo const& endInfo ) override; + void sectionEnded( SectionEndInfo&& endInfo ) override; + void sectionEndedEarly( SectionEndInfo&& endInfo ) override; IGeneratorTracker* acquireGeneratorTracker( StringRef generatorName, @@ -9442,7 +9473,7 @@ namespace Catch { void pushScopedMessage( MessageInfo const& message ) override; void popScopedMessage( MessageInfo const& message ) override; - void emplaceUnscopedMessage( MessageBuilder const& builder ) override; + void emplaceUnscopedMessage( MessageBuilder&& builder ) override; std::string getCurrentTestName() const override; @@ -12565,7 +12596,7 @@ namespace Catch { void writeRun( TestRunNode const& groupNode ); - void writeTestFile(std::string const& filename, std::vector const& testCaseNodes); + void writeTestFile(StringRef filename, std::vector const& testCaseNodes); void writeTestCase(TestCaseNode const& testCaseNode); diff --git a/meson.build b/meson.build index f5b4c9e1c8..5555ee4008 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project( 'catch2', 'cpp', - version: '3.3.0', # CML version placeholder, don't delete + version: '3.3.1', # CML version placeholder, don't delete license: 'BSL-1.0', meson_version: '>=0.50.0', ) diff --git a/src/catch2/catch_version.cpp b/src/catch2/catch_version.cpp index 26fe92c7db..d797a3b12e 100644 --- a/src/catch2/catch_version.cpp +++ b/src/catch2/catch_version.cpp @@ -36,7 +36,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 3, 0, "", 0 ); + static Version version( 3, 3, 1, "", 0 ); return version; } diff --git a/src/catch2/catch_version_macros.hpp b/src/catch2/catch_version_macros.hpp index d8c11d3fef..75075dd5ce 100644 --- a/src/catch2/catch_version_macros.hpp +++ b/src/catch2/catch_version_macros.hpp @@ -10,6 +10,6 @@ #define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MINOR 3 -#define CATCH_VERSION_PATCH 0 +#define CATCH_VERSION_PATCH 1 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED