File indexing completed on 2025-01-18 09:54:07
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_MATCHERS_HPP_INCLUDED
0009 #define CATCH_MATCHERS_HPP_INCLUDED
0010
0011 #include <catch2/matchers/internal/catch_matchers_impl.hpp>
0012 #include <catch2/internal/catch_move_and_forward.hpp>
0013
0014 #include <string>
0015 #include <vector>
0016
0017 namespace Catch {
0018 namespace Matchers {
0019
0020 class MatcherUntypedBase {
0021 public:
0022 MatcherUntypedBase() = default;
0023
0024 MatcherUntypedBase(MatcherUntypedBase const&) = default;
0025 MatcherUntypedBase(MatcherUntypedBase&&) = default;
0026
0027 MatcherUntypedBase& operator = (MatcherUntypedBase const&) = delete;
0028 MatcherUntypedBase& operator = (MatcherUntypedBase&&) = delete;
0029
0030 std::string toString() const;
0031
0032 protected:
0033 virtual ~MatcherUntypedBase();
0034 virtual std::string describe() const = 0;
0035 mutable std::string m_cachedToString;
0036 };
0037
0038
0039 template<typename T>
0040 class MatcherBase : public MatcherUntypedBase {
0041 public:
0042 virtual bool match( T const& arg ) const = 0;
0043 };
0044
0045 namespace Detail {
0046
0047 template<typename ArgT>
0048 class MatchAllOf final : public MatcherBase<ArgT> {
0049 std::vector<MatcherBase<ArgT> const*> m_matchers;
0050
0051 public:
0052 MatchAllOf() = default;
0053 MatchAllOf(MatchAllOf const&) = delete;
0054 MatchAllOf& operator=(MatchAllOf const&) = delete;
0055 MatchAllOf(MatchAllOf&&) = default;
0056 MatchAllOf& operator=(MatchAllOf&&) = default;
0057
0058
0059 bool match( ArgT const& arg ) const override {
0060 for( auto matcher : m_matchers ) {
0061 if (!matcher->match(arg))
0062 return false;
0063 }
0064 return true;
0065 }
0066 std::string describe() const override {
0067 std::string description;
0068 description.reserve( 4 + m_matchers.size()*32 );
0069 description += "( ";
0070 bool first = true;
0071 for( auto matcher : m_matchers ) {
0072 if( first )
0073 first = false;
0074 else
0075 description += " and ";
0076 description += matcher->toString();
0077 }
0078 description += " )";
0079 return description;
0080 }
0081
0082 friend MatchAllOf operator&& (MatchAllOf&& lhs, MatcherBase<ArgT> const& rhs) {
0083 lhs.m_matchers.push_back(&rhs);
0084 return CATCH_MOVE(lhs);
0085 }
0086 friend MatchAllOf operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf&& rhs) {
0087 rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
0088 return CATCH_MOVE(rhs);
0089 }
0090 };
0091
0092
0093
0094 template<typename ArgT>
0095 MatchAllOf<ArgT> operator&& (MatchAllOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
0096
0097
0098 template<typename ArgT>
0099 MatchAllOf<ArgT> operator&& (MatcherBase<ArgT> const& lhs, MatchAllOf<ArgT> const& rhs) = delete;
0100
0101 template<typename ArgT>
0102 class MatchAnyOf final : public MatcherBase<ArgT> {
0103 std::vector<MatcherBase<ArgT> const*> m_matchers;
0104 public:
0105 MatchAnyOf() = default;
0106 MatchAnyOf(MatchAnyOf const&) = delete;
0107 MatchAnyOf& operator=(MatchAnyOf const&) = delete;
0108 MatchAnyOf(MatchAnyOf&&) = default;
0109 MatchAnyOf& operator=(MatchAnyOf&&) = default;
0110
0111 bool match( ArgT const& arg ) const override {
0112 for( auto matcher : m_matchers ) {
0113 if (matcher->match(arg))
0114 return true;
0115 }
0116 return false;
0117 }
0118 std::string describe() const override {
0119 std::string description;
0120 description.reserve( 4 + m_matchers.size()*32 );
0121 description += "( ";
0122 bool first = true;
0123 for( auto matcher : m_matchers ) {
0124 if( first )
0125 first = false;
0126 else
0127 description += " or ";
0128 description += matcher->toString();
0129 }
0130 description += " )";
0131 return description;
0132 }
0133
0134 friend MatchAnyOf operator|| (MatchAnyOf&& lhs, MatcherBase<ArgT> const& rhs) {
0135 lhs.m_matchers.push_back(&rhs);
0136 return CATCH_MOVE(lhs);
0137 }
0138 friend MatchAnyOf operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf&& rhs) {
0139 rhs.m_matchers.insert(rhs.m_matchers.begin(), &lhs);
0140 return CATCH_MOVE(rhs);
0141 }
0142 };
0143
0144
0145
0146 template<typename ArgT>
0147 MatchAnyOf<ArgT> operator|| (MatchAnyOf<ArgT> const& lhs, MatcherBase<ArgT> const& rhs) = delete;
0148
0149
0150 template<typename ArgT>
0151 MatchAnyOf<ArgT> operator|| (MatcherBase<ArgT> const& lhs, MatchAnyOf<ArgT> const& rhs) = delete;
0152
0153 template<typename ArgT>
0154 class MatchNotOf final : public MatcherBase<ArgT> {
0155 MatcherBase<ArgT> const& m_underlyingMatcher;
0156
0157 public:
0158 explicit MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ):
0159 m_underlyingMatcher( underlyingMatcher )
0160 {}
0161
0162 bool match( ArgT const& arg ) const override {
0163 return !m_underlyingMatcher.match( arg );
0164 }
0165
0166 std::string describe() const override {
0167 return "not " + m_underlyingMatcher.toString();
0168 }
0169 };
0170
0171 }
0172
0173 template <typename T>
0174 Detail::MatchAllOf<T> operator&& (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
0175 return Detail::MatchAllOf<T>{} && lhs && rhs;
0176 }
0177 template <typename T>
0178 Detail::MatchAnyOf<T> operator|| (MatcherBase<T> const& lhs, MatcherBase<T> const& rhs) {
0179 return Detail::MatchAnyOf<T>{} || lhs || rhs;
0180 }
0181
0182 template <typename T>
0183 Detail::MatchNotOf<T> operator! (MatcherBase<T> const& matcher) {
0184 return Detail::MatchNotOf<T>{ matcher };
0185 }
0186
0187
0188 }
0189 }
0190
0191
0192 #if defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
0193 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
0194 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
0195
0196 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
0197 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
0198
0199 #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
0200 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
0201
0202 #elif defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
0203
0204 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
0205 #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
0206
0207 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0)
0208 #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
0209
0210 #define CATCH_CHECK_THAT( arg, matcher ) (void)(0)
0211 #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)
0212
0213 #elif !defined(CATCH_CONFIG_PREFIX_ALL) && !defined(CATCH_CONFIG_DISABLE)
0214
0215 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
0216 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )
0217
0218 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
0219 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
0220
0221 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
0222 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
0223
0224 #elif !defined(CATCH_CONFIG_PREFIX_ALL) && defined(CATCH_CONFIG_DISABLE)
0225
0226 #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)
0227 #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
0228
0229 #define CHECK_THROWS_WITH( expr, matcher ) (void)(0)
0230 #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)
0231
0232 #define CHECK_THAT( arg, matcher ) (void)(0)
0233 #define REQUIRE_THAT( arg, matcher ) (void)(0)
0234
0235 #endif
0236
0237 #endif