diff options
| author | Martin Hořeňovský | 2025-09-30 10:54:31 +0200 |
|---|---|---|
| committer | Martin Hořeňovský | 2025-09-30 10:54:31 +0200 |
| commit | b3fb4b9feafcd8d91c5cb510a4775143fdbef02f (patch) | |
| tree | 46a08efa7b84ca625bb83d1845def3e79586115e /extras | |
| parent | 6500dc81496878a02e1dfef8ed358257a209fdaf (diff) | |
| download | catch3-3.11.0.tar.gz | |
v3.11.0v3.11.0
Diffstat (limited to 'extras')
| -rw-r--r-- | extras/catch_amalgamated.cpp | 268 | ||||
| -rw-r--r-- | extras/catch_amalgamated.hpp | 76 |
2 files changed, 214 insertions, 130 deletions
diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp index c85f39b3..892d637d 100644 --- a/extras/catch_amalgamated.cpp +++ b/extras/catch_amalgamated.cpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.10.0 -// Generated: 2025-08-24 16:18:04.775778 +// Catch v3.11.0 +// Generated: 2025-09-30 10:49:12.549018 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -825,6 +825,8 @@ namespace Catch { m_data.reporterSpecifications.push_back( std::move( *parsed ) ); } + // Reading bazel env vars can change some parts of the config data, + // so we have to process the bazel env before acting on the config. if ( enableBazelEnvSupport() ) { readBazelEnvVars(); } @@ -889,6 +891,8 @@ namespace Catch { bool Config::showHelp() const { return m_data.showHelp; } + std::string const& Config::getExitGuardFilePath() const { return m_data.prematureExitGuardFilePath; } + // IConfig interface bool Config::allowThrows() const { return !m_data.noThrow; } StringRef Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } @@ -950,6 +954,26 @@ namespace Catch { m_data.shardCount = bazelShardOptions->shardCount; } } + + const auto bazelExitGuardFile = Detail::getEnv( "TEST_PREMATURE_EXIT_FILE" ); + if (bazelExitGuardFile) { + m_data.prematureExitGuardFilePath = bazelExitGuardFile; + } + + const auto bazelRandomSeed = Detail::getEnv( "TEST_RANDOM_SEED" ); + if ( bazelRandomSeed ) { + auto parsedSeed = parseUInt( bazelRandomSeed, 0 ); + if ( !parsedSeed ) { + // Currently we handle issues with parsing other Bazel Env + // options by warning and ignoring the issue. So we do the + // same for random seed option. + Catch::cerr() + << "Warning: could not parse 'TEST_RANDOM_SEED' ('" + << bazelRandomSeed << "') as proper seed.\n"; + } else { + m_data.rngSeed = *parsedSeed; + } + } } } // end namespace Catch @@ -975,28 +999,26 @@ namespace Catch { ScopedMessage::ScopedMessage( MessageBuilder&& builder ): - m_info( CATCH_MOVE(builder.m_info) ) { - m_info.message = builder.m_stream.str(); - getResultCapture().pushScopedMessage( m_info ); + m_messageId( builder.m_info.sequence ) { + MessageInfo info( CATCH_MOVE( builder.m_info ) ); + info.message = builder.m_stream.str(); + IResultCapture::pushScopedMessage( CATCH_MOVE( info ) ); } ScopedMessage::ScopedMessage( ScopedMessage&& old ) noexcept: - m_info( CATCH_MOVE( old.m_info ) ) { + m_messageId( old.m_messageId ) { old.m_moved = true; } ScopedMessage::~ScopedMessage() { - if ( !m_moved ){ - getResultCapture().popScopedMessage(m_info); - } + if ( !m_moved ) { IResultCapture::popScopedMessage( m_messageId ); } } Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, - StringRef names ): - m_resultCapture( getResultCapture() ) { + StringRef names ) { auto trimmed = [&] (size_t start, size_t end) { while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) { ++start; @@ -1042,8 +1064,8 @@ namespace Catch { case ',': if (start != pos && openings.empty()) { m_messages.emplace_back(macroName, lineInfo, resultType); - m_messages.back().message = static_cast<std::string>(trimmed(start, pos)); - m_messages.back().message += " := "; + m_messages.back().message += trimmed(start, pos); + m_messages.back().message += " := "_sr; start = pos; } break; @@ -1052,20 +1074,20 @@ namespace Catch { } assert(openings.empty() && "Mismatched openings"); m_messages.emplace_back(macroName, lineInfo, resultType); - m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1)); - m_messages.back().message += " := "; + m_messages.back().message += trimmed(start, names.size() - 1); + m_messages.back().message += " := "_sr; } Capturer::~Capturer() { assert( m_captured == m_messages.size() ); - for ( size_t i = 0; i < m_captured; ++i ) { - m_resultCapture.popScopedMessage( m_messages[i] ); + for (auto const& message : m_messages) { + IResultCapture::popScopedMessage( message.sequence ); } } void Capturer::captureValue( size_t index, std::string const& value ) { assert( index < m_messages.size() ); m_messages[index].message += value; - m_resultCapture.pushScopedMessage( m_messages[index] ); + IResultCapture::pushScopedMessage( CATCH_MOVE( m_messages[index] ) ); m_captured++; } @@ -1149,7 +1171,6 @@ namespace Catch { } void cleanUp() { cleanupSingletons(); - cleanUpContext(); } std::string translateActiveException() { return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); @@ -1161,6 +1182,8 @@ namespace Catch { #include <cassert> +#include <cstdio> +#include <cstdlib> #include <exception> #include <iomanip> #include <set> @@ -1275,6 +1298,50 @@ namespace Catch { } } + // Creates empty file at path. The path must be writable, we do not + // try to create directories in path because that's hard in C++14. + void setUpGuardFile( std::string const& guardFilePath ) { + if ( !guardFilePath.empty() ) { +#if defined( _MSC_VER ) + std::FILE* file = nullptr; + if ( fopen_s( &file, guardFilePath.c_str(), "w" ) ) { + char msgBuffer[100]; + const auto err = errno; + std::string errMsg; + if ( !strerror_s( msgBuffer, err ) ) { + errMsg = msgBuffer; + } else { + errMsg = "Could not translate errno to a string"; + } + +#else + std::FILE* file = std::fopen( guardFilePath.c_str(), "w" ); + if ( !file ) { + const auto err = errno; + const char* errMsg = std::strerror( err ); +#endif + + CATCH_RUNTIME_ERROR( "Could not open the exit guard file '" + << guardFilePath << "' because '" + << errMsg << "' (" << err << ')' ); + } + const int ret = std::fclose( file ); + CATCH_ENFORCE( + ret == 0, + "Error when closing the exit guard file: " << ret ); + } + } + + // Removes file at path. Assuming we created it in setUpGuardFile. + void tearDownGuardFile( std::string const& guardFilePath ) { + if ( !guardFilePath.empty() ) { + const int ret = std::remove( guardFilePath.c_str() ); + CATCH_ENFORCE( + ret == 0, + "Error when removing the exit guard file: " << ret ); + } + } + } // anon namespace Session::Session() { @@ -1393,6 +1460,7 @@ namespace Catch { static_cast<void>(std::getchar()); } int exitCode = runInternal(); + if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) { Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << '\n' << std::flush; static_cast<void>(std::getchar()); @@ -1433,6 +1501,10 @@ namespace Catch { CATCH_TRY { config(); // Force config to be constructed + // We need to retrieve potential Bazel config with the full Config + // constructor, so we have to create the guard file after it is created. + setUpGuardFile( m_config->getExitGuardFilePath() ); + seedRng( *m_config ); if (m_configData.filenamesAsTags) { @@ -1462,9 +1534,12 @@ namespace Catch { TestGroup tests { CATCH_MOVE(reporter), m_config.get() }; auto const totals = tests.execute(); + // If we got here, running the tests finished normally-enough. + // They might've failed, but that would've been reported elsewhere. + tearDownGuardFile( m_config->getExitGuardFilePath() ); + if ( tests.hadUnmatchedTestSpecs() && m_config->warnAboutUnmatchedTestSpecs() ) { - // UnmatchedTestSpecExitCode return UnmatchedTestSpecExitCode; } @@ -1974,35 +2049,35 @@ namespace Detail { std::string ret; // This is enough for the "don't escape invisibles" case, and a good // lower bound on the "escape invisibles" case. - ret.reserve(string.size() + 2); + ret.reserve( string.size() + 2 ); - if (!escapeInvisibles) { + if ( !escapeInvisibles ) { ret += '"'; ret += string; ret += '"'; return ret; } + size_t last_start = 0; + auto write_to = [&]( size_t idx ) { + if ( last_start < idx ) { + ret += string.substr( last_start, idx - last_start ); + } + last_start = idx + 1; + }; + ret += '"'; - for (char c : string) { - switch (c) { - case '\r': - ret.append("\\r"); - break; - case '\n': - ret.append("\\n"); - break; - case '\t': - ret.append("\\t"); - break; - case '\f': - ret.append("\\f"); - break; - default: - ret.push_back(c); - break; + for ( size_t i = 0; i < string.size(); ++i ) { + const char c = string[i]; + if ( c == '\r' || c == '\n' || c == '\t' || c == '\f' ) { + write_to( i ); + if ( c == '\r' ) { ret.append( "\\r" ); } + if ( c == '\n' ) { ret.append( "\\n" ); } + if ( c == '\t' ) { ret.append( "\\t" ); } + if ( c == '\f' ) { ret.append( "\\f" ); } } } + write_to( string.size() ); ret += '"'; return ret; @@ -2279,7 +2354,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 10, 0, "", 0 ); + static Version version( 3, 11, 0, "", 0 ); return version; } @@ -2367,8 +2442,14 @@ namespace Catch { namespace Catch { + namespace Detail { + void missingCaptureInstance() { + CATCH_INTERNAL_ERROR( "No result capture instance" ); + } + } // namespace Detail + IResultCapture::~IResultCapture() = default; -} +} // namespace Catch @@ -3361,6 +3442,9 @@ namespace Catch { | Opt( config.allowZeroTests ) ["--allow-running-no-tests"] ( "Treat 'No tests run' as a success" ) + | Opt( config.prematureExitGuardFilePath, "path" ) + ["--premature-exit-guard-file"] + ( "create a file before running tests and delete it during clean exit" ) | Arg( config.testsOrTags, "test name|pattern|tags" ) ( "which test or tests to use" ); @@ -3515,7 +3599,11 @@ namespace { #endif // Windows/ ANSI/ None -#if defined( CATCH_PLATFORM_LINUX ) || defined( CATCH_PLATFORM_MAC ) || defined( __GLIBC__ ) || defined(__FreeBSD__) +#if defined( CATCH_PLATFORM_LINUX ) \ + || defined( CATCH_PLATFORM_MAC ) \ + || defined( __GLIBC__ ) \ + || defined( __FreeBSD__ ) \ + || defined( CATCH_PLATFORM_QNX ) # define CATCH_INTERNAL_HAS_ISATTY # include <unistd.h> #endif @@ -3639,20 +3727,10 @@ namespace Catch { namespace Catch { - Context* Context::currentContext = nullptr; - - void cleanUpContext() { - delete Context::currentContext; - Context::currentContext = nullptr; - } - void Context::createContext() { - currentContext = new Context(); - } + Context Context::currentContext; Context& getCurrentMutableContext() { - if ( !Context::currentContext ) { Context::createContext(); } - // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn) - return *Context::currentContext; + return Context::currentContext; } SimplePcg32& sharedRng() { @@ -3757,7 +3835,7 @@ namespace Catch { #endif } // namespace Catch -#elif defined(CATCH_PLATFORM_LINUX) +#elif defined(CATCH_PLATFORM_LINUX) || defined(CATCH_PLATFORM_QNX) #include <fstream> #include <string> @@ -4091,23 +4169,27 @@ namespace Catch { { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, }; + // Since we do not support multiple instantiations, we put these + // into global variables and rely on cleaning them up in outlined + // constructors/destructors + static LPTOP_LEVEL_EXCEPTION_FILTER previousTopLevelExceptionFilter = nullptr; + + static LONG CALLBACK topLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) { for (auto const& def : signalDefs) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { reportFatal(def.name); } } - // If its not an exception we care about, pass it along. + // If a filter was previously registered, invoke it + if (previousTopLevelExceptionFilter) { + return previousTopLevelExceptionFilter(ExceptionInfo); + } + // Otherwise, pass along all exceptions. // This stops us from eating debugger breaks etc. return EXCEPTION_CONTINUE_SEARCH; } - // Since we do not support multiple instantiations, we put these - // into global variables and rely on cleaning them up in outlined - // constructors/destructors - static LPTOP_LEVEL_EXCEPTION_FILTER previousTopLevelExceptionFilter = nullptr; - - // For MSVC, we reserve part of the stack memory for handling // memory overflow structured exception. FatalConditionHandler::FatalConditionHandler() { @@ -5565,6 +5647,7 @@ ReporterSpec::ReporterSpec( #include <cstdio> #include <sstream> +#include <tuple> #include <vector> namespace Catch { @@ -5576,16 +5659,16 @@ namespace Catch { std::ostringstream m_referenceStream; // Used for copy state/ flags from Detail::Mutex m_mutex; - auto add() -> std::size_t { + auto add() -> std::pair<std::size_t, std::ostringstream*> { Detail::LockGuard _( m_mutex ); if( m_unused.empty() ) { m_streams.push_back( Detail::make_unique<std::ostringstream>() ); - return m_streams.size()-1; + return { m_streams.size()-1, m_streams.back().get() }; } else { auto index = m_unused.back(); m_unused.pop_back(); - return index; + return { index, m_streams[index].get() }; } } @@ -5599,10 +5682,10 @@ namespace Catch { } }; - ReusableStringStream::ReusableStringStream() - : m_index( Singleton<StringStreams>::getMutable().add() ), - m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() ) - {} + ReusableStringStream::ReusableStringStream() { + std::tie( m_index, m_oss ) = + Singleton<StringStreams>::getMutable().add(); + } ReusableStringStream::~ReusableStringStream() { static_cast<std::ostringstream*>( m_oss )->str(""); @@ -6085,28 +6168,6 @@ namespace Catch { m_reporter->benchmarkFailed( error ); } - void RunContext::pushScopedMessage( MessageInfo const& message ) { - Detail::g_messages.push_back( message ); - } - - void RunContext::popScopedMessage( MessageInfo const& message ) { - // Note: On average, it would probably be better to look for the message - // backwards. However, we do not expect to have to deal with more - // messages than low single digits, so the optimization is tiny, - // and we would have to hand-write the loop to avoid terrible - // codegen of reverse iterators in debug mode. - Detail::g_messages.erase( - std::find_if( Detail::g_messages.begin(), - Detail::g_messages.end(), - [id = message.sequence]( MessageInfo const& msg ) { - return msg.sequence == id; - } ) ); - } - - void RunContext::emplaceUnscopedMessage( MessageBuilder&& builder ) { - Detail::g_messageScopes.emplace_back( CATCH_MOVE(builder) ); - } - std::string RunContext::getCurrentTestName() const { return m_activeTestCase ? m_activeTestCase->getTestCaseInfo().name @@ -6433,11 +6494,26 @@ namespace Catch { } } - IResultCapture& getResultCapture() { - if (auto* capture = getCurrentContext().getResultCapture()) - return *capture; - else - CATCH_INTERNAL_ERROR("No result capture instance"); + void IResultCapture::pushScopedMessage( MessageInfo&& message ) { + Detail::g_messages.push_back( CATCH_MOVE( message ) ); + } + + void IResultCapture::popScopedMessage( unsigned int messageId ) { + // Note: On average, it would probably be better to look for the message + // backwards. However, we do not expect to have to deal with more + // messages than low single digits, so the optimization is tiny, + // and we would have to hand-write the loop to avoid terrible + // codegen of reverse iterators in debug mode. + Detail::g_messages.erase( std::find_if( Detail::g_messages.begin(), + Detail::g_messages.end(), + [=]( MessageInfo const& msg ) { + return msg.sequence == + messageId; + } ) ); + } + + void IResultCapture::emplaceUnscopedMessage( MessageBuilder&& builder ) { + Detail::g_messageScopes.emplace_back( CATCH_MOVE( builder ) ); } void seedRng(IConfig const& config) { diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp index a67743b3..d5eb1bb7 100644 --- a/extras/catch_amalgamated.hpp +++ b/extras/catch_amalgamated.hpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.10.0 -// Generated: 2025-08-24 16:18:04.055916 +// Catch v3.11.0 +// Generated: 2025-09-30 10:49:11.225746 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -101,6 +101,9 @@ #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX +#elif defined(__QNX__) +# define CATCH_PLATFORM_QNX + #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) # define CATCH_PLATFORM_WINDOWS @@ -308,13 +311,17 @@ # endif // Universal Windows platform does not support SEH -// Or console colours (or console at all...) -# if defined(CATCH_PLATFORM_WINDOWS_UWP) -# define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32 -# else +# if !defined(CATCH_PLATFORM_WINDOWS_UWP) # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif +// Only some Windows platform families support the console +# if defined(WINAPI_FAMILY_PARTITION) +# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) +# define CATCH_INTERNAL_CONFIG_NO_COLOUR_WIN32 +# endif +# endif + // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ // _MSVC_TRADITIONAL == 0 means new conformant preprocessor // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor @@ -564,11 +571,9 @@ namespace Catch { IConfig const* m_config = nullptr; IResultCapture* m_resultCapture = nullptr; - CATCH_EXPORT static Context* currentContext; + CATCH_EXPORT static Context currentContext; friend Context& getCurrentMutableContext(); friend Context const& getCurrentContext(); - static void createContext(); - friend void cleanUpContext(); public: constexpr IResultCapture* getResultCapture() const { @@ -579,21 +584,14 @@ namespace Catch { m_resultCapture = resultCapture; } constexpr void setConfig( IConfig const* config ) { m_config = config; } - }; Context& getCurrentMutableContext(); inline Context const& getCurrentContext() { - // We duplicate the logic from `getCurrentMutableContext` here, - // to avoid paying the call overhead in debug mode. - if ( !Context::currentContext ) { Context::createContext(); } - // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn) - return *Context::currentContext; + return Context::currentContext; } - void cleanUpContext(); - class SimplePcg32; SimplePcg32& sharedRng(); } @@ -1069,10 +1067,9 @@ namespace Catch { virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0; virtual void benchmarkFailed( StringRef error ) = 0; - virtual void pushScopedMessage( MessageInfo const& message ) = 0; - virtual void popScopedMessage( MessageInfo const& message ) = 0; - - virtual void emplaceUnscopedMessage( MessageBuilder&& builder ) = 0; + static void pushScopedMessage( MessageInfo&& message ); + static void popScopedMessage( unsigned int messageId ); + static void emplaceUnscopedMessage( MessageBuilder&& builder ); virtual void handleFatalErrorCondition( StringRef message ) = 0; @@ -1108,7 +1105,18 @@ namespace Catch { virtual void exceptionEarlyReported() = 0; }; - IResultCapture& getResultCapture(); + namespace Detail { + [[noreturn]] + void missingCaptureInstance(); + } + inline IResultCapture& getResultCapture() { + if (auto* capture = getCurrentContext().getResultCapture()) { + return *capture; + } else { + Detail::missingCaptureInstance(); + } + } + } #endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED @@ -3800,6 +3808,8 @@ namespace Catch { std::vector<std::string> testsOrTags; std::vector<std::string> sectionsToRun; + + std::string prematureExitGuardFilePath; }; @@ -3827,6 +3837,8 @@ namespace Catch { bool showHelp() const; + std::string const& getExitGuardFilePath() const; + // IConfig interface bool allowThrows() const override; StringRef name() const override; @@ -3961,6 +3973,7 @@ namespace Catch { std::string message; SourceLineInfo lineInfo; ResultWas::OfType type; + // The "ID" of the message, used to know when to remove it from reporter context. unsigned int sequence; DEPRECATED( "Explicitly use the 'sequence' member instead" ) @@ -4020,13 +4033,12 @@ namespace Catch { ScopedMessage( ScopedMessage&& old ) noexcept; ~ScopedMessage(); - MessageInfo m_info; + unsigned int m_messageId; bool m_moved = false; }; class Capturer { std::vector<MessageInfo> m_messages; - IResultCapture& m_resultCapture; size_t m_captured = 0; public: Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ); @@ -4074,7 +4086,7 @@ namespace Catch { /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \ - Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ) + Catch::IResultCapture::emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ) #if defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE) @@ -7466,7 +7478,7 @@ namespace Catch { #define CATCH_VERSION_MACROS_HPP_INCLUDED #define CATCH_VERSION_MAJOR 3 -#define CATCH_VERSION_MINOR 10 +#define CATCH_VERSION_MINOR 11 #define CATCH_VERSION_PATCH 0 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED @@ -7882,8 +7894,9 @@ namespace Generators { class FilterGenerator final : public IGenerator<T> { GeneratorWrapper<T> m_generator; Predicate m_predicate; + static_assert(!std::is_reference<Predicate>::value, "This would most likely result in a dangling reference"); public: - template <typename P = Predicate> + template <typename P> FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator): m_generator(CATCH_MOVE(generator)), m_predicate(CATCH_FORWARD(pred)) @@ -7915,7 +7928,7 @@ namespace Generators { template <typename T, typename Predicate> GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) { - return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, Predicate>>(CATCH_FORWARD(pred), CATCH_MOVE(generator))); + return GeneratorWrapper<T>(Catch::Detail::make_unique<FilterGenerator<T, typename std::remove_reference<Predicate>::type>>(CATCH_FORWARD(pred), CATCH_MOVE(generator))); } template <typename T> @@ -9555,7 +9568,7 @@ namespace Catch { #define CATCH_TRAP() __asm__(".inst 0xde01") #endif -#elif defined(CATCH_PLATFORM_LINUX) +#elif defined(CATCH_PLATFORM_LINUX) || defined(CATCH_PLATFORM_QNX) // If we can use inline assembler, do it because this allows us to break // directly at the location of the failing check instead of breaking inside // raise() called from it, i.e. one stack frame below. @@ -10718,11 +10731,6 @@ namespace Catch { void benchmarkEnded( BenchmarkStats<> const& stats ) override; void benchmarkFailed( StringRef error ) override; - void pushScopedMessage( MessageInfo const& message ) override; - void popScopedMessage( MessageInfo const& message ) override; - - void emplaceUnscopedMessage( MessageBuilder&& builder ) override; - std::string getCurrentTestName() const override; const AssertionResult* getLastResult() const override; |