diff options
| author | Martin Hořeňovský | 2024-08-14 12:05:21 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2024-08-14 12:05:21 +0200 |
| commit | 31588bb4f56b638dd5afc28d3ebff9b9dcefb88d (patch) | |
| tree | b5ab431071a20481be60d6faa4c0edf3238b43f9 /extras/catch_amalgamated.hpp | |
| parent | f24569a1b4af70352d454ca46eb3be45a0ba51ef (diff) | |
| download | catch3-3.7.0.tar.gz | |
v3.7.0v3.7.0
Diffstat (limited to 'extras/catch_amalgamated.hpp')
| -rw-r--r-- | extras/catch_amalgamated.hpp | 267 |
1 files changed, 137 insertions, 130 deletions
diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp index 6cc67e76..968aeb8d 100644 --- a/extras/catch_amalgamated.hpp +++ b/extras/catch_amalgamated.hpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.6.0 -// Generated: 2024-05-05 20:53:27.071502 +// Catch v3.7.0 +// Generated: 2024-08-14 12:04:53.220567 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -1584,22 +1584,17 @@ namespace Catch { private: struct callable { virtual void call(Chronometer meter) const = 0; - virtual Catch::Detail::unique_ptr<callable> clone() const = 0; virtual ~callable(); // = default; callable() = default; - callable(callable const&) = default; - callable& operator=(callable const&) = default; + callable(callable&&) = default; + callable& operator=(callable&&) = default; }; template <typename Fun> struct model : public callable { model(Fun&& fun_) : fun(CATCH_MOVE(fun_)) {} model(Fun const& fun_) : fun(fun_) {} - Catch::Detail::unique_ptr<callable> clone() const override { - return Catch::Detail::make_unique<model<Fun>>( *this ); - } - void call(Chronometer meter) const override { call(meter, is_callable<Fun(Chronometer)>()); } @@ -1613,14 +1608,8 @@ namespace Catch { Fun fun; }; - struct do_nothing { void operator()() const {} }; - - template <typename T> - BenchmarkFunction(model<T>* c) : f(c) {} - public: - BenchmarkFunction() - : f(new model<do_nothing>{ {} }) {} + BenchmarkFunction(); template <typename Fun, std::enable_if_t<!is_related<Fun, BenchmarkFunction>::value, int> = 0> @@ -1630,20 +1619,12 @@ namespace Catch { BenchmarkFunction( BenchmarkFunction&& that ) noexcept: f( CATCH_MOVE( that.f ) ) {} - BenchmarkFunction(BenchmarkFunction const& that) - : f(that.f->clone()) {} - BenchmarkFunction& operator=( BenchmarkFunction&& that ) noexcept { f = CATCH_MOVE( that.f ); return *this; } - BenchmarkFunction& operator=(BenchmarkFunction const& that) { - f = that.f->clone(); - return *this; - } - void operator()(Chronometer meter) const { f->call(meter); } private: @@ -1780,7 +1761,7 @@ namespace Catch { template <typename Clock, typename Fun, typename... Args> TimingOf<Fun, Args...> measure(Fun&& fun, Args&&... args) { auto start = Clock::now(); - auto&& r = Detail::complete_invoke(fun, CATCH_FORWARD(args)...); + auto&& r = Detail::complete_invoke(CATCH_FORWARD(fun), CATCH_FORWARD(args)...); auto end = Clock::now(); auto delta = end - start; return { delta, CATCH_FORWARD(r), 1 }; @@ -1946,15 +1927,17 @@ namespace Catch { namespace Detail { template <typename Clock> std::vector<double> resolution(int k) { - std::vector<TimePoint<Clock>> times; - times.reserve(static_cast<size_t>(k + 1)); - for ( int i = 0; i < k + 1; ++i ) { - times.push_back( Clock::now() ); + const size_t points = static_cast<size_t>( k + 1 ); + // To avoid overhead from the branch inside vector::push_back, + // we allocate them all and then overwrite. + std::vector<TimePoint<Clock>> times(points); + for ( auto& time : times ) { + time = Clock::now(); } std::vector<double> deltas; deltas.reserve(static_cast<size_t>(k)); - for ( size_t idx = 1; idx < times.size(); ++idx ) { + for ( size_t idx = 1; idx < points; ++idx ) { deltas.push_back( static_cast<double>( ( times[idx] - times[idx - 1] ).count() ) ); } @@ -2103,12 +2086,12 @@ namespace Catch { : fun(CATCH_MOVE(func)), name(CATCH_MOVE(benchmarkName)) {} template <typename Clock> - ExecutionPlan prepare(const IConfig &cfg, Environment env) const { + ExecutionPlan prepare(const IConfig &cfg, Environment env) { auto min_time = env.clock_resolution.mean * Detail::minimum_ticks; auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime())); auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<IDuration>(run_time), 1, fun); int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed)); - return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FDuration>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations }; + return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), CATCH_MOVE(fun), std::chrono::duration_cast<FDuration>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations }; } template <typename Clock = default_clock> @@ -3347,6 +3330,18 @@ namespace Catch { #endif // CATCH_ASSERTION_RESULT_HPP_INCLUDED +#ifndef CATCH_CASE_SENSITIVE_HPP_INCLUDED +#define CATCH_CASE_SENSITIVE_HPP_INCLUDED + +namespace Catch { + + enum class CaseSensitive { Yes, No }; + +} // namespace Catch + +#endif // CATCH_CASE_SENSITIVE_HPP_INCLUDED + + #ifndef CATCH_CONFIG_HPP_INCLUDED #define CATCH_CONFIG_HPP_INCLUDED @@ -3366,18 +3361,6 @@ namespace Catch { #define CATCH_WILDCARD_PATTERN_HPP_INCLUDED - -#ifndef CATCH_CASE_SENSITIVE_HPP_INCLUDED -#define CATCH_CASE_SENSITIVE_HPP_INCLUDED - -namespace Catch { - - enum class CaseSensitive { Yes, No }; - -} // namespace Catch - -#endif // CATCH_CASE_SENSITIVE_HPP_INCLUDED - #include <string> namespace Catch @@ -5953,6 +5936,8 @@ namespace Catch { class ITestInvoker { public: + virtual void prepareTestCase(); + virtual void tearDownTestCase(); virtual void invoke() const = 0; virtual ~ITestInvoker(); // = default }; @@ -6005,6 +5990,33 @@ Detail::unique_ptr<ITestInvoker> makeTestInvoker( void (C::*testAsMethod)() ) { return Detail::make_unique<TestInvokerAsMethod<C>>( testAsMethod ); } +template <typename C> +class TestInvokerFixture : public ITestInvoker { + void ( C::*m_testAsMethod )() const; + Detail::unique_ptr<C> m_fixture = nullptr; + +public: + TestInvokerFixture( void ( C::*testAsMethod )() const) noexcept : m_testAsMethod( testAsMethod ) {} + + void prepareTestCase() override { + m_fixture = Detail::make_unique<C>(); + } + + void tearDownTestCase() override { + m_fixture.reset(); + } + + void invoke() const override { + auto* f = m_fixture.get(); + ( f->*m_testAsMethod )(); + } +}; + +template<typename C> +Detail::unique_ptr<ITestInvoker> makeTestInvokerFixture( void ( C::*testAsMethod )() const ) { + return Detail::make_unique<TestInvokerFixture<C>>( testAsMethod ); +} + struct NameAndTags { constexpr NameAndTags( StringRef name_ = StringRef(), StringRef tags_ = StringRef() ) noexcept: @@ -6101,6 +6113,26 @@ static int catchInternalSectionHint = 0; #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), ClassName, __VA_ARGS__ ) + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE2( TestName, ClassName, ... ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ + namespace { \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS( ClassName ) { \ + void test() const; \ + }; \ + const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \ + Catch::makeTestInvokerFixture( &TestName::test ), \ + CATCH_INTERNAL_LINEINFO, \ + #ClassName##_catch_sr, \ + Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ + } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ + void TestName::test() const + #define INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE( ClassName, ... ) \ + INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), ClassName, __VA_ARGS__ ) + /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ @@ -6158,6 +6190,7 @@ static int catchInternalSectionHint = 0; #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) + #define CATCH_TEST_CASE_PERSISTENT_FIXTURE( className, ... ) INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE( className, __VA_ARGS__ ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) @@ -6212,6 +6245,7 @@ static int catchInternalSectionHint = 0; #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ )) #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ )) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) + #define CATCH_TEST_CASE_PERSISTENT_FIXTURE( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ )) #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) #define CATCH_SECTION( ... ) #define CATCH_DYNAMIC_SECTION( ... ) @@ -6257,6 +6291,7 @@ static int catchInternalSectionHint = 0; #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) + #define TEST_CASE_PERSISTENT_FIXTURE( className, ... ) INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE( className, __VA_ARGS__ ) #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ ) @@ -6310,6 +6345,7 @@ static int catchInternalSectionHint = 0; #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__) #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ )) #define METHOD_AS_TEST_CASE( method, ... ) + #define TEST_CASE_PERSISTENT_FIXTURE( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__) #define REGISTER_TEST_CASE( Function, ... ) (void)(0) #define SECTION( ... ) #define DYNAMIC_SECTION( ... ) @@ -7103,6 +7139,14 @@ namespace Catch { TestCaseHandle(TestCaseInfo* info, ITestInvoker* invoker) : m_info(info), m_invoker(invoker) {} + void prepareTestCase() const { + m_invoker->prepareTestCase(); + } + + void tearDownTestCase() const { + m_invoker->tearDownTestCase(); + } + void invoke() const { m_invoker->invoke(); } @@ -7271,7 +7315,7 @@ namespace Catch { #define CATCH_VERSION_MACROS_HPP_INCLUDED #define CATCH_VERSION_MAJOR 3 -#define CATCH_VERSION_MINOR 6 +#define CATCH_VERSION_MINOR 7 #define CATCH_VERSION_PATCH 0 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED @@ -10033,106 +10077,67 @@ namespace Catch { #define CATCH_OUTPUT_REDIRECT_HPP_INCLUDED -#include <cstdio> -#include <iosfwd> +#include <cassert> #include <string> namespace Catch { - class RedirectedStream { - std::ostream& m_originalStream; - std::ostream& m_redirectionStream; - std::streambuf* m_prevBuf; - - public: - RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ); - ~RedirectedStream(); - }; - - class RedirectedStdOut { - ReusableStringStream m_rss; - RedirectedStream m_cout; - public: - RedirectedStdOut(); - auto str() const -> std::string; - }; - - // StdErr has two constituent streams in C++, std::cerr and std::clog - // This means that we need to redirect 2 streams into 1 to keep proper - // order of writes - class RedirectedStdErr { - ReusableStringStream m_rss; - RedirectedStream m_cerr; - RedirectedStream m_clog; + class OutputRedirect { + bool m_redirectActive = false; + virtual void activateImpl() = 0; + virtual void deactivateImpl() = 0; public: - RedirectedStdErr(); - auto str() const -> std::string; - }; + enum Kind { + //! No redirect (noop implementation) + None, + //! Redirect std::cout/std::cerr/std::clog streams internally + Streams, + //! Redirect the stdout/stderr file descriptors into files + FileDescriptors, + }; - class RedirectedStreams { - public: - RedirectedStreams(RedirectedStreams const&) = delete; - RedirectedStreams& operator=(RedirectedStreams const&) = delete; - RedirectedStreams(RedirectedStreams&&) = delete; - RedirectedStreams& operator=(RedirectedStreams&&) = delete; + virtual ~OutputRedirect(); // = default; - RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr); - ~RedirectedStreams(); - private: - std::string& m_redirectedCout; - std::string& m_redirectedCerr; - RedirectedStdOut m_redirectedStdOut; - RedirectedStdErr m_redirectedStdErr; + // TODO: Do we want to check that redirect is not active before retrieving the output? + virtual std::string getStdout() = 0; + virtual std::string getStderr() = 0; + virtual void clearBuffers() = 0; + bool isActive() const { return m_redirectActive; } + void activate() { + assert( !m_redirectActive && "redirect is already active" ); + activateImpl(); + m_redirectActive = true; + } + void deactivate() { + assert( m_redirectActive && "redirect is not active" ); + deactivateImpl(); + m_redirectActive = false; + } }; -#if defined(CATCH_CONFIG_NEW_CAPTURE) - - // Windows's implementation of std::tmpfile is terrible (it tries - // to create a file inside system folder, thus requiring elevated - // privileges for the binary), so we have to use tmpnam(_s) and - // create the file ourselves there. - class TempFile { - public: - TempFile(TempFile const&) = delete; - TempFile& operator=(TempFile const&) = delete; - TempFile(TempFile&&) = delete; - TempFile& operator=(TempFile&&) = delete; - - TempFile(); - ~TempFile(); - - std::FILE* getFile(); - std::string getContents(); - - private: - std::FILE* m_file = nullptr; - #if defined(_MSC_VER) - char m_buffer[L_tmpnam] = { 0 }; - #endif - }; + bool isRedirectAvailable( OutputRedirect::Kind kind); + Detail::unique_ptr<OutputRedirect> makeOutputRedirect( bool actual ); + class RedirectGuard { + OutputRedirect* m_redirect; + bool m_activate; + bool m_previouslyActive; + bool m_moved = false; - class OutputRedirect { public: - OutputRedirect(OutputRedirect const&) = delete; - OutputRedirect& operator=(OutputRedirect const&) = delete; - OutputRedirect(OutputRedirect&&) = delete; - OutputRedirect& operator=(OutputRedirect&&) = delete; - + RedirectGuard( bool activate, OutputRedirect& redirectImpl ); + ~RedirectGuard() noexcept( false ); - OutputRedirect(std::string& stdout_dest, std::string& stderr_dest); - ~OutputRedirect(); + RedirectGuard( RedirectGuard const& ) = delete; + RedirectGuard& operator=( RedirectGuard const& ) = delete; - private: - int m_originalStdout = -1; - int m_originalStderr = -1; - TempFile m_stdoutFile; - TempFile m_stderrFile; - std::string& m_stdoutDest; - std::string& m_stderrDest; + // C++14 needs move-able guards to return them from functions + RedirectGuard( RedirectGuard&& rhs ) noexcept; + RedirectGuard& operator=( RedirectGuard&& rhs ) noexcept; }; -#endif + RedirectGuard scopedActivate( OutputRedirect& redirectImpl ); + RedirectGuard scopedDeactivate( OutputRedirect& redirectImpl ); } // end namespace Catch @@ -10455,6 +10460,7 @@ namespace Catch { class IConfig; class IEventListener; using IEventListenerPtr = Detail::unique_ptr<IEventListener>; + class OutputRedirect; /////////////////////////////////////////////////////////////////////////// @@ -10541,7 +10547,7 @@ namespace Catch { private: - void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ); + void runCurrentTest(); void invokeActiveTestCase(); void resetAssertionInfo(); @@ -10574,6 +10580,7 @@ namespace Catch { std::vector<SectionEndInfo> m_unfinishedSections; std::vector<ITracker*> m_activeSections; TrackerContext m_trackerContext; + Detail::unique_ptr<OutputRedirect> m_outputRedirect; FatalConditionHandler m_fatalConditionhandler; bool m_lastAssertionPassed = false; bool m_shouldReportUnexpected = true; |