File indexing completed on 2025-01-18 09:54:07
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
0009 #define CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
0010
0011 #include <catch2/internal/catch_is_permutation.hpp>
0012 #include <catch2/matchers/catch_matchers_templated.hpp>
0013
0014 #include <algorithm>
0015 #include <utility>
0016
0017 namespace Catch {
0018 namespace Matchers {
0019
0020
0021
0022
0023
0024 template <typename TargetRangeLike, typename Equality>
0025 class RangeEqualsMatcher final : public MatcherGenericBase {
0026 TargetRangeLike m_desired;
0027 Equality m_predicate;
0028
0029 public:
0030 template <typename TargetRangeLike2, typename Equality2>
0031 RangeEqualsMatcher( TargetRangeLike2&& range,
0032 Equality2&& predicate ):
0033 m_desired( CATCH_FORWARD( range ) ),
0034 m_predicate( CATCH_FORWARD( predicate ) ) {}
0035
0036 template <typename RangeLike>
0037 bool match( RangeLike&& rng ) const {
0038 auto rng_start = begin( rng );
0039 const auto rng_end = end( rng );
0040 auto target_start = begin( m_desired );
0041 const auto target_end = end( m_desired );
0042
0043 while (rng_start != rng_end && target_start != target_end) {
0044 if (!m_predicate(*rng_start, *target_start)) {
0045 return false;
0046 }
0047 ++rng_start;
0048 ++target_start;
0049 }
0050 return rng_start == rng_end && target_start == target_end;
0051 }
0052
0053 std::string describe() const override {
0054 return "elements are " + Catch::Detail::stringify( m_desired );
0055 }
0056 };
0057
0058
0059
0060
0061
0062 template <typename TargetRangeLike, typename Equality>
0063 class UnorderedRangeEqualsMatcher final : public MatcherGenericBase {
0064 TargetRangeLike m_desired;
0065 Equality m_predicate;
0066
0067 public:
0068 template <typename TargetRangeLike2, typename Equality2>
0069 UnorderedRangeEqualsMatcher( TargetRangeLike2&& range,
0070 Equality2&& predicate ):
0071 m_desired( CATCH_FORWARD( range ) ),
0072 m_predicate( CATCH_FORWARD( predicate ) ) {}
0073
0074 template <typename RangeLike>
0075 bool match( RangeLike&& rng ) const {
0076 using std::begin;
0077 using std::end;
0078 return Catch::Detail::is_permutation( begin( m_desired ),
0079 end( m_desired ),
0080 begin( rng ),
0081 end( rng ),
0082 m_predicate );
0083 }
0084
0085 std::string describe() const override {
0086 return "unordered elements are " +
0087 ::Catch::Detail::stringify( m_desired );
0088 }
0089 };
0090
0091
0092
0093
0094
0095
0096
0097 template <typename RangeLike>
0098 std::enable_if_t<!Detail::is_matcher<RangeLike>::value,
0099 RangeEqualsMatcher<RangeLike, std::equal_to<>>>
0100 RangeEquals( RangeLike&& range ) {
0101 return { CATCH_FORWARD( range ), std::equal_to<>{} };
0102 }
0103
0104
0105
0106
0107
0108
0109
0110 template <typename RangeLike, typename Equality>
0111 RangeEqualsMatcher<RangeLike, Equality>
0112 RangeEquals( RangeLike&& range, Equality&& predicate ) {
0113 return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
0114 }
0115
0116
0117
0118
0119
0120
0121
0122 template <typename RangeLike>
0123 std::enable_if_t<
0124 !Detail::is_matcher<RangeLike>::value,
0125 UnorderedRangeEqualsMatcher<RangeLike, std::equal_to<>>>
0126 UnorderedRangeEquals( RangeLike&& range ) {
0127 return { CATCH_FORWARD( range ), std::equal_to<>{} };
0128 }
0129
0130
0131
0132
0133
0134
0135
0136 template <typename RangeLike, typename Equality>
0137 UnorderedRangeEqualsMatcher<RangeLike, Equality>
0138 UnorderedRangeEquals( RangeLike&& range, Equality&& predicate ) {
0139 return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
0140 }
0141 }
0142 }
0143
0144 #endif