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