diff options
| author | Leitwolf | 2026-10-11 10:09:19 +0300 |
|---|---|---|
| committer | GitHub | 2026-10-11 10:09:19 +0300 |
| commit | ce6fa1996a8e358efdcff53a7628584077d9855c (patch) | |
| tree | d76f5945311828511e3ea55712487f21fbf8f70f /extras | |
| parent | 5633c5c98ec073ae938253bcfc72430d5d9aee89 (diff) | |
| parent | 1f78d8903c2fb18afea8c3055f8df83d8c60d9b5 (diff) | |
| download | catch3-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.cpp | 96 | ||||
| -rw-r--r-- | extras/catch_amalgamated.hpp | 451 |
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" ); + } |