Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/extras/catch_amalgamated.hpp
diff options
context:
space:
mode:
authorMartin Hořeňovský2024-08-14 12:05:21 +0200
committerMartin Hořeňovský2024-08-14 12:05:21 +0200
commit31588bb4f56b638dd5afc28d3ebff9b9dcefb88d (patch)
treeb5ab431071a20481be60d6faa4c0edf3238b43f9 /extras/catch_amalgamated.hpp
parentf24569a1b4af70352d454ca46eb3be45a0ba51ef (diff)
downloadcatch3-3.7.0.tar.gz
v3.7.0v3.7.0
Diffstat (limited to 'extras/catch_amalgamated.hpp')
-rw-r--r--extras/catch_amalgamated.hpp267
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;