This commit is contained in:
Martin Hořeňovský 2023-01-29 23:18:57 +01:00
parent 60264b8807
commit 2ab20a0e00
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
7 changed files with 174 additions and 102 deletions

View File

@ -31,7 +31,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif() endif()
project(Catch2 project(Catch2
VERSION 3.3.0 # CML version placeholder, don't delete VERSION 3.3.1 # CML version placeholder, don't delete
LANGUAGES CXX LANGUAGES CXX
# HOMEPAGE_URL is not supported until CMake version 3.12, which # HOMEPAGE_URL is not supported until CMake version 3.12, which
# we do not target yet. # we do not target yet.

View File

@ -2,6 +2,7 @@
# Release notes # Release notes
**Contents**<br> **Contents**<br>
[3.3.1](#331)<br>
[3.3.0](#330)<br> [3.3.0](#330)<br>
[3.2.1](#321)<br> [3.2.1](#321)<br>
[3.2.0](#320)<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 ## 3.3.0
### Improvements ### Improvements

View File

@ -5,8 +5,8 @@
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// Catch v3.3.0 // Catch v3.3.1
// Generated: 2023-01-22 19:46:24.251531 // Generated: 2023-01-29 22:55:05.183536
// ---------------------------------------------------------- // ----------------------------------------------------------
// This file is an amalgamation of multiple different files. // This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly. // You probably shouldn't edit it directly.
@ -428,9 +428,9 @@ namespace Catch {
return reconstructedExpression; return reconstructedExpression;
} }
AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData&& data )
: m_info( info ), : m_info( info ),
m_resultData( data ) m_resultData( CATCH_MOVE(data) )
{} {}
// Result was a success // Result was a success
@ -758,8 +758,8 @@ namespace Catch {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
ScopedMessage::ScopedMessage( MessageBuilder const& builder ): ScopedMessage::ScopedMessage( MessageBuilder&& builder ):
m_info( builder.m_info ) { m_info( CATCH_MOVE(builder.m_info) ) {
m_info.message = builder.m_stream.str(); m_info.message = builder.m_stream.str();
getResultCapture().pushScopedMessage( m_info ); getResultCapture().pushScopedMessage( m_info );
} }
@ -2022,7 +2022,7 @@ namespace Catch {
} }
Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 3, 3, 0, "", 0 ); static Version version( 3, 3, 1, "", 0 );
return version; return version;
} }
@ -2179,18 +2179,17 @@ namespace Catch {
// Copy message into messages list. // Copy message into messages list.
// !TBD This should have been done earlier, somewhere // !TBD This should have been done earlier, somewhere
MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
builder << assertionResult.getMessage(); builder.m_info.message = static_cast<std::string>(assertionResult.getMessage());
builder.m_info.message = builder.m_stream.str();
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, Counts const& _assertions,
double _durationInSeconds, double _durationInSeconds,
bool _missingAssertions ) bool _missingAssertions )
: sectionInfo( _sectionInfo ), : sectionInfo( CATCH_MOVE(_sectionInfo) ),
assertions( _assertions ), assertions( _assertions ),
durationInSeconds( _durationInSeconds ), durationInSeconds( _durationInSeconds ),
missingAssertions( _missingAssertions ) missingAssertions( _missingAssertions )
@ -4993,12 +4992,12 @@ namespace Catch {
struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker { struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
GeneratorBasePtr m_generator; GeneratorBasePtr m_generator;
GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) GeneratorTracker( TestCaseTracking::NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent )
: TrackerBase( nameAndLocation, ctx, parent ) : TrackerBase( CATCH_MOVE(nameAndLocation), ctx, parent )
{} {}
~GeneratorTracker() override; ~GeneratorTracker() override;
static GeneratorTracker* acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) { static GeneratorTracker* acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocationRef nameAndLocation ) {
GeneratorTracker* tracker; GeneratorTracker* tracker;
ITracker& currentTracker = ctx.currentTracker(); ITracker& currentTracker = ctx.currentTracker();
@ -5190,7 +5189,7 @@ namespace Catch {
uint64_t testRuns = 0; uint64_t testRuns = 0;
do { do {
m_trackerContext.startCycle(); 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); m_reporter->testCasePartialStarting(testInfo, testRuns);
@ -5261,12 +5260,17 @@ namespace Catch {
m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr; m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
} }
bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) { bool RunContext::sectionStarted(StringRef sectionName, SourceLineInfo const& sectionLineInfo, Counts & assertions) {
ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo)); ITracker& sectionTracker =
SectionTracker::acquire( m_trackerContext,
TestCaseTracking::NameAndLocationRef(
sectionName, sectionLineInfo ) );
if (!sectionTracker.isOpen()) if (!sectionTracker.isOpen())
return false; return false;
m_activeSections.push_back(&sectionTracker); m_activeSections.push_back(&sectionTracker);
SectionInfo sectionInfo( sectionLineInfo, static_cast<std::string>(sectionName) );
m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
m_reporter->sectionStarting(sectionInfo); m_reporter->sectionStarting(sectionInfo);
@ -5281,8 +5285,8 @@ namespace Catch {
using namespace Generators; using namespace Generators;
GeneratorTracker* tracker = GeneratorTracker::acquire( GeneratorTracker* tracker = GeneratorTracker::acquire(
m_trackerContext, m_trackerContext,
TestCaseTracking::NameAndLocation( TestCaseTracking::NameAndLocationRef(
static_cast<std::string>( generatorName ), lineInfo ) ); generatorName, lineInfo ) );
m_lastAssertionInfo.lineInfo = lineInfo; m_lastAssertionInfo.lineInfo = lineInfo;
return tracker; return tracker;
} }
@ -5299,7 +5303,7 @@ namespace Catch {
"Trying to create tracker for a genreator that already has one" ); "Trying to create tracker for a genreator that already has one" );
auto newTracker = Catch::Detail::make_unique<Generators::GeneratorTracker>( auto newTracker = Catch::Detail::make_unique<Generators::GeneratorTracker>(
nameAndLoc, m_trackerContext, &currentTracker ); CATCH_MOVE(nameAndLoc), m_trackerContext, &currentTracker );
auto ret = newTracker.get(); auto ret = newTracker.get();
currentTracker.addChild( CATCH_MOVE( newTracker ) ); currentTracker.addChild( CATCH_MOVE( newTracker ) );
@ -5320,7 +5324,7 @@ namespace Catch {
return true; return true;
} }
void RunContext::sectionEnded(SectionEndInfo const & endInfo) { void RunContext::sectionEnded(SectionEndInfo&& endInfo) {
Counts assertions = m_totals.assertions - endInfo.prevAssertions; Counts assertions = m_totals.assertions - endInfo.prevAssertions;
bool missingAssertions = testForMissingAssertions(assertions); bool missingAssertions = testForMissingAssertions(assertions);
@ -5329,19 +5333,20 @@ namespace Catch {
m_activeSections.pop_back(); 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_messages.clear();
m_messageScopes.clear(); m_messageScopes.clear();
} }
void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { void RunContext::sectionEndedEarly(SectionEndInfo&& endInfo) {
if (m_unfinishedSections.empty()) if ( m_unfinishedSections.empty() ) {
m_activeSections.back()->fail(); m_activeSections.back()->fail();
else } else {
m_activeSections.back()->close(); m_activeSections.back()->close();
}
m_activeSections.pop_back(); m_activeSections.pop_back();
m_unfinishedSections.push_back(endInfo); m_unfinishedSections.push_back(CATCH_MOVE(endInfo));
} }
void RunContext::benchmarkPreparing( StringRef name ) { 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()); m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
} }
void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) { void RunContext::emplaceUnscopedMessage( MessageBuilder&& builder ) {
m_messageScopes.emplace_back( builder ); m_messageScopes.emplace_back( CATCH_MOVE(builder) );
} }
std::string RunContext::getCurrentTestName() const { std::string RunContext::getCurrentTestName() const {
@ -5391,7 +5396,7 @@ namespace Catch {
// Instead, fake a result data. // Instead, fake a result data.
AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } ); AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
tempResult.message = static_cast<std::string>(message); tempResult.message = static_cast<std::string>(message);
AssertionResult result(m_lastAssertionInfo, tempResult); AssertionResult result(m_lastAssertionInfo, CATCH_MOVE(tempResult));
assertionEnded(result); assertionEnded(result);
@ -5403,7 +5408,7 @@ namespace Catch {
Counts assertions; Counts assertions;
assertions.failed = 1; assertions.failed = 1;
SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false); SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, 0, false);
m_reporter->sectionEnded(testCaseSectionStats); m_reporter->sectionEnded(testCaseSectionStats);
auto const& testInfo = m_activeTestCase->getTestCaseInfo(); auto const& testInfo = m_activeTestCase->getTestCaseInfo();
@ -5482,7 +5487,7 @@ namespace Catch {
m_messages.clear(); m_messages.clear();
m_messageScopes.clear(); m_messageScopes.clear();
SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, duration, missingAssertions);
m_reporter->sectionEnded(testCaseSectionStats); m_reporter->sectionEnded(testCaseSectionStats);
} }
@ -5506,7 +5511,7 @@ namespace Catch {
itEnd = m_unfinishedSections.rend(); itEnd = m_unfinishedSections.rend();
it != itEnd; it != itEnd;
++it) ++it)
sectionEnded(*it); sectionEnded(CATCH_MOVE(*it));
m_unfinishedSections.clear(); m_unfinishedSections.clear();
} }
@ -5542,7 +5547,7 @@ namespace Catch {
m_lastAssertionInfo = info; m_lastAssertionInfo = info;
AssertionResultData data( resultType, LazyExpression( negated ) ); AssertionResultData data( resultType, LazyExpression( negated ) );
AssertionResult assertionResult{ info, data }; AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
assertionResult.m_resultData.lazyExpression.m_transientExpression = expr; assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;
assertionEnded( assertionResult ); assertionEnded( assertionResult );
@ -5560,7 +5565,8 @@ namespace Catch {
AssertionResultData data( resultType, LazyExpression( false ) ); AssertionResultData data( resultType, LazyExpression( false ) );
data.message = static_cast<std::string>(message); data.message = static_cast<std::string>(message);
AssertionResult assertionResult{ m_lastAssertionInfo, data }; AssertionResult assertionResult{ m_lastAssertionInfo,
CATCH_MOVE( data ) };
assertionEnded( assertionResult ); assertionEnded( assertionResult );
if ( !assertionResult.isOk() ) { if ( !assertionResult.isOk() ) {
populateReaction( reaction ); populateReaction( reaction );
@ -5586,7 +5592,7 @@ namespace Catch {
AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
data.message = message; data.message = message;
AssertionResult assertionResult{ info, data }; AssertionResult assertionResult{ info, CATCH_MOVE(data) };
assertionEnded( assertionResult ); assertionEnded( assertionResult );
populateReaction( reaction ); populateReaction( reaction );
} }
@ -5603,7 +5609,7 @@ namespace Catch {
AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );
data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
AssertionResult assertionResult{ info, data }; AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
assertionEnded( assertionResult ); assertionEnded( assertionResult );
} }
void RunContext::handleNonExpr( void RunContext::handleNonExpr(
@ -5614,7 +5620,7 @@ namespace Catch {
m_lastAssertionInfo = info; m_lastAssertionInfo = info;
AssertionResultData data( resultType, LazyExpression( false ) ); AssertionResultData data( resultType, LazyExpression( false ) );
AssertionResult assertionResult{ info, data }; AssertionResult assertionResult{ info, CATCH_MOVE( data ) };
assertionEnded( assertionResult ); assertionEnded( assertionResult );
if( !assertionResult.isOk() ) if( !assertionResult.isOk() )
@ -5646,7 +5652,7 @@ namespace Catch {
Section::Section( SectionInfo&& info ): Section::Section( SectionInfo&& info ):
m_info( CATCH_MOVE( info ) ), m_info( CATCH_MOVE( info ) ),
m_sectionIncluded( 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 // Non-"included" sections will not use the timing information
// anyway, so don't bother with the potential syscall. // anyway, so don't bother with the potential syscall.
if (m_sectionIncluded) { if (m_sectionIncluded) {
@ -5654,13 +5660,31 @@ namespace Catch {
} }
} }
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() { Section::~Section() {
if( m_sectionIncluded ) { if( m_sectionIncluded ) {
SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() }; SectionEndInfo endInfo{ CATCH_MOVE(m_info), m_assertions, m_timer.getElapsedSeconds() };
if( uncaught_exceptions() ) if ( uncaught_exceptions() ) {
getResultCapture().sectionEndedEarly( endInfo ); getResultCapture().sectionEndedEarly( CATCH_MOVE(endInfo) );
else } else {
getResultCapture().sectionEnded( endInfo ); getResultCapture().sectionEnded( CATCH_MOVE( endInfo ) );
}
} }
} }
@ -6155,8 +6179,8 @@ namespace Catch {
namespace Catch { namespace Catch {
namespace TestCaseTracking { namespace TestCaseTracking {
NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) NameAndLocation::NameAndLocation( std::string&& _name, SourceLineInfo const& _location )
: name( _name ), : name( CATCH_MOVE(_name) ),
location( _location ) location( _location )
{} {}
@ -6171,14 +6195,12 @@ namespace TestCaseTracking {
m_children.push_back( CATCH_MOVE(child) ); m_children.push_back( CATCH_MOVE(child) );
} }
ITracker* ITracker::findChild( NameAndLocation const& nameAndLocation ) { ITracker* ITracker::findChild( NameAndLocationRef nameAndLocation ) {
auto it = std::find_if( auto it = std::find_if(
m_children.begin(), m_children.begin(),
m_children.end(), m_children.end(),
[&nameAndLocation]( ITrackerPtr const& tracker ) { [&nameAndLocation]( ITrackerPtr const& tracker ) {
return tracker->nameAndLocation().location == return tracker->nameAndLocation() == nameAndLocation;
nameAndLocation.location &&
tracker->nameAndLocation().name == nameAndLocation.name;
} ); } );
return ( it != m_children.end() ) ? it->get() : nullptr; return ( it != m_children.end() ) ? it->get() : nullptr;
} }
@ -6241,8 +6263,8 @@ namespace TestCaseTracking {
} }
TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ): TrackerBase::TrackerBase( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
ITracker(nameAndLocation, parent), ITracker(CATCH_MOVE(nameAndLocation), parent),
m_ctx( ctx ) m_ctx( ctx )
{} {}
@ -6302,13 +6324,14 @@ namespace TestCaseTracking {
m_ctx.setCurrentTracker( this ); m_ctx.setCurrentTracker( this );
} }
SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) SectionTracker::SectionTracker( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent )
: TrackerBase( nameAndLocation, ctx, parent ), : TrackerBase( CATCH_MOVE(nameAndLocation), ctx, parent ),
m_trimmed_name(trim(nameAndLocation.name)) m_trimmed_name(trim(ITracker::nameAndLocation().name))
{ {
if( parent ) { if( parent ) {
while( !parent->isSectionTracker() ) while ( !parent->isSectionTracker() ) {
parent = parent->parent(); parent = parent->parent();
}
SectionTracker& parentSection = static_cast<SectionTracker&>( *parent ); SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
addNextFilters( parentSection.m_filters ); addNextFilters( parentSection.m_filters );
@ -6328,24 +6351,30 @@ namespace TestCaseTracking {
bool SectionTracker::isSectionTracker() const { return true; } bool SectionTracker::isSectionTracker() const { return true; }
SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocationRef nameAndLocation ) {
SectionTracker* section; SectionTracker* tracker;
ITracker& currentTracker = ctx.currentTracker(); ITracker& currentTracker = ctx.currentTracker();
if ( ITracker* childTracker = if ( ITracker* childTracker =
currentTracker.findChild( nameAndLocation ) ) { currentTracker.findChild( nameAndLocation ) ) {
assert( childTracker ); assert( childTracker );
assert( childTracker->isSectionTracker() ); assert( childTracker->isSectionTracker() );
section = static_cast<SectionTracker*>( childTracker ); tracker = static_cast<SectionTracker*>( childTracker );
} else { } else {
auto newSection = Catch::Detail::make_unique<SectionTracker>( auto newTracker = Catch::Detail::make_unique<SectionTracker>(
nameAndLocation, ctx, &currentTracker ); NameAndLocation{ static_cast<std::string>(nameAndLocation.name),
section = newSection.get(); nameAndLocation.location },
currentTracker.addChild( CATCH_MOVE( newSection ) ); ctx,
&currentTracker );
tracker = newTracker.get();
currentTracker.addChild( CATCH_MOVE( newTracker ) );
} }
if( !ctx.completedCycle() )
section->tryOpen(); if ( !ctx.completedCycle() ) {
return *section; tracker->tryOpen();
}
return *tracker;
} }
void SectionTracker::tryOpen() { void SectionTracker::tryOpen() {
@ -8809,7 +8838,8 @@ namespace Catch {
void void
CumulativeReporterBase::sectionStarting( SectionInfo const& sectionInfo ) { 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; SectionNode* node;
if ( m_sectionStack.empty() ) { if ( m_sectionStack.empty() ) {
if ( !m_rootSection ) { if ( !m_rootSection ) {
@ -9792,7 +9822,7 @@ namespace Catch {
} }
void SonarQubeReporter::writeRun( TestRunNode const& runNode ) { 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 ) { for ( auto const& child : runNode.children ) {
testsPerFile[child->value.testInfo->lineInfo.file].push_back( testsPerFile[child->value.testInfo->lineInfo.file].push_back(
@ -9804,7 +9834,7 @@ namespace Catch {
} }
} }
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"); XmlWriter::ScopedElement e = xml.scopedElement("file");
xml.writeAttribute("path"_sr, filename); xml.writeAttribute("path"_sr, filename);

View File

@ -5,8 +5,8 @@
// SPDX-License-Identifier: BSL-1.0 // SPDX-License-Identifier: BSL-1.0
// Catch v3.3.0 // Catch v3.3.1
// Generated: 2023-01-22 19:46:23.163056 // Generated: 2023-01-29 22:55:03.856079
// ---------------------------------------------------------- // ----------------------------------------------------------
// This file is an amalgamation of multiple different files. // This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly. // You probably shouldn't edit it directly.
@ -1039,7 +1039,7 @@ namespace Catch {
class AssertionResult { class AssertionResult {
public: public:
AssertionResult() = delete; AssertionResult() = delete;
AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); AssertionResult( AssertionInfo const& info, AssertionResultData&& data );
bool isOk() const; bool isOk() const;
bool succeeded() const; bool succeeded() const;
@ -1217,10 +1217,11 @@ namespace Catch {
public: public:
virtual ~IResultCapture(); virtual ~IResultCapture();
virtual bool sectionStarted( SectionInfo const& sectionInfo, virtual bool sectionStarted( StringRef sectionName,
SourceLineInfo const& sectionLineInfo,
Counts& assertions ) = 0; Counts& assertions ) = 0;
virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; virtual void sectionEnded( SectionEndInfo&& endInfo ) = 0;
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; virtual void sectionEndedEarly( SectionEndInfo&& endInfo ) = 0;
virtual IGeneratorTracker* virtual IGeneratorTracker*
acquireGeneratorTracker( StringRef generatorName, acquireGeneratorTracker( StringRef generatorName,
@ -1238,7 +1239,7 @@ namespace Catch {
virtual void pushScopedMessage( MessageInfo const& message ) = 0; virtual void pushScopedMessage( MessageInfo const& message ) = 0;
virtual void popScopedMessage( 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; virtual void handleFatalErrorCondition( StringRef message ) = 0;
@ -1419,7 +1420,7 @@ namespace Catch {
}; };
struct SectionStats { struct SectionStats {
SectionStats( SectionInfo const& _sectionInfo, SectionStats( SectionInfo&& _sectionInfo,
Counts const& _assertions, Counts const& _assertions,
double _durationInSeconds, double _durationInSeconds,
bool _missingAssertions ); bool _missingAssertions );
@ -2691,7 +2692,7 @@ namespace Catch {
}); });
BenchmarkInfo info { BenchmarkInfo info {
name, CATCH_MOVE(name),
plan.estimated_duration.count(), plan.estimated_duration.count(),
plan.iterations_per_sample, plan.iterations_per_sample,
cfg->benchmarkSamples(), cfg->benchmarkSamples(),
@ -2707,7 +2708,7 @@ namespace Catch {
}); });
auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end()); 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); getResultCapture().benchmarkEnded(stats);
} CATCH_CATCH_ANON (TestFailureException) { } CATCH_CATCH_ANON (TestFailureException) {
getResultCapture().benchmarkFailed("Benchmark failed due to failed assertion"_sr); getResultCapture().benchmarkFailed("Benchmark failed due to failed assertion"_sr);
@ -4459,11 +4460,10 @@ namespace Catch {
ResultWas::OfType type ): ResultWas::OfType type ):
m_info(macroName, lineInfo, type) {} m_info(macroName, lineInfo, type) {}
template<typename T> template<typename T>
MessageBuilder& operator << ( T const& value ) { MessageBuilder&& operator << ( T const& value ) && {
m_stream << value; m_stream << value;
return *this; return CATCH_MOVE(*this);
} }
MessageInfo m_info; MessageInfo m_info;
@ -4471,7 +4471,7 @@ namespace Catch {
class ScopedMessage { class ScopedMessage {
public: public:
explicit ScopedMessage( MessageBuilder const& builder ); explicit ScopedMessage( MessageBuilder&& builder );
ScopedMessage( ScopedMessage& duplicate ) = delete; ScopedMessage( ScopedMessage& duplicate ) = delete;
ScopedMessage( ScopedMessage&& old ) noexcept; ScopedMessage( ScopedMessage&& old ) noexcept;
~ScopedMessage(); ~ScopedMessage();
@ -6071,6 +6071,9 @@ namespace Catch {
class Section : Detail::NonCopyable { class Section : Detail::NonCopyable {
public: public:
Section( SectionInfo&& info ); Section( SectionInfo&& info );
Section( SourceLineInfo const& _lineInfo,
StringRef _name,
const char* const = nullptr );
~Section(); ~Section();
// This indicates whether the section should be executed or not // This indicates whether the section should be executed or not
@ -6089,7 +6092,7 @@ namespace Catch {
#define INTERNAL_CATCH_SECTION( ... ) \ #define INTERNAL_CATCH_SECTION( ... ) \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ 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 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \ #define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
@ -7399,7 +7402,7 @@ namespace Catch {
#define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 3 #define CATCH_VERSION_MINOR 3
#define CATCH_VERSION_PATCH 0 #define CATCH_VERSION_PATCH 1
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED #endif // CATCH_VERSION_MACROS_HPP_INCLUDED
@ -9194,7 +9197,7 @@ namespace TestCaseTracking {
std::string name; std::string name;
SourceLineInfo location; 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) { friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
return lhs.name == rhs.name return lhs.name == rhs.name
&& lhs.location == rhs.location; && 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; class ITracker;
using ITrackerPtr = Catch::Detail::unique_ptr<ITracker>; using ITrackerPtr = Catch::Detail::unique_ptr<ITracker>;
@ -9229,8 +9258,8 @@ namespace TestCaseTracking {
CycleState m_runState = NotStarted; CycleState m_runState = NotStarted;
public: public:
ITracker( NameAndLocation const& nameAndLoc, ITracker* parent ): ITracker( NameAndLocation&& nameAndLoc, ITracker* parent ):
m_nameAndLocation( nameAndLoc ), m_nameAndLocation( CATCH_MOVE(nameAndLoc) ),
m_parent( parent ) m_parent( parent )
{} {}
@ -9269,7 +9298,7 @@ namespace TestCaseTracking {
* *
* Returns nullptr if not found. * Returns nullptr if not found.
*/ */
ITracker* findChild( NameAndLocation const& nameAndLocation ); ITracker* findChild( NameAndLocationRef nameAndLocation );
//! Have any children been added? //! Have any children been added?
bool hasChildren() const { bool hasChildren() const {
return !m_children.empty(); return !m_children.empty();
@ -9326,7 +9355,7 @@ namespace TestCaseTracking {
TrackerContext& m_ctx; TrackerContext& m_ctx;
public: public:
TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); TrackerBase( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent );
bool isComplete() const override; bool isComplete() const override;
@ -9344,13 +9373,13 @@ namespace TestCaseTracking {
std::vector<StringRef> m_filters; std::vector<StringRef> m_filters;
std::string m_trimmed_name; std::string m_trimmed_name;
public: public:
SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); SectionTracker( NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent );
bool isSectionTracker() const override; bool isSectionTracker() const override;
bool isComplete() const override; bool isComplete() const override;
static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); static SectionTracker& acquire( TrackerContext& ctx, NameAndLocationRef nameAndLocation );
void tryOpen(); void tryOpen();
@ -9420,10 +9449,12 @@ namespace Catch {
ResultWas::OfType resultType, ResultWas::OfType resultType,
AssertionReaction &reaction ) override; 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 sectionEnded( SectionEndInfo&& endInfo ) override;
void sectionEndedEarly( SectionEndInfo const& endInfo ) override; void sectionEndedEarly( SectionEndInfo&& endInfo ) override;
IGeneratorTracker* IGeneratorTracker*
acquireGeneratorTracker( StringRef generatorName, acquireGeneratorTracker( StringRef generatorName,
@ -9442,7 +9473,7 @@ namespace Catch {
void pushScopedMessage( MessageInfo const& message ) override; void pushScopedMessage( MessageInfo const& message ) override;
void popScopedMessage( 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; std::string getCurrentTestName() const override;
@ -12565,7 +12596,7 @@ namespace Catch {
void writeRun( TestRunNode const& groupNode ); 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); void writeTestCase(TestCaseNode const& testCaseNode);

View File

@ -8,7 +8,7 @@
project( project(
'catch2', 'catch2',
'cpp', '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', license: 'BSL-1.0',
meson_version: '>=0.50.0', meson_version: '>=0.50.0',
) )

View File

@ -36,7 +36,7 @@ namespace Catch {
} }
Version const& libraryVersion() { Version const& libraryVersion() {
static Version version( 3, 3, 0, "", 0 ); static Version version( 3, 3, 1, "", 0 );
return version; return version;
} }

View File

@ -10,6 +10,6 @@
#define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MAJOR 3
#define CATCH_VERSION_MINOR 3 #define CATCH_VERSION_MINOR 3
#define CATCH_VERSION_PATCH 0 #define CATCH_VERSION_PATCH 1
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED #endif // CATCH_VERSION_MACROS_HPP_INCLUDED