diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bd7e01d..7bad26c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() project(Catch2 - VERSION 3.7.0 # CML version placeholder, don't delete + VERSION 3.7.1 # 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/release-notes.md b/docs/release-notes.md index 77ab7aaf..5f2d92ae 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[3.7.1](#371)
[3.7.0](#370)
[3.6.0](#360)
[3.5.4](#354)
@@ -64,6 +65,26 @@ [Even Older versions](#even-older-versions)
+## 3.7.1 + +### Improvements +* Applied the JUnit reporter's optimization from last release to the SonarQube reporter +* Suppressed `-Wuseless-cast` in `CHECK_THROWS_MATCHES` (#2904) +* Standardize exit codes for various failures + * Running no tests is now guaranteed to exit with 2 (without the `--allow-running-no-tests` flag) + * All tests skipped is now always 4 (...) + * Assertion failures are now always 42 + * and so on + +### Fixes +* Fixed out-of-bounds access when the arg parser encounters single `-` as an argument (#2905) + +### Miscellaneous +* Added `catch_config_prefix_messages.hpp` to meson build (#2903) +* `catch_discover_tests` now supports skipped tests (#2873) + * You can get the old behaviour by calling `catch_discover_tests` with `SKIP_IS_FAILURE` option. + + ## 3.7.0 ### Improvements diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp index 4178e328..f45c18a0 100644 --- a/extras/catch_amalgamated.cpp +++ b/extras/catch_amalgamated.cpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.7.0 -// Generated: 2024-08-14 12:04:53.604337 +// Catch v3.7.1 +// Generated: 2024-09-17 10:36:45.608896 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -627,7 +627,7 @@ std::string StringMaker::convert(Catch::Approx const& value) { namespace Catch { - AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression): + AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const& _lazyExpression): lazyExpression(_lazyExpression), resultType(_resultType) {} @@ -1170,7 +1170,13 @@ namespace Catch { namespace Catch { namespace { - const int MaxExitCode = 255; + static constexpr int TestFailureExitCode = 42; + static constexpr int UnspecifiedErrorExitCode = 1; + static constexpr int AllTestsSkippedExitCode = 4; + static constexpr int NoTestsRunExitCode = 2; + static constexpr int UnmatchedTestSpecExitCode = 3; + static constexpr int InvalidTestSpecExitCode = 5; + IEventListenerPtr createReporter(std::string const& reporterName, ReporterConfig&& config) { auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, CATCH_MOVE(config)); @@ -1334,8 +1340,7 @@ namespace Catch { } int Session::applyCommandLine( int argc, char const * const * argv ) { - if( m_startupExceptions ) - return 1; + if ( m_startupExceptions ) { return UnspecifiedErrorExitCode; } auto result = m_cli.parse( Clara::Args( argc, argv ) ); @@ -1351,7 +1356,7 @@ namespace Catch { << TextFlow::Column( result.errorMessage() ).indent( 2 ) << "\n\n"; errStream->stream() << "Run with -? for usage\n\n" << std::flush; - return MaxExitCode; + return UnspecifiedErrorExitCode; } if( m_configData.showHelp ) @@ -1421,8 +1426,7 @@ namespace Catch { } int Session::runInternal() { - if( m_startupExceptions ) - return 1; + if ( m_startupExceptions ) { return UnspecifiedErrorExitCode; } if (m_configData.showHelp || m_configData.libIdentify) { return 0; @@ -1433,7 +1437,7 @@ namespace Catch { << ") must be greater than the shard index (" << m_configData.shardIndex << ")\n" << std::flush; - return 1; + return UnspecifiedErrorExitCode; } CATCH_TRY { @@ -1456,7 +1460,7 @@ namespace Catch { for ( auto const& spec : invalidSpecs ) { reporter->reportInvalidTestSpec( spec ); } - return 1; + return InvalidTestSpecExitCode; } @@ -1470,29 +1474,29 @@ namespace Catch { if ( tests.hadUnmatchedTestSpecs() && m_config->warnAboutUnmatchedTestSpecs() ) { - return 3; + // UnmatchedTestSpecExitCode + return UnmatchedTestSpecExitCode; } if ( totals.testCases.total() == 0 && !m_config->zeroTestsCountAsSuccess() ) { - return 2; + return NoTestsRunExitCode; } if ( totals.testCases.total() > 0 && totals.testCases.total() == totals.testCases.skipped && !m_config->zeroTestsCountAsSuccess() ) { - return 4; + return AllTestsSkippedExitCode; } - // Note that on unices only the lower 8 bits are usually used, clamping - // the return value to 255 prevents false negative when some multiple - // of 256 tests has failed - return (std::min) (MaxExitCode, static_cast(totals.assertions.failed)); + if ( totals.assertions.failed ) { return TestFailureExitCode; } + return 0; + } #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) catch( std::exception& ex ) { Catch::cerr() << ex.what() << '\n' << std::flush; - return MaxExitCode; + return UnspecifiedErrorExitCode; } #endif } @@ -1528,26 +1532,26 @@ namespace Catch { static_assert(sizeof(TestCaseProperties) == sizeof(TCP_underlying_type), "The size of the TestCaseProperties is different from the assumed size"); - TestCaseProperties operator|(TestCaseProperties lhs, TestCaseProperties rhs) { + constexpr TestCaseProperties operator|(TestCaseProperties lhs, TestCaseProperties rhs) { return static_cast( static_cast(lhs) | static_cast(rhs) ); } - TestCaseProperties& operator|=(TestCaseProperties& lhs, TestCaseProperties rhs) { + constexpr TestCaseProperties& operator|=(TestCaseProperties& lhs, TestCaseProperties rhs) { lhs = static_cast( static_cast(lhs) | static_cast(rhs) ); return lhs; } - TestCaseProperties operator&(TestCaseProperties lhs, TestCaseProperties rhs) { + constexpr TestCaseProperties operator&(TestCaseProperties lhs, TestCaseProperties rhs) { return static_cast( static_cast(lhs) & static_cast(rhs) ); } - bool applies(TestCaseProperties tcp) { + constexpr bool applies(TestCaseProperties tcp) { static_assert(static_cast(TestCaseProperties::None) == 0, "TestCaseProperties::None must be equal to 0"); return tcp != TestCaseProperties::None; @@ -1586,7 +1590,7 @@ namespace Catch { return "Anonymous test case " + std::to_string(++counter); } - StringRef extractFilenamePart(StringRef filename) { + constexpr StringRef extractFilenamePart(StringRef filename) { size_t lastDot = filename.size(); while (lastDot > 0 && filename[lastDot - 1] != '.') { --lastDot; @@ -1604,7 +1608,7 @@ namespace Catch { } // Returns the upper bound on size of extra tags ([#file]+[.]) - size_t sizeOfExtraTags(StringRef filepath) { + constexpr size_t sizeOfExtraTags(StringRef filepath) { // [.] is 3, [#] is another 3 const size_t extras = 3 + 3; return extractFilenamePart(filepath).size() + extras; @@ -1765,10 +1769,6 @@ namespace Catch { return lhs.tags < rhs.tags; } - TestCaseInfo const& TestCaseHandle::getTestCaseInfo() const { - return *m_info; - } - } // end namespace Catch @@ -1909,7 +1909,7 @@ namespace Catch { namespace { static auto getCurrentNanosecondsSinceEpoch() -> uint64_t { - return std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); } } // end unnamed namespace @@ -2280,7 +2280,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 7, 0, "", 0 ); + static Version version( 3, 7, 1, "", 0 ); return version; } @@ -2536,8 +2536,8 @@ namespace Catch { void AssertionHandler::handleExpr( ITransientExpression const& expr ) { m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction ); } - void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef message) { - m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction ); + void AssertionHandler::handleMessage(ResultWas::OfType resultType, std::string&& message) { + m_resultCapture.handleMessage( m_assertionInfo, resultType, CATCH_MOVE(message), m_reaction ); } auto AssertionHandler::allowThrows() const -> bool { @@ -2683,7 +2683,7 @@ namespace Catch { { TokenType::Argument, next.substr( delimiterPos + 1, next.size() ) } ); } else { - if ( next[1] != '-' && next.size() > 2 ) { + if ( next.size() > 1 && next[1] != '-' && next.size() > 2 ) { // Combined short args, e.g. "-ab" for "-a -b" for ( size_t i = 1; i < next.size(); ++i ) { m_tokenBuffer.push_back( @@ -3656,12 +3656,6 @@ namespace Catch { return *Context::currentContext; } - void Context::setResultCapture( IResultCapture* resultCapture ) { - m_resultCapture = resultCapture; - } - - void Context::setConfig( IConfig const* config ) { m_config = config; } - SimplePcg32& sharedRng() { static SimplePcg32 s_rng; return s_rng; @@ -5547,26 +5541,6 @@ ReporterSpec::ReporterSpec( -namespace Catch { - - bool isOk( ResultWas::OfType resultType ) { - return ( resultType & ResultWas::FailureBit ) == 0; - } - bool isJustInfo( int flags ) { - return flags == ResultWas::Info; - } - - ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { - return static_cast( static_cast( lhs ) | static_cast( rhs ) ); - } - - bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } - bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } - -} // end namespace Catch - - - #include #include #include @@ -6232,13 +6206,13 @@ namespace Catch { void RunContext::handleMessage( AssertionInfo const& info, ResultWas::OfType resultType, - StringRef message, + std::string&& message, AssertionReaction& reaction ) { m_lastAssertionInfo = info; AssertionResultData data( resultType, LazyExpression( false ) ); - data.message = static_cast(message); + data.message = CATCH_MOVE( message ); AssertionResult assertionResult{ m_lastAssertionInfo, CATCH_MOVE( data ) }; @@ -7153,7 +7127,7 @@ namespace Catch { TestType m_testAsFunction; public: - TestInvokerAsFunction( TestType testAsFunction ) noexcept: + constexpr TestInvokerAsFunction( TestType testAsFunction ) noexcept: m_testAsFunction( testAsFunction ) {} void invoke() const override { m_testAsFunction(); } @@ -7888,36 +7862,16 @@ namespace { os.flags(f); } - bool shouldNewline(XmlFormatting fmt) { + constexpr bool shouldNewline(XmlFormatting fmt) { return !!(static_cast>(fmt & XmlFormatting::Newline)); } - bool shouldIndent(XmlFormatting fmt) { + constexpr bool shouldIndent(XmlFormatting fmt) { return !!(static_cast>(fmt & XmlFormatting::Indent)); } } // anonymous namespace - XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) { - return static_cast( - static_cast>(lhs) | - static_cast>(rhs) - ); - } - - XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) { - return static_cast( - static_cast>(lhs) & - static_cast>(rhs) - ); - } - - - XmlEncode::XmlEncode( StringRef str, ForWhat forWhat ) - : m_str( str ), - m_forWhat( forWhat ) - {} - void XmlEncode::encodeTo( std::ostream& os ) const { // Apostrophe escaping not necessary if we always use " to write attributes // (see: http://www.w3.org/TR/xml/#syntax) @@ -11050,9 +11004,9 @@ namespace Catch { if (!rootName.empty()) name = rootName + '/' + name; - if ( sectionNode.hasAnyAssertions() + if ( sectionNode.stats.assertions.total() > 0 || !sectionNode.stdOut.empty() - || !sectionNode.stdErr.empty() ) { + || !sectionNode.stdErr.empty() ) { XmlWriter::ScopedElement e = xml.scopedElement("testCase"); xml.writeAttribute("name"_sr, name); xml.writeAttribute("duration"_sr, static_cast(sectionNode.stats.durationInSeconds * 1000)); diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp index 968aeb8d..b7c768b8 100644 --- a/extras/catch_amalgamated.hpp +++ b/extras/catch_amalgamated.hpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.7.0 -// Generated: 2024-08-14 12:04:53.220567 +// Catch v3.7.1 +// Generated: 2024-09-17 10:36:40.974985 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -555,10 +555,15 @@ namespace Catch { friend void cleanUpContext(); public: - IResultCapture* getResultCapture() const { return m_resultCapture; } - IConfig const* getConfig() const { return m_config; } - void setResultCapture( IResultCapture* resultCapture ); - void setConfig( IConfig const* config ); + constexpr IResultCapture* getResultCapture() const { + return m_resultCapture; + } + constexpr IConfig const* getConfig() const { return m_config; } + constexpr void setResultCapture( IResultCapture* resultCapture ) { + m_resultCapture = resultCapture; + } + constexpr void setConfig( IConfig const* config ) { m_config = config; } + }; Context& getCurrentMutableContext(); @@ -669,7 +674,6 @@ namespace Catch { #define CATCH_INTERFACES_CAPTURE_HPP_INCLUDED #include -#include @@ -819,8 +823,10 @@ namespace Catch { }; }; - bool isOk( ResultWas::OfType resultType ); - bool isJustInfo( int flags ); + constexpr bool isOk( ResultWas::OfType resultType ) { + return ( resultType & ResultWas::FailureBit ) == 0; + } + constexpr bool isJustInfo( int flags ) { return flags == ResultWas::Info; } // ResultDisposition::Flags enum @@ -832,11 +838,18 @@ namespace Catch { SuppressFail = 0x08 // Failures are reported but do not fail the test }; }; - ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ); + constexpr ResultDisposition::Flags operator|( ResultDisposition::Flags lhs, + ResultDisposition::Flags rhs ) { + return static_cast( static_cast( lhs ) | + static_cast( rhs ) ); + } - bool shouldContinueOnFailure( int flags ); - inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } - bool shouldSuppressFailure( int flags ); + constexpr bool isFalseTest( int flags ) { + return ( flags & ResultDisposition::FalseTest ) != 0; + } + constexpr bool shouldSuppressFailure( int flags ) { + return ( flags & ResultDisposition::SuppressFail ) != 0; + } } // end namespace Catch @@ -1054,7 +1067,7 @@ namespace Catch { virtual void handleMessage ( AssertionInfo const& info, ResultWas::OfType resultType, - StringRef message, + std::string&& message, AssertionReaction& reaction ) = 0; virtual void handleUnexpectedExceptionNotThrown ( AssertionInfo const& info, @@ -1302,7 +1315,7 @@ namespace Catch { int high_mild = 0; // 1.5 to 3 times IQR above Q3 int high_severe = 0; // more than 3 times IQR above Q3 - int total() const { + constexpr int total() const { return low_severe + low_mild + high_mild + high_severe; } }; @@ -3267,13 +3280,13 @@ namespace Catch { ITransientExpression const* m_transientExpression = nullptr; bool m_isNegated; public: - LazyExpression( bool isNegated ): + constexpr LazyExpression( bool isNegated ): m_isNegated(isNegated) {} - LazyExpression(LazyExpression const& other) = default; + constexpr LazyExpression(LazyExpression const& other) = default; LazyExpression& operator = ( LazyExpression const& ) = delete; - explicit operator bool() const { + constexpr explicit operator bool() const { return m_transientExpression != nullptr; } @@ -4012,7 +4025,7 @@ namespace Catch { do { \ Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \ catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + catchAssertionHandler.complete(); \ } while( false ) /////////////////////////////////////////////////////////////////////////////// @@ -5272,6 +5285,9 @@ namespace Catch { bool m_isBinaryExpression; bool m_result; + protected: + ~ITransientExpression() = default; + public: constexpr auto isBinaryExpression() const -> bool { return m_isBinaryExpression; } constexpr auto getResult() const -> bool { return m_result; } @@ -5283,17 +5299,13 @@ namespace Catch { m_result( result ) {} - ITransientExpression() = default; - ITransientExpression(ITransientExpression const&) = default; - ITransientExpression& operator=(ITransientExpression const&) = default; + constexpr ITransientExpression( ITransientExpression const& ) = default; + constexpr ITransientExpression& operator=( ITransientExpression const& ) = default; friend std::ostream& operator<<(std::ostream& out, ITransientExpression const& expr) { expr.streamReconstructedExpression(out); return out; } - - protected: - ~ITransientExpression() = default; }; void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ); @@ -5602,12 +5614,12 @@ namespace Catch { template - void handleExpr( ExprLhs const& expr ) { + constexpr void handleExpr( ExprLhs const& expr ) { handleExpr( expr.makeUnaryExpr() ); } void handleExpr( ITransientExpression const& expr ); - void handleMessage(ResultWas::OfType resultType, StringRef message); + void handleMessage(ResultWas::OfType resultType, std::string&& message); void handleExceptionThrownAsExpected(); void handleUnexpectedExceptionNotThrown(); @@ -5663,8 +5675,6 @@ namespace Catch { #endif -#define INTERNAL_CATCH_REACT( handler ) handler.complete(); - /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ do { /* NOLINT(bugprone-infinite-loop) */ \ @@ -5677,7 +5687,7 @@ namespace Catch { catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); /* NOLINT(bugprone-chained-comparison) */ \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + catchAssertionHandler.complete(); \ } while( (void)0, (false) && static_cast( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. @@ -5705,7 +5715,7 @@ namespace Catch { catch( ... ) { \ catchAssertionHandler.handleUnexpectedInflightException(); \ } \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + catchAssertionHandler.complete(); \ } while( false ) /////////////////////////////////////////////////////////////////////////////// @@ -5726,7 +5736,7 @@ namespace Catch { } \ else \ catchAssertionHandler.handleThrowingCallSkipped(); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + catchAssertionHandler.complete(); \ } while( false ) /////////////////////////////////////////////////////////////////////////////// @@ -5750,7 +5760,7 @@ namespace Catch { } \ else \ catchAssertionHandler.handleThrowingCallSkipped(); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + catchAssertionHandler.complete(); \ } while( false ) @@ -5774,7 +5784,7 @@ namespace Catch { } \ else \ catchAssertionHandler.handleThrowingCallSkipped(); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + catchAssertionHandler.complete(); \ } while( false ) #endif // CATCH_CONFIG_DISABLE @@ -5975,7 +5985,8 @@ template class TestInvokerAsMethod : public ITestInvoker { void (C::*m_testAsMethod)(); public: - TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {} + constexpr TestInvokerAsMethod( void ( C::*testAsMethod )() ) noexcept: + m_testAsMethod( testAsMethod ) {} void invoke() const override { C obj; @@ -5996,7 +6007,8 @@ class TestInvokerFixture : public ITestInvoker { Detail::unique_ptr m_fixture = nullptr; public: - TestInvokerFixture( void ( C::*testAsMethod )() const) noexcept : m_testAsMethod( testAsMethod ) {} + constexpr TestInvokerFixture( void ( C::*testAsMethod )() const ) noexcept: + m_testAsMethod( testAsMethod ) {} void prepareTestCase() override { m_fixture = Detail::make_unique(); @@ -7136,7 +7148,7 @@ namespace Catch { TestCaseInfo* m_info; ITestInvoker* m_invoker; public: - TestCaseHandle(TestCaseInfo* info, ITestInvoker* invoker) : + constexpr TestCaseHandle(TestCaseInfo* info, ITestInvoker* invoker) : m_info(info), m_invoker(invoker) {} void prepareTestCase() const { @@ -7151,7 +7163,9 @@ namespace Catch { m_invoker->invoke(); } - TestCaseInfo const& getTestCaseInfo() const; + constexpr TestCaseInfo const& getTestCaseInfo() const { + return *m_info; + } }; Detail::unique_ptr @@ -7214,7 +7228,7 @@ namespace Catch { class ExceptionTranslator : public IExceptionTranslator { public: - ExceptionTranslator( std::string(*translateFunction)( T const& ) ) + constexpr ExceptionTranslator( std::string(*translateFunction)( T const& ) ) : m_translateFunction( translateFunction ) {} @@ -7316,7 +7330,7 @@ namespace Catch { #define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MINOR 7 -#define CATCH_VERSION_PATCH 0 +#define CATCH_VERSION_PATCH 1 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED @@ -8043,7 +8057,7 @@ namespace Catch { struct ExtendedMultResult { T upper; T lower; - bool operator==( ExtendedMultResult const& rhs ) const { + constexpr bool operator==( ExtendedMultResult const& rhs ) const { return upper == rhs.upper && lower == rhs.lower; } }; @@ -8161,6 +8175,7 @@ namespace Catch { * get by simple casting ([0, ..., INT_MAX, INT_MIN, ..., -1]) */ template + constexpr std::enable_if_t::value, UnsignedType> transposeToNaturalOrder( UnsignedType in ) { static_assert( @@ -8181,6 +8196,7 @@ namespace Catch { template + constexpr std::enable_if_t::value, UnsignedType> transposeToNaturalOrder(UnsignedType in) { static_assert( @@ -8232,24 +8248,24 @@ class uniform_integer_distribution { // distribution will be reused many times and this is an optimization. UnsignedIntegerType m_rejection_threshold = 0; - UnsignedIntegerType computeDistance(IntegerType a, IntegerType b) const { + static constexpr UnsignedIntegerType computeDistance(IntegerType a, IntegerType b) { // This overflows and returns 0 if a == 0 and b == TYPE_MAX. // We handle that later when generating the number. return transposeTo(b) - transposeTo(a) + 1; } - static UnsignedIntegerType computeRejectionThreshold(UnsignedIntegerType ab_distance) { + static constexpr UnsignedIntegerType computeRejectionThreshold(UnsignedIntegerType ab_distance) { // distance == 0 means that we will return all possible values from // the type's range, and that we shouldn't reject anything. if ( ab_distance == 0 ) { return 0; } return ( ~ab_distance + 1 ) % ab_distance; } - static UnsignedIntegerType transposeTo(IntegerType in) { + static constexpr UnsignedIntegerType transposeTo(IntegerType in) { return Detail::transposeToNaturalOrder( static_cast( in ) ); } - static IntegerType transposeBack(UnsignedIntegerType in) { + static constexpr IntegerType transposeBack(UnsignedIntegerType in) { return static_cast( Detail::transposeToNaturalOrder(in) ); } @@ -8257,7 +8273,7 @@ class uniform_integer_distribution { public: using result_type = IntegerType; - uniform_integer_distribution( IntegerType a, IntegerType b ): + constexpr uniform_integer_distribution( IntegerType a, IntegerType b ): m_a( transposeTo(a) ), m_ab_distance( computeDistance(a, b) ), m_rejection_threshold( computeRejectionThreshold(m_ab_distance) ) { @@ -8265,7 +8281,7 @@ public: } template - result_type operator()( Generator& g ) { + constexpr result_type operator()( Generator& g ) { // All possible values of result_type are valid. if ( m_ab_distance == 0 ) { return transposeBack( Detail::fillBitsFrom( g ) ); @@ -8283,8 +8299,8 @@ public: return transposeBack(m_a + emul.upper); } - result_type a() const { return transposeBack(m_a); } - result_type b() const { return transposeBack(m_ab_distance + m_a - 1); } + constexpr result_type a() const { return transposeBack(m_a); } + constexpr result_type b() const { return transposeBack(m_ab_distance + m_a - 1); } }; } // end namespace Catch @@ -9742,6 +9758,7 @@ namespace Catch { typename Sentinel, typename T, typename Comparator> + constexpr ForwardIter find_sentinel( ForwardIter start, Sentinel sentinel, T const& value, @@ -9757,6 +9774,7 @@ namespace Catch { typename Sentinel, typename T, typename Comparator> + constexpr std::ptrdiff_t count_sentinel( ForwardIter start, Sentinel sentinel, T const& value, @@ -9770,6 +9788,7 @@ namespace Catch { } template + constexpr std::enable_if_t::value, std::ptrdiff_t> sentinel_distance( ForwardIter iter, const Sentinel sentinel ) { @@ -9782,8 +9801,8 @@ namespace Catch { } template - std::ptrdiff_t sentinel_distance( ForwardIter first, - ForwardIter last ) { + constexpr std::ptrdiff_t sentinel_distance( ForwardIter first, + ForwardIter last ) { return std::distance( first, last ); } @@ -9792,11 +9811,11 @@ namespace Catch { typename ForwardIter2, typename Sentinel2, typename Comparator> - bool check_element_counts( ForwardIter1 first_1, - const Sentinel1 end_1, - ForwardIter2 first_2, - const Sentinel2 end_2, - Comparator cmp ) { + constexpr bool check_element_counts( ForwardIter1 first_1, + const Sentinel1 end_1, + ForwardIter2 first_2, + const Sentinel2 end_2, + Comparator cmp ) { auto cursor = first_1; while ( cursor != end_1 ) { if ( find_sentinel( first_1, cursor, *cursor, cmp ) == @@ -9826,11 +9845,11 @@ namespace Catch { typename ForwardIter2, typename Sentinel2, typename Comparator> - bool is_permutation( ForwardIter1 first_1, - const Sentinel1 end_1, - ForwardIter2 first_2, - const Sentinel2 end_2, - Comparator cmp ) { + constexpr bool is_permutation( ForwardIter1 first_1, + const Sentinel1 end_1, + ForwardIter2 first_2, + const Sentinel2 end_2, + Comparator cmp ) { // TODO: no optimization for stronger iterators, because we would also have to constrain on sentinel vs not sentinel types // TODO: Comparator has to be "both sides", e.g. a == b => b == a // This skips shared prefix of the two ranges @@ -10486,7 +10505,7 @@ namespace Catch { void handleMessage ( AssertionInfo const& info, ResultWas::OfType resultType, - StringRef message, + std::string&& message, AssertionReaction& reaction ) override; void handleUnexpectedExceptionNotThrown ( AssertionInfo const& info, @@ -11271,16 +11290,25 @@ namespace Catch { #include #include +#include namespace Catch { - enum class XmlFormatting { + enum class XmlFormatting : std::uint8_t { None = 0x00, Indent = 0x01, Newline = 0x02, }; - XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs); - XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs); + constexpr XmlFormatting operator|( XmlFormatting lhs, XmlFormatting rhs ) { + return static_cast( static_cast( lhs ) | + static_cast( rhs ) ); + } + + constexpr XmlFormatting operator&( XmlFormatting lhs, XmlFormatting rhs ) { + return static_cast( static_cast( lhs ) & + static_cast( rhs ) ); + } + /** * Helper for XML-encoding text (escaping angle brackets, quotes, etc) @@ -11292,7 +11320,9 @@ namespace Catch { public: enum ForWhat { ForTextNodes, ForAttributes }; - XmlEncode( StringRef str, ForWhat forWhat = ForTextNodes ); + constexpr XmlEncode( StringRef str, ForWhat forWhat = ForTextNodes ): + m_str( str ), m_forWhat( forWhat ) {} + void encodeTo( std::ostream& os ) const; @@ -11455,7 +11485,7 @@ namespace Catch { ArgT && m_arg; MatcherT const& m_matcher; public: - MatchExpr( ArgT && arg, MatcherT const& matcher ) + constexpr MatchExpr( ArgT && arg, MatcherT const& matcher ) : ITransientExpression{ true, matcher.match( arg ) }, // not forwarding arg here on purpose m_arg( CATCH_FORWARD(arg) ), m_matcher( matcher ) @@ -11485,7 +11515,8 @@ namespace Catch { void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher ); template - auto makeMatchExpr( ArgT && arg, MatcherT const& matcher ) -> MatchExpr { + constexpr MatchExpr + makeMatchExpr( ArgT&& arg, MatcherT const& matcher ) { return MatchExpr( CATCH_FORWARD(arg), matcher ); } @@ -11499,7 +11530,7 @@ namespace Catch { INTERNAL_CATCH_TRY { \ catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher ) ); \ } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + catchAssertionHandler.complete(); \ } while( false ) @@ -11509,7 +11540,10 @@ namespace Catch { Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ if( catchAssertionHandler.allowThrows() ) \ try { \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \ static_cast(__VA_ARGS__ ); \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ } \ catch( exceptionType const& ex ) { \ @@ -11520,7 +11554,7 @@ namespace Catch { } \ else \ catchAssertionHandler.handleThrowingCallSkipped(); \ - INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + catchAssertionHandler.complete(); \ } while( false ) @@ -12589,12 +12623,14 @@ namespace Catch { public: template + constexpr RangeEqualsMatcher( TargetRangeLike2&& range, Equality2&& predicate ): m_desired( CATCH_FORWARD( range ) ), m_predicate( CATCH_FORWARD( predicate ) ) {} template + constexpr bool match( RangeLike&& rng ) const { auto rng_start = begin( rng ); const auto rng_end = end( rng ); @@ -12627,12 +12663,14 @@ namespace Catch { public: template + constexpr UnorderedRangeEqualsMatcher( TargetRangeLike2&& range, Equality2&& predicate ): m_desired( CATCH_FORWARD( range ) ), m_predicate( CATCH_FORWARD( predicate ) ) {} template + constexpr bool match( RangeLike&& rng ) const { using std::begin; using std::end; @@ -12656,6 +12694,7 @@ namespace Catch { * Uses `std::equal_to` to do the comparison */ template + constexpr std::enable_if_t::value, RangeEqualsMatcher>> RangeEquals( RangeLike&& range ) { @@ -12669,6 +12708,7 @@ namespace Catch { * Uses to provided predicate `predicate` to do the comparisons */ template + constexpr RangeEqualsMatcher RangeEquals( RangeLike&& range, Equality&& predicate ) { return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) }; @@ -12681,6 +12721,7 @@ namespace Catch { * Uses `std::equal_to` to do the comparison */ template + constexpr std::enable_if_t< !Detail::is_matcher::value, UnorderedRangeEqualsMatcher>> @@ -12695,6 +12736,7 @@ namespace Catch { * Uses to provided predicate `predicate` to do the comparisons */ template + constexpr UnorderedRangeEqualsMatcher UnorderedRangeEquals( RangeLike&& range, Equality&& predicate ) { return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) }; @@ -13869,7 +13911,7 @@ namespace Catch { : CumulativeReporterBase(CATCH_MOVE(config)) , xml(m_stream) { m_preferences.shouldRedirectStdOut = true; - m_preferences.shouldReportAllAssertions = true; + m_preferences.shouldReportAllAssertions = false; m_shouldStoreSuccesfulAssertions = false; } diff --git a/meson.build b/meson.build index c7b91bca..99bf3aff 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project( 'catch2', 'cpp', - version: '3.7.0', # CML version placeholder, don't delete + version: '3.7.1', # CML version placeholder, don't delete license: 'BSL-1.0', meson_version: '>=0.54.1', ) diff --git a/src/catch2/catch_version.cpp b/src/catch2/catch_version.cpp index 44560fe0..1701f3ad 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, 7, 0, "", 0 ); + static Version version( 3, 7, 1, "", 0 ); return version; } diff --git a/src/catch2/catch_version_macros.hpp b/src/catch2/catch_version_macros.hpp index 10a63ad0..88b5d0d0 100644 --- a/src/catch2/catch_version_macros.hpp +++ b/src/catch2/catch_version_macros.hpp @@ -10,6 +10,6 @@ #define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MINOR 7 -#define CATCH_VERSION_PATCH 0 +#define CATCH_VERSION_PATCH 1 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED