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

summaryrefslogtreecommitdiffhomepage
path: root/extras
diff options
context:
space:
mode:
authorLeitwolf2026-10-11 10:09:19 +0300
committerGitHub2026-10-11 10:09:19 +0300
commitce6fa1996a8e358efdcff53a7628584077d9855c (patch)
treed76f5945311828511e3ea55712487f21fbf8f70f /extras
parent5633c5c98ec073ae938253bcfc72430d5d9aee89 (diff)
parent1f78d8903c2fb18afea8c3055f8df83d8c60d9b5 (diff)
downloadcatch3-ce6fa1996a8e358efdcff53a7628584077d9855c.tar.gz
Merge pull request #4 from Progmasoft/backport/upstream-3.16.1
Backport Catch2 3.16.1
Diffstat (limited to 'extras')
-rw-r--r--extras/catch_amalgamated.cpp96
-rw-r--r--extras/catch_amalgamated.hpp451
2 files changed, 322 insertions, 225 deletions
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<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");
- }
+#define CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( op ) \
+ template <typename LhsT, typename RhsT, typename T> \
+ auto operator op( BinaryExpr<LhsT, RhsT> const&, T ) \
+ ->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");
- }
+ /*
+ * The operators are **intentionally** not hidden friends.
+ *
+ * If they were hidden friends, all of them would get stamped out when
+ * a `BinaryExpr` is instantiated with a new type. In practice, only
+ * few operators are used for each different `BinaryExpr<LhsT, RhsT>`,
+ * so this avoids bunch of wasted work.
+ */
+ CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( && )
+ CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( || )
+ CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( == )
+ CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( != )
+ CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( > )
+ CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( < )
+ CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( >= )
+ CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR( <= )
- 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");
- }
- };
+#undef CATCH_INTERNAL_DEFINE_BINARY_EXPR_OPERATOR
template<typename LhsT>
class UnaryExpr final : public ITransientExpression {
LhsT m_lhs;
- void streamReconstructedExpression( std::ostream &os ) const override {
- os << Catch::Detail::stringify( m_lhs );
+ static void streamFn( void const* self, std::ostream& os ) {
+ auto const& expr = *static_cast<UnaryExpr const*>(
+ static_cast<ITransientExpression const*>( self ) );
+ os << Catch::Detail::stringify( expr.m_lhs );
}
public:
explicit constexpr UnaryExpr( LhsT lhs )
- : ITransientExpression{ false, static_cast<bool>(lhs) },
+ : ITransientExpression{ &streamFn, false, static_cast<bool>(lhs) },
m_lhs( lhs )
{}
};
@@ -5657,153 +5642,186 @@ namespace Catch {
public:
explicit constexpr ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
+ // We rely on reference collapsing if LhsT is already a reference.
+ // Used in the out-of-class decomposition operators
+ constexpr LhsT& getLhs() { return m_lhs; }
+
+ constexpr auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
+ return UnaryExpr<LhsT>{ m_lhs };
+ }
+ };
+
+/*
+ * The comparison operators are **intentionally** not hidden friends.
+ *
+ * If they were hidden friends, all of them would get stamped out when
+ * a `ExprLhs` is instantiated with a new type. In practice, only few
+ * operators are used for each different `ExprLhs<T>`, so this avoids
+ * a lot of wasted work.
+ */
#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
- -> std::enable_if_t< \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT&& rhs ) \
+ ->std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
Detail::negation<capture_by_value< \
Detail::RemoveCVRef_t<RhsT>>>>::value, \
BinaryExpr<LhsT, RhsT const&>> { \
- return { \
- static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
+ return { static_cast<bool>( lhs.getLhs() op rhs ), \
+ lhs.getLhs(), \
+ #op##_sr, \
+ rhs }; \
} \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- -> std::enable_if_t< \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT rhs ) \
+ ->std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
capture_by_value<RhsT>>::value, \
BinaryExpr<LhsT, RhsT>> { \
- return { \
- static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
+ return { static_cast<bool>( lhs.getLhs() op rhs ), \
+ lhs.getLhs(), \
+ #op##_sr, \
+ rhs }; \
} \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- -> std::enable_if_t< \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT rhs ) \
+ ->std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
- Detail::is_eq_0_comparable<LhsT>, \
- /* We allow long because we want `ptr op NULL` to be accepted */ \
+ Detail::is_eq_0_comparable<LhsT>, /* We allow long because we \
+ want `ptr op NULL` to be \
+ accepted */ \
Detail::disjunction<std::is_same<RhsT, int>, \
std::is_same<RhsT, long>>>::value, \
BinaryExpr<LhsT, RhsT>> { \
if ( rhs != 0 ) { throw_test_failure_exception(); } \
- return { \
- static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
+ return { static_cast<bool>( lhs.getLhs() op 0 ), \
+ lhs.getLhs(), \
+ #op##_sr, \
+ rhs }; \
} \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- -> std::enable_if_t< \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT rhs ) \
+ ->std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
- Detail::is_eq_0_comparable<RhsT>, \
- /* We allow long because we want `ptr op NULL` to be accepted */ \
+ Detail::is_eq_0_comparable<RhsT>, /* We allow long because we \
+ want `ptr op NULL` to be \
+ accepted */ \
Detail::disjunction<std::is_same<LhsT, int>, \
std::is_same<LhsT, long>>>::value, \
BinaryExpr<LhsT, RhsT>> { \
- if ( lhs.m_lhs != 0 ) { throw_test_failure_exception(); } \
- return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
+ if ( lhs.getLhs() != 0 ) { throw_test_failure_exception(); } \
+ return { static_cast<bool>( 0 op rhs ), lhs.getLhs(), #op##_sr, rhs }; \
}
- CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
- CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( ne, != )
-
- #undef CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR
+ CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
+ CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( ne, != )
+#undef CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
- -> std::enable_if_t< \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT&& rhs ) \
+ ->std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
Detail::negation<capture_by_value< \
Detail::RemoveCVRef_t<RhsT>>>>::value, \
BinaryExpr<LhsT, RhsT const&>> { \
- return { \
- static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
+ return { static_cast<bool>( lhs.getLhs() op rhs ), \
+ lhs.getLhs(), \
+ #op##_sr, \
+ rhs }; \
} \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- -> std::enable_if_t< \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT rhs ) \
+ ->std::enable_if_t< \
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
capture_by_value<RhsT>>::value, \
BinaryExpr<LhsT, RhsT>> { \
- return { \
- static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
+ return { static_cast<bool>( lhs.getLhs() op rhs ), \
+ lhs.getLhs(), \
+ #op##_sr, \
+ rhs }; \
} \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- -> std::enable_if_t< \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT rhs ) \
+ ->std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_##id##_0_comparable<LhsT>, \
std::is_same<RhsT, int>>::value, \
BinaryExpr<LhsT, RhsT>> { \
if ( rhs != 0 ) { throw_test_failure_exception(); } \
- return { \
- static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
+ return { static_cast<bool>( lhs.getLhs() op 0 ), \
+ lhs.getLhs(), \
+ #op##_sr, \
+ rhs }; \
} \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- -> std::enable_if_t< \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT rhs ) \
+ ->std::enable_if_t< \
Detail::conjunction< \
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
Detail::is_##id##_0_comparable<RhsT>, \
std::is_same<LhsT, int>>::value, \
BinaryExpr<LhsT, RhsT>> { \
- if ( lhs.m_lhs != 0 ) { throw_test_failure_exception(); } \
- return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
+ if ( lhs.getLhs() != 0 ) { throw_test_failure_exception(); } \
+ return { static_cast<bool>( 0 op rhs ), lhs.getLhs(), #op##_sr, rhs }; \
}
- CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( lt, < )
- CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( le, <= )
- CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( gt, > )
- CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( ge, >= )
-
- #undef CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR
-
-
-#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
- -> std::enable_if_t< \
- !capture_by_value<Detail::RemoveCVRef_t<RhsT>>::value, \
- BinaryExpr<LhsT, RhsT const&>> { \
- return { \
- static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
- } \
- template <typename RhsT> \
- constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
- -> std::enable_if_t<capture_by_value<RhsT>::value, \
- BinaryExpr<LhsT, RhsT>> { \
- return { \
- static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
+ CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( lt, < )
+ CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( le, <= )
+ CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( gt, > )
+ CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( ge, >= )
+
+#undef CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR
+
+#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT&& rhs ) \
+ ->std::enable_if_t< \
+ !capture_by_value<Detail::RemoveCVRef_t<RhsT>>::value, \
+ BinaryExpr<LhsT, RhsT const&>> { \
+ return { static_cast<bool>( lhs.getLhs() op rhs ), \
+ lhs.getLhs(), \
+ #op##_sr, \
+ rhs }; \
+ } \
+ template <typename LhsT, typename RhsT> \
+ constexpr auto operator op( ExprLhs<LhsT>&& lhs, RhsT rhs ) \
+ ->std::enable_if_t<capture_by_value<RhsT>::value, \
+ BinaryExpr<LhsT, RhsT>> { \
+ return { static_cast<bool>( lhs.getLhs() op rhs ), \
+ lhs.getLhs(), \
+ #op##_sr, \
+ rhs }; \
}
- CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(|)
- CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(&)
- CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(^)
+ CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( | )
+ CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( & )
+ CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( ^)
- #undef CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR
+#undef CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR
- template<typename RhsT>
- friend auto operator && ( ExprLhs &&, RhsT && ) -> BinaryExpr<LhsT, RhsT const&> {
- static_assert(always_false<RhsT>::value,
+ template <typename LhsT, typename RhsT>
+ auto operator&&( ExprLhs<LhsT>&&, RhsT&& )
+ -> BinaryExpr<LhsT, RhsT const&> {
+ static_assert(
+ always_false<RhsT>::value,
"operator&& is not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
+ "wrap the expression inside parentheses, or decompose it" );
+ }
- template<typename RhsT>
- friend auto operator || ( ExprLhs &&, RhsT && ) -> BinaryExpr<LhsT, RhsT const&> {
- static_assert(always_false<RhsT>::value,
+ template <typename LhsT, typename RhsT>
+ auto operator||( ExprLhs<LhsT>&&, RhsT&& )
+ -> BinaryExpr<LhsT, RhsT const&> {
+ static_assert(
+ always_false<RhsT>::value,
"operator|| is not supported inside assertions, "
- "wrap the expression inside parentheses, or decompose it");
- }
+ "wrap the expression inside parentheses, or decompose it" );
+ }
</