diff --git a/CMakeLists.txt b/CMakeLists.txt index c0270559..7233477f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ endif() project(Catch2 - VERSION 3.0.1 # CML version placeholder, don't delete + VERSION 3.1.0 # CML version placeholder, don't delete LANGUAGES CXX # HOMEPAGE_URL is not supported until CMake version 3.12, which # we do not target yet. diff --git a/docs/cmake-integration.md b/docs/cmake-integration.md index 9637be9b..dc3efc9d 100644 --- a/docs/cmake-integration.md +++ b/docs/cmake-integration.md @@ -262,7 +262,7 @@ ParseAndAddCatchTests(bar) ### `CatchShardTests.cmake` -> `CatchShardTests.cmake` was introduced in Catch2 X.Y.Z. +> `CatchShardTests.cmake` was introduced in Catch2 3.1.0. `CatchShardTests.cmake` provides a function `catch_add_sharded_tests(TEST_BINARY)` that splits tests from `TEST_BINARY` diff --git a/docs/configuration.md b/docs/configuration.md index d857e792..9fd7f58b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -103,7 +103,7 @@ Catch2 will register a `JUnit` reporter writing to a path pointed by `XML_OUTPUT > `CATCH_CONFIG_BAZEL_SUPPORT` was [introduced](https://github.com/catchorg/Catch2/pull/2399) in Catch2 3.0.1. -> `CATCH_CONFIG_BAZEL_SUPPORT` was [deprecated](https://github.com/catchorg/Catch2/pull/2459) in Catch2 X.Y.Z. +> `CATCH_CONFIG_BAZEL_SUPPORT` was [deprecated](https://github.com/catchorg/Catch2/pull/2459) in Catch2 3.1.0. ## C++11 toggles diff --git a/docs/release-notes.md b/docs/release-notes.md index 3a5de276..da2c598c 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[3.1.0](#310)
[3.0.1](#301)
[2.13.7](#2137)
[2.13.6](#2136)
@@ -49,6 +50,45 @@ [Even Older versions](#even-older-versions)
+## 3.1.0 + +### Improvements +* Improved suppression of `-Wparentheses` for older GCCs + * Turns out that even GCC 9 does not properly handle `_Pragma`s in the C++ frontend. +* Added type constraints onto `random` generator (#2433) + * These constraints copy what the standard says for the underlying `std::uniform_int_distribution` +* Suppressed -Wunused-variable from nvcc (#2306, #2427) +* Suppressed -Wunused-variable from MinGW (#2132) +* Added All/Any/NoneTrue range matchers (#2319) + * These check that all/any/none of boolean values in a range are true. +* The JUnit reporter now normalizes classnames from C++ namespaces to Java-like namespaces (#2468) + * This provides better support for other JUnit based tools. +* The Bazel support now understands `BAZEL_TEST` environment variable (#2459) + * The `CATCH_CONFIG_BAZEL_SUPPORT` configuration option is also still supported. +* Returned support for compiling Catch2 with GCC 5 (#2448) + * This required removing inherited constructors from Catch2's internals. + * I recommend updating to a newer GCC anyway. +* `catch_discover_tests` now has a new options for setting library load path(s) when running the Catch2 binary (#2467) + + +### Fixes +* Fixed crash when listing listeners without any registered listeners (#2442) +* Fixed nvcc compilation error in constructor benchmarking helper (#2477) +* Catch2's CMakeList supports pre-3.12 CMake again (#2428) + * The gain from requiring CMake 3.12 was very minor, but y'all should really update to newer CMake + + +### Miscellaneous +* Fixed SelfTest build on MinGW (#2447) +* The in-repo conan recipe exports the CMake helper (#2460) +* Added experimental CMake script to showcase using test case sharding together with CTest + * Compared to `catch_discover_tests`, it supports very limited number of options and customization +* Added documentation page on best practices when running Catch2 tests +* Catch2 can be built as a dynamic library (#2397, #2398) + * Note that Catch2 does not have visibility annotations, and you are responsible for ensuring correct visibility built into the resulting library. + + + ## 3.0.1 **Catch2 now uses statically compiled library as its distribution model. diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp index bd8c8119..ecda2301 100644 --- a/extras/catch_amalgamated.cpp +++ b/extras/catch_amalgamated.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.0.1 -// Generated: 2022-05-17 22:08:47.054486 +// Catch v3.1.0 +// Generated: 2022-07-17 20:14:05.885021 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -15,6 +15,51 @@ #include "catch_amalgamated.hpp" + + +namespace Catch { + namespace Benchmark { + namespace Detail { + ChronometerConcept::~ChronometerConcept() = default; + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + + + + +namespace Catch { + namespace Benchmark { + namespace Detail { + BenchmarkFunction::callable::~callable() = default; + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + + + +#include + +namespace Catch { + namespace Benchmark { + namespace Detail { + struct optimized_away_error : std::exception { + const char* what() const noexcept override; + }; + + const char* optimized_away_error::what() const noexcept { + return "could not measure benchmark, maybe it was optimized away"; + } + + void throw_optimized_away_error() { + Catch::throw_exception(optimized_away_error{}); + } + + } // namespace Detail + } // namespace Benchmark +} // namespace Catch + + // Adapted from donated nonius code. @@ -265,72 +310,6 @@ namespace Catch { } // namespace Catch -/** \file - * This is a special TU that combines what would otherwise be a very - * small benchmarking-related TUs into one bigger TU. - * - * The reason for this is compilation performance improvements by - * avoiding reparsing headers for many small TUs, instead having this - * one TU include bit more, but having it all parsed only once. - * - * To avoid heavy-tail problem with compilation times, each "subpart" - * of Catch2 has its own combined TU like this. - */ - -//////////////////////////////////////////// -// vvv formerly catch_chronometer.cpp vvv // -//////////////////////////////////////////// - - -namespace Catch { - namespace Benchmark { - namespace Detail { - ChronometerConcept::~ChronometerConcept() = default; - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - - -/////////////////////////////////////////////////// -// vvv formerly catch_benchmark_function.cpp vvv // -/////////////////////////////////////////////////// - - -namespace Catch { - namespace Benchmark { - namespace Detail { - BenchmarkFunction::callable::~callable() = default; - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - - -///////////////////////////////////////////////// -// vvv formerly catch_run_for_at_least.cpp vvv // -///////////////////////////////////////////////// - -#include - -namespace Catch { - namespace Benchmark { - namespace Detail { - struct optimized_away_error : std::exception { - const char* what() const noexcept override; - }; - - const char* optimized_away_error::what() const noexcept { - return "could not measure benchmark, maybe it was optimized away"; - } - - void throw_optimized_away_error() { - Catch::throw_exception(optimized_away_error{}); - } - - } // namespace Detail - } // namespace Benchmark -} // namespace Catch - - #include #include @@ -507,6 +486,28 @@ namespace Catch { +namespace { + bool provideBazelReporterOutput() { +#ifdef CATCH_CONFIG_BAZEL_SUPPORT + return true; +#else + +# if defined( _MSC_VER ) + // On Windows getenv throws a warning as there is no input validation, + // since the switch is hardcoded, this should not be an issue. +# pragma warning( push ) +# pragma warning( disable : 4996 ) +# endif + + return std::getenv( "BAZEL_TEST" ) != nullptr; + +# if defined( _MSC_VER ) +# pragma warning( pop ) +# endif +#endif + } +} + namespace Catch { bool operator==( ProcessedReporterSpec const& lhs, @@ -553,27 +554,27 @@ namespace Catch { } ); } -#if defined( CATCH_CONFIG_BAZEL_SUPPORT ) - // Register a JUnit reporter for Bazel. Bazel sets an environment - // variable with the path to XML output. If this file is written to - // during test, Bazel will not generate a default XML output. - // This allows the XML output file to contain higher level of detail - // than what is possible otherwise. + if(provideBazelReporterOutput()){ + // Register a JUnit reporter for Bazel. Bazel sets an environment + // variable with the path to XML output. If this file is written to + // during test, Bazel will not generate a default XML output. + // This allows the XML output file to contain higher level of detail + // than what is possible otherwise. # if defined( _MSC_VER ) - // On Windows getenv throws a warning as there is no input validation, - // since the key is hardcoded, this should not be an issue. -# pragma warning( push ) -# pragma warning( disable : 4996 ) + // On Windows getenv throws a warning as there is no input validation, + // since the key is hardcoded, this should not be an issue. +# pragma warning( push ) +# pragma warning( disable : 4996 ) # endif - const auto bazelOutputFilePtr = std::getenv( "XML_OUTPUT_FILE" ); + const auto bazelOutputFilePtr = std::getenv( "XML_OUTPUT_FILE" ); # if defined( _MSC_VER ) # pragma warning( pop ) # endif - if ( bazelOutputFilePtr != nullptr ) { - m_data.reporterSpecifications.push_back( - { "junit", std::string( bazelOutputFilePtr ), {}, {} } ); - } -#endif + if ( bazelOutputFilePtr != nullptr ) { + m_data.reporterSpecifications.push_back( + { "junit", std::string( bazelOutputFilePtr ), {}, {} } ); + } + } // We now fixup the reporter specs to handle default output spec, @@ -1180,6 +1181,22 @@ namespace Catch { + +namespace Catch { + + RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) { + CATCH_TRY { + getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo); + } CATCH_CATCH_ALL { + // Do not throw when constructing global objects, instead register the exception to be processed later + getMutableRegistryHub().registerStartupException(); + } + } + +} + + + #include #include #include @@ -1873,7 +1890,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 0, 1, "", 0 ); + static Version version( 3, 1, 0, "", 0 ); return version; } @@ -1882,27 +1899,6 @@ namespace Catch { - -std::uint32_t Catch::Generators::Detail::getSeed() { return sharedRng()(); } - - -/** \file - * This is a special TU that combines what would otherwise be a very - * small generator-related TUs into one bigger TU. - * - * The reason for this is compilation performance improvements by - * avoiding reparsing headers for many small TUs, instead having this - * one TU include bit more, but having it all parsed only once. - * - * To avoid heavy-tail problem with compilation times, each "subpart" - * of Catch2 has its own combined TU like this. - */ - -//////////////////////////////////////////////////// -// vvv formerly catch_generator_exception.cpp vvv // -//////////////////////////////////////////////////// - - namespace Catch { const char* GeneratorException::what() const noexcept { @@ -1912,9 +1908,6 @@ namespace Catch { } // end namespace Catch -/////////////////////////////////////////// -// vvv formerly catch_generators.cpp vvv // -/////////////////////////////////////////// namespace Catch { @@ -1941,21 +1934,12 @@ namespace Detail { } // namespace Catch -/** \file - * This is a special TU that combines what would otherwise be a very - * small interfaces-related TUs into one bigger TU. - * - * The reason for this is compilation performance improvements by - * avoiding reparsing headers for many small TUs, instead having this - * one TU include bit more, but having it all parsed only once. - * - * To avoid heavy-tail problem with compilation times, each "subpart" - * of Catch2 has its own combined TU like this. - */ -/////////////////////////////////////////////////// -// vvv formerly catch_interfaces_capture.cpp vvv // -/////////////////////////////////////////////////// + + +std::uint32_t Catch::Generators::Detail::getSeed() { return sharedRng()(); } + + namespace Catch { @@ -1963,9 +1947,6 @@ namespace Catch { } -////////////////////////////////////////////////// -// vvv formerly catch_interfaces_config.cpp vvv // -////////////////////////////////////////////////// namespace Catch { @@ -1973,9 +1954,6 @@ namespace Catch { } -///////////////////////////////////////////////////// -// vvv formerly catch_interfaces_exception.cpp vvv // -///////////////////////////////////////////////////// namespace Catch { @@ -1984,41 +1962,6 @@ namespace Catch { } -//////////////////////////////////////////////////////// -// vvv formerly catch_interfaces_registry_hub.cpp vvv // -//////////////////////////////////////////////////////// - - -namespace Catch { - IRegistryHub::~IRegistryHub() = default; - IMutableRegistryHub::~IMutableRegistryHub() = default; -} - - -//////////////////////////////////////////////////// -// vvv formerly catch_interfaces_testcase.cpp vvv // -//////////////////////////////////////////////////// - - -namespace Catch { - ITestInvoker::~ITestInvoker() = default; - ITestCaseRegistry::~ITestCaseRegistry() = default; -} - - - -namespace Catch { - IReporterRegistry::~IReporterRegistry() = default; -} - - - -namespace Catch { - IReporterFactory::~IReporterFactory() = default; - EventListenerFactory::~EventListenerFactory() = default; -} - - #include @@ -2046,6 +1989,14 @@ namespace Catch { + +namespace Catch { + IRegistryHub::~IRegistryHub() = default; + IMutableRegistryHub::~IMutableRegistryHub() = default; +} + + + #include #include #include @@ -2134,6 +2085,29 @@ namespace Catch { + +namespace Catch { + IReporterFactory::~IReporterFactory() = default; + EventListenerFactory::~EventListenerFactory() = default; +} + + + + +namespace Catch { + IReporterRegistry::~IReporterRegistry() = default; +} + + + + +namespace Catch { + ITestInvoker::~ITestInvoker() = default; + ITestCaseRegistry::~ITestCaseRegistry() = default; +} + + + namespace Catch { AssertionHandler::AssertionHandler @@ -2672,221 +2646,6 @@ namespace Catch { } // namespace Catch -/** \file - * This is a special TU that combines what would otherwise be a very - * small top-level TUs into one bigger TU. - * - * The reason for this is compilation performance improvements by - * avoiding reparsing headers for many small TUs, instead having this - * one TU include bit more, but having it all parsed only once. - * - * To avoid heavy-tail problem with compilation times, each "subpart" - * of Catch2 has its own combined TU like this. - */ - - -//////////////////////////////////////////////////////// -// vvv formerly catch_tag_alias_autoregistrar.cpp vvv // -//////////////////////////////////////////////////////// - - -namespace Catch { - - RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) { - CATCH_TRY { - getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo); - } CATCH_CATCH_ALL { - // Do not throw when constructing global objects, instead register the exception to be processed later - getMutableRegistryHub().registerStartupException(); - } - } - -} - - -////////////////////////////////////////// -// vvv formerly catch_polyfills.cpp vvv // -////////////////////////////////////////// - -#include - -namespace Catch { - -#if !defined(CATCH_CONFIG_POLYFILL_ISNAN) - bool isnan(float f) { - return std::isnan(f); - } - bool isnan(double d) { - return std::isnan(d); - } -#else - // For now we only use this for embarcadero - bool isnan(float f) { - return std::_isnan(f); - } - bool isnan(double d) { - return std::_isnan(d); - } -#endif - -} // end namespace Catch - - -//////////////////////////////////////////////////// -// vvv formerly catch_uncaught_exceptions.cpp vvv // -//////////////////////////////////////////////////// - - -#include - -namespace Catch { - bool uncaught_exceptions() { -#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - return false; -#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) - return std::uncaught_exceptions() > 0; -#else - return std::uncaught_exception(); -#endif - } -} // end namespace Catch - - -//////////////////////////////////////////// -// vvv formerly catch_errno_guard.cpp vvv // -//////////////////////////////////////////// - -#include - -namespace Catch { - ErrnoGuard::ErrnoGuard():m_oldErrno(errno){} - ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; } -} - - -/////////////////////////////////////////// -// vvv formerly catch_decomposer.cpp vvv // -/////////////////////////////////////////// - -namespace Catch { - - ITransientExpression::~ITransientExpression() = default; - - void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) { - if( lhs.size() + rhs.size() < 40 && - lhs.find('\n') == std::string::npos && - rhs.find('\n') == std::string::npos ) - os << lhs << ' ' << op << ' ' << rhs; - else - os << lhs << '\n' << op << '\n' << rhs; - } -} - - -/////////////////////////////////////////////////////////// -// vvv formerly catch_startup_exception_registry.cpp vvv // -/////////////////////////////////////////////////////////// - -namespace Catch { -#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept { - CATCH_TRY { - m_exceptions.push_back(exception); - } CATCH_CATCH_ALL { - // If we run out of memory during start-up there's really not a lot more we can do about it - std::terminate(); - } - } - - std::vector const& StartupExceptionRegistry::getExceptions() const noexcept { - return m_exceptions; - } -#endif - -} // end namespace Catch - - -////////////////////////////////////////////// -// vvv formerly catch_leak_detector.cpp vvv // -////////////////////////////////////////////// - - -#ifdef CATCH_CONFIG_WINDOWS_CRTDBG -#include - -namespace Catch { - - LeakDetector::LeakDetector() { - int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - flag |= _CRTDBG_LEAK_CHECK_DF; - flag |= _CRTDBG_ALLOC_MEM_DF; - _CrtSetDbgFlag(flag); - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); - // Change this to leaking allocation's number to break there - _CrtSetBreakAlloc(-1); - } -} - -#else // ^^ Windows crt debug heap enabled // Windows crt debug heap disabled vv - - Catch::LeakDetector::LeakDetector() {} - -#endif // CATCH_CONFIG_WINDOWS_CRTDBG - -Catch::LeakDetector::~LeakDetector() { - Catch::cleanUp(); -} - - -///////////////////////////////////////////// -// vvv formerly catch_message_info.cpp vvv // -///////////////////////////////////////////// - - -namespace Catch { - - MessageInfo::MessageInfo( StringRef _macroName, - SourceLineInfo const& _lineInfo, - ResultWas::OfType _type ) - : macroName( _macroName ), - lineInfo( _lineInfo ), - type( _type ), - sequence( ++globalCount ) - {} - - // This may need protecting if threading support is added - unsigned int MessageInfo::globalCount = 0; - -} // end namespace Catch - - - - -////////////////////////////////////////// -// vvv formerly catch_lazy_expr.cpp vvv // -////////////////////////////////////////// - -namespace Catch { - - auto operator << (std::ostream& os, LazyExpression const& lazyExpr) -> std::ostream& { - if (lazyExpr.m_isNegated) - os << '!'; - - if (lazyExpr) { - if (lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression()) - os << '(' << *lazyExpr.m_transientExpression << ')'; - else - os << *lazyExpr.m_transientExpression; - } else { - os << "{** error - unchecked empty expression requested **}"; - } - return os; - } - -} // namespace Catch - - #include @@ -3425,25 +3184,22 @@ namespace Catch { Detail::unique_ptr makeColourImpl( ColourMode implSelection, IStream* stream ) { - if ( implSelection == ColourMode::None ) { - return Detail::make_unique( stream ); - } - if ( implSelection == ColourMode::ANSI ) { - return Detail::make_unique( stream ); - } #if defined( CATCH_CONFIG_COLOUR_WIN32 ) if ( implSelection == ColourMode::Win32 ) { return Detail::make_unique( stream ); } #endif + if ( implSelection == ColourMode::ANSI ) { + return Detail::make_unique( stream ); + } + if ( implSelection == ColourMode::None ) { + return Detail::make_unique( stream ); + } - // todo: check win32 eligibility under ifdef, otherwise ansi if ( implSelection == ColourMode::PlatformDefault) { -#if defined (CATCH_CONFIG_COLOUR_WIN32) +#if defined( CATCH_CONFIG_COLOUR_WIN32 ) if ( Win32ColourImpl::useImplementationForStream( *stream ) ) { return Detail::make_unique( stream ); - } else { - return Detail::make_unique( stream ); } #endif if ( ANSIColourImpl::useImplementationForStream( *stream ) ) { @@ -3679,6 +3435,23 @@ namespace Catch { + +namespace Catch { + + ITransientExpression::~ITransientExpression() = default; + + void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) { + if( lhs.size() + rhs.size() < 40 && + lhs.find('\n') == std::string::npos && + rhs.find('\n') == std::string::npos ) + os << lhs << ' ' << op << ' ' << rhs; + else + os << lhs << '\n' << op << '\n' << rhs; + } +} + + + #include @@ -3779,6 +3552,16 @@ namespace Catch { + +#include + +namespace Catch { + ErrnoGuard::ErrnoGuard():m_oldErrno(errno){} + ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; } +} + + + namespace Catch { ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() { @@ -4256,6 +4039,58 @@ namespace Detail { +namespace Catch { + + auto operator << (std::ostream& os, LazyExpression const& lazyExpr) -> std::ostream& { + if (lazyExpr.m_isNegated) + os << '!'; + + if (lazyExpr) { + if (lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression()) + os << '(' << *lazyExpr.m_transientExpression << ')'; + else + os << *lazyExpr.m_transientExpression; + } else { + os << "{** error - unchecked empty expression requested **}"; + } + return os; + } + +} // namespace Catch + + + + +#ifdef CATCH_CONFIG_WINDOWS_CRTDBG +#include + +namespace Catch { + + LeakDetector::LeakDetector() { + int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flag |= _CRTDBG_LEAK_CHECK_DF; + flag |= _CRTDBG_ALLOC_MEM_DF; + _CrtSetDbgFlag(flag); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + // Change this to leaking allocation's number to break there + _CrtSetBreakAlloc(-1); + } +} + +#else // ^^ Windows crt debug heap enabled // Windows crt debug heap disabled vv + + Catch::LeakDetector::LeakDetector() {} + +#endif // CATCH_CONFIG_WINDOWS_CRTDBG + +Catch::LeakDetector::~LeakDetector() { + Catch::cleanUp(); +} + + + + namespace Catch { namespace { @@ -4390,6 +4225,25 @@ int main (int argc, char * argv[]) { + +namespace Catch { + + MessageInfo::MessageInfo( StringRef _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + +} // end namespace Catch + + + #include #include #include @@ -4528,6 +4382,32 @@ namespace Catch { + +#include + +namespace Catch { + +#if !defined(CATCH_CONFIG_POLYFILL_ISNAN) + bool isnan(float f) { + return std::isnan(f); + } + bool isnan(double d) { + return std::isnan(d); + } +#else + // For now we only use this for embarcadero + bool isnan(float f) { + return std::_isnan(f); + } + bool isnan(double d) { + return std::_isnan(d); + } +#endif + +} // end namespace Catch + + + namespace Catch { namespace { @@ -4784,7 +4664,7 @@ namespace Catch { return {}; } - auto ret = kvPairs.emplace( kv.key, kv.value ); + auto ret = kvPairs.emplace( std::string(kv.key), std::string(kv.value) ); if ( !ret.second ) { // Duplicated key. We might want to handle this differently, // e.g. by overwriting the existing value? @@ -5387,6 +5267,11 @@ namespace Catch { // before running the tests themselves, or the binary can crash // without failed test being reported. FatalConditionHandlerGuard _(&m_fatalConditionhandler); + // We keep having issue where some compilers warn about an unused + // variable, even though the type has non-trivial constructor and + // destructor. This is annoying and ugly, but it makes them stfu. + (void)_; + m_activeTestCase->invoke(); } @@ -5618,6 +5503,27 @@ namespace Catch { +namespace Catch { +#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept { + CATCH_TRY { + m_exceptions.push_back(exception); + } CATCH_CATCH_ALL { + // If we run out of memory during start-up there's really not a lot more we can do about it + std::terminate(); + } + } + + std::vector const& StartupExceptionRegistry::getExceptions() const noexcept { + return m_exceptions; + } +#endif + +} // end namespace Catch + + + + #include @@ -6792,6 +6698,23 @@ namespace Catch { + +#include + +namespace Catch { + bool uncaught_exceptions() { +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + return false; +#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) + return std::uncaught_exceptions() > 0; +#else + return std::uncaught_exception(); +#endif + } +} // end namespace Catch + + + namespace Catch { WildcardPattern::WildcardPattern( std::string const& pattern, @@ -7171,6 +7094,72 @@ namespace { + + +namespace Catch { +namespace Matchers { + + std::string MatcherUntypedBase::toString() const { + if (m_cachedToString.empty()) { + m_cachedToString = describe(); + } + return m_cachedToString; + } + + MatcherUntypedBase::~MatcherUntypedBase() = default; + +} // namespace Matchers +} // namespace Catch + + + + +namespace Catch { +namespace Matchers { + + std::string IsEmptyMatcher::describe() const { + return "is empty"; + } + + std::string HasSizeMatcher::describe() const { + ReusableStringStream sstr; + sstr << "has size == " << m_target_size; + return sstr.str(); + } + + IsEmptyMatcher IsEmpty() { + return {}; + } + + HasSizeMatcher SizeIs(std::size_t sz) { + return HasSizeMatcher{ sz }; + } + +} // end namespace Matchers +} // end namespace Catch + + + +namespace Catch { +namespace Matchers { + +bool ExceptionMessageMatcher::match(std::exception const& ex) const { + return ex.what() == m_message; +} + +std::string ExceptionMessageMatcher::describe() const { + return "exception message matches \"" + m_message + '"'; +} + +ExceptionMessageMatcher Message(std::string const& message) { + return ExceptionMessageMatcher(message); +} + +} // namespace Matchers +} // namespace Catch + + + #include #include #include @@ -7389,6 +7378,35 @@ WithinRelMatcher WithinRel(float target) { + +std::string Catch::Matchers::Detail::finalizeDescription(const std::string& desc) { + if (desc.empty()) { + return "matches undescribed predicate"; + } else { + return "matches predicate: \"" + desc + '"'; + } +} + + + +namespace Catch { + namespace Matchers { + std::string AllTrueMatcher::describe() const { return "contains only true"; } + + AllTrueMatcher AllTrue() { return AllTrueMatcher{}; } + + std::string NoneTrueMatcher::describe() const { return "contains no true"; } + + NoneTrueMatcher NoneTrue() { return NoneTrueMatcher{}; } + + std::string AnyTrueMatcher::describe() const { return "contains at least one true"; } + + AnyTrueMatcher AnyTrue() { return AnyTrueMatcher{}; } + } // namespace Matchers +} // namespace Catch + + + #include namespace Catch { @@ -7528,21 +7546,7 @@ namespace Matchers { } // namespace Catch -/** \file - * This is a special TU that combines what would otherwise be a very - * small matcher-related TUs into one bigger TU. - * - * The reason for this is compilation performance improvements by - * avoiding reparsing headers for many small TUs, instead having this - * one TU include bit more, but having it all parsed only once. - * - * To avoid heavy-tail problem with compilation times, each "subpart" - * of Catch2 has its own combined TU like this. - */ -////////////////////////////////////////////// -// vvv formerly catch_matchers_impl.cpp vvv // -////////////////////////////////////////////// namespace Catch { @@ -7558,97 +7562,6 @@ namespace Catch { } // namespace Catch -////////////////////////////////////////////////////////////// -// vvv formerly catch_matchers_container_properties.cpp vvv // -////////////////////////////////////////////////////////////// - -namespace Catch { -namespace Matchers { - - std::string IsEmptyMatcher::describe() const { - return "is empty"; - } - - std::string HasSizeMatcher::describe() const { - ReusableStringStream sstr; - sstr << "has size == " << m_target_size; - return sstr.str(); - } - - IsEmptyMatcher IsEmpty() { - return {}; - } - - HasSizeMatcher SizeIs(std::size_t sz) { - return HasSizeMatcher{ sz }; - } - -} // end namespace Matchers -} // end namespace Catch - - - -///////////////////////////////////////// -// vvv formerly catch_matchers.cpp vvv // -///////////////////////////////////////// - - -namespace Catch { -namespace Matchers { - - std::string MatcherUntypedBase::toString() const { - if (m_cachedToString.empty()) { - m_cachedToString = describe(); - } - return m_cachedToString; - } - - MatcherUntypedBase::~MatcherUntypedBase() = default; - -} // namespace Matchers -} // namespace Catch - - - -/////////////////////////////////////////////////// -// vvv formerly catch_matchers_predicate.cpp vvv // -/////////////////////////////////////////////////// - -std::string Catch::Matchers::Detail::finalizeDescription(const std::string& desc) { - if (desc.empty()) { - return "matches undescribed predicate"; - } else { - return "matches predicate: \"" + desc + '"'; - } -} - - - - - -/////////////////////////////////////////////////// -// vvv formerly catch_matchers_exception.cpp vvv // -/////////////////////////////////////////////////// - -namespace Catch { -namespace Matchers { - -bool ExceptionMessageMatcher::match(std::exception const& ex) const { - return ex.what() == m_message; -} - -std::string ExceptionMessageMatcher::describe() const { - return "exception message matches \"" + m_message + '"'; -} - -ExceptionMessageMatcher Message(std::string const& message) { - return ExceptionMessageMatcher(message); -} - -} // namespace Matchers -} // namespace Catch - - #include @@ -7677,268 +7590,6 @@ namespace Catch { } // end namespace Catch -/** \file - * This is a special TU that combines what would otherwise be a very - * small reporter-related TUs into one bigger TU. - * - * The reason for this is compilation performance improvements by - * avoiding reparsing headers for many small TUs, instead having this - * one TU include bit more, but having it all parsed only once. - * - * To avoid heavy-tail problem with compilation times, each "subpart" - * of Catch2 has its own combined TU like this. - */ - - -#include -#include -#include -#include -#include - -namespace Catch { - - namespace { - void listTestNamesOnly(std::ostream& out, - std::vector const& tests) { - for (auto const& test : tests) { - auto const& testCaseInfo = test.getTestCaseInfo(); - - if (startsWith(testCaseInfo.name, '#')) { - out << '"' << testCaseInfo.name << '"'; - } else { - out << testCaseInfo.name; - } - - out << '\n'; - } - out << std::flush; - } - } // end unnamed namespace - - - // Because formatting using c++ streams is stateful, drop down to C is - // required Alternatively we could use stringstream, but its performance - // is... not good. - std::string getFormattedDuration( double duration ) { - // Max exponent + 1 is required to represent the whole part - // + 1 for decimal point - // + 3 for the 3 decimal places - // + 1 for null terminator - const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; - char buffer[maxDoubleSize]; - - // Save previous errno, to prevent sprintf from overwriting it - ErrnoGuard guard; -#ifdef _MSC_VER - size_t printedLength = static_cast( - sprintf_s( buffer, "%.3f", duration ) ); -#else - size_t printedLength = static_cast( - std::snprintf( buffer, maxDoubleSize, "%.3f", duration ) ); -#endif - return std::string( buffer, printedLength ); - } - - bool shouldShowDuration( IConfig const& config, double duration ) { - if ( config.showDurations() == ShowDurations::Always ) { - return true; - } - if ( config.showDurations() == ShowDurations::Never ) { - return false; - } - const double min = config.minDuration(); - return min >= 0 && duration >= min; - } - - std::string serializeFilters( std::vector const& filters ) { - // We add a ' ' separator between each filter - size_t serialized_size = filters.size() - 1; - for (auto const& filter : filters) { - serialized_size += filter.size(); - } - - std::string serialized; - serialized.reserve(serialized_size); - bool first = true; - - for (auto const& filter : filters) { - if (!first) { - serialized.push_back(' '); - } - first = false; - serialized.append(filter); - } - - return serialized; - } - - std::ostream& operator<<( std::ostream& out, lineOfChars value ) { - for ( size_t idx = 0; idx < CATCH_CONFIG_CONSOLE_WIDTH - 1; ++idx ) { - out.put( value.c ); - } - return out; - } - - void - defaultListReporters( std::ostream& out, - std::vector const& descriptions, - Verbosity verbosity ) { - out << "Available reporters:\n"; - const auto maxNameLen = - std::max_element( descriptions.begin(), - descriptions.end(), - []( ReporterDescription const& lhs, - ReporterDescription const& rhs ) { - return lhs.name.size() < rhs.name.size(); - } ) - ->name.size(); - - for ( auto const& desc : descriptions ) { - if ( verbosity == Verbosity::Quiet ) { - out << TextFlow::Column( desc.name ) - .indent( 2 ) - .width( 5 + maxNameLen ) - << '\n'; - } else { - out << TextFlow::Column( desc.name + ':' ) - .indent( 2 ) - .width( 5 + maxNameLen ) + - TextFlow::Column( desc.description ) - .initialIndent( 0 ) - .indent( 2 ) - .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8 ) - << '\n'; - } - } - out << '\n' << std::flush; - } - - void defaultListListeners( std::ostream& out, - std::vector const& descriptions ) { - const auto maxNameLen = - std::max_element( descriptions.begin(), - descriptions.end(), - []( ListenerDescription const& lhs, - ListenerDescription const& rhs ) { - return lhs.name.size() < rhs.name.size(); - } ) - ->name.size(); - - out << "Registered listeners:\n"; - for ( auto const& desc : descriptions ) { - out << TextFlow::Column( static_cast( desc.name ) + - ':' ) - .indent( 2 ) - .width( maxNameLen + 5 ) + - TextFlow::Column( desc.description ) - .initialIndent( 0 ) - .indent( 2 ) - .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8 ) - << '\n'; - } - - out << '\n' << std::flush; - } - - void defaultListTags( std::ostream& out, - std::vector const& tags, - bool isFiltered ) { - if ( isFiltered ) { - out << "Tags for matching test cases:\n"; - } else { - out << "All available tags:\n"; - } - - for ( auto const& tagCount : tags ) { - ReusableStringStream rss; - rss << " " << std::setw( 2 ) << tagCount.count << " "; - auto str = rss.str(); - auto wrapper = TextFlow::Column( tagCount.all() ) - .initialIndent( 0 ) - .indent( str.size() ) - .width( CATCH_CONFIG_CONSOLE_WIDTH - 10 ); - out << str << wrapper << '\n'; - } - out << pluralise(tags.size(), "tag"_sr) << "\n\n" << std::flush; - } - - void defaultListTests(std::ostream& out, ColourImpl* streamColour, std::vector const& tests, bool isFiltered, Verbosity verbosity) { - // We special case this to provide the equivalent of old - // `--list-test-names-only`, which could then be used by the - // `--input-file` option. - if (verbosity == Verbosity::Quiet) { - listTestNamesOnly(out, tests); - return; - } - - if (isFiltered) { - out << "Matching test cases:\n"; - } else { - out << "All available test cases:\n"; - } - - for (auto const& test : tests) { - auto const& testCaseInfo = test.getTestCaseInfo(); - Colour::Code colour = testCaseInfo.isHidden() - ? Colour::SecondaryText - : Colour::None; - auto colourGuard = streamColour->guardColour( colour ).engage( out ); - - out << TextFlow::Column(testCaseInfo.name).indent(2) << '\n'; - if (verbosity >= Verbosity::High) { - out << TextFlow::Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << '\n'; - } - if (!testCaseInfo.tags.empty() && - verbosity > Verbosity::Quiet) { - out << TextFlow::Column(testCaseInfo.tagsAsString()).indent(6) << '\n'; - } - } - - if (isFiltered) { - out << pluralise(tests.size(), "matching test case"_sr); - } else { - out << pluralise(tests.size(), "test case"_sr); - } - out << "\n\n" << std::flush; - } - -} // namespace Catch - - - -namespace Catch { - - void EventListenerBase::fatalErrorEncountered( StringRef ) {} - - void EventListenerBase::benchmarkPreparing( StringRef ) {} - void EventListenerBase::benchmarkStarting( BenchmarkInfo const& ) {} - void EventListenerBase::benchmarkEnded( BenchmarkStats<> const& ) {} - void EventListenerBase::benchmarkFailed( StringRef ) {} - - void EventListenerBase::assertionStarting( AssertionInfo const& ) {} - - void EventListenerBase::assertionEnded( AssertionStats const& ) {} - void EventListenerBase::listReporters( - std::vector const& ) {} - void EventListenerBase::listListeners( - std::vector const& ) {} - void EventListenerBase::listTests( std::vector const& ) {} - void EventListenerBase::listTags( std::vector const& ) {} - void EventListenerBase::noMatchingTestCases( StringRef ) {} - void EventListenerBase::reportInvalidTestSpec( StringRef ) {} - void EventListenerBase::testRunStarting( TestRunInfo const& ) {} - void EventListenerBase::testCaseStarting( TestCaseInfo const& ) {} - void EventListenerBase::testCasePartialStarting(TestCaseInfo const&, uint64_t) {} - void EventListenerBase::sectionStarting( SectionInfo const& ) {} - void EventListenerBase::sectionEnded( SectionStats const& ) {} - void EventListenerBase::testCasePartialEnded(TestCaseStats const&, uint64_t) {} - void EventListenerBase::testCaseEnded( TestCaseStats const& ) {} - void EventListenerBase::testRunEnded( TestRunStats const& ) {} - void EventListenerBase::skipTest( TestCaseInfo const& ) {} -} // namespace Catch - - @@ -9116,6 +8767,263 @@ namespace Catch { +namespace Catch { + + void EventListenerBase::fatalErrorEncountered( StringRef ) {} + + void EventListenerBase::benchmarkPreparing( StringRef ) {} + void EventListenerBase::benchmarkStarting( BenchmarkInfo const& ) {} + void EventListenerBase::benchmarkEnded( BenchmarkStats<> const& ) {} + void EventListenerBase::benchmarkFailed( StringRef ) {} + + void EventListenerBase::assertionStarting( AssertionInfo const& ) {} + + void EventListenerBase::assertionEnded( AssertionStats const& ) {} + void EventListenerBase::listReporters( + std::vector const& ) {} + void EventListenerBase::listListeners( + std::vector const& ) {} + void EventListenerBase::listTests( std::vector const& ) {} + void EventListenerBase::listTags( std::vector const& ) {} + void EventListenerBase::noMatchingTestCases( StringRef ) {} + void EventListenerBase::reportInvalidTestSpec( StringRef ) {} + void EventListenerBase::testRunStarting( TestRunInfo const& ) {} + void EventListenerBase::testCaseStarting( TestCaseInfo const& ) {} + void EventListenerBase::testCasePartialStarting(TestCaseInfo const&, uint64_t) {} + void EventListenerBase::sectionStarting( SectionInfo const& ) {} + void EventListenerBase::sectionEnded( SectionStats const& ) {} + void EventListenerBase::testCasePartialEnded(TestCaseStats const&, uint64_t) {} + void EventListenerBase::testCaseEnded( TestCaseStats const& ) {} + void EventListenerBase::testRunEnded( TestRunStats const& ) {} + void EventListenerBase::skipTest( TestCaseInfo const& ) {} +} // namespace Catch + + + + +#include +#include +#include +#include +#include + +namespace Catch { + + namespace { + void listTestNamesOnly(std::ostream& out, + std::vector const& tests) { + for (auto const& test : tests) { + auto const& testCaseInfo = test.getTestCaseInfo(); + + if (startsWith(testCaseInfo.name, '#')) { + out << '"' << testCaseInfo.name << '"'; + } else { + out << testCaseInfo.name; + } + + out << '\n'; + } + out << std::flush; + } + } // end unnamed namespace + + + // Because formatting using c++ streams is stateful, drop down to C is + // required Alternatively we could use stringstream, but its performance + // is... not good. + std::string getFormattedDuration( double duration ) { + // Max exponent + 1 is required to represent the whole part + // + 1 for decimal point + // + 3 for the 3 decimal places + // + 1 for null terminator + const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; + char buffer[maxDoubleSize]; + + // Save previous errno, to prevent sprintf from overwriting it + ErrnoGuard guard; +#ifdef _MSC_VER + size_t printedLength = static_cast( + sprintf_s( buffer, "%.3f", duration ) ); +#else + size_t printedLength = static_cast( + std::snprintf( buffer, maxDoubleSize, "%.3f", duration ) ); +#endif + return std::string( buffer, printedLength ); + } + + bool shouldShowDuration( IConfig const& config, double duration ) { + if ( config.showDurations() == ShowDurations::Always ) { + return true; + } + if ( config.showDurations() == ShowDurations::Never ) { + return false; + } + const double min = config.minDuration(); + return min >= 0 && duration >= min; + } + + std::string serializeFilters( std::vector const& filters ) { + // We add a ' ' separator between each filter + size_t serialized_size = filters.size() - 1; + for (auto const& filter : filters) { + serialized_size += filter.size(); + } + + std::string serialized; + serialized.reserve(serialized_size); + bool first = true; + + for (auto const& filter : filters) { + if (!first) { + serialized.push_back(' '); + } + first = false; + serialized.append(filter); + } + + return serialized; + } + + std::ostream& operator<<( std::ostream& out, lineOfChars value ) { + for ( size_t idx = 0; idx < CATCH_CONFIG_CONSOLE_WIDTH - 1; ++idx ) { + out.put( value.c ); + } + return out; + } + + void + defaultListReporters( std::ostream& out, + std::vector const& descriptions, + Verbosity verbosity ) { + out << "Available reporters:\n"; + const auto maxNameLen = + std::max_element( descriptions.begin(), + descriptions.end(), + []( ReporterDescription const& lhs, + ReporterDescription const& rhs ) { + return lhs.name.size() < rhs.name.size(); + } ) + ->name.size(); + + for ( auto const& desc : descriptions ) { + if ( verbosity == Verbosity::Quiet ) { + out << TextFlow::Column( desc.name ) + .indent( 2 ) + .width( 5 + maxNameLen ) + << '\n'; + } else { + out << TextFlow::Column( desc.name + ':' ) + .indent( 2 ) + .width( 5 + maxNameLen ) + + TextFlow::Column( desc.description ) + .initialIndent( 0 ) + .indent( 2 ) + .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8 ) + << '\n'; + } + } + out << '\n' << std::flush; + } + + void defaultListListeners( std::ostream& out, + std::vector const& descriptions ) { + out << "Registered listeners:\n"; + + if(descriptions.empty()) { + return; + } + + const auto maxNameLen = + std::max_element( descriptions.begin(), + descriptions.end(), + []( ListenerDescription const& lhs, + ListenerDescription const& rhs ) { + return lhs.name.size() < rhs.name.size(); + } ) + ->name.size(); + + for ( auto const& desc : descriptions ) { + out << TextFlow::Column( static_cast( desc.name ) + + ':' ) + .indent( 2 ) + .width( maxNameLen + 5 ) + + TextFlow::Column( desc.description ) + .initialIndent( 0 ) + .indent( 2 ) + .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8 ) + << '\n'; + } + + out << '\n' << std::flush; + } + + void defaultListTags( std::ostream& out, + std::vector const& tags, + bool isFiltered ) { + if ( isFiltered ) { + out << "Tags for matching test cases:\n"; + } else { + out << "All available tags:\n"; + } + + for ( auto const& tagCount : tags ) { + ReusableStringStream rss; + rss << " " << std::setw( 2 ) << tagCount.count << " "; + auto str = rss.str(); + auto wrapper = TextFlow::Column( tagCount.all() ) + .initialIndent( 0 ) + .indent( str.size() ) + .width( CATCH_CONFIG_CONSOLE_WIDTH - 10 ); + out << str << wrapper << '\n'; + } + out << pluralise(tags.size(), "tag"_sr) << "\n\n" << std::flush; + } + + void defaultListTests(std::ostream& out, ColourImpl* streamColour, std::vector const& tests, bool isFiltered, Verbosity verbosity) { + // We special case this to provide the equivalent of old + // `--list-test-names-only`, which could then be used by the + // `--input-file` option. + if (verbosity == Verbosity::Quiet) { + listTestNamesOnly(out, tests); + return; + } + + if (isFiltered) { + out << "Matching test cases:\n"; + } else { + out << "All available test cases:\n"; + } + + for (auto const& test : tests) { + auto const& testCaseInfo = test.getTestCaseInfo(); + Colour::Code colour = testCaseInfo.isHidden() + ? Colour::SecondaryText + : Colour::None; + auto colourGuard = streamColour->guardColour( colour ).engage( out ); + + out << TextFlow::Column(testCaseInfo.name).indent(2) << '\n'; + if (verbosity >= Verbosity::High) { + out << TextFlow::Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << '\n'; + } + if (!testCaseInfo.tags.empty() && + verbosity > Verbosity::Quiet) { + out << TextFlow::Column(testCaseInfo.tagsAsString()).indent(6) << '\n'; + } + } + + if (isFiltered) { + out << pluralise(tests.size(), "matching test case"_sr); + } else { + out << pluralise(tests.size(), "test case"_sr); + } + out << "\n\n" << std::flush; + } + +} // namespace Catch + + + + #include #include #include @@ -9168,6 +9076,15 @@ namespace Catch { return rss.str(); } + static void normalizeNamespaceMarkers(std::string& str) { + std::size_t pos = str.find( "::" ); + while ( pos != str.npos ) { + str.replace( pos, 2, "." ); + pos += 1; + pos = str.find( "::", pos ); + } + } + } // anonymous namespace JunitReporter::JunitReporter( ReporterConfig&& _config ) @@ -9271,6 +9188,8 @@ namespace Catch { if ( !m_config->name().empty() ) className = static_cast(m_config->name()) + '.' + className; + normalizeNamespaceMarkers(className); + writeSection( className, "", rootSection, stats.testInfo->okToFail() ); } diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp index 5c1caa36..757e10c5 100644 --- a/extras/catch_amalgamated.hpp +++ b/extras/catch_amalgamated.hpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.0.1 -// Generated: 2022-05-17 22:08:46.674860 +// Catch v3.1.0 +// Generated: 2022-07-17 20:14:04.055157 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -360,11 +360,23 @@ namespace Catch { #endif +#if defined(__CUDACC__) && !defined(__clang__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic pop" ) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "nv_diag_suppress 177" ) +#endif + +// clang-cl defines _MSC_VER as well as __clang__, which could cause the +// start/stop internal suppression macros to be double defined. #if defined(__clang__) && !defined(_MSC_VER) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) +#endif // __clang__ && !_MSC_VER + +#if defined(__clang__) + // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug // which results in calls to destructors being emitted for each temporary, // without a matching initialization. In practice, this can result in something @@ -2320,7 +2332,7 @@ namespace Catch { double z1 = normal_quantile((1. - confidence_level) / 2.); auto cumn = [n]( double x ) -> long { - return std::lround( normal_cdf( x ) * n ); + return std::lround( normal_cdf( x ) * static_cast(n) ); }; auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); }; double b1 = bias + z1; @@ -2730,7 +2742,7 @@ namespace Catch { } T const& stored_object() const { - return *static_cast(static_cast(data)); + return *static_cast(static_cast(data)); } @@ -5568,9 +5580,9 @@ namespace Catch { #endif // CATCH_ASSERTION_HANDLER_HPP_INCLUDED -// We need this suppression to leak, because it took until GCC 9 +// We need this suppression to leak, because it took until GCC 10 // for the front end to handle local suppression via _Pragma properly -#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ < 9 +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ <= 9 #pragma GCC diagnostic ignored "-Wparentheses" #endif @@ -5879,6 +5891,7 @@ struct AutoReg : Detail::NonCopyable { static void TestName(); \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ static void TestName() @@ -5889,6 +5902,7 @@ struct AutoReg : Detail::NonCopyable { #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION @@ -5896,6 +5910,7 @@ struct AutoReg : Detail::NonCopyable { #define INTERNAL_CATCH_TEST_CASE_METHOD2( 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(); \ @@ -5912,6 +5927,7 @@ struct AutoReg : Detail::NonCopyable { do { \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ } while(false) @@ -7046,8 +7062,8 @@ namespace Catch { #define CATCH_VERSION_MACROS_HPP_INCLUDED #define CATCH_VERSION_MAJOR 3 -#define CATCH_VERSION_MINOR 0 -#define CATCH_VERSION_PATCH 1 +#define CATCH_VERSION_MINOR 1 +#define CATCH_VERSION_PATCH 0 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED @@ -7752,12 +7768,17 @@ public: } }; -// TODO: Ideally this would be also constrained against the various char types, -// but I don't expect users to run into that in practice. template -std::enable_if_t::value && !std::is_same::value, -GeneratorWrapper> +std::enable_if_t::value, GeneratorWrapper> random(T a, T b) { + static_assert( + !std::is_same::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value, + "The requested type is not supported by the underlying random distributions from std" ); return GeneratorWrapper( Catch::Detail::make_unique>(a, b, Detail::getSeed()) ); @@ -8097,6 +8118,9 @@ namespace Catch { #ifndef CATCH_CONSOLE_WIDTH_HPP_INCLUDED #define CATCH_CONSOLE_WIDTH_HPP_INCLUDED +// This include must be kept so that user's configured value for CONSOLE_WIDTH +// is used before we attempt to provide a default value + #ifndef CATCH_CONFIG_CONSOLE_WIDTH #define CATCH_CONFIG_CONSOLE_WIDTH 80 #endif @@ -10455,7 +10479,6 @@ namespace Catch { class IsEmptyMatcher final : public MatcherGenericBase { public: - // todo: Use polyfills template bool match(RangeLike&& rng) const { #if defined(CATCH_CONFIG_POLYFILL_NONMEMBER_CONTAINER_ACCESS) @@ -10856,7 +10879,55 @@ namespace Catch { } }; - // Creates a matcher that checks whether a range contains element matching a matcher + // Matcher for checking that all elements in range are true. + class AllTrueMatcher final : public MatcherGenericBase { + public: + std::string describe() const override; + + template + bool match(RangeLike&& rng) const { + for (auto&& elem : rng) { + if (!elem) { + return false; + } + } + return true; + } + }; + + // Matcher for checking that no element in range is true. + class NoneTrueMatcher final : public MatcherGenericBase { + public: + std::string describe() const override; + + template + bool match(RangeLike&& rng) const { + for (auto&& elem : rng) { + if (elem) { + return false; + } + } + return true; + } + }; + + // Matcher for checking that any element in range is true. + class AnyTrueMatcher final : public MatcherGenericBase { + public: + std::string describe() const override; + + template + bool match(RangeLike&& rng) const { + for (auto&& elem : rng) { + if (elem) { + return true; + } + } + return false; + } + }; + + // Creates a matcher that checks whether all elements in a range match a matcher template AllMatchMatcher AllMatch(Matcher&& matcher) { return { CATCH_FORWARD(matcher) }; @@ -10873,6 +10944,15 @@ namespace Catch { AnyMatchMatcher AnyMatch(Matcher&& matcher) { return { CATCH_FORWARD(matcher) }; } + + // Creates a matcher that checks whether all elements in a range are true + AllTrueMatcher AllTrue(); + + // Creates a matcher that checks whether no element in a range is true + NoneTrueMatcher NoneTrue(); + + // Creates a matcher that checks whether any element in a range is true + AnyTrueMatcher AnyTrue(); } } @@ -11252,7 +11332,11 @@ namespace Catch { class StreamingReporterBase : public ReporterBase { public: - using ReporterBase::ReporterBase; + // GCC5 compat: we cannot use inherited constructor, because it + // doesn't implement backport of P0136 + StreamingReporterBase(ReporterConfig&& _config): + ReporterBase(CATCH_MOVE(_config)) + {} ~StreamingReporterBase() override; void benchmarkPreparing( StringRef ) override {} @@ -11309,7 +11393,11 @@ namespace Catch { class AutomakeReporter final : public StreamingReporterBase { public: - using StreamingReporterBase::StreamingReporterBase; + // GCC5 compat: we cannot use inherited constructor, because it + // doesn't implement backport of P0136 + AutomakeReporter(ReporterConfig&& _config): + StreamingReporterBase(CATCH_MOVE(_config)) + {} ~AutomakeReporter() override; static std::string getDescription() { @@ -11505,7 +11593,11 @@ namespace Catch { using TestCaseNode = Node; using TestRunNode = Node; - using ReporterBase::ReporterBase; + // GCC5 compat: we cannot use inherited constructor, because it + // doesn't implement backport of P0136 + CumulativeReporterBase(ReporterConfig&& _config): + ReporterBase(CATCH_MOVE(_config)) + {} ~CumulativeReporterBase() override; void benchmarkPreparing( StringRef ) override {} diff --git a/src/catch2/catch_version.cpp b/src/catch2/catch_version.cpp index ed539297..a7075f30 100644 --- a/src/catch2/catch_version.cpp +++ b/src/catch2/catch_version.cpp @@ -36,7 +36,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 0, 1, "", 0 ); + static Version version( 3, 1, 0, "", 0 ); return version; } diff --git a/src/catch2/catch_version_macros.hpp b/src/catch2/catch_version_macros.hpp index 29e18567..c7212e3a 100644 --- a/src/catch2/catch_version_macros.hpp +++ b/src/catch2/catch_version_macros.hpp @@ -9,7 +9,7 @@ #define CATCH_VERSION_MACROS_HPP_INCLUDED #define CATCH_VERSION_MAJOR 3 -#define CATCH_VERSION_MINOR 0 -#define CATCH_VERSION_PATCH 1 +#define CATCH_VERSION_MINOR 1 +#define CATCH_VERSION_PATCH 0 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED