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

summaryrefslogtreecommitdiffhomepage
path: root/extras/catch_amalgamated.hpp
diff options
context:
space:
mode:
authorMartin Hořeňovský2023-01-22 19:43:11 +0100
committerMartin Hořeňovský2023-01-22 19:53:12 +0100
commitc837cb4a8aaa2064f63e67ed0a7f7055dbf159c5 (patch)
tree2df4e0575eed9d5555b2992a465c5b69630c6830 /extras/catch_amalgamated.hpp
parent8359a6b244a26cffabd4440b17fac8b1392815af (diff)
downloadcatch3-3.3.0.tar.gz
v3.3.0v3.3.0
Diffstat (limited to 'extras/catch_amalgamated.hpp')
-rw-r--r--extras/catch_amalgamated.hpp481
1 files changed, 350 insertions, 131 deletions
diff --git a/extras/catch_amalgamated.hpp b/extras/catch_amalgamated.hpp
index e91734a4..25928e4e 100644
--- a/extras/catch_amalgamated.hpp
+++ b/extras/catch_amalgamated.hpp
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: BSL-1.0
-// Catch v3.2.1
-// Generated: 2022-12-09 23:01:14.526666
+// Catch v3.3.0
+// Generated: 2023-01-22 19:46:23.163056
// ----------------------------------------------------------
// This file is an amalgamation of multiple different files.
// You probably shouldn't edit it directly.
@@ -372,9 +372,14 @@ namespace Catch {
#endif
#if defined(__CUDACC__) && !defined(__clang__)
+# ifdef __NVCC_DIAG_PRAGMA_SUPPORT__
+// New pragmas introduced in CUDA 11.5+
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "nv_diagnostic pop" )
# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "nv_diag_suppress 177" )
+# else
+# define CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS _Pragma( "diag_suppress 177" )
+# endif
#endif
// clang-cl defines _MSC_VER as well as __clang__, which could cause the
@@ -492,8 +497,14 @@ namespace Catch {
// Visual C++
#if defined(_MSC_VER)
-# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
-# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
+// We want to defer to nvcc-specific warning suppression if we are compiled
+// with nvcc masquerading for MSVC.
+# if !defined( __CUDACC__ )
+# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ __pragma( warning( push ) )
+# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ __pragma( warning( pop ) )
+# endif
// Universal Windows platform does not support SEH
// Or console colours (or console at all...)
@@ -850,6 +861,7 @@ namespace Catch {
std::uint64_t passed = 0;
std::uint64_t failed = 0;
std::uint64_t failedButOk = 0;
+ std::uint64_t skipped = 0;
};
struct Totals {
@@ -916,6 +928,8 @@ namespace Catch {
Ok = 0,
Info = 1,
Warning = 2,
+ // TODO: Should explicit skip be considered "not OK" (cf. isOk)? I.e., should it have the failure bit?
+ ExplicitSkip = 4,
FailureBit = 0x10,
@@ -1062,116 +1076,6 @@ namespace Catch {
#include <chrono>
-namespace Catch {
-
- class AssertionResult;
- struct AssertionInfo;
- struct SectionInfo;
- struct SectionEndInfo;
- struct MessageInfo;
- struct MessageBuilder;
- struct Counts;
- struct AssertionReaction;
- struct SourceLineInfo;
-
- class ITransientExpression;
- class IGeneratorTracker;
-
- struct BenchmarkInfo;
- template <typename Duration = std::chrono::duration<double, std::nano>>
- struct BenchmarkStats;
-
- class IResultCapture {
- public:
- virtual ~IResultCapture();
-
- virtual bool sectionStarted( SectionInfo const& sectionInfo,
- Counts& assertions ) = 0;
- virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
- virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
-
- virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
-
- virtual void benchmarkPreparing( StringRef name ) = 0;
- virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
- virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
- virtual void benchmarkFailed( StringRef error ) = 0;
-
- virtual void pushScopedMessage( MessageInfo const& message ) = 0;
- virtual void popScopedMessage( MessageInfo const& message ) = 0;
-
- virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
-
- virtual void handleFatalErrorCondition( StringRef message ) = 0;
-
- virtual void handleExpr
- ( AssertionInfo const& info,
- ITransientExpression const& expr,
- AssertionReaction& reaction ) = 0;
- virtual void handleMessage
- ( AssertionInfo const& info,
- ResultWas::OfType resultType,
- StringRef message,
- AssertionReaction& reaction ) = 0;
- virtual void handleUnexpectedExceptionNotThrown
- ( AssertionInfo const& info,
- AssertionReaction& reaction ) = 0;
- virtual void handleUnexpectedInflightException
- ( AssertionInfo const& info,
- std::string const& message,
- AssertionReaction& reaction ) = 0;
- virtual void handleIncomplete
- ( AssertionInfo const& info ) = 0;
- virtual void handleNonExpr
- ( AssertionInfo const &info,
- ResultWas::OfType resultType,
- AssertionReaction &reaction ) = 0;
-
-
-
- virtual bool lastAssertionPassed() = 0;
- virtual void assertionPassed() = 0;
-
- // Deprecated, do not use:
- virtual std::string getCurrentTestName() const = 0;
- virtual const AssertionResult* getLastResult() const = 0;
- virtual void exceptionEarlyReported() = 0;
- };
-
- IResultCapture& getResultCapture();
-}
-
-#endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
-
-#include <string>
-
-namespace Catch {
-
- struct MessageInfo {
- MessageInfo( StringRef _macroName,
- SourceLineInfo const& _lineInfo,
- ResultWas::OfType _type );
-
- StringRef macroName;
- std::string message;
- SourceLineInfo lineInfo;
- ResultWas::OfType type;
- unsigned int sequence;
-
- bool operator == (MessageInfo const& other) const {
- return sequence == other.sequence;
- }
- bool operator < (MessageInfo const& other) const {
- return sequence < other.sequence;
- }
- private:
- static unsigned int globalCount;
- };
-
-} // end namespace Catch
-
-#endif // CATCH_MESSAGE_INFO_HPP_INCLUDED
-
#ifndef CATCH_UNIQUE_PTR_HPP_INCLUDED
#define CATCH_UNIQUE_PTR_HPP_INCLUDED
@@ -1284,6 +1188,128 @@ namespace Detail {
#endif // CATCH_UNIQUE_PTR_HPP_INCLUDED
+namespace Catch {
+
+ class AssertionResult;
+ struct AssertionInfo;
+ struct SectionInfo;
+ struct SectionEndInfo;
+ struct MessageInfo;
+ struct MessageBuilder;
+ struct Counts;
+ struct AssertionReaction;
+ struct SourceLineInfo;
+
+ class ITransientExpression;
+ class IGeneratorTracker;
+
+ struct BenchmarkInfo;
+ template <typename Duration = std::chrono::duration<double, std::nano>>
+ struct BenchmarkStats;
+
+ namespace Generators {
+ class GeneratorUntypedBase;
+ using GeneratorBasePtr = Catch::Detail::unique_ptr<GeneratorUntypedBase>;
+ }
+
+
+ class IResultCapture {
+ public:
+ virtual ~IResultCapture();
+
+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
+ Counts& assertions ) = 0;
+ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
+
+ virtual IGeneratorTracker*
+ acquireGeneratorTracker( StringRef generatorName,
+ SourceLineInfo const& lineInfo ) = 0;
+ virtual IGeneratorTracker*
+ createGeneratorTracker( StringRef generatorName,
+ SourceLineInfo lineInfo,
+ Generators::GeneratorBasePtr&& generator ) = 0;
+
+ virtual void benchmarkPreparing( StringRef name ) = 0;
+ virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
+ virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;
+ virtual void benchmarkFailed( StringRef error ) = 0;
+
+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+ virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
+
+ virtual void handleFatalErrorCondition( StringRef message ) = 0;
+
+ virtual void handleExpr
+ ( AssertionInfo const& info,
+ ITransientExpression const& expr,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleMessage
+ ( AssertionInfo const& info,
+ ResultWas::OfType resultType,
+ StringRef message,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleUnexpectedExceptionNotThrown
+ ( AssertionInfo const& info,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleUnexpectedInflightException
+ ( AssertionInfo const& info,
+ std::string const& message,
+ AssertionReaction& reaction ) = 0;
+ virtual void handleIncomplete
+ ( AssertionInfo const& info ) = 0;
+ virtual void handleNonExpr
+ ( AssertionInfo const &info,
+ ResultWas::OfType resultType,
+ AssertionReaction &reaction ) = 0;
+
+
+
+ virtual bool lastAssertionPassed() = 0;
+ virtual void assertionPassed() = 0;
+
+ // Deprecated, do not use:
+ virtual std::string getCurrentTestName() const = 0;
+ virtual const AssertionResult* getLastResult() const = 0;
+ virtual void exceptionEarlyReported() = 0;
+ };
+
+ IResultCapture& getResultCapture();
+}
+
+#endif // CATCH_INTERFACES_CAPTURE_HPP_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct MessageInfo {
+ MessageInfo( StringRef _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type );
+
+ StringRef macroName;
+ std::string message;
+ SourceLineInfo lineInfo;
+ ResultWas::OfType type;
+ unsigned int sequence;
+
+ bool operator == (MessageInfo const& other) const {
+ return sequence == other.sequence;
+ }
+ bool operator < (MessageInfo const& other) const {
+ return sequence < other.sequence;
+ }
+ private:
+ static unsigned int globalCount;
+ };
+
+} // end namespace Catch
+
+#endif // CATCH_MESSAGE_INFO_HPP_INCLUDED
+
// Adapted from donated nonius code.
@@ -1557,7 +1583,12 @@ namespace Catch {
*/
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
- //! Called with test cases that are skipped due to the test run aborting
+ /**
+ * Called with test cases that are skipped due to the test run aborting.
+ * NOT called for test cases that are explicitly skipped using the `SKIP` macro.
+ *
+ * Deprecated - will be removed in the next major release.
+ */
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
//! Called if a fatal error (signal/structured exception) occured
@@ -1748,6 +1779,9 @@ namespace Catch {
*/
[[noreturn]] void throw_test_failure_exception();
+ //! Used to signal that the remainder of a test should be skipped
+ struct TestSkipException{};
+
} // namespace Catch
#endif // CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
@@ -4058,6 +4092,7 @@ namespace Catch {
Error = BrightRed,
Success = Green,
+ Skip = LightGrey,
OriginalExpression = Cyan,
ReconstructedExpression = BrightYellow,
@@ -5811,6 +5846,7 @@ namespace Catch {
struct AssertionReaction {
bool shouldDebugBreak = false;
bool shouldThrow = false;
+ bool shouldSkip = false;
};
class AssertionHandler {
@@ -6183,7 +6219,7 @@ struct AutoReg : Detail::NonCopyable {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ namespace{ const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
@@ -6194,7 +6230,7 @@ struct AutoReg : Detail::NonCopyable {
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
- namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+ namespace{ const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
///////////////////////////////////////////////////////////////////////////////
@@ -6206,7 +6242,7 @@ struct AutoReg : Detail::NonCopyable {
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
void test(); \
}; \
- Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+ const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
void TestName::test()
@@ -6260,6 +6296,7 @@ struct AutoReg : Detail::NonCopyable {
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+ #define CATCH_SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
@@ -6313,6 +6350,7 @@ struct AutoReg : Detail::NonCopyable {
#define CATCH_FAIL( ... ) (void)(0)
#define CATCH_FAIL_CHECK( ... ) (void)(0)
#define CATCH_SUCCEED( ... ) (void)(0)
+ #define CATCH_SKIP( ... ) (void)(0)
#define CATCH_STATIC_REQUIRE( ... ) (void)(0)
#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
@@ -6357,6 +6395,7 @@ struct AutoReg : Detail::NonCopyable {
#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+ #define SKIP( ... ) INTERNAL_CATCH_MSG( "SKIP", Catch::ResultWas::ExplicitSkip, Catch::ResultDisposition::Normal, __VA_ARGS__ )
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
@@ -6409,6 +6448,7 @@ struct AutoReg : Detail::NonCopyable {
#define FAIL( ... ) (void)(0)
#define FAIL_CHECK( ... ) (void)(0)
#define SUCCEED( ... ) (void)(0)
+ #define SKIP( ... ) (void)(0)
#define STATIC_REQUIRE( ... ) (void)(0)
#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
@@ -7098,6 +7138,7 @@ struct AutoReg : Detail::NonCopyable {
+#include <cstdint>
#include <string>
#include <vector>
@@ -7357,8 +7398,8 @@ namespace Catch {
#define CATCH_VERSION_MACROS_HPP_INCLUDED
#define CATCH_VERSION_MAJOR 3
-#define CATCH_VERSION_MINOR 2
-#define CATCH_VERSION_PATCH 1
+#define CATCH_VERSION_MINOR 3
+#define CATCH_VERSION_PATCH 0
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
@@ -7682,21 +7723,28 @@ namespace Detail {
return makeGenerators( value( T( CATCH_FORWARD( val ) ) ), CATCH_FORWARD( moreGenerators )... );
}
- auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
+ IGeneratorTracker* acquireGeneratorTracker( StringRef generatorName,
+ SourceLineInfo const& lineInfo );
+ IGeneratorTracker* createGeneratorTracker( StringRef generatorName,
+ SourceLineInfo lineInfo,
+ GeneratorBasePtr&& generator );
template<typename L>
- // Note: The type after -> is weird, because VS2015 cannot parse
- // the expression used in the typedef inside, when it is in
- // return type. Yeah.
- auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
+ auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> typename decltype(generatorExpression())::type {
using UnderlyingType = typename decltype(generatorExpression())::type;
- IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
- if (!tracker.hasGenerator()) {
- tracker.setGenerator(Catch::Detail::make_unique<Generators<UnderlyingType>>(generatorExpression()));
+ IGeneratorTracker* tracker = acquireGeneratorTracker( generatorName, lineInfo );
+ // Creation of tracker is delayed after generator creation, so
+ // that constructing generator can fail without breaking everything.
+ if (!tracker) {
+ tracker = createGeneratorTracker(
+ generatorName,
+ lineInfo,
+ Catch::Detail::make_unique<Generators<UnderlyingType>>(
+ generatorExpression() ) );
}
- auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );
+ auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker->getGenerator() );
return generator.get();
}
@@ -8515,7 +8563,10 @@ namespace Catch {
#if defined(__i386__) || defined(__x86_64__)
#define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
#elif defined(__aarch64__)
- #define CATCH_TRAP() __asm__(".inst 0xd43e0000")
+ #define CATCH_TRAP() __asm__(".inst 0xd43e0000")
+ #elif defined(__POWERPC__)
+ #define CATCH_TRAP() __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
+ : : : "memory","r0","r3","r4" ) /* NOLINT */
#endif
#elif defined(CATCH_PLATFORM_IPHONE)
@@ -9148,6 +9199,10 @@ namespace TestCaseTracking {
return lhs.name == rhs.name
&& lhs.location == rhs.location;
}
+ friend bool operator!=(NameAndLocation const& lhs,
+ NameAndLocation const& rhs) {
+ return !( lhs == rhs );
+ }
};
class ITracker;
@@ -9370,7 +9425,14 @@ namespace Catch {
void sectionEnded( SectionEndInfo const& endInfo ) override;
void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
- auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
+ IGeneratorTracker*
+ acquireGeneratorTracker( StringRef generatorName,
+ SourceLineInfo const& lineInfo ) override;
+ IGeneratorTracker* createGeneratorTracker(
+ StringRef generatorName,
+ SourceLineInfo lineInfo,
+ Generators::GeneratorBasePtr&& generator ) override;
+
void benchmarkPreparing( StringRef name ) override;
void benchmarkStarting( BenchmarkInfo const& info ) override;
@@ -9568,6 +9630,7 @@ namespace Catch {
#define CATCH_STRING_MANIP_HPP_INCLUDED
+#include <cstdint>
#include <string>
#include <iosfwd>
#include <vector>
@@ -10960,6 +11023,32 @@ public:
//! Creates a matcher that checks whether a std derived exception has the provided message
ExceptionMessageMatcher Message(std::string const& message);
+template <typename StringMatcherType>
+class ExceptionMessageMatchesMatcher final
+ : public MatcherBase<std::exception> {
+ StringMatcherType m_matcher;
+
+public:
+ ExceptionMessageMatchesMatcher( StringMatcherType matcher ):
+ m_matcher( CATCH_MOVE( matcher ) ) {}
+
+ bool match( std::exception const& ex ) const override {
+ return m_matcher.match( ex.what() );
+ }
+
+ std::string describe() const override {
+ return " matches \"" + m_matcher.describe() + '"';
+ }
+};
+
+//! Creates a matcher that checks whether a message from an std derived
+//! exception matches a provided matcher
+template <typename StringMatcherType>
+ExceptionMessageMatchesMatcher<StringMatcherType>
+MessageMatches( StringMatcherType&& matcher ) {
+ return { CATCH_FORWARD( matcher ) };
+}
+
} // namespace Matchers
} // namespace Catch
@@ -11247,6 +11336,136 @@ namespace Catch {
#endif // CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED
+#ifndef CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
+#define CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
+
+#include <algorithm>
+#include <utility>
+
+namespace Catch {
+ namespace Matchers {
+
+ /**
+ * Matcher for checking that an element contains the same
+ * elements in the same order
+ */
+ template <typename TargetRangeLike, typename Equality>
+ class RangeEqualsMatcher final : public MatcherGenericBase {
+ TargetRangeLike m_desired;
+ Equality m_predicate;
+
+ public:
+ template <typename TargetRangeLike2, typename Equality2>
+ RangeEqualsMatcher( TargetRangeLike2&& range,
+ Equality2&& predicate ):
+ m_desired( CATCH_FORWARD( range ) ),
+ m_predicate( CATCH_FORWARD( predicate ) ) {}
+
+ template <typename RangeLike>
+ bool match( RangeLike&& rng ) const {
+ using std::begin;
+ using std::end;
+ return std::equal( begin(m_desired),
+ end(m_desired),
+ begin(rng),
+ end(rng),
+ m_predicate );
+ }
+
+ std::string describe() const override {
+ return "elements are " + Catch::Detail::stringify( m_desired );
+ }
+ };
+
+ /**
+ * Matcher for checking that an element contains the same
+ * elements (but not necessarily in the same order)
+ */
+ template <typename TargetRangeLike, typename Equality>
+ class UnorderedRangeEqualsMatcher final : public MatcherGenericBase {
+ TargetRangeLike m_desired;
+ Equality m_predicate;
+
+ public:
+ template <typename TargetRangeLike2, typename Equality2>
+ UnorderedRangeEqualsMatcher( TargetRangeLike2&& range,
+ Equality2&& predicate ):
+ m_desired( CATCH_FORWARD( range ) ),
+ m_predicate( CATCH_FORWARD( predicate ) ) {}
+
+ template <typename RangeLike>
+ bool match( RangeLike&& rng ) const {
+ using std::begin;
+ using std::end;
+ return std::is_permutation( begin( m_desired ),
+ end( m_desired ),
+ begin( rng ),
+ end( rng ),
+ m_predicate );
+ }
+
+ std::string describe() const override {
+ return "unordered elements are " +
+ ::Catch::Detail::stringify( m_desired );
+ }
+ };
+
+ /**
+ * Creates a matcher that checks if all elements in a range are equal
+ * to all elements in another range.
+ *
+ * Uses `std::equal_to` to do the comparison
+ */
+ template <typename RangeLike>
+ std::enable_if_t<!Detail::is_matcher<RangeLike>::value,
+ RangeEqualsMatcher<RangeLike, std::equal_to<>>>
+ RangeEquals( RangeLike&& range ) {
+ return { CATCH_FORWARD( range ), std::equal_to<>{} };
+ }
+
+ /**
+ * Creates a matcher that checks if all elements in a range are equal
+ * to all elements in another range.
+ *
+ * Uses to provided predicate `predicate` to do the comparisons
+ */
+ template <typename RangeLike, typename Equality>
+ RangeEqualsMatcher<RangeLike, Equality>
+ RangeEquals( RangeLike&& range, Equality&& predicate ) {
+ return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
+ }
+
+ /**
+ * Creates a matcher that checks if all elements in a range are equal
+ * to all elements in another range, in some permutation
+ *
+ * Uses `std::equal_to` to do the comparison
+ */
+ template <typename RangeLike>
+ std::enable_if_t<
+ !Detail::is_matcher<RangeLike>::value,
+ UnorderedRangeEqualsMatcher<RangeLike, std::equal_to<>>>
+ UnorderedRangeEquals( RangeLike&& range ) {
+ return { CATCH_FORWARD( range ), std::equal_to<>{} };
+ }
+
+ /**
+ * Creates a matcher that checks if all elements in a range are equal
+ * to all elements in another range, in some permuation.
+ *
+ * Uses to provided predicate `predicate` to do the comparisons
+ */
+ template <typename RangeLike, typename Equality>
+ UnorderedRangeEqualsMatcher<RangeLike, Equality>
+ UnorderedRangeEquals( RangeLike&& range, Equality&& predicate ) {
+ return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
+ }
+ } // namespace Matchers
+} // namespace Catch
+
+#endif // CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
+
+
#ifndef CATCH_MATCHERS_STRING_HPP_INCLUDED
#define CATCH_MATCHERS_STRING_HPP_INCLUDED