File indexing completed on 2025-09-15 08:54:36
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 constexpr
0032 RangeEqualsMatcher( TargetRangeLike2&& range,
0033 Equality2&& predicate ):
0034 m_desired( CATCH_FORWARD( range ) ),
0035 m_predicate( CATCH_FORWARD( predicate ) ) {}
0036
0037 template <typename RangeLike>
0038 constexpr
0039 bool match( RangeLike&& rng ) const {
0040 auto rng_start = begin( rng );
0041 const auto rng_end = end( rng );
0042 auto target_start = begin( m_desired );
0043 const auto target_end = end( m_desired );
0044
0045 while (rng_start != rng_end && target_start != target_end) {
0046 if (!m_predicate(*rng_start, *target_start)) {
0047 return false;
0048 }
0049 ++rng_start;
0050 ++target_start;
0051 }
0052 return rng_start == rng_end && target_start == target_end;
0053 }
0054
0055 std::string describe() const override {
0056 return "elements are " + Catch::Detail::stringify( m_desired );
0057 }
0058 };
0059
0060
0061
0062
0063
0064 template <typename TargetRangeLike, typename Equality>
0065 class UnorderedRangeEqualsMatcher final : public MatcherGenericBase {
0066 TargetRangeLike m_desired;
0067 Equality m_predicate;
0068
0069 public:
0070 template <typename TargetRangeLike2, typename Equality2>
0071 constexpr
0072 UnorderedRangeEqualsMatcher( TargetRangeLike2&& range,
0073 Equality2&& predicate ):
0074 m_desired( CATCH_FORWARD( range ) ),
0075 m_predicate( CATCH_FORWARD( predicate ) ) {}
0076
0077 template <typename RangeLike>
0078 constexpr
0079 bool match( RangeLike&& rng ) const {
0080 using std::begin;
0081 using std::end;
0082 return Catch::Detail::is_permutation( begin( m_desired ),
0083 end( m_desired ),
0084 begin( rng ),
0085 end( rng ),
0086 m_predicate );
0087 }
0088
0089 std::string describe() const override {
0090 return "unordered elements are " +
0091 ::Catch::Detail::stringify( m_desired );
0092 }
0093 };
0094
0095
0096
0097
0098
0099
0100
0101
0102 template <typename RangeLike,
0103 typename Equality = decltype( std::equal_to<>{} )>
0104 constexpr
0105 RangeEqualsMatcher<RangeLike, Equality>
0106 RangeEquals( RangeLike&& range,
0107 Equality&& predicate = std::equal_to<>{} ) {
0108 return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
0109 }
0110
0111
0112
0113
0114
0115
0116
0117
0118 template <typename T,
0119 typename Equality = decltype( std::equal_to<>{} )>
0120 constexpr
0121 RangeEqualsMatcher<std::initializer_list<T>, Equality>
0122 RangeEquals( std::initializer_list<T> range,
0123 Equality&& predicate = std::equal_to<>{} ) {
0124 return { range, CATCH_FORWARD( predicate ) };
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134 template <typename RangeLike,
0135 typename Equality = decltype( std::equal_to<>{} )>
0136 constexpr
0137 UnorderedRangeEqualsMatcher<RangeLike, Equality>
0138 UnorderedRangeEquals( RangeLike&& range,
0139 Equality&& predicate = std::equal_to<>{} ) {
0140 return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
0141 }
0142
0143
0144
0145
0146
0147
0148
0149
0150 template <typename T,
0151 typename Equality = decltype( std::equal_to<>{} )>
0152 constexpr
0153 UnorderedRangeEqualsMatcher<std::initializer_list<T>, Equality>
0154 UnorderedRangeEquals( std::initializer_list<T> range,
0155 Equality&& predicate = std::equal_to<>{} ) {
0156 return { range, CATCH_FORWARD( predicate ) };
0157 }
0158 }
0159 }
0160
0161 #endif