diff --git a/include/catch_session.hpp b/include/catch_session.hpp index 63dba448..d0dc9e9d 100644 --- a/include/catch_session.hpp +++ b/include/catch_session.hpp @@ -23,30 +23,28 @@ namespace Catch { IStreamingReporterPtr createReporter( std::string const& reporterName, IConfigPtr const& config ) { - IStreamingReporterPtr reporter = getRegistryHub().getReporterRegistry().create( reporterName, config ); - if( !reporter ) { - std::ostringstream oss; - oss << "No reporter registered with name: '" << reporterName << "'"; - throw std::domain_error( oss.str() ); - } - return reporter; + if( auto reporter = getRegistryHub().getReporterRegistry().create( reporterName, config ) ) + return reporter; + + std::ostringstream oss; + oss << "No reporter registered with name: '" << reporterName << "'"; + throw std::domain_error( oss.str() ); } IStreamingReporterPtr makeReporter( std::shared_ptr const& config ) { - std::vector reporters = config->getReporterNames(); - if( reporters.empty() ) - reporters.push_back( "console" ); + auto const& reporterNames = config->getReporterNames(); + if( reporterNames.empty() ) + return createReporter( "console", config ); IStreamingReporterPtr reporter; - for( auto const& name : reporters ) - reporter = addReporter( reporter, createReporter( name, config ) ); + for( auto const& name : reporterNames ) + addReporter( reporter, createReporter( name, config ) ); return reporter; } - IStreamingReporterPtr addListeners( IConfigPtr const& config, IStreamingReporterPtr reporters ) { + void addListeners( IStreamingReporterPtr& reporters, IConfigPtr const& config ) { auto const& listeners = getRegistryHub().getReporterRegistry().getListeners(); for( auto const& listener : listeners ) - reporters = addReporter(reporters, listener->create( ReporterConfig( config ) ) ); - return reporters; + addReporter(reporters, listener->create( ReporterConfig( config ) ) ); } @@ -55,9 +53,9 @@ namespace Catch { IConfigPtr iconfig = config; IStreamingReporterPtr reporter = makeReporter( config ); - reporter = addListeners( iconfig, reporter ); + addListeners( reporter, iconfig ); - RunContext context( iconfig, reporter ); + RunContext context( iconfig, std::move( reporter ) ); Totals totals; @@ -72,7 +70,7 @@ namespace Catch { if( !context.aborting() && matchTest( testCase, testSpec, *iconfig ) ) totals += context.runTest( testCase ); else - reporter->skipTest( testCase ); + context.reporter().skipTest( testCase ); } context.testGroupEnded( iconfig->name(), totals, 1, 1 ); diff --git a/include/internal/catch_interfaces_reporter.h b/include/internal/catch_interfaces_reporter.h index b1f09f90..7a42f097 100644 --- a/include/internal/catch_interfaces_reporter.h +++ b/include/internal/catch_interfaces_reporter.h @@ -232,9 +232,9 @@ namespace Catch virtual void skipTest( TestCaseInfo const& testInfo ) = 0; - virtual MultipleReporters* tryAsMulti() { return nullptr; } + virtual bool isMulti() const { return false; } }; - using IStreamingReporterPtr = std::shared_ptr; + using IStreamingReporterPtr = std::unique_ptr; struct IReporterFactory { virtual ~IReporterFactory(); @@ -253,8 +253,7 @@ namespace Catch virtual Listeners const& getListeners() const = 0; }; - IStreamingReporterPtr addReporter( IStreamingReporterPtr const& existingReporter, IStreamingReporterPtr const& additionalReporter ); - + void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ); } #endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED diff --git a/include/internal/catch_reporter_registrars.hpp b/include/internal/catch_reporter_registrars.hpp index 759b0edb..06c16cb5 100644 --- a/include/internal/catch_reporter_registrars.hpp +++ b/include/internal/catch_reporter_registrars.hpp @@ -18,7 +18,7 @@ namespace Catch { class ReporterFactory : public IReporterFactory { virtual IStreamingReporterPtr create( ReporterConfig const& config ) const { - return std::make_shared( config ); + return std::unique_ptr( new T( config ) ); } virtual std::string getDescription() const { diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp index 7f38eb4a..feb192ed 100644 --- a/include/internal/catch_run_context.hpp +++ b/include/internal/catch_run_context.hpp @@ -59,11 +59,11 @@ namespace Catch { public: - explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr const& reporter ) + explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter ) : m_runInfo( _config->name() ), m_context( getCurrentMutableContext() ), m_config( _config ), - m_reporter( reporter ) + m_reporter( std::move( reporter ) ) { m_context.setRunner( this ); m_context.setConfig( m_config ); @@ -131,6 +131,9 @@ namespace Catch { IConfigPtr config() const { return m_config; } + IStreamingReporter& reporter() const { + return *m_reporter; + } private: // IResultCapture diff --git a/include/reporters/catch_reporter_multi.hpp b/include/reporters/catch_reporter_multi.hpp index 859e3f83..589c34e0 100644 --- a/include/reporters/catch_reporter_multi.hpp +++ b/include/reporters/catch_reporter_multi.hpp @@ -13,12 +13,12 @@ namespace Catch { class MultipleReporters : public IStreamingReporter { - typedef std::vector Reporters; + typedef std::vector Reporters; Reporters m_reporters; public: - void add( IStreamingReporterPtr const& reporter ) { - m_reporters.push_back( reporter ); + void add( IStreamingReporterPtr&& reporter ) { + m_reporters.push_back( std::move( reporter ) ); } public: // IStreamingReporter @@ -95,31 +95,31 @@ public: // IStreamingReporter reporter->skipTest( testInfo ); } - virtual MultipleReporters* tryAsMulti() override { - return this; + virtual bool isMulti() const override { + return true; } }; -IStreamingReporterPtr addReporter( IStreamingReporterPtr const& existingReporter, IStreamingReporterPtr const& additionalReporter ) { - IStreamingReporterPtr resultingReporter; +void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ) { - if( existingReporter ) { - MultipleReporters* multi = existingReporter->tryAsMulti(); - if( !multi ) { - multi = new MultipleReporters; - resultingReporter = IStreamingReporterPtr( multi ); - if( existingReporter ) - multi->add( existingReporter ); - } - else - resultingReporter = existingReporter; - multi->add( additionalReporter ); + if( !existingReporter ) { + existingReporter = std::move( additionalReporter ); + return; } - else - resultingReporter = additionalReporter; - return resultingReporter; + MultipleReporters* multi = nullptr; + + if( existingReporter->isMulti() ) { + multi = static_cast( existingReporter.get() ); + } + else { + auto newMulti = std::unique_ptr( new MultipleReporters ); + newMulti->add( std::move( existingReporter ) ); + multi = newMulti.get(); + existingReporter = std::move( newMulti ); + } + multi->add( std::move( additionalReporter ) ); }