diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9bd7e01d67..7bad26c3ac 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 77ab7aaf2f..5f2d92ae91 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 4178e32899..f45c18a011 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 968aeb8d1e..b7c768b8d5 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 @@ class uniform_integer_distribution {
}
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 @@ class uniform_integer_distribution {
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 c7b91bca49..99bf3aff31 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 44560fe0fc..1701f3adf5 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 10a63ad003..88b5d0d02b 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