Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package Catch2 for openSUSE:Factory checked in at 2023-02-19 18:19:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/Catch2 (Old) and /work/SRC/openSUSE:Factory/.Catch2.new.22824 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "Catch2" Sun Feb 19 18:19:06 2023 rev:11 rq:1066557 version:3.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/Catch2/Catch2.changes 2023-01-24 20:16:58.899450480 +0100 +++ /work/SRC/openSUSE:Factory/.Catch2.new.22824/Catch2.changes 2023-02-19 18:19:11.697569860 +0100 @@ -1,0 +2,7 @@ +Tue Feb 14 05:37:32 UTC 2023 - Atri Bhattacharya <badshah...@gmail.com> + +- Update to version 3.3.1: + * Reduced allocations and improved performance, mainly from + smarter handling of `SECTION`s, especially sibling `SECTION`s. + +------------------------------------------------------------------- Old: ---- Catch2-3.3.0.tar.gz New: ---- Catch2-3.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ Catch2.spec ++++++ --- /var/tmp/diff_new_pack.c2gT3y/_old 2023-02-19 18:19:12.101572427 +0100 +++ /var/tmp/diff_new_pack.c2gT3y/_new 2023-02-19 18:19:12.109572478 +0100 @@ -17,7 +17,7 @@ Name: Catch2 -Version: 3.3.0 +Version: 3.3.1 Release: 0 Summary: A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD License: BSL-1.0 ++++++ Catch2-3.3.0.tar.gz -> Catch2-3.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/CMakeLists.txt new/Catch2-3.3.1/CMakeLists.txt --- old/Catch2-3.3.0/CMakeLists.txt 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/CMakeLists.txt 2023-01-29 23:18:57.000000000 +0100 @@ -31,7 +31,7 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/docs/release-notes.md new/Catch2-3.3.1/docs/release-notes.md --- old/Catch2-3.3.0/docs/release-notes.md 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/docs/release-notes.md 2023-01-29 23:18:57.000000000 +0100 @@ -2,6 +2,7 @@ # Release notes **Contents**<br> +[3.3.1](#331)<br> [3.3.0](#330)<br> [3.2.1](#321)<br> [3.2.0](#320)<br> @@ -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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/extras/catch_amalgamated.cpp new/Catch2-3.3.1/extras/catch_amalgamated.cpp --- old/Catch2-3.3.0/extras/catch_amalgamated.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/extras/catch_amalgamated.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -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 @@ 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 @@ //////////////////////////////////////////////////////////////////////////// - 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 @@ } Version const& libraryVersion() { - static Version version( 3, 3, 0, "", 0 ); + static Version version( 3, 3, 1, "", 0 ); return version; } @@ -2179,18 +2179,17 @@ // 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<std::string>(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 @@ 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 @@ 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 @@ 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<std::string>(sectionName) ); m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; m_reporter->sectionStarting(sectionInfo); @@ -5281,8 +5285,8 @@ using namespace Generators; GeneratorTracker* tracker = GeneratorTracker::acquire( m_trackerContext, - TestCaseTracking::NameAndLocation( - static_cast<std::string>( generatorName ), lineInfo ) ); + TestCaseTracking::NameAndLocationRef( + generatorName, lineInfo ) ); m_lastAssertionInfo.lineInfo = lineInfo; return tracker; } @@ -5299,7 +5303,7 @@ "Trying to create tracker for a genreator that already has one" ); auto newTracker = Catch::Detail::make_unique<Generators::GeneratorTracker>( - nameAndLoc, m_trackerContext, ¤tTracker ); + CATCH_MOVE(nameAndLoc), m_trackerContext, ¤tTracker ); auto ret = newTracker.get(); currentTracker.addChild( CATCH_MOVE( newTracker ) ); @@ -5320,7 +5324,7 @@ 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 @@ 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 @@ 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 @@ // Instead, fake a result data. AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } ); tempResult.message = static_cast<std::string>(message); - AssertionResult result(m_lastAssertionInfo, tempResult); + AssertionResult result(m_lastAssertionInfo, CATCH_MOVE(tempResult)); assertionEnded(result); @@ -5403,7 +5408,7 @@ 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 @@ 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 @@ itEnd = m_unfinishedSections.rend(); it != itEnd; ++it) - sectionEnded(*it); + sectionEnded(CATCH_MOVE(*it)); m_unfinishedSections.clear(); } @@ -5542,7 +5547,7 @@ 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 @@ AssertionResultData data( resultType, LazyExpression( false ) ); data.message = static_cast<std::string>(message); - AssertionResult assertionResult{ m_lastAssertionInfo, data }; + AssertionResult assertionResult{ m_lastAssertionInfo, + CATCH_MOVE( data ) }; assertionEnded( assertionResult ); if ( !assertionResult.isOk() ) { populateReaction( reaction ); @@ -5586,7 +5592,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } + Section::Section( SourceLineInfo const& _lineInfo, + StringRef _name, + const char* const ): + m_info( { "invalid", static_cast<std::size_t>(-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<std::string>( _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 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 @@ 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 @@ } - 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 @@ 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<SectionTracker&>( *parent ); addNextFilters( parentSection.m_filters ); @@ -6328,24 +6351,30 @@ 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<SectionTracker*>( childTracker ); + tracker = static_cast<SectionTracker*>( childTracker ); } else { - auto newSection = Catch::Detail::make_unique<SectionTracker>( - nameAndLocation, ctx, ¤tTracker ); - section = newSection.get(); - currentTracker.addChild( CATCH_MOVE( newSection ) ); - } - if( !ctx.completedCycle() ) - section->tryOpen(); - return *section; + auto newTracker = Catch::Detail::make_unique<SectionTracker>( + NameAndLocation{ static_cast<std::string>(nameAndLocation.name), + nameAndLocation.location }, + ctx, + ¤tTracker ); + tracker = newTracker.get(); + currentTracker.addChild( CATCH_MOVE( newTracker ) ); + } + + if ( !ctx.completedCycle() ) { + tracker->tryOpen(); + } + + return *tracker; } void SectionTracker::tryOpen() { @@ -8809,7 +8838,8 @@ 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 @@ } void SonarQubeReporter::writeRun( TestRunNode const& runNode ) { - std::map<std::string, std::vector<TestCaseNode const*>> testsPerFile; + std::map<StringRef, std::vector<TestCaseNode const*>> testsPerFile; for ( auto const& child : runNode.children ) { testsPerFile[child->value.testInfo->lineInfo.file].push_back( @@ -9804,7 +9834,7 @@ } } - void SonarQubeReporter::writeTestFile(std::string const& filename, std::vector<TestCaseNode const*> const& testCaseNodes) { + void SonarQubeReporter::writeTestFile(StringRef filename, std::vector<TestCaseNode const*> const& testCaseNodes) { XmlWriter::ScopedElement e = xml.scopedElement("file"); xml.writeAttribute("path"_sr, filename); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/extras/catch_amalgamated.hpp new/Catch2-3.3.1/extras/catch_amalgamated.hpp --- old/Catch2-3.3.0/extras/catch_amalgamated.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/extras/catch_amalgamated.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -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 @@ 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 @@ 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 @@ 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 @@ }; struct SectionStats { - SectionStats( SectionInfo const& _sectionInfo, + SectionStats( SectionInfo&& _sectionInfo, Counts const& _assertions, double _durationInSeconds, bool _missingAssertions ); @@ -2691,7 +2692,7 @@ }); BenchmarkInfo info { - name, + CATCH_MOVE(name), plan.estimated_duration.count(), plan.iterations_per_sample, cfg->benchmarkSamples(), @@ -2707,7 +2708,7 @@ }); auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end()); - BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; + BenchmarkStats<FloatDuration<Clock>> 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 @@ ResultWas::OfType type ): m_info(macroName, lineInfo, type) {} - template<typename T> - 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 @@ 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 @@ 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 @@ #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 @@ #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 @@ 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 @@ } }; + /** + * 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<ITracker>; @@ -9229,8 +9258,8 @@ 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 @@ * * 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 @@ 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 @@ std::vector<StringRef> 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 @@ 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 @@ 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 @@ void writeRun( TestRunNode const& groupNode ); - void writeTestFile(std::string const& filename, std::vector<TestCaseNode const*> const& testCaseNodes); + void writeTestFile(StringRef filename, std::vector<TestCaseNode const*> const& testCaseNodes); void writeTestCase(TestCaseNode const& testCaseNode); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/meson.build new/Catch2-3.3.1/meson.build --- old/Catch2-3.3.0/meson.build 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/meson.build 2023-01-29 23:18:57.000000000 +0100 @@ -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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/benchmark/catch_benchmark.hpp new/Catch2-3.3.1/src/catch2/benchmark/catch_benchmark.hpp --- old/Catch2-3.3.0/src/catch2/benchmark/catch_benchmark.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/benchmark/catch_benchmark.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -64,7 +64,7 @@ }); BenchmarkInfo info { - name, + CATCH_MOVE(name), plan.estimated_duration.count(), plan.iterations_per_sample, cfg->benchmarkSamples(), @@ -80,7 +80,7 @@ }); auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end()); - BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance }; + BenchmarkStats<FloatDuration<Clock>> 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); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/catch_assertion_result.cpp new/Catch2-3.3.1/src/catch2/catch_assertion_result.cpp --- old/Catch2-3.3.0/src/catch2/catch_assertion_result.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/catch_assertion_result.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -7,6 +7,7 @@ // SPDX-License-Identifier: BSL-1.0 #include <catch2/catch_assertion_result.hpp> #include <catch2/internal/catch_reusable_string_stream.hpp> +#include <catch2/internal/catch_move_and_forward.hpp> namespace Catch { @@ -26,9 +27,9 @@ 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/catch_assertion_result.hpp new/Catch2-3.3.1/src/catch2/catch_assertion_result.hpp --- old/Catch2-3.3.0/src/catch2/catch_assertion_result.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/catch_assertion_result.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -35,7 +35,7 @@ class AssertionResult { public: AssertionResult() = delete; - AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); + AssertionResult( AssertionInfo const& info, AssertionResultData&& data ); bool isOk() const; bool succeeded() const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/catch_message.cpp new/Catch2-3.3.1/src/catch2/catch_message.cpp --- old/Catch2-3.3.0/src/catch2/catch_message.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/catch_message.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -19,8 +19,8 @@ //////////////////////////////////////////////////////////////////////////// - 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 ); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/catch_message.hpp new/Catch2-3.3.1/src/catch2/catch_message.hpp --- old/Catch2-3.3.0/src/catch2/catch_message.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/catch_message.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -39,11 +39,10 @@ ResultWas::OfType type ): m_info(macroName, lineInfo, type) {} - template<typename T> - MessageBuilder& operator << ( T const& value ) { + MessageBuilder&& operator << ( T const& value ) && { m_stream << value; - return *this; + return CATCH_MOVE(*this); } MessageInfo m_info; @@ -51,7 +50,7 @@ class ScopedMessage { public: - explicit ScopedMessage( MessageBuilder const& builder ); + explicit ScopedMessage( MessageBuilder&& builder ); ScopedMessage( ScopedMessage& duplicate ) = delete; ScopedMessage( ScopedMessage&& old ) noexcept; ~ScopedMessage(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/catch_version.cpp new/Catch2-3.3.1/src/catch2/catch_version.cpp --- old/Catch2-3.3.0/src/catch2/catch_version.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/catch_version.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -36,7 +36,7 @@ } Version const& libraryVersion() { - static Version version( 3, 3, 0, "", 0 ); + static Version version( 3, 3, 1, "", 0 ); return version; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/catch_version_macros.hpp new/Catch2-3.3.1/src/catch2/catch_version_macros.hpp --- old/Catch2-3.3.0/src/catch2/catch_version_macros.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/catch_version_macros.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/interfaces/catch_interfaces_capture.hpp new/Catch2-3.3.1/src/catch2/interfaces/catch_interfaces_capture.hpp --- old/Catch2-3.3.0/src/catch2/interfaces/catch_interfaces_capture.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/interfaces/catch_interfaces_capture.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -44,10 +44,11 @@ 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, @@ -65,7 +66,7 @@ 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; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/interfaces/catch_interfaces_reporter.cpp new/Catch2-3.3.1/src/catch2/interfaces/catch_interfaces_reporter.cpp --- old/Catch2-3.3.0/src/catch2/interfaces/catch_interfaces_reporter.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/interfaces/catch_interfaces_reporter.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -60,18 +60,17 @@ // 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<std::string>(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 ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/interfaces/catch_interfaces_reporter.hpp new/Catch2-3.3.1/src/catch2/interfaces/catch_interfaces_reporter.hpp --- old/Catch2-3.3.0/src/catch2/interfaces/catch_interfaces_reporter.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/interfaces/catch_interfaces_reporter.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -78,7 +78,7 @@ }; struct SectionStats { - SectionStats( SectionInfo const& _sectionInfo, + SectionStats( SectionInfo&& _sectionInfo, Counts const& _assertions, double _durationInSeconds, bool _missingAssertions ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/internal/catch_run_context.cpp new/Catch2-3.3.1/src/catch2/internal/catch_run_context.cpp --- old/Catch2-3.3.0/src/catch2/internal/catch_run_context.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/internal/catch_run_context.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -29,12 +29,12 @@ 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(); @@ -226,7 +226,7 @@ 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); @@ -297,12 +297,17 @@ 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<std::string>(sectionName) ); m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; m_reporter->sectionStarting(sectionInfo); @@ -317,8 +322,8 @@ using namespace Generators; GeneratorTracker* tracker = GeneratorTracker::acquire( m_trackerContext, - TestCaseTracking::NameAndLocation( - static_cast<std::string>( generatorName ), lineInfo ) ); + TestCaseTracking::NameAndLocationRef( + generatorName, lineInfo ) ); m_lastAssertionInfo.lineInfo = lineInfo; return tracker; } @@ -335,7 +340,7 @@ "Trying to create tracker for a genreator that already has one" ); auto newTracker = Catch::Detail::make_unique<Generators::GeneratorTracker>( - nameAndLoc, m_trackerContext, ¤tTracker ); + CATCH_MOVE(nameAndLoc), m_trackerContext, ¤tTracker ); auto ret = newTracker.get(); currentTracker.addChild( CATCH_MOVE( newTracker ) ); @@ -356,7 +361,7 @@ return true; } - void RunContext::sectionEnded(SectionEndInfo const & endInfo) { + void RunContext::sectionEnded(SectionEndInfo&& endInfo) { Counts assertions = m_totals.assertions - endInfo.prevAssertions; bool missingAssertions = testForMissingAssertions(assertions); @@ -365,19 +370,20 @@ 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 ) { @@ -401,8 +407,8 @@ 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 { @@ -427,7 +433,7 @@ // Instead, fake a result data. AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } ); tempResult.message = static_cast<std::string>(message); - AssertionResult result(m_lastAssertionInfo, tempResult); + AssertionResult result(m_lastAssertionInfo, CATCH_MOVE(tempResult)); assertionEnded(result); @@ -439,7 +445,7 @@ 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(); @@ -518,7 +524,7 @@ m_messages.clear(); m_messageScopes.clear(); - SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); + SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, duration, missingAssertions); m_reporter->sectionEnded(testCaseSectionStats); } @@ -542,7 +548,7 @@ itEnd = m_unfinishedSections.rend(); it != itEnd; ++it) - sectionEnded(*it); + sectionEnded(CATCH_MOVE(*it)); m_unfinishedSections.clear(); } @@ -578,7 +584,7 @@ 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 ); @@ -596,7 +602,8 @@ AssertionResultData data( resultType, LazyExpression( false ) ); data.message = static_cast<std::string>(message); - AssertionResult assertionResult{ m_lastAssertionInfo, data }; + AssertionResult assertionResult{ m_lastAssertionInfo, + CATCH_MOVE( data ) }; assertionEnded( assertionResult ); if ( !assertionResult.isOk() ) { populateReaction( reaction ); @@ -622,7 +629,7 @@ AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); data.message = message; - AssertionResult assertionResult{ info, data }; + AssertionResult assertionResult{ info, CATCH_MOVE(data) }; assertionEnded( assertionResult ); populateReaction( reaction ); } @@ -639,7 +646,7 @@ 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( @@ -650,7 +657,7 @@ m_lastAssertionInfo = info; AssertionResultData data( resultType, LazyExpression( false ) ); - AssertionResult assertionResult{ info, data }; + AssertionResult assertionResult{ info, CATCH_MOVE( data ) }; assertionEnded( assertionResult ); if( !assertionResult.isOk() ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/internal/catch_run_context.hpp new/Catch2-3.3.1/src/catch2/internal/catch_run_context.hpp --- old/Catch2-3.3.0/src/catch2/internal/catch_run_context.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/internal/catch_run_context.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -68,10 +68,12 @@ 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, @@ -90,7 +92,7 @@ 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; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/internal/catch_section.cpp new/Catch2-3.3.1/src/catch2/internal/catch_section.cpp --- old/Catch2-3.3.0/src/catch2/internal/catch_section.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/internal/catch_section.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -15,7 +15,7 @@ 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) { @@ -23,13 +23,31 @@ } } + Section::Section( SourceLineInfo const& _lineInfo, + StringRef _name, + const char* const ): + m_info( { "invalid", static_cast<std::size_t>(-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<std::string>( _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 ) ); + } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/internal/catch_section.hpp new/Catch2-3.3.1/src/catch2/internal/catch_section.hpp --- old/Catch2-3.3.0/src/catch2/internal/catch_section.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/internal/catch_section.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -20,6 +20,9 @@ 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 @@ -38,7 +41,7 @@ #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( ... ) \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/internal/catch_test_case_tracker.cpp new/Catch2-3.3.1/src/catch2/internal/catch_test_case_tracker.cpp --- old/Catch2-3.3.0/src/catch2/internal/catch_test_case_tracker.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/internal/catch_test_case_tracker.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -22,8 +22,8 @@ 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 ) {} @@ -38,14 +38,12 @@ 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; } @@ -108,8 +106,8 @@ } - 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 ) {} @@ -169,13 +167,14 @@ 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<SectionTracker&>( *parent ); addNextFilters( parentSection.m_filters ); @@ -195,24 +194,30 @@ 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<SectionTracker*>( childTracker ); + tracker = static_cast<SectionTracker*>( childTracker ); } else { - auto newSection = Catch::Detail::make_unique<SectionTracker>( - nameAndLocation, ctx, ¤tTracker ); - section = newSection.get(); - currentTracker.addChild( CATCH_MOVE( newSection ) ); - } - if( !ctx.completedCycle() ) - section->tryOpen(); - return *section; + auto newTracker = Catch::Detail::make_unique<SectionTracker>( + NameAndLocation{ static_cast<std::string>(nameAndLocation.name), + nameAndLocation.location }, + ctx, + ¤tTracker ); + tracker = newTracker.get(); + currentTracker.addChild( CATCH_MOVE( newTracker ) ); + } + + if ( !ctx.completedCycle() ) { + tracker->tryOpen(); + } + + return *tracker; } void SectionTracker::tryOpen() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/internal/catch_test_case_tracker.hpp new/Catch2-3.3.1/src/catch2/internal/catch_test_case_tracker.hpp --- old/Catch2-3.3.0/src/catch2/internal/catch_test_case_tracker.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/internal/catch_test_case_tracker.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -22,7 +22,7 @@ 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; @@ -33,6 +33,32 @@ } }; + /** + * 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<ITracker>; @@ -57,8 +83,8 @@ 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 ) {} @@ -97,7 +123,7 @@ * * 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(); @@ -154,7 +180,7 @@ TrackerContext& m_ctx; public: - TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); + TrackerBase( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent ); bool isComplete() const override; @@ -172,13 +198,13 @@ std::vector<StringRef> 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(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/reporters/catch_reporter_cumulative_base.cpp new/Catch2-3.3.1/src/catch2/reporters/catch_reporter_cumulative_base.cpp --- old/Catch2-3.3.0/src/catch2/reporters/catch_reporter_cumulative_base.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/reporters/catch_reporter_cumulative_base.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -70,7 +70,8 @@ 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 ) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/reporters/catch_reporter_sonarqube.cpp new/Catch2-3.3.1/src/catch2/reporters/catch_reporter_sonarqube.cpp --- old/Catch2-3.3.0/src/catch2/reporters/catch_reporter_sonarqube.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/reporters/catch_reporter_sonarqube.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -40,7 +40,7 @@ } void SonarQubeReporter::writeRun( TestRunNode const& runNode ) { - std::map<std::string, std::vector<TestCaseNode const*>> testsPerFile; + std::map<StringRef, std::vector<TestCaseNode const*>> testsPerFile; for ( auto const& child : runNode.children ) { testsPerFile[child->value.testInfo->lineInfo.file].push_back( @@ -52,7 +52,7 @@ } } - void SonarQubeReporter::writeTestFile(std::string const& filename, std::vector<TestCaseNode const*> const& testCaseNodes) { + void SonarQubeReporter::writeTestFile(StringRef filename, std::vector<TestCaseNode const*> const& testCaseNodes) { XmlWriter::ScopedElement e = xml.scopedElement("file"); xml.writeAttribute("path"_sr, filename); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/src/catch2/reporters/catch_reporter_sonarqube.hpp new/Catch2-3.3.1/src/catch2/reporters/catch_reporter_sonarqube.hpp --- old/Catch2-3.3.0/src/catch2/reporters/catch_reporter_sonarqube.hpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/src/catch2/reporters/catch_reporter_sonarqube.hpp 2023-01-29 23:18:57.000000000 +0100 @@ -41,7 +41,7 @@ void writeRun( TestRunNode const& groupNode ); - void writeTestFile(std::string const& filename, std::vector<TestCaseNode const*> const& testCaseNodes); + void writeTestFile(StringRef filename, std::vector<TestCaseNode const*> const& testCaseNodes); void writeTestCase(TestCaseNode const& testCaseNode); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Catch2-3.3.0/tests/SelfTest/IntrospectiveTests/PartTracker.tests.cpp new/Catch2-3.3.1/tests/SelfTest/IntrospectiveTests/PartTracker.tests.cpp --- old/Catch2-3.3.0/tests/SelfTest/IntrospectiveTests/PartTracker.tests.cpp 2023-01-22 19:53:12.000000000 +0100 +++ new/Catch2-3.3.1/tests/SelfTest/IntrospectiveTests/PartTracker.tests.cpp 2023-01-29 23:18:57.000000000 +0100 @@ -14,8 +14,8 @@ using namespace Catch; namespace { -Catch::TestCaseTracking::NameAndLocation makeNAL( std::string const& name ) { - return Catch::TestCaseTracking::NameAndLocation( name, Catch::SourceLineInfo("",0) ); +Catch::TestCaseTracking::NameAndLocationRef makeNAL( StringRef name ) { + return Catch::TestCaseTracking::NameAndLocationRef( name, Catch::SourceLineInfo("",0) ); } }