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

summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLeitwolf2026-10-11 10:09:19 +0300
committerGitHub2026-10-11 10:09:19 +0300
commitce6fa1996a8e358efdcff53a7628584077d9855c (patch)
treed76f5945311828511e3ea55712487f21fbf8f70f
parent5633c5c98ec073ae938253bcfc72430d5d9aee89 (diff)
parent1f78d8903c2fb18afea8c3055f8df83d8c60d9b5 (diff)
downloadcatch3-ce6fa1996a8e358efdcff53a7628584077d9855c.tar.gz
Merge pull request #4 from Progmasoft/backport/upstream-3.16.1
Backport Catch2 3.16.1
-rw-r--r--.github/workflows/mac-builds.yml2
-rw-r--r--CMakeLists.txt2
-rw-r--r--README.md2
-rw-r--r--docs/deprecations.md10
-rw-r--r--docs/release-notes.md35
-rw-r--r--docs/upstream-status.md27
-rw-r--r--docs/why-catch3.md4
-rw-r--r--extras/catch_amalgamated.cpp96
-rw-r--r--extras/catch_amalgamated.hpp451
-rw-r--r--meson.build2
-rw-r--r--src/catch2/benchmark/catch_optimizer.hpp2
-rw-r--r--src/catch2/catch_session.cpp12
-rw-r--r--src/catch2/catch_session.hpp1
-rw-r--r--src/catch2/catch_version.cpp2
-rw-r--r--src/catch2/catch_version_macros.hpp2
-rw-r--r--src/catch2/internal/catch_assertion_handler.cpp2
-rw-r--r--src/catch2/internal/catch_assertion_handler.hpp15
-rw-r--r--src/catch2/internal/catch_decomposer.cpp7
-rw-r--r--src/catch2/internal/catch_decomposer.hpp342
-rw-r--r--src/catch2/internal/catch_preprocessor.hpp4
-rw-r--r--src/catch2/internal/catch_test_macro_impl.hpp16
-rw-r--r--src/catch2/matchers/internal/catch_matchers_impl.hpp17
-rw-r--r--src/catch2/reporters/catch_reporter_automake.cpp9
-rw-r--r--src/catch2/reporters/catch_reporter_automake.hpp6
-rw-r--r--src/catch2/reporters/catch_reporter_compact.cpp7
-rw-r--r--src/catch2/reporters/catch_reporter_compact.hpp6
-rw-r--r--src/catch2/reporters/catch_reporter_console.cpp1
-rw-r--r--src/catch2/reporters/catch_reporter_helpers.cpp13
-rw-r--r--src/catch2/reporters/catch_reporter_helpers.hpp13
-rw-r--r--src/catch2/reporters/catch_reporter_json.cpp2
-rw-r--r--src/catch2/reporters/catch_reporter_junit.cpp4
-rw-r--r--src/catch2/reporters/catch_reporter_sonarqube.cpp10
-rw-r--r--src/catch2/reporters/catch_reporter_sonarqube.hpp9
-rw-r--r--src/catch2/reporters/catch_reporter_tap.cpp8
-rw-r--r--src/catch2/reporters/catch_reporter_tap.hpp6
-rw-r--r--src/catch2/reporters/catch_reporter_teamcity.cpp8
-rw-r--r--src/catch2/reporters/catch_reporter_teamcity.hpp8
-rw-r--r--src/catch2/reporters/catch_reporter_xml.cpp2
-rw-r--r--tests/ExtraTests/CMakeLists.txt35
-rw-r--r--tests/ExtraTests/X38-ThrowingReporter.cpp79
-rw-r--r--tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp14
-rw-r--r--xmake.lua2
42 files changed, 840 insertions, 455 deletions
diff --git a/.github/workflows/mac-builds.yml b/.github/workflows/mac-builds.yml
index 7ba8dac5..7162646b 100644
--- a/.github/workflows/mac-builds.yml
+++ b/.github/workflows/mac-builds.yml
@@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- image: [macos-14, macos-15, macos-15-intel]
+ image: [macos-15, macos-15-intel]
build_type: [Debug, Release]
std: [14, 17]
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 291af7c5..a8f1da6d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,7 +35,7 @@ if(CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
endif()
project(Catch2
- VERSION 3.16.0 # CML version placeholder, don't delete
+ VERSION 3.16.1 # CML version placeholder, don't delete
LANGUAGES CXX
HOMEPAGE_URL "https://github.com/catchorg/Catch2"
DESCRIPTION "A modern, C++-native, unit test framework."
diff --git a/README.md b/README.md
index fae1e037..d1ef75e0 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ owned C++20 library for property checks, snapshots, structured results, and XML
serialization.
> Catch3 is not an official Catch2 release and is not endorsed by Catch2's
-> maintainers. Its current compatibility engine is based on Catch2 3.16.0;
+> maintainers. Its current compatibility engine is based on Catch2 3.16.1;
> upstream-originated files keep their upstream license. Progmasoft-authored
> additions have their own licensing terms. See [the project scope and
> compatibility notes](docs/why-catch3.md).
diff --git a/docs/deprecations.md b/docs/deprecations.md
index 3915ddbc..82f044cc 100644
--- a/docs/deprecations.md
+++ b/docs/deprecations.md
@@ -62,6 +62,16 @@ specified the filters through the new `-p/--path-filter` parameter, which
means that generators are taken into account.
+### Reporter event handling functions without noexcept
+
+> Deprecated in Catch2 3.16.1
+
+Catch2 does not try to support reporters throwing from arbitrary
+`fooStarting` or `fooEnded` test running event. For legacy reasons, the
+event listener interface is declared without `noexcept`, but in the future
+it will be changed to use `noexcept` to make this limitation explicit.
+
+
### Generator interfaces
#### Defaulted `UntypedGeneratorBase::isFinite()`
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 3a2c7734..2ba3b663 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -5,6 +5,7 @@
# Release notes
**Contents**<br>
+[3.16.1](#3161)<br>
[3.16.0](#3160)<br>
[3.15.3](#3153)<br>
[3.15.2](#3152)<br>
@@ -82,6 +83,40 @@
[Even Older versions](#even-older-versions)<br>
+## 3.16.1
+
+### Fixes
+* Fixed optimizations being disabled after including benchmarking headers under MSVC. (#3212)
+ * This was introduced in 3.16.0's fix for the deopt implementation for MSVC never being used.
+* Fixed Console reporter replacing `\0xFF`s in user-provided strings.
+* Added missing `<cassert>` include to `catch_generators_range.hpp`. (#3205)
+
+### Improvements
+* Workaround for GCC's quadratic scaling for release builds with number of test cases.
+ * In practice the improvement is only noticeable with unity builds and/or template product tests.
+* Changed how decomposer operators are defined for better compilation times.
+ * For Catch2's `SelfTest` binary, this provides ~2% build time improvement.
+* Changed how decomposer handles stringification for smaller binary sizes.
+ * For the `SelfTest` binary this is about ~8%.
+* Improved compilation costs of multiple assertions in one test cases for release builds.
+* Optimized initial test registration at process start:
+ * Fewer allocations for test cases with many tags.
+ * Faster processing for test cases with <=2 tags.
+ * Faster tag validation.
+ * Faster checking for duplicated test cases.
+* Optimized test selection and filtering:
+* Optimized filtering tests by test name.
+ * Running `SelfTest` with `abc*` as the filter pattern is ~10% faster.
+
+### Miscellaneous
+* `catch_discover_tests` registers individual tests with `--order decl` for faster startup.
+ * For `SelfTest`, this provides 20% improvement in Debug and 5% in Release builds.
+* `CMakeConfig::` family of tests use the main build's toolchain file. (#3202)
+* Deprecated throwing exceptions from the reporter interface functions.
+ * Previously, throwing from e.g. `assertionEnded` might, or might not, have worked depending on which assertion has ended. As it is not practical for Catch2 to guard against the reporters failing randomly, and marking so with `noexcept` can provide compilation throughput improvements, I decided to fully forbid it.
+ * Reporter constructors are allowed to throw and the test binary will report the error nicely before exiting.
+ * Due to C++ limitations, this deprecation cannot be marked inside the code, only in docs.
+
## 3.16.0
diff --git a/docs/upstream-status.md b/docs/upstream-status.md
index 99182ad7..ac87b654 100644
--- a/docs/upstream-status.md
+++ b/docs/upstream-status.md
@@ -13,6 +13,33 @@ licenses or compiler options:
- `222e233903d287cda4713fb08e1a959e8d71fd6d`: isolate Clang's pointer-to-bool
diagnostic at the upstream reusable-string-stream compatibility boundary.
+The branch was reviewed again through
+`08092139210881f01a34e60c5f2fd6afa0ea4024`, the commit of Catch2 3.16.1, on
+2026-10-11. The eleven changes since the previous reviewed revision were all
+backported, in upstream order, and the compatibility engine is now 3.16.1:
+
+- `d7683484`: a better message when a reporter cannot be initialized.
+- `ea5020f0`: every first-party reporter validates its custom arguments.
+- `aa01559e`: the throwing-reporter test also throws in `assertionEnded`.
+- `45cd3987`: `handleUnexpectedInflightException` is `noexcept`.
+- `6adbd539`: MSVC optimizations are enabled again after the benchmark
+ headers (upstream issue 3212).
+- `e87f2882`: test registration with non-type template parameters no longer
+ scales quadratically.
+- `73d546cd`: `REQUIRE` expands its arguments fewer times under GCC and
+ Clang.
+- `b710039a`: the decomposer operators are plain functions and no longer
+ hidden friends.
+- `f899467b`: streaming of reconstructed expressions is type-erased.
+- `8f0e70ca`: the retired `macos-14` runner is dropped from the macOS builds.
+- `08092139`: version 3.16.1, with its release notes.
+
+Each applied without a conflict in the sources. The amalgamated distribution
+under `extras/` did conflict, because it is generated; it was generated again
+from the sources of this repository with `generateAmalgamatedFiles.py`, which
+also brought it up to date with fork changes it had not yet picked up. No
+fork-owned file under `src/Progmasoft` needed a change.
+
These are compatibility fixes, not a claim that every future upstream change
is automatically incorporated. The existing Windows/macOS build and test
workflows remain the verification gate for the fork.
diff --git a/docs/why-catch3.md b/docs/why-catch3.md
index 7fbeef44..8c900ac7 100644
--- a/docs/why-catch3.md
+++ b/docs/why-catch3.md
@@ -7,7 +7,7 @@ namespace, build-target, and licensing boundary.
The name does **not** mean that this is an official Catch2 v3 release, a new
upstream version, or a project endorsed by Catch2's maintainers. The current
-compatibility engine is based on Catch2's 3.16.0 development line. The project
+compatibility engine is based on Catch2's 3.16.1 development line. The project
is still early-stage and does not yet replace or independently reimplement the
Catch2 runner.
@@ -35,7 +35,7 @@ Catch2's `Catch` namespace, established headers, macros, command-line behavior,
reporters, and coding style remain the compatibility surface. Progmasoft
features should be added under `Progmasoft::Catch3` and must not require users
to rename existing Catch2 tests. The first compatibility goal is source-level
-continuity with the included Catch2 3.16.0 base; this is not a promise that every
+continuity with the included Catch2 3.16.1 base; this is not a promise that every
future Catch2 upstream change will be adopted unchanged or that all downstream
projects have already been validated.
diff --git a/extras/catch_amalgamated.cpp b/extras/catch_amalgamated.cpp
index c6a8de36..230849f1 100644
--- a/extras/catch_amalgamated.cpp
+++ b/extras/catch_amalgamated.cpp
@@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.16.0
-// Generated: 2026-09-28 00:12:28.744397
+// Catch v3.16.1
+// Generated: 2026-10-11 02:09:25.622664
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -1458,7 +1458,9 @@ namespace Catch {
int err = 0;
std::FILE* const file = openGuardFile( guardFilePath, err );
if ( file == nullptr ) {
+#if defined( _MSC_VER )
char msgBuffer[100] = {};
+#endif
std::string errMsg;
#if defined( _MSC_VER )
if ( !strerror_s( msgBuffer, err ) ) {
@@ -1677,7 +1679,17 @@ namespace Catch {
getCurrentMutableContext().setConfig(m_config.get());
// Create reporter(s) so we can route listings through them
- auto reporter = prepareReporters(m_config.get());
+ IEventListenerPtr reporter;
+ CATCH_TRY {
+ auto reporter_ = prepareReporters( m_config.get() );
+ swap( reporter, reporter_ );
+ }
+#if !defined( CATCH_CONFIG_DISABLE_EXCEPTIONS )
+ catch ( std::exception& ex ) {
+ Catch::cerr() << "Error when creating reporter: " << ex.what() << '\n' << std::flush;
+ return ReporterConstructionErrorExitCode;
+ }
+#endif
auto const& invalidSpecs = m_config->testSpec().getInvalidSpecs();
if ( !invalidSpecs.empty() ) {
@@ -2586,7 +2598,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 3, 16, 0, "", 0 );
+ static Version version( 3, 16, 1, "", 0 );
return version;
}
@@ -2922,7 +2934,7 @@ namespace Catch {
}
}
- void AssertionHandler::handleUnexpectedInflightException() {
+ void AssertionHandler::handleUnexpectedInflightException() noexcept {
m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );
}
@@ -4234,13 +4246,6 @@ namespace Catch {
namespace Catch {
- void ITransientExpression::streamReconstructedExpression(
- std::ostream& os ) const {
- // We can't make this function pure virtual to keep ITransientExpression
- // constexpr, so we write error message instead
- os << "Some class derived from ITransientExpression without overriding streamReconstructedExpression";
- }
-
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 &&
@@ -6056,6 +6061,7 @@ ReporterSpec::ReporterSpec(
#include <cstdio>
+#include <list>
#include <sstream>
#include <tuple>
#include <vector>
@@ -6065,7 +6071,10 @@ namespace Catch {
// This class encapsulates the idea of a pool of ostringstreams that can be reused.
struct StringStreams {
std::vector<Detail::unique_ptr<std::ostringstream>> m_streams;
- std::vector<std::size_t> m_unused;
+ // The library can be linked into ASan-instrumented clients without
+ // instrumenting Catch3 itself. A list avoids mixed-mode libc++ vector
+ // container annotations for the reusable-index pool.
+ std::list<std::size_t> m_unused;
std::ostringstream m_referenceStream; // Used for copy state/ flags from
Detail::Mutex m_mutex;
@@ -9530,12 +9539,20 @@ namespace Catch {
+
#include <ostream>
namespace Catch {
AutomakeReporter::~AutomakeReporter() = default;
+ AutomakeReporter::AutomakeReporter( ReporterConfig&& _config ):
+ StreamingReporterBase( CATCH_MOVE( _config ) ) {
+ rejectSuperfluousConfigKeys( m_customOptions, {} );
+
+ m_preferences.shouldReportAllAssertionStarts = false;
+ }
+
void AutomakeReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
// Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR.
m_stream << ":test-result: ";
@@ -9837,6 +9854,13 @@ private:
}
CompactReporter::~CompactReporter() = default;
+ CompactReporter::CompactReporter( ReporterConfig&& _config ):
+ StreamingReporterBase( CATCH_MOVE( _config ) ) {
+ rejectSuperfluousConfigKeys( m_customOptions, {} );
+
+ m_preferences.shouldReportAllAssertionStarts = false;
+ }
+
} // end namespace Catch
@@ -10224,6 +10248,7 @@ ConsoleReporter::ConsoleReporter(ReporterConfig&& config):
};
}
}())) {
+ rejectSuperfluousConfigKeys( m_customOptions, {} );
m_preferences.shouldReportAllAssertionStarts = false;
}
@@ -11037,6 +11062,18 @@ namespace Catch {
printSummaryRow( stream, streamColour, "assertions"_sr, columns, 1 );
}
+ void rejectSuperfluousConfigKeys(
+ std::map<std::string, std::string> const& options,
+ std::initializer_list<StringRef> knownKeys ) {
+ for ( auto const& option : options ) {
+ StringRef key( option.first );
+ CATCH_ENFORCE( std::find( knownKeys.begin(),
+ knownKeys.end(),
+ key ) != knownKeys.end(),
+ "Unknown reporter argument: " << key );
+ }
+ }
+
} // namespace Catch
@@ -11075,6 +11112,7 @@ namespace Catch {
JsonReporter::JsonReporter( ReporterConfig&& config ):
StreamingReporterBase{ CATCH_MOVE( config ) } {
+ rejectSuperfluousConfigKeys( m_customOptions, {} );
m_preferences.shouldRedirectStdOut = true;
// TBD: Do we want to report all assertions? XML reporter does
@@ -11480,11 +11518,13 @@ namespace Catch {
: CumulativeReporterBase( CATCH_MOVE(_config) ),
xml( m_stream )
{
+ rejectSuperfluousConfigKeys( m_customOptions, {} );
+
m_preferences.shouldRedirectStdOut = true;
m_preferences.shouldReportAllAssertions = false;
m_preferences.shouldReportAllAssertionStarts = false;
m_shouldStoreSuccesfulAssertions = false;
- }
+ }
std::string JunitReporter::getDescription() {
return "Reports test results in an XML format that looks like Ant's junitreport target";
@@ -11947,6 +11987,16 @@ namespace Catch {
}
}
+ SonarQubeReporter::SonarQubeReporter( ReporterConfig&& config ):
+ CumulativeReporterBase( CATCH_MOVE( config ) ), xml( m_stream ) {
+ rejectSuperfluousConfigKeys( m_customOptions, {} );
+
+ m_preferences.shouldRedirectStdOut = true;
+ m_preferences.shouldReportAllAssertions = false;
+ m_preferences.shouldReportAllAssertionStarts = false;
+ m_shouldStoreSuccesfulAssertions = false;
+ }
+
void SonarQubeReporter::testRunStarting(TestRunInfo const& testRunInfo) {
CumulativeReporterBase::testRunStarting(testRunInfo);
@@ -12275,6 +12325,14 @@ namespace Catch {
} // End anonymous namespace
+ TAPReporter::TAPReporter( ReporterConfig&& config ):
+ StreamingReporterBase( CATCH_MOVE( config ) ) {
+ rejectSuperfluousConfigKeys( m_customOptions, {} );
+
+ m_preferences.shouldReportAllAssertions = true;
+ m_preferences.shouldReportAllAssertionStarts = false;
+ }
+
void TAPReporter::testRunStarting( TestRunInfo const& ) {
if ( m_config->testSpec().hasFilters() ) {
m_stream << "# filters: " << m_config->testSpec() << '\n';
@@ -12346,6 +12404,14 @@ namespace Catch {
} // end anonymous namespace
+ TeamCityReporter::TeamCityReporter( ReporterConfig&& _config ):
+ StreamingReporterBase( CATCH_MOVE( _config ) ) {
+ rejectSuperfluousConfigKeys( m_customOptions, {} );
+
+ m_preferences.shouldRedirectStdOut = true;
+ m_preferences.shouldReportAllAssertionStarts = false;
+ }
+
TeamCityReporter::~TeamCityReporter() = default;
void TeamCityReporter::testRunStarting( TestRunInfo const& runInfo ) {
@@ -12492,6 +12558,8 @@ namespace Catch {
: StreamingReporterBase( CATCH_MOVE(_config) ),
m_xml(m_stream)
{
+ rejectSuperfluousConfigKeys( m_customOptions, {} );
+
m_preferences.shouldRedirectStdOut = true;
m_preferences.shouldReportAllAssertions = true;
m_preferences.shouldReportAllAssertionStarts = false;
diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp
index 29279da0..25207b85 100644
--- a/extras/catch_amalgamated.hpp
+++ b/extras/catch_amalgamated.hpp
@@ -6,8 +6,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.16.0
-// Generated: 2026-09-28 00:12:28.337654
+// Catch v3.16.1
+// Generated: 2026-10-11 02:09:25.452537
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -1520,7 +1520,7 @@ namespace Catch {
*reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);
}
// TODO equivalent keep_memory()
-#if defined(_MSVC_VER)
+#if defined(_MSC_VER)
#pragma optimize("", on)
#endif
@@ -2513,6 +2513,9 @@ namespace Catch {
// be null...
#pragma GCC diagnostic ignored "-Waddress"
#pragma GCC diagnostic ignored "-Wnonnull-compare"
+#elif defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpointer-bool-conversion"
#endif
template<typename T>
@@ -2523,6 +2526,8 @@ namespace Catch {
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
+#elif defined(__clang__)
+#pragma clang diagnostic pop
#endif
auto get() -> std::ostream& { return *m_oss; }
};
@@ -5130,6 +5135,7 @@ namespace Catch {
constexpr int UnmatchedTestSpecExitCode = 3;
constexpr int AllTestsSkippedExitCode = 4;
constexpr int InvalidTestSpecExitCode = 5;
+ constexpr int ReporterConstructionErrorExitCode = 6;
constexpr int TestFailureExitCode = 42;
class Session : Detail::NonCopyable {
@@ -5531,28 +5537,27 @@ namespace Catch {
struct always_false : std::false_type {};
class ITransientExpression {
+ //! Type-erased streaming function for the derived expression
+ using StreamFn = void ( * )( void const*, std::ostream& );
+
+ StreamFn m_streamFn;
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; }
- //! This function **has** to be overridden by the derived class.
- virtual void streamReconstructedExpression( std::ostream& os ) const;
- constexpr ITransientExpression( bool isBinaryExpression, bool result )
- : m_isBinaryExpression( isBinaryExpression ),
- m_result( result )
- {}
-
- constexpr ITransientExpression( ITransientExpression const& ) = default;
- constexpr ITransientExpression& operator=( ITransientExpression const& ) = default;
+ constexpr ITransientExpression( StreamFn streamFn,
+ bool isBinaryExpression,
+ bool result ):
+ m_streamFn( streamFn ),
+ m_isBinaryExpression( isBinaryExpression ),
+ m_result( result ) {}
- friend std::ostream& operator<<(std::ostream& out, ITransientExpression const& expr) {
- expr.streamReconstructedExpression(out);
+ friend std::ostream& operator<<( std::ostream& out,
+ ITransientExpression const& expr ) {
+ expr.m_streamFn( &expr, out );
return out;
}
};
@@ -5565,87 +5570,67 @@ namespace Catch {
StringRef m_op;
RhsT m_rhs;
- void streamReconstructedExpression( std::ostream &os ) const override {
- formatReconstructedExpression
- ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );
+ static void streamFn( void const* self, std::ostream& out ) {
+ auto const& expr = *static_cast<BinaryExpr const*>(
+ static_cast<ITransientExpression const*>( self ) );
+ formatReconstructedExpression(
+ out,
+ Catch::Detail::stringify( expr.m_lhs ),
+ expr.m_op,
+ Catch::Detail::stringify( expr.m_rhs ) );
}
public:
constexpr BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
- : ITransientExpression{ true, comparisonResult },
+ : ITransientExpression{ &streamFn, true, comparisonResult },
m_lhs( lhs ),
m_op( op ),
m_rhs( rhs )
{}
+ };
- template<typename T>
- auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template<typename T>
- auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {
- static_assert(always_false<T>::value,
- "chained comparisons are not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
-
- template&