File indexing completed on 2025-01-18 09:54:07
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_MATCHERS_VECTOR_HPP_INCLUDED
0009 #define CATCH_MATCHERS_VECTOR_HPP_INCLUDED
0010
0011 #include <catch2/matchers/catch_matchers.hpp>
0012 #include <catch2/catch_approx.hpp>
0013
0014 #include <algorithm>
0015
0016 namespace Catch {
0017 namespace Matchers {
0018
0019 template<typename T, typename Alloc>
0020 class VectorContainsElementMatcher final : public MatcherBase<std::vector<T, Alloc>> {
0021 T const& m_comparator;
0022
0023 public:
0024 VectorContainsElementMatcher(T const& comparator):
0025 m_comparator(comparator)
0026 {}
0027
0028 bool match(std::vector<T, Alloc> const& v) const override {
0029 for (auto const& el : v) {
0030 if (el == m_comparator) {
0031 return true;
0032 }
0033 }
0034 return false;
0035 }
0036
0037 std::string describe() const override {
0038 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
0039 }
0040 };
0041
0042 template<typename T, typename AllocComp, typename AllocMatch>
0043 class ContainsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
0044 std::vector<T, AllocComp> const& m_comparator;
0045
0046 public:
0047 ContainsMatcher(std::vector<T, AllocComp> const& comparator):
0048 m_comparator( comparator )
0049 {}
0050
0051 bool match(std::vector<T, AllocMatch> const& v) const override {
0052
0053 if (m_comparator.size() > v.size())
0054 return false;
0055 for (auto const& comparator : m_comparator) {
0056 auto present = false;
0057 for (const auto& el : v) {
0058 if (el == comparator) {
0059 present = true;
0060 break;
0061 }
0062 }
0063 if (!present) {
0064 return false;
0065 }
0066 }
0067 return true;
0068 }
0069 std::string describe() const override {
0070 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
0071 }
0072 };
0073
0074 template<typename T, typename AllocComp, typename AllocMatch>
0075 class EqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
0076 std::vector<T, AllocComp> const& m_comparator;
0077
0078 public:
0079 EqualsMatcher(std::vector<T, AllocComp> const& comparator):
0080 m_comparator( comparator )
0081 {}
0082
0083 bool match(std::vector<T, AllocMatch> const& v) const override {
0084
0085
0086
0087
0088 if ( m_comparator.size() != v.size() ) { return false; }
0089 for ( std::size_t i = 0; i < v.size(); ++i ) {
0090 if ( !( m_comparator[i] == v[i] ) ) { return false; }
0091 }
0092 return true;
0093 }
0094 std::string describe() const override {
0095 return "Equals: " + ::Catch::Detail::stringify( m_comparator );
0096 }
0097 };
0098
0099 template<typename T, typename AllocComp, typename AllocMatch>
0100 class ApproxMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
0101 std::vector<T, AllocComp> const& m_comparator;
0102 mutable Catch::Approx approx = Catch::Approx::custom();
0103
0104 public:
0105 ApproxMatcher(std::vector<T, AllocComp> const& comparator):
0106 m_comparator( comparator )
0107 {}
0108
0109 bool match(std::vector<T, AllocMatch> const& v) const override {
0110 if (m_comparator.size() != v.size())
0111 return false;
0112 for (std::size_t i = 0; i < v.size(); ++i)
0113 if (m_comparator[i] != approx(v[i]))
0114 return false;
0115 return true;
0116 }
0117 std::string describe() const override {
0118 return "is approx: " + ::Catch::Detail::stringify( m_comparator );
0119 }
0120 template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
0121 ApproxMatcher& epsilon( T const& newEpsilon ) {
0122 approx.epsilon(static_cast<double>(newEpsilon));
0123 return *this;
0124 }
0125 template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
0126 ApproxMatcher& margin( T const& newMargin ) {
0127 approx.margin(static_cast<double>(newMargin));
0128 return *this;
0129 }
0130 template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
0131 ApproxMatcher& scale( T const& newScale ) {
0132 approx.scale(static_cast<double>(newScale));
0133 return *this;
0134 }
0135 };
0136
0137 template<typename T, typename AllocComp, typename AllocMatch>
0138 class UnorderedEqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
0139 std::vector<T, AllocComp> const& m_target;
0140
0141 public:
0142 UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target):
0143 m_target(target)
0144 {}
0145 bool match(std::vector<T, AllocMatch> const& vec) const override {
0146 if (m_target.size() != vec.size()) {
0147 return false;
0148 }
0149 return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
0150 }
0151
0152 std::string describe() const override {
0153 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
0154 }
0155 };
0156
0157
0158
0159
0160
0161
0162 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
0163 ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
0164 return ContainsMatcher<T, AllocComp, AllocMatch>(comparator);
0165 }
0166
0167
0168 template<typename T, typename Alloc = std::allocator<T>>
0169 VectorContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {
0170 return VectorContainsElementMatcher<T, Alloc>(comparator);
0171 }
0172
0173
0174 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
0175 EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
0176 return EqualsMatcher<T, AllocComp, AllocMatch>(comparator);
0177 }
0178
0179
0180 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
0181 ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
0182 return ApproxMatcher<T, AllocComp, AllocMatch>(comparator);
0183 }
0184
0185
0186 template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
0187 UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {
0188 return UnorderedEqualsMatcher<T, AllocComp, AllocMatch>(target);
0189 }
0190
0191 }
0192 }
0193
0194 #endif