mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 05:59:32 +01:00 
			
		
		
		
	Don't take ownership of SECTION's name for inactive sections
This eliminates 1945 (432709 -> 430764) allocations from running `./tests/SelfTest -o /dev/null`. In general terms, this saves an allocation every time an unvisited `SECTION` is passed, which means that the saved allocations are quadratic in number of sibling (same level) `SECTION`s in a test case.
This commit is contained in:
		@@ -44,7 +44,8 @@ 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&& endInfo ) = 0;
 | 
					        virtual void sectionEnded( SectionEndInfo&& endInfo ) = 0;
 | 
				
			||||||
        virtual void sectionEndedEarly( SectionEndInfo&& endInfo ) = 0;
 | 
					        virtual void sectionEndedEarly( SectionEndInfo&& endInfo ) = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -297,13 +297,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::NameAndLocationRef(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(§ionTracker);
 | 
					        m_activeSections.push_back(§ionTracker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,7 +68,9 @@ 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&& endInfo ) override;
 | 
					        void sectionEnded( SectionEndInfo&& endInfo ) override;
 | 
				
			||||||
        void sectionEndedEarly( SectionEndInfo&& endInfo ) override;
 | 
					        void sectionEndedEarly( SectionEndInfo&& endInfo ) override;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,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) {
 | 
				
			||||||
@@ -23,6 +23,23 @@ 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{ CATCH_MOVE(m_info), m_assertions, m_timer.getElapsedSeconds() };
 | 
					            SectionEndInfo endInfo{ CATCH_MOVE(m_info), m_assertions, m_timer.getElapsedSeconds() };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,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
 | 
				
			||||||
@@ -38,7 +41,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( ... ) \
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user